]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/rs6000/rs6000.c
Merge basic-improvements-branch to trunk
[thirdparty/gcc.git] / gcc / config / rs6000 / rs6000.c
CommitLineData
9878760c 1/* Subroutines used for code generation on IBM RS/6000.
9ebbca7d 2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
95385cbb 3 2000, 2001, 2002 Free Software Foundation, Inc.
fab3bcc3 4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
9878760c
RK
5
6This file is part of GNU CC.
7
8GNU CC is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2, or (at your option)
11any later version.
12
13GNU CC is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GNU CC; see the file COPYING. If not, write to
c15c9075
RK
20the Free Software Foundation, 59 Temple Place - Suite 330,
21Boston, MA 02111-1307, USA. */
9878760c 22
956d6950 23#include "config.h"
c4d38ccb 24#include "system.h"
4977bab6
ZW
25#include "coretypes.h"
26#include "tm.h"
9878760c
RK
27#include "rtl.h"
28#include "regs.h"
29#include "hard-reg-set.h"
30#include "real.h"
31#include "insn-config.h"
32#include "conditions.h"
9878760c
RK
33#include "insn-attr.h"
34#include "flags.h"
35#include "recog.h"
9878760c 36#include "obstack.h"
9b30bae2 37#include "tree.h"
dfafc897 38#include "expr.h"
2fc1c679 39#include "optabs.h"
2a430ec1 40#include "except.h"
a7df97e6 41#include "function.h"
296b8152 42#include "output.h"
d5fa86ba 43#include "basic-block.h"
d0101753 44#include "integrate.h"
296b8152 45#include "toplev.h"
c8023011 46#include "ggc.h"
9ebbca7d
GK
47#include "hashtab.h"
48#include "tm_p.h"
672a6f42
NB
49#include "target.h"
50#include "target-def.h"
3ac88239 51#include "langhooks.h"
24ea750e 52#include "reload.h"
9b30bae2 53
7509c759
MM
54#ifndef TARGET_NO_PROTOTYPE
55#define TARGET_NO_PROTOTYPE 0
56#endif
57
9878760c
RK
58#define min(A,B) ((A) < (B) ? (A) : (B))
59#define max(A,B) ((A) > (B) ? (A) : (B))
60
5248c961
RK
61/* Target cpu type */
62
63enum processor_type rs6000_cpu;
8e3f41e7
MM
64struct rs6000_cpu_select rs6000_select[3] =
65{
815cdc52
MM
66 /* switch name, tune arch */
67 { (const char *)0, "--with-cpu=", 1, 1 },
68 { (const char *)0, "-mcpu=", 1, 1 },
69 { (const char *)0, "-mtune=", 1, 0 },
8e3f41e7 70};
5248c961 71
6fa3f289
ZW
72/* Size of long double */
73const char *rs6000_long_double_size_string;
74int rs6000_long_double_type_size;
75
76/* Whether -mabi=altivec has appeared */
77int rs6000_altivec_abi;
78
08b57fb3
AH
79/* Whether VRSAVE instructions should be generated. */
80int rs6000_altivec_vrsave;
81
82/* String from -mvrsave= option. */
83const char *rs6000_altivec_vrsave_string;
84
a3170dc6
AH
85/* Nonzero if we want SPE ABI extensions. */
86int rs6000_spe_abi;
87
88/* Whether isel instructions should be generated. */
89int rs6000_isel;
90
91/* Nonzero if we have FPRs. */
92int rs6000_fprs = 1;
93
94/* String from -misel=. */
95const char *rs6000_isel_string;
96
a0ab749a 97/* Set to nonzero once AIX common-mode calls have been defined. */
c764f757 98static int common_mode_defined;
c81bebd7 99
0e5dbd9b
DE
100/* Private copy of original value of flag_pic for ABI_AIX. */
101static int rs6000_flag_pic;
102
9878760c
RK
103/* Save information from a "cmpxx" operation until the branch or scc is
104 emitted. */
9878760c
RK
105rtx rs6000_compare_op0, rs6000_compare_op1;
106int rs6000_compare_fp_p;
874a0744 107
874a0744
MM
108/* Label number of label created for -mrelocatable, to call to so we can
109 get the address of the GOT section */
110int rs6000_pic_labelno;
c81bebd7 111
b91da81f 112#ifdef USING_ELFOS_H
c81bebd7 113/* Which abi to adhere to */
815cdc52 114const char *rs6000_abi_name = RS6000_ABI_NAME;
d9407988
MM
115
116/* Semantics of the small data area */
117enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
118
119/* Which small data model to use */
815cdc52 120const char *rs6000_sdata_name = (char *)0;
9ebbca7d
GK
121
122/* Counter for labels which are to be placed in .fixup. */
123int fixuplabelno = 0;
874a0744 124#endif
4697a36c 125
b6c9286a
MM
126/* ABI enumeration available for subtarget to use. */
127enum rs6000_abi rs6000_current_abi;
128
0ac081f6
AH
129/* ABI string from -mabi= option. */
130const char *rs6000_abi_string;
131
38c1f2d7 132/* Debug flags */
815cdc52 133const char *rs6000_debug_name;
38c1f2d7
MM
134int rs6000_debug_stack; /* debug stack applications */
135int rs6000_debug_arg; /* debug argument handling */
136
57ac7be9
AM
137const char *rs6000_traceback_name;
138static enum {
139 traceback_default = 0,
140 traceback_none,
141 traceback_part,
142 traceback_full
143} rs6000_traceback;
144
38c1f2d7
MM
145/* Flag to say the TOC is initialized */
146int toc_initialized;
9ebbca7d 147char toc_label_name[10];
38c1f2d7 148
9ebbca7d
GK
149/* Alias set for saves and restores from the rs6000 stack. */
150static int rs6000_sr_alias_set;
c8023011 151
a5c76ee6
ZW
152/* Call distance, overridden by -mlongcall and #pragma longcall(1).
153 The only place that looks at this is rs6000_set_default_type_attributes;
154 everywhere else should rely on the presence or absence of a longcall
155 attribute on the function declaration. */
156int rs6000_default_long_calls;
157const char *rs6000_longcall_switch;
158
a3170dc6
AH
159struct builtin_description
160{
161 /* mask is not const because we're going to alter it below. This
162 nonsense will go away when we rewrite the -march infrastructure
163 to give us more target flag bits. */
164 unsigned int mask;
165 const enum insn_code icode;
166 const char *const name;
167 const enum rs6000_builtins code;
168};
169
4977bab6 170static bool rs6000_function_ok_for_sibcall PARAMS ((tree, tree));
9ebbca7d
GK
171static void rs6000_add_gc_roots PARAMS ((void));
172static int num_insns_constant_wide PARAMS ((HOST_WIDE_INT));
39a10a29
GK
173static void validate_condition_mode
174 PARAMS ((enum rtx_code, enum machine_mode));
175static rtx rs6000_generate_compare PARAMS ((enum rtx_code));
e50f5f3d 176static void rs6000_maybe_dead PARAMS ((rtx));
9ebbca7d
GK
177static void rs6000_emit_stack_tie PARAMS ((void));
178static void rs6000_frame_related PARAMS ((rtx, rtx, HOST_WIDE_INT, rtx, rtx));
89e7058f
AH
179static void emit_frame_save PARAMS ((rtx, rtx, enum machine_mode,
180 unsigned int, int, int));
a3170dc6 181static rtx gen_frame_mem_offset PARAMS ((enum machine_mode, rtx, int));
9ebbca7d
GK
182static void rs6000_emit_allocate_stack PARAMS ((HOST_WIDE_INT, int));
183static unsigned rs6000_hash_constant PARAMS ((rtx));
184static unsigned toc_hash_function PARAMS ((const void *));
185static int toc_hash_eq PARAMS ((const void *, const void *));
2eba1afa 186static int toc_hash_mark_entry PARAMS ((void **, void *));
9ebbca7d
GK
187static void toc_hash_mark_table PARAMS ((void *));
188static int constant_pool_expr_1 PARAMS ((rtx, int *, int *));
e2500fed 189static struct machine_function * rs6000_init_machine_status PARAMS ((void));
301d03af 190static bool rs6000_assemble_integer PARAMS ((rtx, unsigned int, int));
5add3202 191#ifdef HAVE_GAS_HIDDEN
25fdb4dc 192static void rs6000_assemble_visibility PARAMS ((tree, int));
5add3202 193#endif
71f123ca 194static int rs6000_ra_ever_killed PARAMS ((void));
91d231cb
JM
195static tree rs6000_handle_longcall_attribute PARAMS ((tree *, tree, tree, int, bool *));
196const struct attribute_spec rs6000_attribute_table[];
a5c76ee6 197static void rs6000_set_default_type_attributes PARAMS ((tree));
08c148a8
NB
198static void rs6000_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
199static void rs6000_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
3961e8fe
RH
200static void rs6000_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
201 HOST_WIDE_INT, tree));
2bfcf297
DB
202static rtx rs6000_emit_set_long_const PARAMS ((rtx,
203 HOST_WIDE_INT, HOST_WIDE_INT));
7c262518
RH
204#if TARGET_ELF
205static unsigned int rs6000_elf_section_type_flags PARAMS ((tree, const char *,
206 int));
d9f6800d
RH
207static void rs6000_elf_asm_out_constructor PARAMS ((rtx, int));
208static void rs6000_elf_asm_out_destructor PARAMS ((rtx, int));
ae46c4e0
RH
209static void rs6000_elf_select_section PARAMS ((tree, int,
210 unsigned HOST_WIDE_INT));
211static void rs6000_elf_unique_section PARAMS ((tree, int));
b64a1b53
RH
212static void rs6000_elf_select_rtx_section PARAMS ((enum machine_mode, rtx,
213 unsigned HOST_WIDE_INT));
0e5dbd9b
DE
214static void rs6000_elf_encode_section_info PARAMS ((tree, int))
215 ATTRIBUTE_UNUSED;
772c5265 216static const char *rs6000_elf_strip_name_encoding PARAMS ((const char *));
0e5dbd9b 217static bool rs6000_elf_in_small_data_p PARAMS ((tree));
7c262518 218#endif
cbaaba19 219#if TARGET_XCOFF
b275d088
DE
220static void rs6000_xcoff_asm_globalize_label PARAMS ((FILE *, const char *));
221static void rs6000_xcoff_asm_named_section PARAMS ((const char *, unsigned int));
ae46c4e0
RH
222static void rs6000_xcoff_select_section PARAMS ((tree, int,
223 unsigned HOST_WIDE_INT));
224static void rs6000_xcoff_unique_section PARAMS ((tree, int));
b64a1b53
RH
225static void rs6000_xcoff_select_rtx_section PARAMS ((enum machine_mode, rtx,
226 unsigned HOST_WIDE_INT));
772c5265 227static const char * rs6000_xcoff_strip_name_encoding PARAMS ((const char *));
5add3202 228static unsigned int rs6000_xcoff_section_type_flags PARAMS ((tree, const char *, int));
7c262518 229#endif
fb49053f
RH
230static void rs6000_xcoff_encode_section_info PARAMS ((tree, int))
231 ATTRIBUTE_UNUSED;
2bcc50d0 232static bool rs6000_binds_local_p PARAMS ((tree));
c237e94a
ZW
233static int rs6000_adjust_cost PARAMS ((rtx, rtx, rtx, int));
234static int rs6000_adjust_priority PARAMS ((rtx, int));
235static int rs6000_issue_rate PARAMS ((void));
236
6fa3f289 237static void rs6000_init_builtins PARAMS ((void));
92898235
AH
238static rtx rs6000_expand_unop_builtin PARAMS ((enum insn_code, tree, rtx));
239static rtx rs6000_expand_binop_builtin PARAMS ((enum insn_code, tree, rtx));
240static rtx rs6000_expand_ternop_builtin PARAMS ((enum insn_code, tree, rtx));
0ac081f6 241static rtx rs6000_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
92898235 242static void altivec_init_builtins PARAMS ((void));
a3170dc6
AH
243static void rs6000_common_init_builtins PARAMS ((void));
244
245static void enable_mask_for_builtins PARAMS ((struct builtin_description *,
246 int, enum rs6000_builtins,
247 enum rs6000_builtins));
248static void spe_init_builtins PARAMS ((void));
249static rtx spe_expand_builtin PARAMS ((tree, rtx, bool *));
250static rtx spe_expand_predicate_builtin PARAMS ((enum insn_code, tree, rtx));
251static rtx spe_expand_evsel_builtin PARAMS ((enum insn_code, tree, rtx));
252static int rs6000_emit_int_cmove PARAMS ((rtx, rtx, rtx, rtx));
253
92898235 254static rtx altivec_expand_builtin PARAMS ((tree, rtx, bool *));
3a9b8c7e
AH
255static rtx altivec_expand_ld_builtin PARAMS ((tree, rtx, bool *));
256static rtx altivec_expand_st_builtin PARAMS ((tree, rtx, bool *));
257static rtx altivec_expand_dst_builtin PARAMS ((tree, rtx, bool *));
100c4561 258static rtx altivec_expand_abs_builtin PARAMS ((enum insn_code, tree, rtx));
ae4b4a02 259static rtx altivec_expand_predicate_builtin PARAMS ((enum insn_code, const char *, tree, rtx));
6525c0e7 260static rtx altivec_expand_stv_builtin PARAMS ((enum insn_code, tree));
0ac081f6 261static void rs6000_parse_abi_options PARAMS ((void));
08b57fb3 262static void rs6000_parse_vrsave_option PARAMS ((void));
a3170dc6 263static void rs6000_parse_isel_option PARAMS ((void));
00b960c7
AH
264static int first_altivec_reg_to_save PARAMS ((void));
265static unsigned int compute_vrsave_mask PARAMS ((void));
266static void is_altivec_return_reg PARAMS ((rtx, void *));
9aa86737
AH
267static rtx generate_set_vrsave PARAMS ((rtx, rs6000_stack_t *, int));
268static void altivec_frame_fixup PARAMS ((rtx, rtx, HOST_WIDE_INT));
69ef87e2 269static int easy_vector_constant PARAMS ((rtx));
c81bebd7
MM
270\f
271/* Default register names. */
272char rs6000_reg_names[][8] =
273{
802a0058
MM
274 "0", "1", "2", "3", "4", "5", "6", "7",
275 "8", "9", "10", "11", "12", "13", "14", "15",
276 "16", "17", "18", "19", "20", "21", "22", "23",
277 "24", "25", "26", "27", "28", "29", "30", "31",
278 "0", "1", "2", "3", "4", "5", "6", "7",
279 "8", "9", "10", "11", "12", "13", "14", "15",
280 "16", "17", "18", "19", "20", "21", "22", "23",
281 "24", "25", "26", "27", "28", "29", "30", "31",
282 "mq", "lr", "ctr","ap",
283 "0", "1", "2", "3", "4", "5", "6", "7",
0ac081f6
AH
284 "xer",
285 /* AltiVec registers. */
0cd5e3a1
AH
286 "0", "1", "2", "3", "4", "5", "6", "7",
287 "8", "9", "10", "11", "12", "13", "14", "15",
288 "16", "17", "18", "19", "20", "21", "22", "23",
289 "24", "25", "26", "27", "28", "29", "30", "31",
0ac081f6 290 "vrsave"
c81bebd7
MM
291};
292
293#ifdef TARGET_REGNAMES
8b60264b 294static const char alt_reg_names[][8] =
c81bebd7 295{
802a0058
MM
296 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
297 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
298 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
299 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
300 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
301 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
302 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
303 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
304 "mq", "lr", "ctr", "ap",
305 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
0ac081f6
AH
306 "xer",
307 /* AltiVec registers. */
308 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
309 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
310 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
311 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
76a773f3 312 "vrsave"
c81bebd7
MM
313};
314#endif
9878760c 315\f
daf11973
MM
316#ifndef MASK_STRICT_ALIGN
317#define MASK_STRICT_ALIGN 0
318#endif
3961e8fe
RH
319
320/* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
321#define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
672a6f42
NB
322\f
323/* Initialize the GCC target structure. */
91d231cb
JM
324#undef TARGET_ATTRIBUTE_TABLE
325#define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
a5c76ee6
ZW
326#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
327#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
daf11973 328
301d03af
RS
329#undef TARGET_ASM_ALIGNED_DI_OP
330#define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
331
332/* Default unaligned ops are only provided for ELF. Find the ops needed
333 for non-ELF systems. */
334#ifndef OBJECT_FORMAT_ELF
cbaaba19 335#if TARGET_XCOFF
ae6c1efd 336/* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
301d03af
RS
337 64-bit targets. */
338#undef TARGET_ASM_UNALIGNED_HI_OP
339#define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
340#undef TARGET_ASM_UNALIGNED_SI_OP
341#define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
342#undef TARGET_ASM_UNALIGNED_DI_OP
343#define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
344#else
345/* For Darwin. */
346#undef TARGET_ASM_UNALIGNED_HI_OP
347#define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
348#undef TARGET_ASM_UNALIGNED_SI_OP
349#define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
350#endif
351#endif
352
353/* This hook deals with fixups for relocatable code and DI-mode objects
354 in 64-bit code. */
355#undef TARGET_ASM_INTEGER
356#define TARGET_ASM_INTEGER rs6000_assemble_integer
357
93638d7a
AM
358#ifdef HAVE_GAS_HIDDEN
359#undef TARGET_ASM_ASSEMBLE_VISIBILITY
360#define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
361#endif
362
08c148a8
NB
363#undef TARGET_ASM_FUNCTION_PROLOGUE
364#define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
365#undef TARGET_ASM_FUNCTION_EPILOGUE
366#define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
367
c237e94a
ZW
368#undef TARGET_SCHED_ISSUE_RATE
369#define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
370#undef TARGET_SCHED_ADJUST_COST
371#define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
372#undef TARGET_SCHED_ADJUST_PRIORITY
373#define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
374
0ac081f6
AH
375#undef TARGET_INIT_BUILTINS
376#define TARGET_INIT_BUILTINS rs6000_init_builtins
377
378#undef TARGET_EXPAND_BUILTIN
379#define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
380
0e5dbd9b
DE
381#undef TARGET_BINDS_LOCAL_P
382#define TARGET_BINDS_LOCAL_P rs6000_binds_local_p
383
3961e8fe
RH
384#undef TARGET_ASM_OUTPUT_MI_THUNK
385#define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
386
387/* ??? Should work everywhere, but ask dje@watson.ibm.com before
388 enabling for AIX. */
389#if TARGET_OBJECT_FORMAT != OBJECT_XCOFF
390#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
391#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
392#endif
00b960c7 393
4977bab6
ZW
394#undef TARGET_FUNCTION_OK_FOR_SIBCALL
395#define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
396
f6897b10 397struct gcc_target targetm = TARGET_INITIALIZER;
672a6f42 398\f
5248c961
RK
399/* Override command line options. Mostly we process the processor
400 type and sometimes adjust other TARGET_ options. */
401
402void
8e3f41e7 403rs6000_override_options (default_cpu)
d330fd93 404 const char *default_cpu;
5248c961 405{
c4d38ccb 406 size_t i, j;
8e3f41e7 407 struct rs6000_cpu_select *ptr;
5248c961 408
85638c0d
RK
409 /* Simplify the entries below by making a mask for any POWER
410 variant and any PowerPC variant. */
411
938937d8 412#define POWER_MASKS (MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING)
68c49ffa
RK
413#define POWERPC_MASKS (MASK_POWERPC | MASK_PPC_GPOPT \
414 | MASK_PPC_GFXOPT | MASK_POWERPC64)
415#define POWERPC_OPT_MASKS (MASK_PPC_GPOPT | MASK_PPC_GFXOPT)
85638c0d 416
5248c961
RK
417 static struct ptt
418 {
8b60264b
KG
419 const char *const name; /* Canonical processor name. */
420 const enum processor_type processor; /* Processor type enum value. */
421 const int target_enable; /* Target flags to enable. */
422 const int target_disable; /* Target flags to disable. */
423 } const processor_target_table[]
cf27b467
MM
424 = {{"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS,
425 POWER_MASKS | POWERPC_MASKS},
db7f1e43 426 {"power", PROCESSOR_POWER,
938937d8 427 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43 428 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
8e3f41e7
MM
429 {"power2", PROCESSOR_POWER,
430 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
431 POWERPC_MASKS | MASK_NEW_MNEMONICS},
c71791e0
DE
432 {"power3", PROCESSOR_PPC630,
433 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
434 POWER_MASKS | MASK_PPC_GPOPT},
309323c2
DE
435 {"power4", PROCESSOR_POWER4,
436 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
437 POWER_MASKS | MASK_PPC_GPOPT},
db7f1e43
RK
438 {"powerpc", PROCESSOR_POWERPC,
439 MASK_POWERPC | MASK_NEW_MNEMONICS,
68c49ffa 440 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
3cb999d8
DE
441 {"powerpc64", PROCESSOR_POWERPC64,
442 MASK_POWERPC | MASK_POWERPC64 | MASK_NEW_MNEMONICS,
443 POWER_MASKS | POWERPC_OPT_MASKS},
db7f1e43 444 {"rios", PROCESSOR_RIOS1,
938937d8 445 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
446 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
447 {"rios1", PROCESSOR_RIOS1,
938937d8 448 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
449 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
450 {"rsc", PROCESSOR_PPC601,
938937d8 451 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
452 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
453 {"rsc1", PROCESSOR_PPC601,
938937d8 454 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
455 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
456 {"rios2", PROCESSOR_RIOS2,
938937d8 457 MASK_POWER | MASK_MULTIPLE | MASK_STRING | MASK_POWER2,
db7f1e43 458 POWERPC_MASKS | MASK_NEW_MNEMONICS},
3cb999d8
DE
459 {"rs64a", PROCESSOR_RS64A,
460 MASK_POWERPC | MASK_NEW_MNEMONICS,
461 POWER_MASKS | POWERPC_OPT_MASKS},
a3a1dbf6
MM
462 {"401", PROCESSOR_PPC403,
463 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
464 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
49a0b204 465 {"403", PROCESSOR_PPC403,
daf11973 466 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS | MASK_STRICT_ALIGN,
49a0b204 467 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
d7a5e253
DE
468 {"405", PROCESSOR_PPC405,
469 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
470 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
4977bab6
ZW
471 {"405f", PROCESSOR_PPC405,
472 MASK_POWERPC | MASK_NEW_MNEMONICS,
473 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
cf27b467
MM
474 {"505", PROCESSOR_MPCCORE,
475 MASK_POWERPC | MASK_NEW_MNEMONICS,
476 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
5248c961 477 {"601", PROCESSOR_PPC601,
938937d8 478 MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_MULTIPLE | MASK_STRING,
68c49ffa 479 MASK_POWER2 | POWERPC_OPT_MASKS | MASK_POWERPC64},
1ec26da6 480 {"602", PROCESSOR_PPC603,
cf27b467
MM
481 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
482 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
5248c961 483 {"603", PROCESSOR_PPC603,
68c49ffa
RK
484 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
485 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
b6c9286a
MM
486 {"603e", PROCESSOR_PPC603,
487 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
488 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
b5370a88 489 {"ec603e", PROCESSOR_PPC603,
a3a1dbf6
MM
490 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
491 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
5248c961 492 {"604", PROCESSOR_PPC604,
b6c9286a
MM
493 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
494 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
cac8ce95 495 {"604e", PROCESSOR_PPC604e,
07e6159a
MM
496 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
497 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
b6c9286a 498 {"620", PROCESSOR_PPC620,
68c49ffa 499 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
a260abc9 500 POWER_MASKS | MASK_PPC_GPOPT},
3cb999d8
DE
501 {"630", PROCESSOR_PPC630,
502 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
503 POWER_MASKS | MASK_PPC_GPOPT},
bef84347
VM
504 {"740", PROCESSOR_PPC750,
505 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
506 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
507 {"750", PROCESSOR_PPC750,
508 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
509 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
a4f6c312
SS
510 {"7400", PROCESSOR_PPC7400,
511 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
512 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
513 {"7450", PROCESSOR_PPC7450,
514 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
515 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
a3170dc6
AH
516 {"8540", PROCESSOR_PPC8540,
517 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
518 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
07e6159a
MM
519 {"801", PROCESSOR_MPCCORE,
520 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
521 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
cf27b467
MM
522 {"821", PROCESSOR_MPCCORE,
523 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
524 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
07e6159a
MM
525 {"823", PROCESSOR_MPCCORE,
526 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
527 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
cf27b467
MM
528 {"860", PROCESSOR_MPCCORE,
529 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
530 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}};
5248c961 531
ca7558fc 532 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
5248c961 533
a4f6c312
SS
534 /* Save current -mmultiple/-mno-multiple status. */
535 int multiple = TARGET_MULTIPLE;
536 /* Save current -mstring/-mno-string status. */
537 int string = TARGET_STRING;
8a61d227 538
a4f6c312 539 /* Identify the processor type. */
8e3f41e7 540 rs6000_select[0].string = default_cpu;
3cb999d8 541 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
8e3f41e7 542
b6a1cbae 543 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
5248c961 544 {
8e3f41e7
MM
545 ptr = &rs6000_select[i];
546 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
5248c961 547 {
8e3f41e7
MM
548 for (j = 0; j < ptt_size; j++)
549 if (! strcmp (ptr->string, processor_target_table[j].name))
550 {
551 if (ptr->set_tune_p)
552 rs6000_cpu = processor_target_table[j].processor;
553
554 if (ptr->set_arch_p)
555 {
556 target_flags |= processor_target_table[j].target_enable;
557 target_flags &= ~processor_target_table[j].target_disable;
558 }
559 break;
560 }
561
4406229e 562 if (j == ptt_size)
8e3f41e7 563 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
5248c961
RK
564 }
565 }
8a61d227 566
a3170dc6
AH
567 if (rs6000_cpu == PROCESSOR_PPC8540)
568 rs6000_isel = 1;
569
dff9f1b6
DE
570 /* If we are optimizing big endian systems for space, use the load/store
571 multiple and string instructions. */
ef792183 572 if (BYTES_BIG_ENDIAN && optimize_size)
dff9f1b6 573 target_flags |= MASK_MULTIPLE | MASK_STRING;
ef792183 574
8a61d227
MM
575 /* If -mmultiple or -mno-multiple was explicitly used, don't
576 override with the processor default */
577 if (TARGET_MULTIPLE_SET)
578 target_flags = (target_flags & ~MASK_MULTIPLE) | multiple;
7e69e155 579
a4f6c312
SS
580 /* If -mstring or -mno-string was explicitly used, don't override
581 with the processor default. */
938937d8 582 if (TARGET_STRING_SET)
1f5515bf 583 target_flags = (target_flags & ~MASK_STRING) | string;
938937d8 584
a4f6c312
SS
585 /* Don't allow -mmultiple or -mstring on little endian systems
586 unless the cpu is a 750, because the hardware doesn't support the
587 instructions used in little endian mode, and causes an alignment
588 trap. The 750 does not cause an alignment trap (except when the
589 target is unaligned). */
bef84347 590
bfc79d3b 591 if (! BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
7e69e155
MM
592 {
593 if (TARGET_MULTIPLE)
594 {
595 target_flags &= ~MASK_MULTIPLE;
596 if (TARGET_MULTIPLE_SET)
597 warning ("-mmultiple is not supported on little endian systems");
598 }
599
600 if (TARGET_STRING)
601 {
602 target_flags &= ~MASK_STRING;
938937d8
MM
603 if (TARGET_STRING_SET)
604 warning ("-mstring is not supported on little endian systems");
7e69e155
MM
605 }
606 }
3933e0e1 607
ee2ca2a2 608 if (flag_pic != 0 && DEFAULT_ABI == ABI_AIX)
a260abc9 609 {
0e5dbd9b 610 rs6000_flag_pic = flag_pic;
ee2ca2a2 611 flag_pic = 0;
a260abc9
DE
612 }
613
c72bfda7
SS
614 /* For Darwin, always silently make -fpic and -fPIC identical. */
615 if (flag_pic == 1 && DEFAULT_ABI == ABI_DARWIN)
616 flag_pic = 2;
617
38c1f2d7
MM
618 /* Set debug flags */
619 if (rs6000_debug_name)
620 {
bfc79d3b 621 if (! strcmp (rs6000_debug_name, "all"))
38c1f2d7 622 rs6000_debug_stack = rs6000_debug_arg = 1;
bfc79d3b 623 else if (! strcmp (rs6000_debug_name, "stack"))
38c1f2d7 624 rs6000_debug_stack = 1;
bfc79d3b 625 else if (! strcmp (rs6000_debug_name, "arg"))
38c1f2d7
MM
626 rs6000_debug_arg = 1;
627 else
c725bd79 628 error ("unknown -mdebug-%s switch", rs6000_debug_name);
38c1f2d7
MM
629 }
630
57ac7be9
AM
631 if (rs6000_traceback_name)
632 {
633 if (! strncmp (rs6000_traceback_name, "full", 4))
634 rs6000_traceback = traceback_full;
635 else if (! strncmp (rs6000_traceback_name, "part", 4))
636 rs6000_traceback = traceback_part;
637 else if (! strncmp (rs6000_traceback_name, "no", 2))
638 rs6000_traceback = traceback_none;
639 else
640 error ("unknown -mtraceback arg `%s'; expecting `full', `partial' or `none'",
641 rs6000_traceback_name);
642 }
643
6fa3f289
ZW
644 /* Set size of long double */
645 rs6000_long_double_type_size = 64;
646 if (rs6000_long_double_size_string)
647 {
648 char *tail;
649 int size = strtol (rs6000_long_double_size_string, &tail, 10);
650 if (*tail != '\0' || (size != 64 && size != 128))
651 error ("Unknown switch -mlong-double-%s",
652 rs6000_long_double_size_string);
653 else
654 rs6000_long_double_type_size = size;
655 }
656
0ac081f6
AH
657 /* Handle -mabi= options. */
658 rs6000_parse_abi_options ();
659
08b57fb3
AH
660 /* Handle -mvrsave= option. */
661 rs6000_parse_vrsave_option ();
662
a3170dc6
AH
663 /* Handle -misel= option. */
664 rs6000_parse_isel_option ();
665
a7ae18e2
AH
666#ifdef SUBTARGET_OVERRIDE_OPTIONS
667 SUBTARGET_OVERRIDE_OPTIONS;
668#endif
669#ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
670 SUBSUBTARGET_OVERRIDE_OPTIONS;
671#endif
672
a5c76ee6
ZW
673 /* Handle -m(no-)longcall option. This is a bit of a cheap hack,
674 using TARGET_OPTIONS to handle a toggle switch, but we're out of
675 bits in target_flags so TARGET_SWITCHES cannot be used.
676 Assumption here is that rs6000_longcall_switch points into the
677 text of the complete option, rather than being a copy, so we can
678 scan back for the presence or absence of the no- modifier. */
679 if (rs6000_longcall_switch)
680 {
681 const char *base = rs6000_longcall_switch;
682 while (base[-1] != 'm') base--;
683
684 if (*rs6000_longcall_switch != '\0')
685 error ("invalid option `%s'", base);
686 rs6000_default_long_calls = (base[0] != 'n');
687 }
688
c81bebd7 689#ifdef TARGET_REGNAMES
a4f6c312
SS
690 /* If the user desires alternate register names, copy in the
691 alternate names now. */
c81bebd7 692 if (TARGET_REGNAMES)
4e135bdd 693 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
c81bebd7
MM
694#endif
695
6fa3f289
ZW
696 /* Set TARGET_AIX_STRUCT_RET last, after the ABI is determined.
697 If -maix-struct-return or -msvr4-struct-return was explicitly
698 used, don't override with the ABI default. */
699 if (!(target_flags & MASK_AIX_STRUCT_RET_SET))
700 {
701 if (DEFAULT_ABI == ABI_V4 && !DRAFT_V4_STRUCT_RET)
702 target_flags = (target_flags & ~MASK_AIX_STRUCT_RET);
703 else
704 target_flags |= MASK_AIX_STRUCT_RET;
705 }
706
fcce224d
DE
707 if (TARGET_LONG_DOUBLE_128
708 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN))
709 real_format_for_mode[TFmode - QFmode] = &ibm_extended_format;
710
c8023011
MM
711 /* Register global variables with the garbage collector. */
712 rs6000_add_gc_roots ();
9ebbca7d
GK
713
714 /* Allocate an alias set for register saves & restores from stack. */
715 rs6000_sr_alias_set = new_alias_set ();
716
717 if (TARGET_TOC)
718 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
71f123ca 719
301d03af
RS
720 /* We can only guarantee the availability of DI pseudo-ops when
721 assembling for 64-bit targets. */
ae6c1efd 722 if (!TARGET_64BIT)
301d03af
RS
723 {
724 targetm.asm_out.aligned_op.di = NULL;
725 targetm.asm_out.unaligned_op.di = NULL;
726 }
727
71f123ca
FS
728 /* Arrange to save and restore machine status around nested functions. */
729 init_machine_status = rs6000_init_machine_status;
5248c961 730}
5accd822 731
a3170dc6
AH
732/* Handle -misel= option. */
733static void
734rs6000_parse_isel_option ()
735{
736 if (rs6000_isel_string == 0)
737 return;
738 else if (! strcmp (rs6000_isel_string, "yes"))
739 rs6000_isel = 1;
740 else if (! strcmp (rs6000_isel_string, "no"))
741 rs6000_isel = 0;
742 else
743 error ("unknown -misel= option specified: '%s'",
744 rs6000_isel_string);
745}
746
08b57fb3
AH
747/* Handle -mvrsave= options. */
748static void
749rs6000_parse_vrsave_option ()
750{
751 /* Generate VRSAVE instructions by default. */
752 if (rs6000_altivec_vrsave_string == 0
753 || ! strcmp (rs6000_altivec_vrsave_string, "yes"))
754 rs6000_altivec_vrsave = 1;
755 else if (! strcmp (rs6000_altivec_vrsave_string, "no"))
756 rs6000_altivec_vrsave = 0;
757 else
758 error ("unknown -mvrsave= option specified: '%s'",
759 rs6000_altivec_vrsave_string);
760}
761
0ac081f6 762/* Handle -mabi= options. */
00b960c7
AH
763static void
764rs6000_parse_abi_options ()
0ac081f6
AH
765{
766 if (rs6000_abi_string == 0)
767 return;
768 else if (! strcmp (rs6000_abi_string, "altivec"))
6fa3f289 769 rs6000_altivec_abi = 1;
76a773f3
AH
770 else if (! strcmp (rs6000_abi_string, "no-altivec"))
771 rs6000_altivec_abi = 0;
a3170dc6
AH
772 else if (! strcmp (rs6000_abi_string, "spe"))
773 rs6000_spe_abi = 1;
774 else if (! strcmp (rs6000_abi_string, "no-spe"))
775 rs6000_spe_abi = 0;
0ac081f6 776 else
c725bd79 777 error ("unknown ABI specified: '%s'", rs6000_abi_string);
0ac081f6
AH
778}
779
5accd822
DE
780void
781optimization_options (level, size)
e2c953b6 782 int level ATTRIBUTE_UNUSED;
5accd822
DE
783 int size ATTRIBUTE_UNUSED;
784{
5accd822 785}
3cfa4909
MM
786\f
787/* Do anything needed at the start of the asm file. */
788
789void
790rs6000_file_start (file, default_cpu)
791 FILE *file;
d330fd93 792 const char *default_cpu;
3cfa4909 793{
c4d38ccb 794 size_t i;
3cfa4909 795 char buffer[80];
d330fd93 796 const char *start = buffer;
3cfa4909
MM
797 struct rs6000_cpu_select *ptr;
798
799 if (flag_verbose_asm)
800 {
801 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
802 rs6000_select[0].string = default_cpu;
803
b6a1cbae 804 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3cfa4909
MM
805 {
806 ptr = &rs6000_select[i];
807 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
808 {
809 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
810 start = "";
811 }
812 }
813
b91da81f 814#ifdef USING_ELFOS_H
3cfa4909
MM
815 switch (rs6000_sdata)
816 {
817 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
818 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
819 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
820 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
821 }
822
823 if (rs6000_sdata && g_switch_value)
824 {
825 fprintf (file, "%s -G %d", start, g_switch_value);
826 start = "";
827 }
828#endif
829
830 if (*start == '\0')
949ea356 831 putc ('\n', file);
3cfa4909
MM
832 }
833}
5248c961 834\f
a0ab749a 835/* Return nonzero if this function is known to have a null epilogue. */
9878760c
RK
836
837int
838direct_return ()
839{
4697a36c
MM
840 if (reload_completed)
841 {
842 rs6000_stack_t *info = rs6000_stack_info ();
843
844 if (info->first_gp_reg_save == 32
845 && info->first_fp_reg_save == 64
00b960c7 846 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
c81fc13e
DE
847 && ! info->lr_save_p
848 && ! info->cr_save_p
00b960c7 849 && info->vrsave_mask == 0
c81fc13e 850 && ! info->push_p)
4697a36c
MM
851 return 1;
852 }
853
854 return 0;
9878760c
RK
855}
856
857/* Returns 1 always. */
858
859int
860any_operand (op, mode)
592696dd 861 rtx op ATTRIBUTE_UNUSED;
296b8152 862 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
863{
864 return 1;
865}
866
a4f6c312 867/* Returns 1 if op is the count register. */
38c1f2d7 868int
a4f6c312 869count_register_operand (op, mode)
592696dd 870 rtx op;
296b8152 871 enum machine_mode mode ATTRIBUTE_UNUSED;
b6c9286a
MM
872{
873 if (GET_CODE (op) != REG)
874 return 0;
875
876 if (REGNO (op) == COUNT_REGISTER_REGNUM)
877 return 1;
878
879 if (REGNO (op) > FIRST_PSEUDO_REGISTER)
880 return 1;
881
882 return 0;
883}
884
0ec4e2a8
AH
885/* Returns 1 if op is an altivec register. */
886int
887altivec_register_operand (op, mode)
888 rtx op;
889 enum machine_mode mode ATTRIBUTE_UNUSED;
890{
891
892 return (register_operand (op, mode)
893 && (GET_CODE (op) != REG
894 || REGNO (op) > FIRST_PSEUDO_REGISTER
895 || ALTIVEC_REGNO_P (REGNO (op))));
896}
897
38c1f2d7 898int
a4f6c312 899xer_operand (op, mode)
592696dd 900 rtx op;
296b8152 901 enum machine_mode mode ATTRIBUTE_UNUSED;
802a0058
MM
902{
903 if (GET_CODE (op) != REG)
904 return 0;
905
9ebbca7d 906 if (XER_REGNO_P (REGNO (op)))
802a0058
MM
907 return 1;
908
802a0058
MM
909 return 0;
910}
911
c859cda6 912/* Return 1 if OP is a signed 8-bit constant. Int multiplication
6f317ef3 913 by such constants completes more quickly. */
c859cda6
DJ
914
915int
916s8bit_cint_operand (op, mode)
917 rtx op;
918 enum machine_mode mode ATTRIBUTE_UNUSED;
919{
920 return ( GET_CODE (op) == CONST_INT
921 && (INTVAL (op) >= -128 && INTVAL (op) <= 127));
922}
923
9878760c
RK
924/* Return 1 if OP is a constant that can fit in a D field. */
925
926int
927short_cint_operand (op, mode)
592696dd 928 rtx op;
296b8152 929 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 930{
5f59ecb7
DE
931 return (GET_CODE (op) == CONST_INT
932 && CONST_OK_FOR_LETTER_P (INTVAL (op), 'I'));
9878760c
RK
933}
934
5519a4f9 935/* Similar for an unsigned D field. */
9878760c
RK
936
937int
938u_short_cint_operand (op, mode)
592696dd 939 rtx op;
296b8152 940 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 941{
19684119 942 return (GET_CODE (op) == CONST_INT
c1f11548 943 && CONST_OK_FOR_LETTER_P (INTVAL (op) & GET_MODE_MASK (mode), 'K'));
9878760c
RK
944}
945
dcfedcd0
RK
946/* Return 1 if OP is a CONST_INT that cannot fit in a signed D field. */
947
948int
949non_short_cint_operand (op, mode)
592696dd 950 rtx op;
296b8152 951 enum machine_mode mode ATTRIBUTE_UNUSED;
dcfedcd0
RK
952{
953 return (GET_CODE (op) == CONST_INT
a7653a2c 954 && (unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) >= 0x10000);
dcfedcd0
RK
955}
956
2bfcf297
DB
957/* Returns 1 if OP is a CONST_INT that is a positive value
958 and an exact power of 2. */
959
960int
961exact_log2_cint_operand (op, mode)
592696dd 962 rtx op;
2bfcf297
DB
963 enum machine_mode mode ATTRIBUTE_UNUSED;
964{
965 return (GET_CODE (op) == CONST_INT
966 && INTVAL (op) > 0
967 && exact_log2 (INTVAL (op)) >= 0);
968}
969
9878760c
RK
970/* Returns 1 if OP is a register that is not special (i.e., not MQ,
971 ctr, or lr). */
972
973int
cd2b37d9 974gpc_reg_operand (op, mode)
592696dd 975 rtx op;
9878760c
RK
976 enum machine_mode mode;
977{
978 return (register_operand (op, mode)
802a0058 979 && (GET_CODE (op) != REG
9ebbca7d
GK
980 || (REGNO (op) >= ARG_POINTER_REGNUM
981 && !XER_REGNO_P (REGNO (op)))
982 || REGNO (op) < MQ_REGNO));
9878760c
RK
983}
984
985/* Returns 1 if OP is either a pseudo-register or a register denoting a
986 CR field. */
987
988int
989cc_reg_operand (op, mode)
592696dd 990 rtx op;
9878760c
RK
991 enum machine_mode mode;
992{
993 return (register_operand (op, mode)
994 && (GET_CODE (op) != REG
995 || REGNO (op) >= FIRST_PSEUDO_REGISTER
996 || CR_REGNO_P (REGNO (op))));
997}
998
815cdc52
MM
999/* Returns 1 if OP is either a pseudo-register or a register denoting a
1000 CR field that isn't CR0. */
1001
1002int
1003cc_reg_not_cr0_operand (op, mode)
592696dd 1004 rtx op;
815cdc52
MM
1005 enum machine_mode mode;
1006{
1007 return (register_operand (op, mode)
1008 && (GET_CODE (op) != REG
1009 || REGNO (op) >= FIRST_PSEUDO_REGISTER
1010 || CR_REGNO_NOT_CR0_P (REGNO (op))));
1011}
1012
a4f6c312
SS
1013/* Returns 1 if OP is either a constant integer valid for a D-field or
1014 a non-special register. If a register, it must be in the proper
1015 mode unless MODE is VOIDmode. */
9878760c
RK
1016
1017int
1018reg_or_short_operand (op, mode)
592696dd 1019 rtx op;
9878760c
RK
1020 enum machine_mode mode;
1021{
f5a28898 1022 return short_cint_operand (op, mode) || gpc_reg_operand (op, mode);
9878760c
RK
1023}
1024
a4f6c312
SS
1025/* Similar, except check if the negation of the constant would be
1026 valid for a D-field. */
9878760c
RK
1027
1028int
1029reg_or_neg_short_operand (op, mode)
592696dd 1030 rtx op;
9878760c
RK
1031 enum machine_mode mode;
1032{
1033 if (GET_CODE (op) == CONST_INT)
1034 return CONST_OK_FOR_LETTER_P (INTVAL (op), 'P');
1035
cd2b37d9 1036 return gpc_reg_operand (op, mode);
9878760c
RK
1037}
1038
768070a0
TR
1039/* Returns 1 if OP is either a constant integer valid for a DS-field or
1040 a non-special register. If a register, it must be in the proper
1041 mode unless MODE is VOIDmode. */
1042
1043int
1044reg_or_aligned_short_operand (op, mode)
1045 rtx op;
1046 enum machine_mode mode;
1047{
1048 if (gpc_reg_operand (op, mode))
1049 return 1;
1050 else if (short_cint_operand (op, mode) && !(INTVAL (op) & 3))
1051 return 1;
1052
1053 return 0;
1054}
1055
1056
a4f6c312
SS
1057/* Return 1 if the operand is either a register or an integer whose
1058 high-order 16 bits are zero. */
9878760c
RK
1059
1060int
1061reg_or_u_short_operand (op, mode)
592696dd 1062 rtx op;
9878760c
RK
1063 enum machine_mode mode;
1064{
e675f625 1065 return u_short_cint_operand (op, mode) || gpc_reg_operand (op, mode);
9878760c
RK
1066}
1067
1068/* Return 1 is the operand is either a non-special register or ANY
1069 constant integer. */
1070
1071int
1072reg_or_cint_operand (op, mode)
592696dd 1073 rtx op;
9878760c
RK
1074 enum machine_mode mode;
1075{
a4f6c312 1076 return (GET_CODE (op) == CONST_INT || gpc_reg_operand (op, mode));
f6bf7de2
DE
1077}
1078
1079/* Return 1 is the operand is either a non-special register or ANY
1080 32-bit signed constant integer. */
1081
1082int
1083reg_or_arith_cint_operand (op, mode)
592696dd 1084 rtx op;
f6bf7de2
DE
1085 enum machine_mode mode;
1086{
a4f6c312
SS
1087 return (gpc_reg_operand (op, mode)
1088 || (GET_CODE (op) == CONST_INT
f6bf7de2 1089#if HOST_BITS_PER_WIDE_INT != 32
a4f6c312
SS
1090 && ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80000000)
1091 < (unsigned HOST_WIDE_INT) 0x100000000ll)
f6bf7de2 1092#endif
a4f6c312 1093 ));
9878760c
RK
1094}
1095
2bfcf297
DB
1096/* Return 1 is the operand is either a non-special register or a 32-bit
1097 signed constant integer valid for 64-bit addition. */
1098
1099int
1100reg_or_add_cint64_operand (op, mode)
592696dd 1101 rtx op;
2bfcf297
DB
1102 enum machine_mode mode;
1103{
a4f6c312
SS
1104 return (gpc_reg_operand (op, mode)
1105 || (GET_CODE (op) == CONST_INT
a65c591c 1106#if HOST_BITS_PER_WIDE_INT == 32
a4f6c312 1107 && INTVAL (op) < 0x7fff8000
a65c591c 1108#else
a4f6c312
SS
1109 && ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80008000)
1110 < 0x100000000ll)
2bfcf297 1111#endif
a4f6c312 1112 ));
2bfcf297
DB
1113}
1114
1115/* Return 1 is the operand is either a non-special register or a 32-bit
1116 signed constant integer valid for 64-bit subtraction. */
1117
1118int
1119reg_or_sub_cint64_operand (op, mode)
592696dd 1120 rtx op;
2bfcf297
DB
1121 enum machine_mode mode;
1122{
a4f6c312
SS
1123 return (gpc_reg_operand (op, mode)
1124 || (GET_CODE (op) == CONST_INT
a65c591c 1125#if HOST_BITS_PER_WIDE_INT == 32
a4f6c312 1126 && (- INTVAL (op)) < 0x7fff8000
a65c591c 1127#else
a4f6c312
SS
1128 && ((unsigned HOST_WIDE_INT) ((- INTVAL (op)) + 0x80008000)
1129 < 0x100000000ll)
2bfcf297 1130#endif
a4f6c312 1131 ));
2bfcf297
DB
1132}
1133
9ebbca7d
GK
1134/* Return 1 is the operand is either a non-special register or ANY
1135 32-bit unsigned constant integer. */
1136
1137int
1d328b19 1138reg_or_logical_cint_operand (op, mode)
592696dd 1139 rtx op;
9ebbca7d
GK
1140 enum machine_mode mode;
1141{
1d328b19
GK
1142 if (GET_CODE (op) == CONST_INT)
1143 {
1144 if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT)
1145 {
1146 if (GET_MODE_BITSIZE (mode) <= 32)
a4f6c312 1147 abort ();
1d328b19
GK
1148
1149 if (INTVAL (op) < 0)
1150 return 0;
1151 }
1152
1153 return ((INTVAL (op) & GET_MODE_MASK (mode)
0858c623 1154 & (~ (unsigned HOST_WIDE_INT) 0xffffffff)) == 0);
1d328b19
GK
1155 }
1156 else if (GET_CODE (op) == CONST_DOUBLE)
1157 {
1158 if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
1159 || mode != DImode)
a4f6c312 1160 abort ();
1d328b19
GK
1161
1162 return CONST_DOUBLE_HIGH (op) == 0;
1163 }
1164 else
1165 return gpc_reg_operand (op, mode);
9ebbca7d
GK
1166}
1167
51d3e7d6 1168/* Return 1 if the operand is an operand that can be loaded via the GOT. */
766a866c
MM
1169
1170int
1171got_operand (op, mode)
592696dd 1172 rtx op;
296b8152 1173 enum machine_mode mode ATTRIBUTE_UNUSED;
766a866c
MM
1174{
1175 return (GET_CODE (op) == SYMBOL_REF
1176 || GET_CODE (op) == CONST
1177 || GET_CODE (op) == LABEL_REF);
1178}
1179
38c1f2d7
MM
1180/* Return 1 if the operand is a simple references that can be loaded via
1181 the GOT (labels involving addition aren't allowed). */
1182
1183int
1184got_no_const_operand (op, mode)
592696dd 1185 rtx op;
296b8152 1186 enum machine_mode mode ATTRIBUTE_UNUSED;
38c1f2d7
MM
1187{
1188 return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF);
1189}
1190
4e74d8ec
MM
1191/* Return the number of instructions it takes to form a constant in an
1192 integer register. */
1193
1194static int
1195num_insns_constant_wide (value)
1196 HOST_WIDE_INT value;
1197{
1198 /* signed constant loadable with {cal|addi} */
5f59ecb7 1199 if (CONST_OK_FOR_LETTER_P (value, 'I'))
0865c631
GK
1200 return 1;
1201
4e74d8ec 1202 /* constant loadable with {cau|addis} */
5f59ecb7 1203 else if (CONST_OK_FOR_LETTER_P (value, 'L'))
4e74d8ec
MM
1204 return 1;
1205
5f59ecb7 1206#if HOST_BITS_PER_WIDE_INT == 64
c81fc13e 1207 else if (TARGET_POWERPC64)
4e74d8ec 1208 {
a65c591c
DE
1209 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
1210 HOST_WIDE_INT high = value >> 31;
4e74d8ec 1211
a65c591c 1212 if (high == 0 || high == -1)
4e74d8ec
MM
1213 return 2;
1214
a65c591c 1215 high >>= 1;
4e74d8ec 1216
a65c591c 1217 if (low == 0)
4e74d8ec 1218 return num_insns_constant_wide (high) + 1;
4e74d8ec
MM
1219 else
1220 return (num_insns_constant_wide (high)
e396202a 1221 + num_insns_constant_wide (low) + 1);
4e74d8ec
MM
1222 }
1223#endif
1224
1225 else
1226 return 2;
1227}
1228
1229int
1230num_insns_constant (op, mode)
1231 rtx op;
1232 enum machine_mode mode;
1233{
4e74d8ec 1234 if (GET_CODE (op) == CONST_INT)
0d30d435
DE
1235 {
1236#if HOST_BITS_PER_WIDE_INT == 64
4e2c1c44
DE
1237 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
1238 && mask64_operand (op, mode))
0d30d435
DE
1239 return 2;
1240 else
1241#endif
1242 return num_insns_constant_wide (INTVAL (op));
1243 }
4e74d8ec 1244
6fc48950
MM
1245 else if (GET_CODE (op) == CONST_DOUBLE && mode == SFmode)
1246 {
1247 long l;
1248 REAL_VALUE_TYPE rv;
1249
1250 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1251 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
e72247f4 1252 return num_insns_constant_wide ((HOST_WIDE_INT) l);
6fc48950
MM
1253 }
1254
47ad8c61 1255 else if (GET_CODE (op) == CONST_DOUBLE)
4e74d8ec 1256 {
47ad8c61
MM
1257 HOST_WIDE_INT low;
1258 HOST_WIDE_INT high;
1259 long l[2];
1260 REAL_VALUE_TYPE rv;
1261 int endian = (WORDS_BIG_ENDIAN == 0);
4e74d8ec 1262
47ad8c61
MM
1263 if (mode == VOIDmode || mode == DImode)
1264 {
1265 high = CONST_DOUBLE_HIGH (op);
1266 low = CONST_DOUBLE_LOW (op);
1267 }
1268 else
1269 {
1270 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1271 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
1272 high = l[endian];
1273 low = l[1 - endian];
1274 }
4e74d8ec 1275
47ad8c61
MM
1276 if (TARGET_32BIT)
1277 return (num_insns_constant_wide (low)
1278 + num_insns_constant_wide (high));
4e74d8ec
MM
1279
1280 else
47ad8c61 1281 {
e72247f4 1282 if (high == 0 && low >= 0)
47ad8c61
MM
1283 return num_insns_constant_wide (low);
1284
e72247f4 1285 else if (high == -1 && low < 0)
47ad8c61
MM
1286 return num_insns_constant_wide (low);
1287
a260abc9
DE
1288 else if (mask64_operand (op, mode))
1289 return 2;
1290
47ad8c61
MM
1291 else if (low == 0)
1292 return num_insns_constant_wide (high) + 1;
1293
1294 else
1295 return (num_insns_constant_wide (high)
1296 + num_insns_constant_wide (low) + 1);
1297 }
4e74d8ec
MM
1298 }
1299
1300 else
1301 abort ();
1302}
1303
a4f6c312
SS
1304/* Return 1 if the operand is a CONST_DOUBLE and it can be put into a
1305 register with one instruction per word. We only do this if we can
1306 safely read CONST_DOUBLE_{LOW,HIGH}. */
9878760c
RK
1307
1308int
1309easy_fp_constant (op, mode)
592696dd
SS
1310 rtx op;
1311 enum machine_mode mode;
9878760c 1312{
9878760c
RK
1313 if (GET_CODE (op) != CONST_DOUBLE
1314 || GET_MODE (op) != mode
4e74d8ec 1315 || (GET_MODE_CLASS (mode) != MODE_FLOAT && mode != DImode))
9878760c
RK
1316 return 0;
1317
a4f6c312 1318 /* Consider all constants with -msoft-float to be easy. */
a3170dc6
AH
1319 if ((TARGET_SOFT_FLOAT || !TARGET_FPRS)
1320 && mode != DImode)
b6c9286a
MM
1321 return 1;
1322
a4f6c312 1323 /* If we are using V.4 style PIC, consider all constants to be hard. */
f607bc57 1324 if (flag_pic && DEFAULT_ABI == ABI_V4)
a7273471
MM
1325 return 0;
1326
5ae4759c 1327#ifdef TARGET_RELOCATABLE
a4f6c312
SS
1328 /* Similarly if we are using -mrelocatable, consider all constants
1329 to be hard. */
5ae4759c
MM
1330 if (TARGET_RELOCATABLE)
1331 return 0;
1332#endif
1333
fcce224d
DE
1334 if (mode == TFmode)
1335 {
1336 long k[4];
1337 REAL_VALUE_TYPE rv;
1338
1339 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1340 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
1341
1342 return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1
1343 && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1
1344 && num_insns_constant_wide ((HOST_WIDE_INT) k[2]) == 1
1345 && num_insns_constant_wide ((HOST_WIDE_INT) k[3]) == 1);
1346 }
1347
1348 else if (mode == DFmode)
042259f2
DE
1349 {
1350 long k[2];
1351 REAL_VALUE_TYPE rv;
1352
1353 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1354 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
9878760c 1355
a65c591c
DE
1356 return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1
1357 && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1);
042259f2 1358 }
4e74d8ec
MM
1359
1360 else if (mode == SFmode)
042259f2
DE
1361 {
1362 long l;
1363 REAL_VALUE_TYPE rv;
1364
1365 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1366 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
9878760c 1367
4e74d8ec 1368 return num_insns_constant_wide (l) == 1;
042259f2 1369 }
4e74d8ec 1370
a260abc9 1371 else if (mode == DImode)
c81fc13e 1372 return ((TARGET_POWERPC64
a260abc9
DE
1373 && GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_LOW (op) == 0)
1374 || (num_insns_constant (op, DImode) <= 2));
4e74d8ec 1375
a9098fd0
GK
1376 else if (mode == SImode)
1377 return 1;
4e74d8ec
MM
1378 else
1379 abort ();
9878760c 1380}
8f75773e 1381
69ef87e2
AH
1382/* Return 1 if the operand is a CONST_INT and can be put into a
1383 register with one instruction. */
1384
1385static int
1386easy_vector_constant (op)
1387 rtx op;
1388{
1389 rtx elt;
1390 int units, i;
1391
1392 if (GET_CODE (op) != CONST_VECTOR)
1393 return 0;
1394
1395 units = CONST_VECTOR_NUNITS (op);
1396
1397 /* We can generate 0 easily. Look for that. */
1398 for (i = 0; i < units; ++i)
1399 {
1400 elt = CONST_VECTOR_ELT (op, i);
1401
1402 /* We could probably simplify this by just checking for equality
1403 with CONST0_RTX for the current mode, but let's be safe
1404 instead. */
1405
98ef3137
JJ
1406 switch (GET_CODE (elt))
1407 {
1408 case CONST_INT:
1409 if (INTVAL (elt) != 0)
1410 return 0;
1411 break;
1412 case CONST_DOUBLE:
1413 if (CONST_DOUBLE_LOW (elt) != 0 || CONST_DOUBLE_HIGH (elt) != 0)
1414 return 0;
1415 break;
1416 default:
1417 return 0;
1418 }
69ef87e2
AH
1419 }
1420
1421 /* We could probably generate a few other constants trivially, but
1422 gcc doesn't generate them yet. FIXME later. */
98ef3137 1423 return 1;
69ef87e2
AH
1424}
1425
1426/* Return 1 if the operand is the constant 0. This works for scalars
1427 as well as vectors. */
1428int
1429zero_constant (op, mode)
1430 rtx op;
1431 enum machine_mode mode;
1432{
1433 return op == CONST0_RTX (mode);
1434}
1435
50a0b056
GK
1436/* Return 1 if the operand is 0.0. */
1437int
1438zero_fp_constant (op, mode)
592696dd
SS
1439 rtx op;
1440 enum machine_mode mode;
50a0b056
GK
1441{
1442 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
1443}
1444
a4f6c312
SS
1445/* Return 1 if the operand is in volatile memory. Note that during
1446 the RTL generation phase, memory_operand does not return TRUE for
b6c9286a
MM
1447 volatile memory references. So this function allows us to
1448 recognize volatile references where its safe. */
1449
1450int
1451volatile_mem_operand (op, mode)
592696dd 1452 rtx op;
b6c9286a
MM
1453 enum machine_mode mode;
1454{
1455 if (GET_CODE (op) != MEM)
1456 return 0;
1457
1458 if (!MEM_VOLATILE_P (op))
1459 return 0;
1460
1461 if (mode != GET_MODE (op))
1462 return 0;
1463
1464 if (reload_completed)
1465 return memory_operand (op, mode);
1466
1467 if (reload_in_progress)
1468 return strict_memory_address_p (mode, XEXP (op, 0));
1469
1470 return memory_address_p (mode, XEXP (op, 0));
1471}
1472
97f6e72f 1473/* Return 1 if the operand is an offsettable memory operand. */
914c2e77
RK
1474
1475int
97f6e72f 1476offsettable_mem_operand (op, mode)
592696dd 1477 rtx op;
914c2e77
RK
1478 enum machine_mode mode;
1479{
97f6e72f 1480 return ((GET_CODE (op) == MEM)
677a9668 1481 && offsettable_address_p (reload_completed || reload_in_progress,
97f6e72f 1482 mode, XEXP (op, 0)));
914c2e77
RK
1483}
1484
9878760c
RK
1485/* Return 1 if the operand is either an easy FP constant (see above) or
1486 memory. */
1487
1488int
1489mem_or_easy_const_operand (op, mode)
592696dd 1490 rtx op;
9878760c
RK
1491 enum machine_mode mode;
1492{
1493 return memory_operand (op, mode) || easy_fp_constant (op, mode);
1494}
1495
1496/* Return 1 if the operand is either a non-special register or an item
5f59ecb7 1497 that can be used as the operand of a `mode' add insn. */
9878760c
RK
1498
1499int
1500add_operand (op, mode)
592696dd 1501 rtx op;
9878760c
RK
1502 enum machine_mode mode;
1503{
2bfcf297 1504 if (GET_CODE (op) == CONST_INT)
e72247f4
DE
1505 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
1506 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
2bfcf297
DB
1507
1508 return gpc_reg_operand (op, mode);
9878760c
RK
1509}
1510
dcfedcd0
RK
1511/* Return 1 if OP is a constant but not a valid add_operand. */
1512
1513int
1514non_add_cint_operand (op, mode)
592696dd 1515 rtx op;
296b8152 1516 enum machine_mode mode ATTRIBUTE_UNUSED;
dcfedcd0
RK
1517{
1518 return (GET_CODE (op) == CONST_INT
e72247f4
DE
1519 && !CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
1520 && !CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
dcfedcd0
RK
1521}
1522
9878760c
RK
1523/* Return 1 if the operand is a non-special register or a constant that
1524 can be used as the operand of an OR or XOR insn on the RS/6000. */
1525
1526int
1527logical_operand (op, mode)
592696dd 1528 rtx op;
9878760c
RK
1529 enum machine_mode mode;
1530{
40501e5f 1531 HOST_WIDE_INT opl, oph;
1d328b19 1532
dfbdccdb
GK
1533 if (gpc_reg_operand (op, mode))
1534 return 1;
1d328b19 1535
dfbdccdb 1536 if (GET_CODE (op) == CONST_INT)
40501e5f
AM
1537 {
1538 opl = INTVAL (op) & GET_MODE_MASK (mode);
1539
1540#if HOST_BITS_PER_WIDE_INT <= 32
1541 if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT && opl < 0)
1542 return 0;
1543#endif
1544 }
dfbdccdb
GK
1545 else if (GET_CODE (op) == CONST_DOUBLE)
1546 {
1d328b19 1547 if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
40501e5f 1548 abort ();
1d328b19
GK
1549
1550 opl = CONST_DOUBLE_LOW (op);
1551 oph = CONST_DOUBLE_HIGH (op);
40501e5f 1552 if (oph != 0)
38886f37 1553 return 0;
dfbdccdb
GK
1554 }
1555 else
1556 return 0;
1d328b19 1557
40501e5f
AM
1558 return ((opl & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0
1559 || (opl & ~ (unsigned HOST_WIDE_INT) 0xffff0000) == 0);
9878760c
RK
1560}
1561
dcfedcd0 1562/* Return 1 if C is a constant that is not a logical operand (as
1d328b19 1563 above), but could be split into one. */
dcfedcd0
RK
1564
1565int
1566non_logical_cint_operand (op, mode)
592696dd 1567 rtx op;
5f59ecb7 1568 enum machine_mode mode;
dcfedcd0 1569{
dfbdccdb 1570 return ((GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE)
1d328b19
GK
1571 && ! logical_operand (op, mode)
1572 && reg_or_logical_cint_operand (op, mode));
dcfedcd0
RK
1573}
1574
19ba8161 1575/* Return 1 if C is a constant that can be encoded in a 32-bit mask on the
9878760c
RK
1576 RS/6000. It is if there are no more than two 1->0 or 0->1 transitions.
1577 Reject all ones and all zeros, since these should have been optimized
1578 away and confuse the making of MB and ME. */
1579
1580int
19ba8161 1581mask_operand (op, mode)
592696dd 1582 rtx op;
19ba8161 1583 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 1584{
02071907 1585 HOST_WIDE_INT c, lsb;
9878760c 1586
19ba8161
DE
1587 if (GET_CODE (op) != CONST_INT)
1588 return 0;
1589
1590 c = INTVAL (op);
1591
57deb3a1
AM
1592 /* Fail in 64-bit mode if the mask wraps around because the upper
1593 32-bits of the mask will all be 1s, contrary to GCC's internal view. */
1594 if (TARGET_POWERPC64 && (c & 0x80000001) == 0x80000001)
1595 return 0;
1596
c5059423
AM
1597 /* We don't change the number of transitions by inverting,
1598 so make sure we start with the LS bit zero. */
1599 if (c & 1)
1600 c = ~c;
1601
1602 /* Reject all zeros or all ones. */
1603 if (c == 0)
9878760c
RK
1604 return 0;
1605
c5059423
AM
1606 /* Find the first transition. */
1607 lsb = c & -c;
1608
1609 /* Invert to look for a second transition. */
1610 c = ~c;
9878760c 1611
c5059423
AM
1612 /* Erase first transition. */
1613 c &= -lsb;
9878760c 1614
c5059423
AM
1615 /* Find the second transition (if any). */
1616 lsb = c & -c;
1617
1618 /* Match if all the bits above are 1's (or c is zero). */
1619 return c == -lsb;
9878760c
RK
1620}
1621
0ba1b2ff
AM
1622/* Return 1 for the PowerPC64 rlwinm corner case. */
1623
1624int
1625mask_operand_wrap (op, mode)
1626 rtx op;
1627 enum machine_mode mode ATTRIBUTE_UNUSED;
1628{
1629 HOST_WIDE_INT c, lsb;
1630
1631 if (GET_CODE (op) != CONST_INT)
1632 return 0;
1633
1634 c = INTVAL (op);
1635
1636 if ((c & 0x80000001) != 0x80000001)
1637 return 0;
1638
1639 c = ~c;
1640 if (c == 0)
1641 return 0;
1642
1643 lsb = c & -c;
1644 c = ~c;
1645 c &= -lsb;
1646 lsb = c & -c;
1647 return c == -lsb;
1648}
1649
a260abc9
DE
1650/* Return 1 if the operand is a constant that is a PowerPC64 mask.
1651 It is if there are no more than one 1->0 or 0->1 transitions.
0ba1b2ff
AM
1652 Reject all zeros, since zero should have been optimized away and
1653 confuses the making of MB and ME. */
9878760c
RK
1654
1655int
a260abc9 1656mask64_operand (op, mode)
592696dd 1657 rtx op;
0ba1b2ff 1658 enum machine_mode mode ATTRIBUTE_UNUSED;
a260abc9
DE
1659{
1660 if (GET_CODE (op) == CONST_INT)
1661 {
02071907 1662 HOST_WIDE_INT c, lsb;
a260abc9 1663
c5059423 1664 c = INTVAL (op);
a260abc9 1665
0ba1b2ff 1666 /* Reject all zeros. */
c5059423 1667 if (c == 0)
e2c953b6
DE
1668 return 0;
1669
0ba1b2ff
AM
1670 /* We don't change the number of transitions by inverting,
1671 so make sure we start with the LS bit zero. */
1672 if (c & 1)
1673 c = ~c;
1674
c5059423
AM
1675 /* Find the transition, and check that all bits above are 1's. */
1676 lsb = c & -c;
1677 return c == -lsb;
e2c953b6 1678 }
0ba1b2ff
AM
1679 return 0;
1680}
1681
1682/* Like mask64_operand, but allow up to three transitions. This
1683 predicate is used by insn patterns that generate two rldicl or
1684 rldicr machine insns. */
1685
1686int
1687mask64_2_operand (op, mode)
1688 rtx op;
1689 enum machine_mode mode ATTRIBUTE_UNUSED;
1690{
1691 if (GET_CODE (op) == CONST_INT)
a260abc9 1692 {
0ba1b2ff 1693 HOST_WIDE_INT c, lsb;
a260abc9 1694
0ba1b2ff 1695 c = INTVAL (op);
a260abc9 1696
0ba1b2ff
AM
1697 /* Disallow all zeros. */
1698 if (c == 0)
1699 return 0;
a260abc9 1700
0ba1b2ff
AM
1701 /* We don't change the number of transitions by inverting,
1702 so make sure we start with the LS bit zero. */
1703 if (c & 1)
1704 c = ~c;
a260abc9 1705
0ba1b2ff
AM
1706 /* Find the first transition. */
1707 lsb = c & -c;
a260abc9 1708
0ba1b2ff
AM
1709 /* Invert to look for a second transition. */
1710 c = ~c;
1711
1712 /* Erase first transition. */
1713 c &= -lsb;
1714
1715 /* Find the second transition. */
1716 lsb = c & -c;
1717
1718 /* Invert to look for a third transition. */
1719 c = ~c;
1720
1721 /* Erase second transition. */
1722 c &= -lsb;
1723
1724 /* Find the third transition (if any). */
1725 lsb = c & -c;
1726
1727 /* Match if all the bits above are 1's (or c is zero). */
1728 return c == -lsb;
1729 }
1730 return 0;
1731}
1732
1733/* Generates shifts and masks for a pair of rldicl or rldicr insns to
1734 implement ANDing by the mask IN. */
1735void
1736build_mask64_2_operands (in, out)
1737 rtx in;
1738 rtx *out;
1739{
1740#if HOST_BITS_PER_WIDE_INT >= 64
1741 unsigned HOST_WIDE_INT c, lsb, m1, m2;
1742 int shift;
1743
1744 if (GET_CODE (in) != CONST_INT)
1745 abort ();
1746
1747 c = INTVAL (in);
1748 if (c & 1)
1749 {
1750 /* Assume c initially something like 0x00fff000000fffff. The idea
1751 is to rotate the word so that the middle ^^^^^^ group of zeros
1752 is at the MS end and can be cleared with an rldicl mask. We then
1753 rotate back and clear off the MS ^^ group of zeros with a
1754 second rldicl. */
1755 c = ~c; /* c == 0xff000ffffff00000 */
1756 lsb = c & -c; /* lsb == 0x0000000000100000 */
1757 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
1758 c = ~c; /* c == 0x00fff000000fffff */
1759 c &= -lsb; /* c == 0x00fff00000000000 */
1760 lsb = c & -c; /* lsb == 0x0000100000000000 */
1761 c = ~c; /* c == 0xff000fffffffffff */
1762 c &= -lsb; /* c == 0xff00000000000000 */
1763 shift = 0;
1764 while ((lsb >>= 1) != 0)
1765 shift++; /* shift == 44 on exit from loop */
1766 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
1767 m1 = ~m1; /* m1 == 0x000000ffffffffff */
1768 m2 = ~c; /* m2 == 0x00ffffffffffffff */
a260abc9
DE
1769 }
1770 else
0ba1b2ff
AM
1771 {
1772 /* Assume c initially something like 0xff000f0000000000. The idea
1773 is to rotate the word so that the ^^^ middle group of zeros
1774 is at the LS end and can be cleared with an rldicr mask. We then
1775 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
1776 a second rldicr. */
1777 lsb = c & -c; /* lsb == 0x0000010000000000 */
1778 m2 = -lsb; /* m2 == 0xffffff0000000000 */
1779 c = ~c; /* c == 0x00fff0ffffffffff */
1780 c &= -lsb; /* c == 0x00fff00000000000 */
1781 lsb = c & -c; /* lsb == 0x0000100000000000 */
1782 c = ~c; /* c == 0xff000fffffffffff */
1783 c &= -lsb; /* c == 0xff00000000000000 */
1784 shift = 0;
1785 while ((lsb >>= 1) != 0)
1786 shift++; /* shift == 44 on exit from loop */
1787 m1 = ~c; /* m1 == 0x00ffffffffffffff */
1788 m1 >>= shift; /* m1 == 0x0000000000000fff */
1789 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
1790 }
1791
1792 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
1793 masks will be all 1's. We are guaranteed more than one transition. */
1794 out[0] = GEN_INT (64 - shift);
1795 out[1] = GEN_INT (m1);
1796 out[2] = GEN_INT (shift);
1797 out[3] = GEN_INT (m2);
1798#else
045572c7
GK
1799 (void)in;
1800 (void)out;
0ba1b2ff
AM
1801 abort ();
1802#endif
a260abc9
DE
1803}
1804
1805/* Return 1 if the operand is either a non-special register or a constant
1806 that can be used as the operand of a PowerPC64 logical AND insn. */
1807
1808int
1809and64_operand (op, mode)
592696dd 1810 rtx op;
9878760c
RK
1811 enum machine_mode mode;
1812{
a4f6c312 1813 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
52d3af72
DE
1814 return (gpc_reg_operand (op, mode) || mask64_operand (op, mode));
1815
1816 return (logical_operand (op, mode) || mask64_operand (op, mode));
9878760c
RK
1817}
1818
0ba1b2ff
AM
1819/* Like the above, but also match constants that can be implemented
1820 with two rldicl or rldicr insns. */
1821
1822int
1823and64_2_operand (op, mode)
1824 rtx op;
1825 enum machine_mode mode;
1826{
1827 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
1828 return gpc_reg_operand (op, mode) || mask64_2_operand (op, mode);
1829
1830 return logical_operand (op, mode) || mask64_2_operand (op, mode);
1831}
1832
a260abc9
DE
1833/* Return 1 if the operand is either a non-special register or a
1834 constant that can be used as the operand of an RS/6000 logical AND insn. */
dcfedcd0
RK
1835
1836int
a260abc9 1837and_operand (op, mode)
592696dd 1838 rtx op;
a260abc9 1839 enum machine_mode mode;
dcfedcd0 1840{
a4f6c312 1841 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
52d3af72
DE
1842 return (gpc_reg_operand (op, mode) || mask_operand (op, mode));
1843
1844 return (logical_operand (op, mode) || mask_operand (op, mode));
dcfedcd0
RK
1845}
1846
9878760c
RK
1847/* Return 1 if the operand is a general register or memory operand. */
1848
1849int
1850reg_or_mem_operand (op, mode)
592696dd
SS
1851 rtx op;
1852 enum machine_mode mode;
9878760c 1853{
b6c9286a
MM
1854 return (gpc_reg_operand (op, mode)
1855 || memory_operand (op, mode)
1856 || volatile_mem_operand (op, mode));
9878760c
RK
1857}
1858
a7a813f7 1859/* Return 1 if the operand is a general register or memory operand without
3cb999d8 1860 pre_inc or pre_dec which produces invalid form of PowerPC lwa
a7a813f7
RK
1861 instruction. */
1862
1863int
1864lwa_operand (op, mode)
592696dd
SS
1865 rtx op;
1866 enum machine_mode mode;
a7a813f7
RK
1867{
1868 rtx inner = op;
1869
1870 if (reload_completed && GET_CODE (inner) == SUBREG)
1871 inner = SUBREG_REG (inner);
1872
1873 return gpc_reg_operand (inner, mode)
1874 || (memory_operand (inner, mode)
1875 && GET_CODE (XEXP (inner, 0)) != PRE_INC
6a40a9d6
DE
1876 && GET_CODE (XEXP (inner, 0)) != PRE_DEC
1877 && (GET_CODE (XEXP (inner, 0)) != PLUS
e903c96a
DE
1878 || GET_CODE (XEXP (XEXP (inner, 0), 1)) != CONST_INT
1879 || INTVAL (XEXP (XEXP (inner, 0), 1)) % 4 == 0));
a7a813f7
RK
1880}
1881
cc4d5fec
JH
1882/* Return 1 if the operand, used inside a MEM, is a SYMBOL_REF. */
1883
1884int
1885symbol_ref_operand (op, mode)
1886 rtx op;
1887 enum machine_mode mode;
1888{
1889 if (mode != VOIDmode && GET_MODE (op) != mode)
1890 return 0;
1891
1892 return (GET_CODE (op) == SYMBOL_REF);
1893}
1894
9878760c 1895/* Return 1 if the operand, used inside a MEM, is a valid first argument
cc4d5fec 1896 to CALL. This is a SYMBOL_REF, a pseudo-register, LR or CTR. */
9878760c
RK
1897
1898int
1899call_operand (op, mode)
592696dd 1900 rtx op;
9878760c
RK
1901 enum machine_mode mode;
1902{
1903 if (mode != VOIDmode && GET_MODE (op) != mode)
1904 return 0;
1905
1906 return (GET_CODE (op) == SYMBOL_REF
cc4d5fec
JH
1907 || (GET_CODE (op) == REG
1908 && (REGNO (op) == LINK_REGISTER_REGNUM
1909 || REGNO (op) == COUNT_REGISTER_REGNUM
1910 || REGNO (op) >= FIRST_PSEUDO_REGISTER)));
9878760c
RK
1911}
1912
2af3d377 1913/* Return 1 if the operand is a SYMBOL_REF for a function known to be in
a4f6c312 1914 this file and the function is not weakly defined. */
2af3d377
RK
1915
1916int
1917current_file_function_operand (op, mode)
592696dd 1918 rtx op;
296b8152 1919 enum machine_mode mode ATTRIBUTE_UNUSED;
2af3d377
RK
1920{
1921 return (GET_CODE (op) == SYMBOL_REF
1922 && (SYMBOL_REF_FLAG (op)
8f1b829e 1923 || (op == XEXP (DECL_RTL (current_function_decl), 0)
c81fc13e 1924 && ! DECL_WEAK (current_function_decl))));
2af3d377
RK
1925}
1926
9878760c
RK
1927/* Return 1 if this operand is a valid input for a move insn. */
1928
1929int
1930input_operand (op, mode)
592696dd 1931 rtx op;
9878760c
RK
1932 enum machine_mode mode;
1933{
eb4e8003 1934 /* Memory is always valid. */
9878760c
RK
1935 if (memory_operand (op, mode))
1936 return 1;
1937
34792e82 1938 /* Only a tiny bit of handling for CONSTANT_P_RTX is necessary. */
01b4cf2b 1939 if (GET_CODE (op) == CONSTANT_P_RTX)
34792e82
JL
1940 return 1;
1941
eb4e8003
RK
1942 /* For floating-point, easy constants are valid. */
1943 if (GET_MODE_CLASS (mode) == MODE_FLOAT
1944 && CONSTANT_P (op)
1945 && easy_fp_constant (op, mode))
1946 return 1;
1947
4e74d8ec
MM
1948 /* Allow any integer constant. */
1949 if (GET_MODE_CLASS (mode) == MODE_INT
e675f625 1950 && (GET_CODE (op) == CONST_INT
e675f625 1951 || GET_CODE (op) == CONST_DOUBLE))
4e74d8ec
MM
1952 return 1;
1953
eb4e8003
RK
1954 /* For floating-point or multi-word mode, the only remaining valid type
1955 is a register. */
9878760c
RK
1956 if (GET_MODE_CLASS (mode) == MODE_FLOAT
1957 || GET_MODE_SIZE (mode) > UNITS_PER_WORD)
eb4e8003 1958 return register_operand (op, mode);
9878760c 1959
88fe15a1
RK
1960 /* The only cases left are integral modes one word or smaller (we
1961 do not get called for MODE_CC values). These can be in any
1962 register. */
1963 if (register_operand (op, mode))
a8b3aeda 1964 return 1;
88fe15a1 1965
84cf9dda 1966 /* A SYMBOL_REF referring to the TOC is valid. */
7fec4abd 1967 if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (op))
84cf9dda
RK
1968 return 1;
1969
9ebbca7d
GK
1970 /* A constant pool expression (relative to the TOC) is valid */
1971 if (TOC_RELATIVE_EXPR_P (op))
b6c9286a
MM
1972 return 1;
1973
88228c4b
MM
1974 /* V.4 allows SYMBOL_REFs and CONSTs that are in the small data region
1975 to be valid. */
f607bc57 1976 if (DEFAULT_ABI == ABI_V4
88228c4b
MM
1977 && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST)
1978 && small_data_operand (op, Pmode))
1979 return 1;
1980
042259f2 1981 return 0;
9878760c 1982}
7509c759 1983
a4f6c312 1984/* Return 1 for an operand in small memory on V.4/eabi. */
7509c759
MM
1985
1986int
1987small_data_operand (op, mode)
296b8152
KG
1988 rtx op ATTRIBUTE_UNUSED;
1989 enum machine_mode mode ATTRIBUTE_UNUSED;
7509c759 1990{
38c1f2d7 1991#if TARGET_ELF
5f59ecb7 1992 rtx sym_ref;
7509c759 1993
d9407988 1994 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
a54d04b7 1995 return 0;
a54d04b7 1996
f607bc57 1997 if (DEFAULT_ABI != ABI_V4)
7509c759
MM
1998 return 0;
1999
88228c4b
MM
2000 if (GET_CODE (op) == SYMBOL_REF)
2001 sym_ref = op;
2002
2003 else if (GET_CODE (op) != CONST
2004 || GET_CODE (XEXP (op, 0)) != PLUS
2005 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
2006 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
7509c759
MM
2007 return 0;
2008
88228c4b 2009 else
dbf55e53
MM
2010 {
2011 rtx sum = XEXP (op, 0);
2012 HOST_WIDE_INT summand;
2013
2014 /* We have to be careful here, because it is the referenced address
2015 that must be 32k from _SDA_BASE_, not just the symbol. */
2016 summand = INTVAL (XEXP (sum, 1));
2017 if (summand < 0 || summand > g_switch_value)
2018 return 0;
2019
2020 sym_ref = XEXP (sum, 0);
2021 }
88228c4b
MM
2022
2023 if (*XSTR (sym_ref, 0) != '@')
7509c759
MM
2024 return 0;
2025
2026 return 1;
d9407988
MM
2027
2028#else
2029 return 0;
2030#endif
7509c759 2031}
9ebbca7d
GK
2032\f
2033static int
2034constant_pool_expr_1 (op, have_sym, have_toc)
2035 rtx op;
2036 int *have_sym;
2037 int *have_toc;
2038{
2039 switch (GET_CODE(op))
2040 {
2041 case SYMBOL_REF:
a4f6c312
SS
2042 if (CONSTANT_POOL_ADDRESS_P (op))
2043 {
2044 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op), Pmode))
2045 {
2046 *have_sym = 1;
2047 return 1;
2048 }
2049 else
2050 return 0;
2051 }
2052 else if (! strcmp (XSTR (op, 0), toc_label_name))
2053 {
2054 *have_toc = 1;
2055 return 1;
2056 }
2057 else
2058 return 0;
9ebbca7d
GK
2059 case PLUS:
2060 case MINUS:
c1f11548
DE
2061 return (constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc)
2062 && constant_pool_expr_1 (XEXP (op, 1), have_sym, have_toc));
9ebbca7d 2063 case CONST:
a4f6c312 2064 return constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc);
9ebbca7d 2065 case CONST_INT:
a4f6c312 2066 return 1;
9ebbca7d 2067 default:
a4f6c312 2068 return 0;
9ebbca7d
GK
2069 }
2070}
2071
2072int
2073constant_pool_expr_p (op)
2074 rtx op;
2075{
2076 int have_sym = 0;
2077 int have_toc = 0;
2078 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym;
2079}
2080
2081int
2082toc_relative_expr_p (op)
2083 rtx op;
2084{
2085 int have_sym = 0;
2086 int have_toc = 0;
2087 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
2088}
2089
2090/* Try machine-dependent ways of modifying an illegitimate address
2091 to be legitimate. If we find one, return the new, valid address.
2092 This is used from only one place: `memory_address' in explow.c.
2093
a4f6c312
SS
2094 OLDX is the address as it was before break_out_memory_refs was
2095 called. In some cases it is useful to look at this to decide what
2096 needs to be done.
9ebbca7d 2097
a4f6c312 2098 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
9ebbca7d 2099
a4f6c312
SS
2100 It is always safe for this function to do nothing. It exists to
2101 recognize opportunities to optimize the output.
9ebbca7d
GK
2102
2103 On RS/6000, first check for the sum of a register with a constant
2104 integer that is out of range. If so, generate code to add the
2105 constant with the low-order 16 bits masked to the register and force
2106 this result into another register (this can be done with `cau').
2107 Then generate an address of REG+(CONST&0xffff), allowing for the
2108 possibility of bit 16 being a one.
2109
2110 Then check for the sum of a register and something not constant, try to
2111 load the other things into a register and return the sum. */
2112rtx
2113rs6000_legitimize_address (x, oldx, mode)
2114 rtx x;
2115 rtx oldx ATTRIBUTE_UNUSED;
2116 enum machine_mode mode;
0ac081f6 2117{
9ebbca7d
GK
2118 if (GET_CODE (x) == PLUS
2119 && GET_CODE (XEXP (x, 0)) == REG
2120 && GET_CODE (XEXP (x, 1)) == CONST_INT
2121 && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) >= 0x10000)
2122 {
2123 HOST_WIDE_INT high_int, low_int;
2124 rtx sum;
a65c591c
DE
2125 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
2126 high_int = INTVAL (XEXP (x, 1)) - low_int;
9ebbca7d
GK
2127 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
2128 GEN_INT (high_int)), 0);
2129 return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));
2130 }
2131 else if (GET_CODE (x) == PLUS
2132 && GET_CODE (XEXP (x, 0)) == REG
2133 && GET_CODE (XEXP (x, 1)) != CONST_INT
6ac7bf2c 2134 && GET_MODE_NUNITS (mode) == 1
a3170dc6
AH
2135 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
2136 || TARGET_POWERPC64
fcce224d 2137 || (mode != DFmode && mode != TFmode))
9ebbca7d
GK
2138 && (TARGET_POWERPC64 || mode != DImode)
2139 && mode != TImode)
2140 {
2141 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
2142 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
2143 }
0ac081f6
AH
2144 else if (ALTIVEC_VECTOR_MODE (mode))
2145 {
2146 rtx reg;
2147
2148 /* Make sure both operands are registers. */
2149 if (GET_CODE (x) == PLUS)
9f85ed45 2150 return gen_rtx_PLUS (Pmode, force_reg (Pmode, XEXP (x, 0)),
0ac081f6
AH
2151 force_reg (Pmode, XEXP (x, 1)));
2152
2153 reg = force_reg (Pmode, x);
2154 return reg;
2155 }
a3170dc6
AH
2156 else if (SPE_VECTOR_MODE (mode))
2157 {
2158 /* We accept [reg + reg] and [reg + OFFSET]. */
2159
2160 if (GET_CODE (x) == PLUS)
2161 {
2162 rtx op1 = XEXP (x, 0);
2163 rtx op2 = XEXP (x, 1);
2164
2165 op1 = force_reg (Pmode, op1);
2166
2167 if (GET_CODE (op2) != REG
2168 && (GET_CODE (op2) != CONST_INT
2169 || !SPE_CONST_OFFSET_OK (INTVAL (op2))))
2170 op2 = force_reg (Pmode, op2);
2171
2172 return gen_rtx_PLUS (Pmode, op1, op2);
2173 }
2174
2175 return force_reg (Pmode, x);
2176 }
9ebbca7d
GK
2177 else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC && ! flag_pic
2178 && GET_CODE (x) != CONST_INT
2179 && GET_CODE (x) != CONST_DOUBLE
2180 && CONSTANT_P (x)
6ac7bf2c
GK
2181 && GET_MODE_NUNITS (mode) == 1
2182 && (GET_MODE_BITSIZE (mode) <= 32
a3170dc6 2183 || ((TARGET_HARD_FLOAT && TARGET_FPRS) && mode == DFmode)))
9ebbca7d
GK
2184 {
2185 rtx reg = gen_reg_rtx (Pmode);
2186 emit_insn (gen_elf_high (reg, (x)));
2187 return gen_rtx_LO_SUM (Pmode, reg, (x));
2188 }
ee890fe2
SS
2189 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
2190 && ! flag_pic
2191 && GET_CODE (x) != CONST_INT
2192 && GET_CODE (x) != CONST_DOUBLE
2193 && CONSTANT_P (x)
a3170dc6 2194 && ((TARGET_HARD_FLOAT && TARGET_FPRS) || mode != DFmode)
ee890fe2
SS
2195 && mode != DImode
2196 && mode != TImode)
2197 {
2198 rtx reg = gen_reg_rtx (Pmode);
2199 emit_insn (gen_macho_high (reg, (x)));
2200 return gen_rtx_LO_SUM (Pmode, reg, (x));
2201 }
9ebbca7d
GK
2202 else if (TARGET_TOC
2203 && CONSTANT_POOL_EXPR_P (x)
a9098fd0 2204 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
9ebbca7d
GK
2205 {
2206 return create_TOC_reference (x);
2207 }
2208 else
2209 return NULL_RTX;
2210}
258bfae2 2211
24ea750e
DJ
2212/* The convention appears to be to define this wherever it is used.
2213 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
2214 is now used here. */
2215#ifndef REG_MODE_OK_FOR_BASE_P
2216#define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
2217#endif
2218
2219/* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
2220 replace the input X, or the original X if no replacement is called for.
2221 The output parameter *WIN is 1 if the calling macro should goto WIN,
2222 0 if it should not.
2223
2224 For RS/6000, we wish to handle large displacements off a base
2225 register by splitting the addend across an addiu/addis and the mem insn.
2226 This cuts number of extra insns needed from 3 to 1.
2227
2228 On Darwin, we use this to generate code for floating point constants.
2229 A movsf_low is generated so we wind up with 2 instructions rather than 3.
2230 The Darwin code is inside #if TARGET_MACHO because only then is
2231 machopic_function_base_name() defined. */
2232rtx
2233rs6000_legitimize_reload_address (x, mode, opnum, type, ind_levels, win)
2234 rtx x;
2235 enum machine_mode mode;
2236 int opnum;
2237 int type;
2238 int ind_levels ATTRIBUTE_UNUSED;
2239 int *win;
2240{
2241 /* We must recognize output that we have already generated ourselves. */
2242 if (GET_CODE (x) == PLUS
2243 && GET_CODE (XEXP (x, 0)) == PLUS
2244 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
2245 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
2246 && GET_CODE (XEXP (x, 1)) == CONST_INT)
2247 {
2248 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2249 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
2250 opnum, (enum reload_type)type);
2251 *win = 1;
2252 return x;
2253 }
3deb2758 2254
24ea750e
DJ
2255#if TARGET_MACHO
2256 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
2257 && GET_CODE (x) == LO_SUM
2258 && GET_CODE (XEXP (x, 0)) == PLUS
2259 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
2260 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
2261 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == CONST
2262 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
2263 && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
2264 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
2265 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF)
2266 {
2267 /* Result of previous invocation of this function on Darwin
6f317ef3 2268 floating point constant. */
24ea750e
DJ
2269 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2270 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
2271 opnum, (enum reload_type)type);
2272 *win = 1;
2273 return x;
2274 }
2275#endif
2276 if (GET_CODE (x) == PLUS
2277 && GET_CODE (XEXP (x, 0)) == REG
2278 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
2279 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
78c875e8 2280 && GET_CODE (XEXP (x, 1)) == CONST_INT
93638d7a 2281 && !SPE_VECTOR_MODE (mode)
78c875e8 2282 && !ALTIVEC_VECTOR_MODE (mode))
24ea750e
DJ
2283 {
2284 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
2285 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
2286 HOST_WIDE_INT high
2287 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
2288
2289 /* Check for 32-bit overflow. */
2290 if (high + low != val)
2291 {
2292 *win = 0;
2293 return x;
2294 }
2295
2296 /* Reload the high part into a base reg; leave the low part
2297 in the mem directly. */
2298
2299 x = gen_rtx_PLUS (GET_MODE (x),
2300 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
2301 GEN_INT (high)),
2302 GEN_INT (low));
2303
2304 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2305 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
2306 opnum, (enum reload_type)type);
2307 *win = 1;
2308 return x;
2309 }
2310#if TARGET_MACHO
2311 if (GET_CODE (x) == SYMBOL_REF
2312 && DEFAULT_ABI == ABI_DARWIN
69ef87e2 2313 && !ALTIVEC_VECTOR_MODE (mode)
24ea750e
DJ
2314 && flag_pic)
2315 {
2316 /* Darwin load of floating point constant. */
2317 rtx offset = gen_rtx (CONST, Pmode,
2318 gen_rtx (MINUS, Pmode, x,
2319 gen_rtx (SYMBOL_REF, Pmode,
2320 machopic_function_base_name ())));
2321 x = gen_rtx (LO_SUM, GET_MODE (x),
2322 gen_rtx (PLUS, Pmode, pic_offset_table_rtx,
2323 gen_rtx (HIGH, Pmode, offset)), offset);
2324 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2325 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
2326 opnum, (enum reload_type)type);
2327 *win = 1;
2328 return x;
2329 }
2330#endif
2331 if (TARGET_TOC
c1f11548
DE
2332 && CONSTANT_POOL_EXPR_P (x)
2333 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
24ea750e
DJ
2334 {
2335 (x) = create_TOC_reference (x);
2336 *win = 1;
2337 return x;
2338 }
2339 *win = 0;
2340 return x;
2341}
2342
258bfae2
FS
2343/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
2344 that is a valid memory address for an instruction.
2345 The MODE argument is the machine mode for the MEM expression
2346 that wants to use this address.
2347
2348 On the RS/6000, there are four valid address: a SYMBOL_REF that
2349 refers to a constant pool entry of an address (or the sum of it
2350 plus a constant), a short (16-bit signed) constant plus a register,
2351 the sum of two registers, or a register indirect, possibly with an
2352 auto-increment. For DFmode and DImode with an constant plus register,
2353 we must ensure that both words are addressable or PowerPC64 with offset
2354 word aligned.
2355
2356 For modes spanning multiple registers (DFmode in 32-bit GPRs,
2357 32-bit DImode, TImode), indexed addressing cannot be used because
2358 adjacent memory cells are accessed by adding word-sized offsets
2359 during assembly output. */
2360int
2361rs6000_legitimate_address (mode, x, reg_ok_strict)
2362 enum machine_mode mode;
2363 rtx x;
2364 int reg_ok_strict;
2365{
2366 if (LEGITIMATE_INDIRECT_ADDRESS_P (x, reg_ok_strict))
2367 return 1;
2368 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
0d6d6892 2369 && !ALTIVEC_VECTOR_MODE (mode)
a3170dc6 2370 && !SPE_VECTOR_MODE (mode)
258bfae2
FS
2371 && TARGET_UPDATE
2372 && LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (x, 0), reg_ok_strict))
2373 return 1;
2374 if (LEGITIMATE_SMALL_DATA_P (mode, x))
2375 return 1;
2376 if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
2377 return 1;
2378 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
2379 if (! reg_ok_strict
2380 && GET_CODE (x) == PLUS
2381 && GET_CODE (XEXP (x, 0)) == REG
2382 && XEXP (x, 0) == virtual_stack_vars_rtx
2383 && GET_CODE (XEXP (x, 1)) == CONST_INT)
2384 return 1;
2385 if (LEGITIMATE_OFFSET_ADDRESS_P (mode, x, reg_ok_strict))
2386 return 1;
2387 if (mode != TImode
a3170dc6
AH
2388 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
2389 || TARGET_POWERPC64
fcce224d 2390 || (mode != DFmode && mode != TFmode))
258bfae2
FS
2391 && (TARGET_POWERPC64 || mode != DImode)
2392 && LEGITIMATE_INDEXED_ADDRESS_P (x, reg_ok_strict))
2393 return 1;
2394 if (LEGITIMATE_LO_SUM_ADDRESS_P (mode, x, reg_ok_strict))
2395 return 1;
2396 return 0;
2397}
fb4d4348 2398\f
a4f6c312
SS
2399/* Try to output insns to set TARGET equal to the constant C if it can
2400 be done in less than N insns. Do all computations in MODE.
2401 Returns the place where the output has been placed if it can be
2402 done and the insns have been emitted. If it would take more than N
2403 insns, zero is returned and no insns and emitted. */
2bfcf297
DB
2404
2405rtx
2406rs6000_emit_set_const (dest, mode, source, n)
2407 rtx dest, source;
2408 enum machine_mode mode;
2409 int n ATTRIBUTE_UNUSED;
2410{
af8cb5c5 2411 rtx result, insn, set;
2bfcf297
DB
2412 HOST_WIDE_INT c0, c1;
2413
af8cb5c5 2414 if (mode == QImode || mode == HImode)
2bfcf297
DB
2415 {
2416 if (dest == NULL)
2417 dest = gen_reg_rtx (mode);
2418 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
2419 return dest;
2420 }
af8cb5c5 2421 else if (mode == SImode)
2bfcf297 2422 {
af8cb5c5
DE
2423 result = no_new_pseudos ? dest : gen_reg_rtx (SImode);
2424
2425 emit_insn (gen_rtx_SET (VOIDmode, result,
2426 GEN_INT (INTVAL (source)
2427 & (~ (HOST_WIDE_INT) 0xffff))));
2428 emit_insn (gen_rtx_SET (VOIDmode, dest,
2429 gen_rtx_IOR (SImode, result,
2430 GEN_INT (INTVAL (source) & 0xffff))));
2431 result = dest;
2bfcf297 2432 }
af8cb5c5 2433 else if (mode == DImode)
2bfcf297 2434 {
af8cb5c5
DE
2435 if (GET_CODE (source) == CONST_INT)
2436 {
2437 c0 = INTVAL (source);
2438 c1 = -(c0 < 0);
2439 }
2440 else if (GET_CODE (source) == CONST_DOUBLE)
2441 {
2bfcf297 2442#if HOST_BITS_PER_WIDE_INT >= 64
af8cb5c5
DE
2443 c0 = CONST_DOUBLE_LOW (source);
2444 c1 = -(c0 < 0);
2bfcf297 2445#else
af8cb5c5
DE
2446 c0 = CONST_DOUBLE_LOW (source);
2447 c1 = CONST_DOUBLE_HIGH (source);
2bfcf297 2448#endif
af8cb5c5
DE
2449 }
2450 else
2451 abort ();
2452
2453 result = rs6000_emit_set_long_const (dest, c0, c1);
2bfcf297
DB
2454 }
2455 else
a4f6c312 2456 abort ();
2bfcf297 2457
af8cb5c5
DE
2458 insn = get_last_insn ();
2459 set = single_set (insn);
2460 if (! CONSTANT_P (SET_SRC (set)))
2461 set_unique_reg_note (insn, REG_EQUAL, source);
2462
2463 return result;
2bfcf297
DB
2464}
2465
2466/* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
2467 fall back to a straight forward decomposition. We do this to avoid
2468 exponential run times encountered when looking for longer sequences
2469 with rs6000_emit_set_const. */
2470static rtx
2471rs6000_emit_set_long_const (dest, c1, c2)
2472 rtx dest;
2473 HOST_WIDE_INT c1, c2;
2474{
2475 if (!TARGET_POWERPC64)
2476 {
2477 rtx operand1, operand2;
2478
2479 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
2480 DImode);
2481 operand2 = operand_subword_force (dest, WORDS_BIG_ENDIAN != 0,
2482 DImode);
2483 emit_move_insn (operand1, GEN_INT (c1));
2484 emit_move_insn (operand2, GEN_INT (c2));
2485 }
2486 else
2487 {
bc06712d 2488 HOST_WIDE_INT ud1, ud2, ud3, ud4;
252b88f7 2489
bc06712d
TR
2490 ud1 = c1 & 0xffff;
2491 ud2 = (c1 & 0xffff0000) >> 16;
2bfcf297 2492#if HOST_BITS_PER_WIDE_INT >= 64
bc06712d 2493 c2 = c1 >> 32;
2bfcf297 2494#endif
bc06712d
TR
2495 ud3 = c2 & 0xffff;
2496 ud4 = (c2 & 0xffff0000) >> 16;
2bfcf297 2497
bc06712d
TR
2498 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
2499 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
2bfcf297 2500 {
bc06712d
TR
2501 if (ud1 & 0x8000)
2502 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
2503 else
2504 emit_move_insn (dest, GEN_INT (ud1));
2bfcf297 2505 }
2bfcf297 2506
bc06712d
TR
2507 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
2508 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
252b88f7 2509 {
bc06712d
TR
2510 if (ud2 & 0x8000)
2511 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
2512 - 0x80000000));
252b88f7 2513 else
bc06712d
TR
2514 emit_move_insn (dest, GEN_INT (ud2 << 16));
2515 if (ud1 != 0)
2516 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
252b88f7 2517 }
bc06712d
TR
2518 else if ((ud4 == 0xffff && (ud3 & 0x8000))
2519 || (ud4 == 0 && ! (ud3 & 0x8000)))
2520 {
2521 if (ud3 & 0x8000)
2522 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
2523 - 0x80000000));
2524 else
2525 emit_move_insn (dest, GEN_INT (ud3 << 16));
2526
2527 if (ud2 != 0)
2528 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud2)));
2529 emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (16)));
2530 if (ud1 != 0)
2531 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
2532 }
2533 else
2534 {
2535 if (ud4 & 0x8000)
2536 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
2537 - 0x80000000));
2538 else
2539 emit_move_insn (dest, GEN_INT (ud4 << 16));
2540
2541 if (ud3 != 0)
2542 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud3)));
2bfcf297 2543
bc06712d
TR
2544 emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32)));
2545 if (ud2 != 0)
2546 emit_move_insn (dest, gen_rtx_IOR (DImode, dest,
2547 GEN_INT (ud2 << 16)));
2548 if (ud1 != 0)
2549 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
2550 }
2551 }
2bfcf297
DB
2552 return dest;
2553}
2554
fb4d4348
GK
2555/* Emit a move from SOURCE to DEST in mode MODE. */
2556void
2557rs6000_emit_move (dest, source, mode)
2558 rtx dest;
2559 rtx source;
2560 enum machine_mode mode;
2561{
2562 rtx operands[2];
2563 operands[0] = dest;
2564 operands[1] = source;
2565
2566 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
2567 if (GET_CODE (operands[1]) == CONST_DOUBLE
2568 && ! FLOAT_MODE_P (mode)
2569 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
2570 {
2571 /* FIXME. This should never happen. */
2572 /* Since it seems that it does, do the safe thing and convert
2573 to a CONST_INT. */
2496c7bd 2574 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
fb4d4348
GK
2575 }
2576 if (GET_CODE (operands[1]) == CONST_DOUBLE
2577 && ! FLOAT_MODE_P (mode)
2578 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2579 && CONST_DOUBLE_LOW (operands[1]) >= 0)
2580 || (CONST_DOUBLE_HIGH (operands[1]) == -1
2581 && CONST_DOUBLE_LOW (operands[1]) < 0)))
2582 abort ();
c9e8cb32
DD
2583
2584 /* Check if GCC is setting up a block move that will end up using FP
2585 registers as temporaries. We must make sure this is acceptable. */
2586 if (GET_CODE (operands[0]) == MEM
2587 && GET_CODE (operands[1]) == MEM
2588 && mode == DImode
41543739
GK
2589 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
2590 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
2591 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
2592 ? 32 : MEM_ALIGN (operands[0])))
2593 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
2594 ? 32
2595 : MEM_ALIGN (operands[1]))))
2596 && ! MEM_VOLATILE_P (operands [0])
2597 && ! MEM_VOLATILE_P (operands [1]))
c9e8cb32 2598 {
41543739
GK
2599 emit_move_insn (adjust_address (operands[0], SImode, 0),
2600 adjust_address (operands[1], SImode, 0));
2601 emit_move_insn (adjust_address (operands[0], SImode, 4),
2602 adjust_address (operands[1], SImode, 4));
c9e8cb32
DD
2603 return;
2604 }
fb4d4348 2605
67cef334
DE
2606 if (!no_new_pseudos)
2607 {
2608 if (GET_CODE (operands[1]) == MEM && optimize > 0
2609 && (mode == QImode || mode == HImode || mode == SImode)
2610 && GET_MODE_SIZE (mode) < GET_MODE_SIZE (word_mode))
2611 {
2612 rtx reg = gen_reg_rtx (word_mode);
2613
2614 emit_insn (gen_rtx_SET (word_mode, reg,
2615 gen_rtx_ZERO_EXTEND (word_mode,
2616 operands[1])));
2617 operands[1] = gen_lowpart (mode, reg);
2618 }
2619 if (GET_CODE (operands[0]) != REG)
2620 operands[1] = force_reg (mode, operands[1]);
2621 }
a9098fd0 2622
a3170dc6
AH
2623 if (mode == SFmode && ! TARGET_POWERPC
2624 && TARGET_HARD_FLOAT && TARGET_FPRS
ffc14f31 2625 && GET_CODE (operands[0]) == MEM)
fb4d4348 2626 {
ffc14f31
GK
2627 int regnum;
2628
2629 if (reload_in_progress || reload_completed)
2630 regnum = true_regnum (operands[1]);
2631 else if (GET_CODE (operands[1]) == REG)
2632 regnum = REGNO (operands[1]);
2633 else
2634 regnum = -1;
fb4d4348
GK
2635
2636 /* If operands[1] is a register, on POWER it may have
2637 double-precision data in it, so truncate it to single
2638 precision. */
2639 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
2640 {
2641 rtx newreg;
2642 newreg = (no_new_pseudos ? operands[1] : gen_reg_rtx (mode));
2643 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
2644 operands[1] = newreg;
2645 }
2646 }
2647
a9098fd0
GK
2648 /* Handle the case where reload calls us with an invalid address;
2649 and the case of CONSTANT_P_RTX. */
16861f33 2650 if (!ALTIVEC_VECTOR_MODE (mode)
69ef87e2
AH
2651 && (! general_operand (operands[1], mode)
2652 || ! nonimmediate_operand (operands[0], mode)
2653 || GET_CODE (operands[1]) == CONSTANT_P_RTX))
fb4d4348
GK
2654 {
2655 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2656 return;
2657 }
a9098fd0 2658
fb4d4348
GK
2659 /* FIXME: In the long term, this switch statement should go away
2660 and be replaced by a sequence of tests based on things like
2661 mode == Pmode. */
2662 switch (mode)
2663 {
2664 case HImode:
2665 case QImode:
2666 if (CONSTANT_P (operands[1])
2667 && GET_CODE (operands[1]) != CONST_INT)
a9098fd0 2668 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
2669 break;
2670
06f4e019 2671 case TFmode:
fb4d4348
GK
2672 case DFmode:
2673 case SFmode:
2674 if (CONSTANT_P (operands[1])
2675 && ! easy_fp_constant (operands[1], mode))
a9098fd0 2676 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
2677 break;
2678
0ac081f6
AH
2679 case V16QImode:
2680 case V8HImode:
2681 case V4SFmode:
2682 case V4SImode:
a3170dc6
AH
2683 case V4HImode:
2684 case V2SFmode:
2685 case V2SImode:
00a892b8 2686 case V1DImode:
69ef87e2
AH
2687 if (CONSTANT_P (operands[1])
2688 && !easy_vector_constant (operands[1]))
0ac081f6
AH
2689 operands[1] = force_const_mem (mode, operands[1]);
2690 break;
2691
fb4d4348 2692 case SImode:
a9098fd0 2693 case DImode:
fb4d4348
GK
2694 /* Use default pattern for address of ELF small data */
2695 if (TARGET_ELF
a9098fd0 2696 && mode == Pmode
f607bc57 2697 && DEFAULT_ABI == ABI_V4
a9098fd0
GK
2698 && (GET_CODE (operands[1]) == SYMBOL_REF
2699 || GET_CODE (operands[1]) == CONST)
2700 && small_data_operand (operands[1], mode))
fb4d4348
GK
2701 {
2702 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2703 return;
2704 }
2705
f607bc57 2706 if (DEFAULT_ABI == ABI_V4
a9098fd0
GK
2707 && mode == Pmode && mode == SImode
2708 && flag_pic == 1 && got_operand (operands[1], mode))
fb4d4348
GK
2709 {
2710 emit_insn (gen_movsi_got (operands[0], operands[1]));
2711 return;
2712 }
2713
ee890fe2
SS
2714 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
2715 && TARGET_NO_TOC && ! flag_pic
a9098fd0 2716 && mode == Pmode
fb4d4348
GK
2717 && CONSTANT_P (operands[1])
2718 && GET_CODE (operands[1]) != HIGH
2719 && GET_CODE (operands[1]) != CONST_INT)
2720 {
a9098fd0 2721 rtx target = (no_new_pseudos ? operands[0] : gen_reg_rtx (mode));
fb4d4348
GK
2722
2723 /* If this is a function address on -mcall-aixdesc,
2724 convert it to the address of the descriptor. */
2725 if (DEFAULT_ABI == ABI_AIX
2726 && GET_CODE (operands[1]) == SYMBOL_REF
2727 && XSTR (operands[1], 0)[0] == '.')
2728 {
2729 const char *name = XSTR (operands[1], 0);
2730 rtx new_ref;
2731 while (*name == '.')
2732 name++;
2733 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
2734 CONSTANT_POOL_ADDRESS_P (new_ref)
2735 = CONSTANT_POOL_ADDRESS_P (operands[1]);
2736 SYMBOL_REF_FLAG (new_ref) = SYMBOL_REF_FLAG (operands[1]);
2737 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
2738 operands[1] = new_ref;
2739 }
7509c759 2740
ee890fe2
SS
2741 if (DEFAULT_ABI == ABI_DARWIN)
2742 {
2743 emit_insn (gen_macho_high (target, operands[1]));
2744 emit_insn (gen_macho_low (operands[0], target, operands[1]));
2745 return;
2746 }
2747
fb4d4348
GK
2748 emit_insn (gen_elf_high (target, operands[1]));
2749 emit_insn (gen_elf_low (operands[0], target, operands[1]));
2750 return;
2751 }
2752
a9098fd0
GK
2753 /* If this is a SYMBOL_REF that refers to a constant pool entry,
2754 and we have put it in the TOC, we just need to make a TOC-relative
2755 reference to it. */
2756 if (TARGET_TOC
2757 && GET_CODE (operands[1]) == SYMBOL_REF
2758 && CONSTANT_POOL_EXPR_P (operands[1])
2759 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
2760 get_pool_mode (operands[1])))
fb4d4348 2761 {
a9098fd0 2762 operands[1] = create_TOC_reference (operands[1]);
fb4d4348 2763 }
a9098fd0
GK
2764 else if (mode == Pmode
2765 && CONSTANT_P (operands[1])
38886f37
AO
2766 && ((GET_CODE (operands[1]) != CONST_INT
2767 && ! easy_fp_constant (operands[1], mode))
2768 || (GET_CODE (operands[1]) == CONST_INT
2769 && num_insns_constant (operands[1], mode) > 2)
2770 || (GET_CODE (operands[0]) == REG
2771 && FP_REGNO_P (REGNO (operands[0]))))
a9098fd0
GK
2772 && GET_CODE (operands[1]) != HIGH
2773 && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1])
2774 && ! TOC_RELATIVE_EXPR_P (operands[1]))
fb4d4348
GK
2775 {
2776 /* Emit a USE operation so that the constant isn't deleted if
2777 expensive optimizations are turned on because nobody
2778 references it. This should only be done for operands that
2779 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
2780 This should not be done for operands that contain LABEL_REFs.
2781 For now, we just handle the obvious case. */
2782 if (GET_CODE (operands[1]) != LABEL_REF)
2783 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
2784
c859cda6 2785#if TARGET_MACHO
ee890fe2
SS
2786 /* Darwin uses a special PIC legitimizer. */
2787 if (DEFAULT_ABI == ABI_DARWIN && flag_pic)
2788 {
ee890fe2
SS
2789 operands[1] =
2790 rs6000_machopic_legitimize_pic_address (operands[1], mode,
c859cda6
DJ
2791 operands[0]);
2792 if (operands[0] != operands[1])
2793 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
ee890fe2
SS
2794 return;
2795 }
c859cda6 2796#endif
ee890fe2 2797
fb4d4348
GK
2798 /* If we are to limit the number of things we put in the TOC and
2799 this is a symbol plus a constant we can add in one insn,
2800 just put the symbol in the TOC and add the constant. Don't do
2801 this if reload is in progress. */
2802 if (GET_CODE (operands[1]) == CONST
2803 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
2804 && GET_CODE (XEXP (operands[1], 0)) == PLUS
a9098fd0 2805 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
fb4d4348
GK
2806 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
2807 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
2808 && ! side_effects_p (operands[0]))
2809 {
a4f6c312
SS
2810 rtx sym =
2811 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
fb4d4348
GK
2812 rtx other = XEXP (XEXP (operands[1], 0), 1);
2813
a9098fd0
GK
2814 sym = force_reg (mode, sym);
2815 if (mode == SImode)
2816 emit_insn (gen_addsi3 (operands[0], sym, other));
2817 else
2818 emit_insn (gen_adddi3 (operands[0], sym, other));
fb4d4348
GK
2819 return;
2820 }
2821
a9098fd0 2822 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
2823
2824 if (TARGET_TOC
d34c5b80
DE
2825 && CONSTANT_POOL_EXPR_P (XEXP (operands[1], 0))
2826 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
2827 get_pool_constant (XEXP (operands[1], 0)),
2828 get_pool_mode (XEXP (operands[1], 0))))
a9098fd0 2829 {
ba4828e0
RK
2830 operands[1]
2831 = gen_rtx_MEM (mode,
2832 create_TOC_reference (XEXP (operands[1], 0)));
2833 set_mem_alias_set (operands[1], get_TOC_alias_set ());
fb4d4348 2834 RTX_UNCHANGING_P (operands[1]) = 1;
a9098fd0 2835 }
fb4d4348
GK
2836 }
2837 break;
a9098fd0 2838
fb4d4348
GK
2839 case TImode:
2840 if (GET_CODE (operands[0]) == MEM
2841 && GET_CODE (XEXP (operands[0], 0)) != REG
2842 && ! reload_in_progress)
792760b9
RK
2843 operands[0]
2844 = replace_equiv_address (operands[0],
2845 copy_addr_to_reg (XEXP (operands[0], 0)));
fb4d4348
GK
2846
2847 if (GET_CODE (operands[1]) == MEM
2848 && GET_CODE (XEXP (operands[1], 0)) != REG
2849 && ! reload_in_progress)
792760b9
RK
2850 operands[1]
2851 = replace_equiv_address (operands[1],
2852 copy_addr_to_reg (XEXP (operands[1], 0)));
fb4d4348
GK
2853 break;
2854
2855 default:
2856 abort ();
2857 }
2858
a9098fd0
GK
2859 /* Above, we may have called force_const_mem which may have returned
2860 an invalid address. If we can, fix this up; otherwise, reload will
2861 have to deal with it. */
2862 if (GET_CODE (operands[1]) == MEM
2863 && ! memory_address_p (mode, XEXP (operands[1], 0))
2864 && ! reload_in_progress)
f4ef873c 2865 operands[1] = adjust_address (operands[1], mode, 0);
a9098fd0 2866
fb4d4348 2867 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
02a4ec28 2868 return;
fb4d4348 2869}
4697a36c
MM
2870\f
2871/* Initialize a variable CUM of type CUMULATIVE_ARGS
2872 for a call to a function whose data type is FNTYPE.
2873 For a library call, FNTYPE is 0.
2874
2875 For incoming args we set the number of arguments in the prototype large
1c20ae99 2876 so we never return a PARALLEL. */
4697a36c
MM
2877
2878void
2879init_cumulative_args (cum, fntype, libname, incoming)
2880 CUMULATIVE_ARGS *cum;
2881 tree fntype;
296b8152 2882 rtx libname ATTRIBUTE_UNUSED;
4697a36c
MM
2883 int incoming;
2884{
2885 static CUMULATIVE_ARGS zero_cumulative;
2886
2887 *cum = zero_cumulative;
2888 cum->words = 0;
2889 cum->fregno = FP_ARG_MIN_REG;
0ac081f6 2890 cum->vregno = ALTIVEC_ARG_MIN_REG;
4697a36c 2891 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
7509c759 2892 cum->call_cookie = CALL_NORMAL;
4cc833b7 2893 cum->sysv_gregno = GP_ARG_MIN_REG;
4697a36c
MM
2894
2895 if (incoming)
bd227acc 2896 cum->nargs_prototype = 1000; /* don't return a PARALLEL */
4697a36c
MM
2897
2898 else if (cum->prototype)
2899 cum->nargs_prototype = (list_length (TYPE_ARG_TYPES (fntype)) - 1
2900 + (TYPE_MODE (TREE_TYPE (fntype)) == BLKmode
2901 || RETURN_IN_MEMORY (TREE_TYPE (fntype))));
2902
2903 else
2904 cum->nargs_prototype = 0;
2905
2906 cum->orig_nargs = cum->nargs_prototype;
7509c759 2907
a5c76ee6
ZW
2908 /* Check for a longcall attribute. */
2909 if (fntype
2910 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
2911 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype)))
6a4cee5f
MM
2912 cum->call_cookie = CALL_LONG;
2913
4697a36c
MM
2914 if (TARGET_DEBUG_ARG)
2915 {
2916 fprintf (stderr, "\ninit_cumulative_args:");
2917 if (fntype)
2918 {
2919 tree ret_type = TREE_TYPE (fntype);
2920 fprintf (stderr, " ret code = %s,",
2921 tree_code_name[ (int)TREE_CODE (ret_type) ]);
2922 }
2923
6a4cee5f
MM
2924 if (cum->call_cookie & CALL_LONG)
2925 fprintf (stderr, " longcall,");
2926
4697a36c
MM
2927 fprintf (stderr, " proto = %d, nargs = %d\n",
2928 cum->prototype, cum->nargs_prototype);
2929 }
2930}
2931\f
c229cba9
DE
2932/* If defined, a C expression which determines whether, and in which
2933 direction, to pad out an argument with extra space. The value
2934 should be of type `enum direction': either `upward' to pad above
2935 the argument, `downward' to pad below, or `none' to inhibit
2936 padding.
2937
2938 For the AIX ABI structs are always stored left shifted in their
2939 argument slot. */
2940
9ebbca7d 2941enum direction
c229cba9
DE
2942function_arg_padding (mode, type)
2943 enum machine_mode mode;
2944 tree type;
2945{
c85f7c16 2946 if (type != 0 && AGGREGATE_TYPE_P (type))
9ebbca7d 2947 return upward;
c229cba9
DE
2948
2949 /* This is the default definition. */
2950 return (! BYTES_BIG_ENDIAN
9ebbca7d 2951 ? upward
c229cba9
DE
2952 : ((mode == BLKmode
2953 ? (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
2954 && int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT))
2955 : GET_MODE_BITSIZE (mode) < PARM_BOUNDARY)
9ebbca7d 2956 ? downward : upward));
c229cba9
DE
2957}
2958
b6c9286a
MM
2959/* If defined, a C expression that gives the alignment boundary, in bits,
2960 of an argument with the specified mode and type. If it is not defined,
2961 PARM_BOUNDARY is used for all arguments.
2962
2310f99a 2963 V.4 wants long longs to be double word aligned. */
b6c9286a
MM
2964
2965int
2966function_arg_boundary (mode, type)
2967 enum machine_mode mode;
9ebbca7d 2968 tree type ATTRIBUTE_UNUSED;
b6c9286a 2969{
f607bc57 2970 if (DEFAULT_ABI == ABI_V4 && (mode == DImode || mode == DFmode))
e1f83b4d 2971 return 64;
a3170dc6
AH
2972 else if (SPE_VECTOR_MODE (mode))
2973 return 64;
0ac081f6
AH
2974 else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
2975 return 128;
9ebbca7d 2976 else
b6c9286a 2977 return PARM_BOUNDARY;
b6c9286a
MM
2978}
2979\f
4697a36c
MM
2980/* Update the data in CUM to advance over an argument
2981 of mode MODE and data type TYPE.
2982 (TYPE is null for libcalls where that information may not be available.) */
2983
2984void
2985function_arg_advance (cum, mode, type, named)
2986 CUMULATIVE_ARGS *cum;
2987 enum machine_mode mode;
2988 tree type;
2989 int named;
2990{
2991 cum->nargs_prototype--;
2992
0ac081f6
AH
2993 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
2994 {
2995 if (cum->vregno <= ALTIVEC_ARG_MAX_REG && cum->nargs_prototype >= 0)
2996 cum->vregno++;
2997 else
2998 cum->words += RS6000_ARG_SIZE (mode, type);
2999 }
a4b0320c
AH
3000 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
3001 && named && cum->sysv_gregno <= GP_ARG_MAX_REG)
3002 cum->sysv_gregno++;
f607bc57 3003 else if (DEFAULT_ABI == ABI_V4)
4697a36c 3004 {
a3170dc6 3005 if (TARGET_HARD_FLOAT && TARGET_FPRS
4cc833b7 3006 && (mode == SFmode || mode == DFmode))
4697a36c 3007 {
4cc833b7
RH
3008 if (cum->fregno <= FP_ARG_V4_MAX_REG)
3009 cum->fregno++;
3010 else
3011 {
3012 if (mode == DFmode)
3013 cum->words += cum->words & 1;
d34c5b80 3014 cum->words += RS6000_ARG_SIZE (mode, type);
4cc833b7 3015 }
4697a36c 3016 }
4cc833b7
RH
3017 else
3018 {
3019 int n_words;
3020 int gregno = cum->sysv_gregno;
3021
3022 /* Aggregates and IEEE quad get passed by reference. */
3023 if ((type && AGGREGATE_TYPE_P (type))
3024 || mode == TFmode)
3025 n_words = 1;
3026 else
d34c5b80 3027 n_words = RS6000_ARG_SIZE (mode, type);
4cc833b7 3028
a4b0320c 3029 /* Long long and SPE vectors are put in odd registers. */
4cc833b7
RH
3030 if (n_words == 2 && (gregno & 1) == 0)
3031 gregno += 1;
3032
a4b0320c
AH
3033 /* Long long and SPE vectors are not split between registers
3034 and stack. */
4cc833b7
RH
3035 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
3036 {
3037 /* Long long is aligned on the stack. */
3038 if (n_words == 2)
3039 cum->words += cum->words & 1;
3040 cum->words += n_words;
3041 }
4697a36c 3042
4cc833b7
RH
3043 /* Note: continuing to accumulate gregno past when we've started
3044 spilling to the stack indicates the fact that we've started
3045 spilling to the stack to expand_builtin_saveregs. */
3046 cum->sysv_gregno = gregno + n_words;
3047 }
4697a36c 3048
4cc833b7
RH
3049 if (TARGET_DEBUG_ARG)
3050 {
3051 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
3052 cum->words, cum->fregno);
3053 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
3054 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
3055 fprintf (stderr, "mode = %4s, named = %d\n",
3056 GET_MODE_NAME (mode), named);
3057 }
4697a36c
MM
3058 }
3059 else
4cc833b7
RH
3060 {
3061 int align = (TARGET_32BIT && (cum->words & 1) != 0
3062 && function_arg_boundary (mode, type) == 64) ? 1 : 0;
a4f6c312 3063
d34c5b80 3064 cum->words += align + RS6000_ARG_SIZE (mode, type);
4697a36c 3065
a3170dc6
AH
3066 if (GET_MODE_CLASS (mode) == MODE_FLOAT
3067 && TARGET_HARD_FLOAT && TARGET_FPRS)
fcce224d 3068 cum->fregno += (mode == TFmode ? 2 : 1);
4cc833b7
RH
3069
3070 if (TARGET_DEBUG_ARG)
3071 {
3072 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
3073 cum->words, cum->fregno);
3074 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
3075 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
3076 fprintf (stderr, "named = %d, align = %d\n", named, align);
3077 }
3078 }
4697a36c
MM
3079}
3080\f
3081/* Determine where to put an argument to a function.
3082 Value is zero to push the argument on the stack,
3083 or a hard register in which to store the argument.
3084
3085 MODE is the argument's machine mode.
3086 TYPE is the data type of the argument (as a tree).
3087 This is null for libcalls where that information may
3088 not be available.
3089 CUM is a variable of type CUMULATIVE_ARGS which gives info about
3090 the preceding args and about the function being called.
3091 NAMED is nonzero if this argument is a named parameter
3092 (otherwise it is an extra parameter matching an ellipsis).
3093
3094 On RS/6000 the first eight words of non-FP are normally in registers
3095 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
3096 Under V.4, the first 8 FP args are in registers.
3097
3098 If this is floating-point and no prototype is specified, we use
3099 both an FP and integer register (or possibly FP reg and stack). Library
3100 functions (when TYPE is zero) always have the proper types for args,
3101 so we can pass the FP value just in one register. emit_library_function
1c20ae99 3102 doesn't support PARALLEL anyway. */
4697a36c
MM
3103
3104struct rtx_def *
3105function_arg (cum, mode, type, named)
3106 CUMULATIVE_ARGS *cum;
3107 enum machine_mode mode;
3108 tree type;
20c29ebe 3109 int named;
4697a36c 3110{
4cc833b7 3111 enum rs6000_abi abi = DEFAULT_ABI;
4697a36c 3112
a4f6c312
SS
3113 /* Return a marker to indicate whether CR1 needs to set or clear the
3114 bit that V.4 uses to say fp args were passed in registers.
3115 Assume that we don't need the marker for software floating point,
3116 or compiler generated library calls. */
4697a36c
MM
3117 if (mode == VOIDmode)
3118 {
f607bc57 3119 if (abi == ABI_V4
7509c759 3120 && cum->nargs_prototype < 0
4697a36c 3121 && type && (cum->prototype || TARGET_NO_PROTOTYPE))
7509c759 3122 {
a3170dc6
AH
3123 /* For the SPE, we need to crxor CR6 always. */
3124 if (TARGET_SPE_ABI)
3125 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
3126 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
3127 return GEN_INT (cum->call_cookie
3128 | ((cum->fregno == FP_ARG_MIN_REG)
3129 ? CALL_V4_SET_FP_ARGS
3130 : CALL_V4_CLEAR_FP_ARGS));
7509c759 3131 }
4697a36c 3132
7509c759 3133 return GEN_INT (cum->call_cookie);
4697a36c
MM
3134 }
3135
0ac081f6
AH
3136 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
3137 {
20c29ebe 3138 if (named && cum->vregno <= ALTIVEC_ARG_MAX_REG)
0ac081f6
AH
3139 return gen_rtx_REG (mode, cum->vregno);
3140 else
3141 return NULL;
3142 }
a4b0320c 3143 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode) && named)
a3170dc6 3144 {
a4b0320c 3145 if (cum->sysv_gregno <= GP_ARG_MAX_REG)
a3170dc6
AH
3146 return gen_rtx_REG (mode, cum->sysv_gregno);
3147 else
3148 return NULL;
3149 }
f607bc57 3150 else if (abi == ABI_V4)
4697a36c 3151 {
a3170dc6 3152 if (TARGET_HARD_FLOAT && TARGET_FPRS
4cc833b7
RH
3153 && (mode == SFmode || mode == DFmode))
3154 {
3155 if (cum->fregno <= FP_ARG_V4_MAX_REG)
3156 return gen_rtx_REG (mode, cum->fregno);
3157 else
3158 return NULL;
3159 }
3160 else
3161 {
3162 int n_words;
3163 int gregno = cum->sysv_gregno;
3164
3165 /* Aggregates and IEEE quad get passed by reference. */
3166 if ((type && AGGREGATE_TYPE_P (type))
3167 || mode == TFmode)
3168 n_words = 1;
3169 else
d34c5b80 3170 n_words = RS6000_ARG_SIZE (mode, type);
4cc833b7 3171
a4b0320c 3172 /* Long long and SPE vectors are put in odd registers. */
4cc833b7
RH
3173 if (n_words == 2 && (gregno & 1) == 0)
3174 gregno += 1;
3175
a4b0320c
AH
3176 /* Long long and SPE vectors are not split between registers
3177 and stack. */
4cc833b7 3178 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
a4b0320c
AH
3179 {
3180 /* SPE vectors in ... get split into 2 registers. */
3181 if (TARGET_SPE && TARGET_SPE_ABI
3182 && SPE_VECTOR_MODE (mode) && !named)
3183 {
3184 rtx r1, r2;
57de2c8f 3185 enum machine_mode m = SImode;
f9dd72da 3186
a4b0320c
AH
3187 r1 = gen_rtx_REG (m, gregno);
3188 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
3189 r2 = gen_rtx_REG (m, gregno + 1);
3190 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
3191 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
3192 }
3193 return gen_rtx_REG (mode, gregno);
3194 }
4cc833b7
RH
3195 else
3196 return NULL;
3197 }
4697a36c 3198 }
4cc833b7
RH
3199 else
3200 {
3201 int align = (TARGET_32BIT && (cum->words & 1) != 0
3202 && function_arg_boundary (mode, type) == 64) ? 1 : 0;
3203 int align_words = cum->words + align;
4697a36c 3204
4cc833b7
RH
3205 if (type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
3206 return NULL_RTX;
3207
3208 if (USE_FP_FOR_ARG_P (*cum, mode, type))
3209 {
3210 if (! type
3211 || ((cum->nargs_prototype > 0)
3212 /* IBM AIX extended its linkage convention definition always
3213 to require FP args after register save area hole on the
3214 stack. */
3215 && (DEFAULT_ABI != ABI_AIX
3216 || ! TARGET_XL_CALL
3217 || (align_words < GP_ARG_NUM_REG))))
3218 return gen_rtx_REG (mode, cum->fregno);
3219
3220 return gen_rtx_PARALLEL (mode,
3221 gen_rtvec (2,
39403d82 3222 gen_rtx_EXPR_LIST (VOIDmode,
1c20ae99
JW
3223 ((align_words >= GP_ARG_NUM_REG)
3224 ? NULL_RTX
3225 : (align_words
d34c5b80 3226 + RS6000_ARG_SIZE (mode, type)
1c20ae99
JW
3227 > GP_ARG_NUM_REG
3228 /* If this is partially on the stack, then
3229 we only include the portion actually
3230 in registers here. */
39403d82 3231 ? gen_rtx_REG (SImode,
1c20ae99 3232 GP_ARG_MIN_REG + align_words)
39403d82 3233 : gen_rtx_REG (mode,
1c20ae99
JW
3234 GP_ARG_MIN_REG + align_words))),
3235 const0_rtx),
39403d82
DE
3236 gen_rtx_EXPR_LIST (VOIDmode,
3237 gen_rtx_REG (mode, cum->fregno),
1c20ae99 3238 const0_rtx)));
4cc833b7
RH
3239 }
3240 else if (align_words < GP_ARG_NUM_REG)
3241 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
3242 else
3243 return NULL_RTX;
4697a36c 3244 }
4697a36c
MM
3245}
3246\f
3247/* For an arg passed partly in registers and partly in memory,
3248 this is the number of registers used.
3249 For args passed entirely in registers or entirely in memory, zero. */
3250
3251int
3252function_arg_partial_nregs (cum, mode, type, named)
3253 CUMULATIVE_ARGS *cum;
3254 enum machine_mode mode;
3255 tree type;
d34c5b80 3256 int named ATTRIBUTE_UNUSED;
4697a36c 3257{
f607bc57 3258 if (DEFAULT_ABI == ABI_V4)
4697a36c 3259 return 0;
4697a36c 3260
0ac081f6
AH
3261 if (USE_FP_FOR_ARG_P (*cum, mode, type)
3262 || USE_ALTIVEC_FOR_ARG_P (*cum, mode, type))
4697a36c
MM
3263 {
3264 if (cum->nargs_prototype >= 0)
3265 return 0;
3266 }
3267
3268 if (cum->words < GP_ARG_NUM_REG
d34c5b80 3269 && GP_ARG_NUM_REG < (cum->words + RS6000_ARG_SIZE (mode, type)))
4697a36c
MM
3270 {
3271 int ret = GP_ARG_NUM_REG - cum->words;
3272 if (ret && TARGET_DEBUG_ARG)
3273 fprintf (stderr, "function_arg_partial_nregs: %d\n", ret);
3274
3275 return ret;
3276 }
3277
3278 return 0;
3279}
3280\f
3281/* A C expression that indicates when an argument must be passed by
3282 reference. If nonzero for an argument, a copy of that argument is
3283 made in memory and a pointer to the argument is passed instead of
3284 the argument itself. The pointer is passed in whatever way is
3285 appropriate for passing a pointer to that type.
3286
3287 Under V.4, structures and unions are passed by reference. */
3288
3289int
3290function_arg_pass_by_reference (cum, mode, type, named)
296b8152
KG
3291 CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
3292 enum machine_mode mode ATTRIBUTE_UNUSED;
4697a36c 3293 tree type;
296b8152 3294 int named ATTRIBUTE_UNUSED;
4697a36c 3295{
f607bc57 3296 if (DEFAULT_ABI == ABI_V4
4cc833b7
RH
3297 && ((type && AGGREGATE_TYPE_P (type))
3298 || mode == TFmode))
4697a36c
MM
3299 {
3300 if (TARGET_DEBUG_ARG)
3301 fprintf (stderr, "function_arg_pass_by_reference: aggregate\n");
3302
3303 return 1;
3304 }
4697a36c
MM
3305
3306 return 0;
3307}
4697a36c
MM
3308\f
3309/* Perform any needed actions needed for a function that is receiving a
3310 variable number of arguments.
3311
3312 CUM is as above.
3313
3314 MODE and TYPE are the mode and type of the current parameter.
3315
3316 PRETEND_SIZE is a variable that should be set to the amount of stack
3317 that must be pushed by the prolog to pretend that our caller pushed
3318 it.
3319
3320 Normally, this macro will push all remaining incoming registers on the
3321 stack and set PRETEND_SIZE to the length of the registers pushed. */
3322
3323void
3324setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
3325 CUMULATIVE_ARGS *cum;
3326 enum machine_mode mode;
3327 tree type;
3328 int *pretend_size;
3329 int no_rtl;
3330
3331{
4cc833b7
RH
3332 CUMULATIVE_ARGS next_cum;
3333 int reg_size = TARGET_32BIT ? 4 : 8;
ca5adc63 3334 rtx save_area = NULL_RTX, mem;
dfafc897 3335 int first_reg_offset, set;
d34c5b80
DE
3336 tree fntype;
3337 int stdarg_p;
4697a36c 3338
d34c5b80
DE
3339 fntype = TREE_TYPE (current_function_decl);
3340 stdarg_p = (TYPE_ARG_TYPES (fntype) != 0
3341 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3342 != void_type_node));
4cc833b7 3343
d34c5b80
DE
3344 /* For varargs, we do not want to skip the dummy va_dcl argument.
3345 For stdargs, we do want to skip the last named argument. */
3346 next_cum = *cum;
3347 if (stdarg_p)
3348 function_arg_advance (&next_cum, mode, type, 1);
4cc833b7 3349
f607bc57 3350 if (DEFAULT_ABI == ABI_V4)
d34c5b80 3351 {
4cc833b7 3352 /* Indicate to allocate space on the stack for varargs save area. */
00dba523 3353 cfun->machine->sysv_varargs_p = 1;
60e2d0ca 3354 if (! no_rtl)
2c4974b7 3355 save_area = plus_constant (virtual_stack_vars_rtx,
bd227acc 3356 - RS6000_VARARGS_SIZE);
4cc833b7
RH
3357
3358 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
4697a36c 3359 }
60e2d0ca 3360 else
4697a36c 3361 {
d34c5b80 3362 first_reg_offset = next_cum.words;
4cc833b7 3363 save_area = virtual_incoming_args_rtx;
00dba523 3364 cfun->machine->sysv_varargs_p = 0;
4697a36c
MM
3365
3366 if (MUST_PASS_IN_STACK (mode, type))
d34c5b80 3367 first_reg_offset += RS6000_ARG_SIZE (TYPE_MODE (type), type);
4cc833b7 3368 }
4697a36c 3369
dfafc897 3370 set = get_varargs_alias_set ();
c81fc13e 3371 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG)
4cc833b7 3372 {
dfafc897
FS
3373 mem = gen_rtx_MEM (BLKmode,
3374 plus_constant (save_area,
3375 first_reg_offset * reg_size)),
ba4828e0 3376 set_mem_alias_set (mem, set);
8ac61af7 3377 set_mem_align (mem, BITS_PER_WORD);
dfafc897 3378
4cc833b7 3379 move_block_from_reg
dfafc897 3380 (GP_ARG_MIN_REG + first_reg_offset, mem,
4cc833b7
RH
3381 GP_ARG_NUM_REG - first_reg_offset,
3382 (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD);
3383
3384 /* ??? Does ABI_V4 need this at all? */
4697a36c
MM
3385 *pretend_size = (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD;
3386 }
3387
4697a36c 3388 /* Save FP registers if needed. */
f607bc57 3389 if (DEFAULT_ABI == ABI_V4
a3170dc6
AH
3390 && TARGET_HARD_FLOAT && TARGET_FPRS
3391 && ! no_rtl
4cc833b7 3392 && next_cum.fregno <= FP_ARG_V4_MAX_REG)
4697a36c 3393 {
4cc833b7 3394 int fregno = next_cum.fregno;
9ebbca7d 3395 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
4cc833b7
RH
3396 rtx lab = gen_label_rtx ();
3397 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG) * 8);
4697a36c 3398
4cc833b7 3399 emit_jump_insn (gen_rtx_SET (VOIDmode,
4697a36c 3400 pc_rtx,
39403d82 3401 gen_rtx_IF_THEN_ELSE (VOIDmode,
4cc833b7
RH
3402 gen_rtx_NE (VOIDmode, cr1,
3403 const0_rtx),
39403d82 3404 gen_rtx_LABEL_REF (VOIDmode, lab),
4697a36c
MM
3405 pc_rtx)));
3406
4cc833b7
RH
3407 while (fregno <= FP_ARG_V4_MAX_REG)
3408 {
dfafc897 3409 mem = gen_rtx_MEM (DFmode, plus_constant (save_area, off));
ba4828e0 3410 set_mem_alias_set (mem, set);
dfafc897 3411 emit_move_insn (mem, gen_rtx_REG (DFmode, fregno));
4cc833b7
RH
3412 fregno++;
3413 off += 8;
4697a36c 3414 }
4cc833b7
RH
3415
3416 emit_label (lab);
4697a36c 3417 }
4697a36c 3418}
4697a36c 3419
dfafc897 3420/* Create the va_list data type. */
2c4974b7 3421
dfafc897
FS
3422tree
3423rs6000_build_va_list ()
3424{
bab45a51 3425 tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
4697a36c 3426
9ebbca7d
GK
3427 /* For AIX, prefer 'char *' because that's what the system
3428 header files like. */
f607bc57 3429 if (DEFAULT_ABI != ABI_V4)
9ebbca7d 3430 return build_pointer_type (char_type_node);
dfafc897 3431
f1e639b1 3432 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
bab45a51 3433 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
0f4fd75d 3434
9ebbca7d
GK
3435 f_gpr = build_decl (FIELD_DECL, get_identifier ("gpr"),
3436 unsigned_char_type_node);
3437 f_fpr = build_decl (FIELD_DECL, get_identifier ("fpr"),
3438 unsigned_char_type_node);
dfafc897
FS
3439 f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"),
3440 ptr_type_node);
3441 f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
3442 ptr_type_node);
3443
3444 DECL_FIELD_CONTEXT (f_gpr) = record;
3445 DECL_FIELD_CONTEXT (f_fpr) = record;
3446 DECL_FIELD_CONTEXT (f_ovf) = record;
3447 DECL_FIELD_CONTEXT (f_sav) = record;
3448
bab45a51
FS
3449 TREE_CHAIN (record) = type_decl;
3450 TYPE_NAME (record) = type_decl;
dfafc897
FS
3451 TYPE_FIELDS (record) = f_gpr;
3452 TREE_CHAIN (f_gpr) = f_fpr;
3453 TREE_CHAIN (f_fpr) = f_ovf;
3454 TREE_CHAIN (f_ovf) = f_sav;
3455
3456 layout_type (record);
3457
3458 /* The correct type is an array type of one element. */
3459 return build_array_type (record, build_index_type (size_zero_node));
3460}
3461
3462/* Implement va_start. */
3463
3464void
e5faf155 3465rs6000_va_start (valist, nextarg)
dfafc897
FS
3466 tree valist;
3467 rtx nextarg;
4697a36c 3468{
dfafc897
FS
3469 HOST_WIDE_INT words, n_gpr, n_fpr;
3470 tree f_gpr, f_fpr, f_ovf, f_sav;
3471 tree gpr, fpr, ovf, sav, t;
2c4974b7 3472
dfafc897 3473 /* Only SVR4 needs something special. */
f607bc57 3474 if (DEFAULT_ABI != ABI_V4)
dfafc897 3475 {
e5faf155 3476 std_expand_builtin_va_start (valist, nextarg);
dfafc897
FS
3477 return;
3478 }
3479
973a648b 3480 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
dfafc897
FS
3481 f_fpr = TREE_CHAIN (f_gpr);
3482 f_ovf = TREE_CHAIN (f_fpr);
3483 f_sav = TREE_CHAIN (f_ovf);
3484
8ebecc3b 3485 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
dfafc897
FS
3486 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
3487 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
3488 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
3489 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
3490
3491 /* Count number of gp and fp argument registers used. */
4cc833b7 3492 words = current_function_args_info.words;
dfafc897
FS
3493 n_gpr = current_function_args_info.sysv_gregno - GP_ARG_MIN_REG;
3494 n_fpr = current_function_args_info.fregno - FP_ARG_MIN_REG;
3495
3496 if (TARGET_DEBUG_ARG)
78e1b90d
DE
3497 {
3498 fputs ("va_start: words = ", stderr);
3499 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, words);
3500 fputs (", n_gpr = ", stderr);
3501 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, n_gpr);
3502 fputs (", n_fpr = ", stderr);
3503 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, n_fpr);
3504 putc ('\n', stderr);
3505 }
dfafc897
FS
3506
3507 t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, build_int_2 (n_gpr, 0));
3508 TREE_SIDE_EFFECTS (t) = 1;
3509 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3510
3511 t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr, build_int_2 (n_fpr, 0));
3512 TREE_SIDE_EFFECTS (t) = 1;
3513 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3514
3515 /* Find the overflow area. */
3516 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
3517 if (words != 0)
3518 t = build (PLUS_EXPR, TREE_TYPE (ovf), t,
3519 build_int_2 (words * UNITS_PER_WORD, 0));
3520 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
3521 TREE_SIDE_EFFECTS (t) = 1;
3522 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3523
3524 /* Find the register save area. */
3525 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
3526 t = build (PLUS_EXPR, TREE_TYPE (sav), t,
3527 build_int_2 (-RS6000_VARARGS_SIZE, -1));
3528 t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
3529 TREE_SIDE_EFFECTS (t) = 1;
3530 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3531}
3532
3533/* Implement va_arg. */
3534
3535rtx
3536rs6000_va_arg (valist, type)
3537 tree valist, type;
3538{
3539 tree f_gpr, f_fpr, f_ovf, f_sav;
3540 tree gpr, fpr, ovf, sav, reg, t, u;
3541 int indirect_p, size, rsize, n_reg, sav_ofs, sav_scale;
3542 rtx lab_false, lab_over, addr_rtx, r;
3543
f607bc57 3544 if (DEFAULT_ABI != ABI_V4)
2a55fd42 3545 return std_expand_builtin_va_arg (valist, type);
dfafc897 3546
973a648b 3547 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
dfafc897
FS
3548 f_fpr = TREE_CHAIN (f_gpr);
3549 f_ovf = TREE_CHAIN (f_fpr);
3550 f_sav = TREE_CHAIN (f_ovf);
3551
8ebecc3b 3552 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
dfafc897
FS
3553 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
3554 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
3555 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
3556 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
3557
3558 size = int_size_in_bytes (type);
3559 rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
4cc833b7 3560
dfafc897 3561 if (AGGREGATE_TYPE_P (type) || TYPE_MODE (type) == TFmode)
4cc833b7 3562 {
dfafc897
FS
3563 /* Aggregates and long doubles are passed by reference. */
3564 indirect_p = 1;
3565 reg = gpr;
3566 n_reg = 1;
3567 sav_ofs = 0;
3568 sav_scale = 4;
d3294cd9
FS
3569 size = UNITS_PER_WORD;
3570 rsize = 1;
dfafc897 3571 }
a3170dc6 3572 else if (FLOAT_TYPE_P (type) && TARGET_HARD_FLOAT && TARGET_FPRS)
dfafc897
FS
3573 {
3574 /* FP args go in FP registers, if present. */
3575 indirect_p = 0;
3576 reg = fpr;
3577 n_reg = 1;
3578 sav_ofs = 8*4;
3579 sav_scale = 8;
4cc833b7 3580 }
dfafc897
FS
3581 else
3582 {
3583 /* Otherwise into GP registers. */
3584 indirect_p = 0;
3585 reg = gpr;
3586 n_reg = rsize;
3587 sav_ofs = 0;
3588 sav_scale = 4;
3589 }
3590
a4f6c312 3591 /* Pull the value out of the saved registers ... */
dfafc897
FS
3592
3593 lab_false = gen_label_rtx ();
3594 lab_over = gen_label_rtx ();
3595 addr_rtx = gen_reg_rtx (Pmode);
3596
16861f33
AH
3597 /* AltiVec vectors never go in registers. */
3598 if (!TARGET_ALTIVEC || TREE_CODE (type) != VECTOR_TYPE)
2c4974b7 3599 {
41daaf0e
AH
3600 TREE_THIS_VOLATILE (reg) = 1;
3601 emit_cmp_and_jump_insns
3602 (expand_expr (reg, NULL_RTX, QImode, EXPAND_NORMAL),
3603 GEN_INT (8 - n_reg + 1), GE, const1_rtx, QImode, 1,
3604 lab_false);
dfafc897 3605
41daaf0e
AH
3606 /* Long long is aligned in the registers. */
3607 if (n_reg > 1)
3608 {
3609 u = build (BIT_AND_EXPR, TREE_TYPE (reg), reg,
3610 build_int_2 (n_reg - 1, 0));
3611 u = build (PLUS_EXPR, TREE_TYPE (reg), reg, u);
3612 u = build (MODIFY_EXPR, TREE_TYPE (reg), reg, u);
3613 TREE_SIDE_EFFECTS (u) = 1;
3614 expand_expr (u, const0_rtx, VOIDmode, EXPAND_NORMAL);
3615 }
2c4974b7 3616
41daaf0e
AH
3617 if (sav_ofs)
3618 t = build (PLUS_EXPR, ptr_type_node, sav, build_int_2 (sav_ofs, 0));
3619 else
3620 t = sav;
2c4974b7 3621
41daaf0e
AH
3622 u = build (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg,
3623 build_int_2 (n_reg, 0));
3624 TREE_SIDE_EFFECTS (u) = 1;
2c4974b7 3625
41daaf0e
AH
3626 u = build1 (CONVERT_EXPR, integer_type_node, u);
3627 TREE_SIDE_EFFECTS (u) = 1;
dfafc897 3628
41daaf0e
AH
3629 u = build (MULT_EXPR, integer_type_node, u, build_int_2 (sav_scale, 0));
3630 TREE_SIDE_EFFECTS (u) = 1;
dfafc897 3631
41daaf0e
AH
3632 t = build (PLUS_EXPR, ptr_type_node, t, u);
3633 TREE_SIDE_EFFECTS (t) = 1;
3634
3635 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
3636 if (r != addr_rtx)
3637 emit_move_insn (addr_rtx, r);
3638
3639 emit_jump_insn (gen_jump (lab_over));
3640 emit_barrier ();
3641 }
dfafc897 3642
dfafc897
FS
3643 emit_label (lab_false);
3644
a4f6c312 3645 /* ... otherwise out of the overflow area. */
dfafc897 3646
41daaf0e
AH
3647 /* Make sure we don't find reg 7 for the next int arg.
3648
3649 All AltiVec vectors go in the overflow area. So in the AltiVec
3650 case we need to get the vectors from the overflow area, but
3651 remember where the GPRs and FPRs are. */
16861f33
AH
3652 if (n_reg > 1 && (TREE_CODE (type) != VECTOR_TYPE
3653 || !TARGET_ALTIVEC))
dfafc897
FS
3654 {
3655 t = build (MODIFY_EXPR, TREE_TYPE (reg), reg, build_int_2 (8, 0));
3656 TREE_SIDE_EFFECTS (t) = 1;
3657 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3658 }
3659
3660 /* Care for on-stack alignment if needed. */
3661 if (rsize <= 1)
3662 t = ovf;
3663 else
3664 {
41daaf0e
AH
3665 int align;
3666
16861f33
AH
3667 /* AltiVec vectors are 16 byte aligned. */
3668 if (TARGET_ALTIVEC && TREE_CODE (type) == VECTOR_TYPE)
41daaf0e
AH
3669 align = 15;
3670 else
3671 align = 7;
3672
3673 t = build (PLUS_EXPR, TREE_TYPE (ovf), ovf, build_int_2 (align, 0));
3674 t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align-1, -1));
dfafc897
FS
3675 }
3676 t = save_expr (t);
3677
3678 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
3679 if (r != addr_rtx)
3680 emit_move_insn (addr_rtx, r);
3681
3682 t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (size, 0));
3683 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
3684 TREE_SIDE_EFFECTS (t) = 1;
3685 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3686
3687 emit_label (lab_over);
3688
3689 if (indirect_p)
3690 {
3691 r = gen_rtx_MEM (Pmode, addr_rtx);
ba4828e0 3692 set_mem_alias_set (r, get_varargs_alias_set ());
dfafc897
FS
3693 emit_move_insn (addr_rtx, r);
3694 }
3695
3696 return addr_rtx;
4697a36c 3697}
0ac081f6
AH
3698
3699/* Builtins. */
3700
6a2dd09a
RS
3701#define def_builtin(MASK, NAME, TYPE, CODE) \
3702do { \
3703 if ((MASK) & target_flags) \
3704 builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
3705 NULL, NULL_TREE); \
0ac081f6
AH
3706} while (0)
3707
24408032
AH
3708/* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
3709
2212663f 3710static const struct builtin_description bdesc_3arg[] =
24408032
AH
3711{
3712 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
3713 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
3714 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
3715 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
3716 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
3717 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
3718 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
3719 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
3720 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
3721 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
3722 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
3723 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
3724 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
3725 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
3726 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_16qi, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
3727 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
3728 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
3729 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
3730 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
3731 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
3732 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
3733 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
3734 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
3735};
2212663f 3736
95385cbb
AH
3737/* DST operations: void foo (void *, const int, const char). */
3738
3739static const struct builtin_description bdesc_dst[] =
3740{
3741 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
3742 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
3743 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
3744 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT }
3745};
3746
2212663f 3747/* Simple binary operations: VECc = foo (VECa, VECb). */
24408032 3748
a3170dc6 3749static struct builtin_description bdesc_2arg[] =
0ac081f6 3750{
f18c054f
DB
3751 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
3752 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
3753 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
3754 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
0ac081f6
AH
3755 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
3756 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
3757 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
3758 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
3759 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
3760 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
3761 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
f18c054f 3762 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
0ac081f6
AH
3763 { MASK_ALTIVEC, CODE_FOR_altivec_vandc, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
3764 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
3765 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
3766 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
3767 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
3768 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
3769 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
617e0e1d
DB
3770 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
3771 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
0ac081f6
AH
3772 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
3773 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequb, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
3774 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequh, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
3775 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequw, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
3776 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpeqfp, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
3777 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgefp, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
3778 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtub, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
3779 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsb, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
3780 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuh, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
3781 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsh, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
3782 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuw, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
3783 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsw, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
3784 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtfp, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
617e0e1d
DB
3785 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
3786 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
f18c054f
DB
3787 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
3788 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
df966bff
AH
3789 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
3790 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
3791 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
3792 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
3793 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
0ac081f6
AH
3794 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
3795 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
3796 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
3797 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
3798 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
3799 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
f18c054f
DB
3800 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
3801 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
3802 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
3803 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
3804 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
3805 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
3806 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
0ac081f6
AH
3807 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
3808 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
3809 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
3810 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
3811 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
3812 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
3813 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
3814 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
3815 { MASK_ALTIVEC, CODE_FOR_altivec_vnor, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
f18c054f 3816 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
0ac081f6
AH
3817 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
3818 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
3819 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
3820 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhss, "__builtin_altivec_vpkuhss", ALTIVEC_BUILTIN_VPKUHSS },
3821 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
3822 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwss, "__builtin_altivec_vpkuwss", ALTIVEC_BUILTIN_VPKUWSS },
3823 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
3824 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
3825 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
3826 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
3827 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
3828 { MASK_ALTIVEC, CODE_FOR_altivec_vrlb, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
3829 { MASK_ALTIVEC, CODE_FOR_altivec_vrlh, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
3830 { MASK_ALTIVEC, CODE_FOR_altivec_vrlw, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
3831 { MASK_ALTIVEC, CODE_FOR_altivec_vslb, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
3832 { MASK_ALTIVEC, CODE_FOR_altivec_vslh, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
3833 { MASK_ALTIVEC, CODE_FOR_altivec_vslw, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
3834 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
3835 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
2212663f
DB
3836 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
3837 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
3838 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
0ac081f6 3839 { MASK_ALTIVEC, CODE_FOR_altivec_vsrb, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
f18c054f
DB
3840 { MASK_ALTIVEC, CODE_FOR_altivec_vsrh, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
3841 { MASK_ALTIVEC, CODE_FOR_altivec_vsrw, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
0ac081f6
AH
3842 { MASK_ALTIVEC, CODE_FOR_altivec_vsrab, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
3843 { MASK_ALTIVEC, CODE_FOR_altivec_vsrah, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
3844 { MASK_ALTIVEC, CODE_FOR_altivec_vsraw, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
3845 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
3846 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
f18c054f
DB
3847 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
3848 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
3849 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
3850 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
0ac081f6
AH
3851 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
3852 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
3853 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
3854 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
3855 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
3856 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
3857 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
3858 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
3859 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
3860 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
3861 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
3862 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
f18c054f 3863 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
a3170dc6
AH
3864
3865 /* Place holder, leave as first spe builtin. */
3866 { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
3867 { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
3868 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
3869 { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
3870 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
3871 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
3872 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
3873 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
3874 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
3875 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
3876 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
3877 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
3878 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
3879 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
3880 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
3881 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
3882 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
3883 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
3884 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
3885 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
3886 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
3887 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
3888 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
3889 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
3890 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
3891 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
3892 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
3893 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
3894 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
3895 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
3896 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
3897 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
3898 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
3899 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
3900 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
3901 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
3902 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
3903 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
3904 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
3905 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
3906 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
3907 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
3908 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
3909 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
3910 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
3911 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
3912 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
3913 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
3914 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
3915 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
3916 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
3917 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
3918 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
3919 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
3920 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
3921 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
3922 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
3923 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
3924 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
3925 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
3926 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
3927 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
3928 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
3929 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
3930 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
3931 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
3932 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
3933 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
3934 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
3935 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
3936 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
3937 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
3938 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
3939 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
a3170dc6
AH
3940 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
3941 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
a3170dc6
AH
3942 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
3943 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
3944 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
3945 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
3946 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
3947 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
3948 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
3949 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
3950 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
3951 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
3952 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
3953 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
3954 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
3955 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
3956 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
3957 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
3958 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
3959 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
3960 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
3961 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
3962 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
3963 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
3964 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
3965 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
3966 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
3967 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
3968 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
3969 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
3970 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
3971 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
3972 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
3973 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
3974 { 0, CODE_FOR_spe_evsubfw, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
3975
3976 /* SPE binary operations expecting a 5-bit unsigned literal. */
3977 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
3978
3979 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
3980 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
3981 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
3982 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
3983 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
3984 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
3985 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
3986 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
3987 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
3988 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
3989 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
3990 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
3991 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
3992 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
3993 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
3994 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
3995 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
3996 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
3997 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
3998 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
3999 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
4000 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
4001 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
4002 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
4003 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
4004 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
4005
4006 /* Place-holder. Leave as last binary SPE builtin. */
4007 { 0, CODE_FOR_spe_evxor, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR },
ae4b4a02
AH
4008};
4009
4010/* AltiVec predicates. */
4011
4012struct builtin_description_predicates
4013{
4014 const unsigned int mask;
4015 const enum insn_code icode;
4016 const char *opcode;
4017 const char *const name;
4018 const enum rs6000_builtins code;
4019};
4020
4021static const struct builtin_description_predicates bdesc_altivec_preds[] =
4022{
4023 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P },
4024 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
4025 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
4026 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
4027 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P },
4028 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P },
4029 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P },
4030 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P },
4031 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P },
4032 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P },
4033 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P },
4034 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P },
4035 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P }
0ac081f6 4036};
24408032 4037
a3170dc6
AH
4038/* SPE predicates. */
4039static struct builtin_description bdesc_spe_predicates[] =
4040{
4041 /* Place-holder. Leave as first. */
4042 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
4043 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
4044 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
4045 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
4046 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
4047 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
4048 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
4049 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
4050 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
4051 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
4052 /* Place-holder. Leave as last. */
4053 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
4054};
4055
4056/* SPE evsel predicates. */
4057static struct builtin_description bdesc_spe_evsel[] =
4058{
4059 /* Place-holder. Leave as first. */
4060 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
4061 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
4062 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
4063 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
4064 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
4065 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
4066 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
4067 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
4068 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
4069 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
4070 /* Place-holder. Leave as last. */
4071 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
4072};
4073
100c4561
AH
4074/* ABS* opreations. */
4075
4076static const struct builtin_description bdesc_abs[] =
4077{
4078 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
4079 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
4080 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
4081 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
4082 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
4083 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
4084 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI }
4085};
4086
617e0e1d
DB
4087/* Simple unary operations: VECb = foo (unsigned literal) or VECb =
4088 foo (VECa). */
24408032 4089
a3170dc6 4090static struct builtin_description bdesc_1arg[] =
2212663f 4091{
617e0e1d
DB
4092 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
4093 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
4094 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
4095 { MASK_ALTIVEC, CODE_FOR_altivec_vrfim, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
4096 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
4097 { MASK_ALTIVEC, CODE_FOR_altivec_vrfip, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
4098 { MASK_ALTIVEC, CODE_FOR_ftruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
4099 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
2212663f
DB
4100 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
4101 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
4102 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
20e26713
AH
4103 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
4104 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
4105 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
4106 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
4107 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
4108 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
a3170dc6
AH
4109
4110 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
4111 end with SPE_BUILTIN_EVSUBFUSIAAW. */
4112 { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
4113 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
4114 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
4115 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
4116 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
4117 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
4118 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
4119 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
4120 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
4121 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
4122 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
4123 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
4124 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
4125 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
4126 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
4127 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
4128 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
4129 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
4130 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
4131 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
4132 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
4133 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
4134 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
4135 { 0, CODE_FOR_spe_evneg, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
4136 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
4137 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
4138 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
4139 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
4140 { 0, CODE_FOR_spe_evsplatfi, "__builtin_spe_evsplatfi", SPE_BUILTIN_EVSPLATFI },
4141 { 0, CODE_FOR_spe_evsplati, "__builtin_spe_evsplati", SPE_BUILTIN_EVSPLATI },
4142
4143 /* Place-holder. Leave as last unary SPE builtin. */
4144 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
2212663f
DB
4145};
4146
4147static rtx
92898235 4148rs6000_expand_unop_builtin (icode, arglist, target)
2212663f
DB
4149 enum insn_code icode;
4150 tree arglist;
4151 rtx target;
4152{
4153 rtx pat;
4154 tree arg0 = TREE_VALUE (arglist);
4155 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4156 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4157 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4158
0559cc77
DE
4159 if (icode == CODE_FOR_nothing)
4160 /* Builtin not supported on this processor. */
4161 return 0;
4162
20e26713
AH
4163 /* If we got invalid arguments bail out before generating bad rtl. */
4164 if (arg0 == error_mark_node)
9a171fcd 4165 return const0_rtx;
20e26713 4166
0559cc77
DE
4167 if (icode == CODE_FOR_altivec_vspltisb
4168 || icode == CODE_FOR_altivec_vspltish
4169 || icode == CODE_FOR_altivec_vspltisw
4170 || icode == CODE_FOR_spe_evsplatfi
4171 || icode == CODE_FOR_spe_evsplati)
b44140e7
AH
4172 {
4173 /* Only allow 5-bit *signed* literals. */
b44140e7
AH
4174 if (GET_CODE (op0) != CONST_INT
4175 || INTVAL (op0) > 0x1f
4176 || INTVAL (op0) < -0x1f)
4177 {
4178 error ("argument 1 must be a 5-bit signed literal");
9a171fcd 4179 return const0_rtx;
b44140e7 4180 }
b44140e7
AH
4181 }
4182
c62f2db5 4183 if (target == 0
2212663f
DB
4184 || GET_MODE (target) != tmode
4185 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4186 target = gen_reg_rtx (tmode);
4187
4188 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4189 op0 = copy_to_mode_reg (mode0, op0);
4190
4191 pat = GEN_FCN (icode) (target, op0);
4192 if (! pat)
4193 return 0;
4194 emit_insn (pat);
0ac081f6 4195
2212663f
DB
4196 return target;
4197}
ae4b4a02 4198
100c4561
AH
4199static rtx
4200altivec_expand_abs_builtin (icode, arglist, target)
4201 enum insn_code icode;
4202 tree arglist;
4203 rtx target;
4204{
4205 rtx pat, scratch1, scratch2;
4206 tree arg0 = TREE_VALUE (arglist);
4207 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4208 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4209 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4210
4211 /* If we have invalid arguments, bail out before generating bad rtl. */
4212 if (arg0 == error_mark_node)
9a171fcd 4213 return const0_rtx;
100c4561
AH
4214
4215 if (target == 0
4216 || GET_MODE (target) != tmode
4217 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4218 target = gen_reg_rtx (tmode);
4219
4220 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4221 op0 = copy_to_mode_reg (mode0, op0);
4222
4223 scratch1 = gen_reg_rtx (mode0);
4224 scratch2 = gen_reg_rtx (mode0);
4225
4226 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
4227 if (! pat)
4228 return 0;
4229 emit_insn (pat);
4230
4231 return target;
4232}
4233
0ac081f6 4234static rtx
92898235 4235rs6000_expand_binop_builtin (icode, arglist, target)
0ac081f6
AH
4236 enum insn_code icode;
4237 tree arglist;
4238 rtx target;
4239{
4240 rtx pat;
4241 tree arg0 = TREE_VALUE (arglist);
4242 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4243 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4244 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4245 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4246 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4247 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4248
0559cc77
DE
4249 if (icode == CODE_FOR_nothing)
4250 /* Builtin not supported on this processor. */
4251 return 0;
4252
20e26713
AH
4253 /* If we got invalid arguments bail out before generating bad rtl. */
4254 if (arg0 == error_mark_node || arg1 == error_mark_node)
9a171fcd 4255 return const0_rtx;
20e26713 4256
0559cc77
DE
4257 if (icode == CODE_FOR_altivec_vcfux
4258 || icode == CODE_FOR_altivec_vcfsx
4259 || icode == CODE_FOR_altivec_vctsxs
4260 || icode == CODE_FOR_altivec_vctuxs
4261 || icode == CODE_FOR_altivec_vspltb
4262 || icode == CODE_FOR_altivec_vsplth
4263 || icode == CODE_FOR_altivec_vspltw
4264 || icode == CODE_FOR_spe_evaddiw
4265 || icode == CODE_FOR_spe_evldd
4266 || icode == CODE_FOR_spe_evldh
4267 || icode == CODE_FOR_spe_evldw
4268 || icode == CODE_FOR_spe_evlhhesplat
4269 || icode == CODE_FOR_spe_evlhhossplat
4270 || icode == CODE_FOR_spe_evlhhousplat
4271 || icode == CODE_FOR_spe_evlwhe
4272 || icode == CODE_FOR_spe_evlwhos
4273 || icode == CODE_FOR_spe_evlwhou
4274 || icode == CODE_FOR_spe_evlwhsplat
4275 || icode == CODE_FOR_spe_evlwwsplat
4276 || icode == CODE_FOR_spe_evrlwi
4277 || icode == CODE_FOR_spe_evslwi
4278 || icode == CODE_FOR_spe_evsrwis
4279 || icode == CODE_FOR_spe_evsrwiu)
b44140e7
AH
4280 {
4281 /* Only allow 5-bit unsigned literals. */
b44140e7
AH
4282 if (TREE_CODE (arg1) != INTEGER_CST
4283 || TREE_INT_CST_LOW (arg1) & ~0x1f)
4284 {
4285 error ("argument 2 must be a 5-bit unsigned literal");
9a171fcd 4286 return const0_rtx;
b44140e7 4287 }
b44140e7
AH
4288 }
4289
c62f2db5 4290 if (target == 0
0ac081f6
AH
4291 || GET_MODE (target) != tmode
4292 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4293 target = gen_reg_rtx (tmode);
4294
4295 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4296 op0 = copy_to_mode_reg (mode0, op0);
4297 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4298 op1 = copy_to_mode_reg (mode1, op1);
4299
4300 pat = GEN_FCN (icode) (target, op0, op1);
4301 if (! pat)
4302 return 0;
4303 emit_insn (pat);
4304
4305 return target;
4306}
6525c0e7 4307
ae4b4a02
AH
4308static rtx
4309altivec_expand_predicate_builtin (icode, opcode, arglist, target)
4310 enum insn_code icode;
4311 const char *opcode;
4312 tree arglist;
4313 rtx target;
4314{
4315 rtx pat, scratch;
4316 tree cr6_form = TREE_VALUE (arglist);
4317 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
4318 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4319 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4320 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4321 enum machine_mode tmode = SImode;
4322 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4323 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4324 int cr6_form_int;
4325
4326 if (TREE_CODE (cr6_form) != INTEGER_CST)
4327 {
4328 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9a171fcd 4329 return const0_rtx;
ae4b4a02
AH
4330 }
4331 else
4332 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
4333
4334 if (mode0 != mode1)
4335 abort ();
4336
4337 /* If we have invalid arguments, bail out before generating bad rtl. */
4338 if (arg0 == error_mark_node || arg1 == error_mark_node)
9a171fcd 4339 return const0_rtx;
ae4b4a02
AH
4340
4341 if (target == 0
4342 || GET_MODE (target) != tmode
4343 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4344 target = gen_reg_rtx (tmode);
4345
4346 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4347 op0 = copy_to_mode_reg (mode0, op0);
4348 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4349 op1 = copy_to_mode_reg (mode1, op1);
4350
4351 scratch = gen_reg_rtx (mode0);
4352
4353 pat = GEN_FCN (icode) (scratch, op0, op1,
4354 gen_rtx (SYMBOL_REF, Pmode, opcode));
4355 if (! pat)
4356 return 0;
4357 emit_insn (pat);
4358
4359 /* The vec_any* and vec_all* predicates use the same opcodes for two
4360 different operations, but the bits in CR6 will be different
4361 depending on what information we want. So we have to play tricks
4362 with CR6 to get the right bits out.
4363
4364 If you think this is disgusting, look at the specs for the
4365 AltiVec predicates. */
4366
4367 switch (cr6_form_int)
4368 {
4369 case 0:
4370 emit_insn (gen_cr6_test_for_zero (target));
4371 break;
4372 case 1:
4373 emit_insn (gen_cr6_test_for_zero_reverse (target));
4374 break;
4375 case 2:
4376 emit_insn (gen_cr6_test_for_lt (target));
4377 break;
4378 case 3:
4379 emit_insn (gen_cr6_test_for_lt_reverse (target));
4380 break;
4381 default:
4382 error ("argument 1 of __builtin_altivec_predicate is out of range");
4383 break;
4384 }
4385
4386 return target;
4387}
4388
6525c0e7
AH
4389static rtx
4390altivec_expand_stv_builtin (icode, arglist)
4391 enum insn_code icode;
4392 tree arglist;
4393{
4394 tree arg0 = TREE_VALUE (arglist);
4395 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4396 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4397 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4398 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4399 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4400 rtx pat;
4401 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
4402 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
4403 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
4404
4405 /* Invalid arguments. Bail before doing anything stoopid! */
4406 if (arg0 == error_mark_node
4407 || arg1 == error_mark_node
4408 || arg2 == error_mark_node)
9a171fcd 4409 return const0_rtx;
6525c0e7
AH
4410
4411 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
4412 op0 = copy_to_mode_reg (mode2, op0);
4413 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
4414 op1 = copy_to_mode_reg (mode0, op1);
4415 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
4416 op2 = copy_to_mode_reg (mode1, op2);
4417
4418 pat = GEN_FCN (icode) (op1, op2, op0);
4419 if (pat)
4420 emit_insn (pat);
4421 return NULL_RTX;
4422}
4423
2212663f 4424static rtx
92898235 4425rs6000_expand_ternop_builtin (icode, arglist, target)
2212663f
DB
4426 enum insn_code icode;
4427 tree arglist;
4428 rtx target;
4429{
4430 rtx pat;
4431 tree arg0 = TREE_VALUE (arglist);
4432 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4433 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4434 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4435 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4436 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4437 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4438 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4439 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4440 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
0ac081f6 4441
774b5662
DE
4442 if (icode == CODE_FOR_nothing)
4443 /* Builtin not supported on this processor. */
4444 return 0;
4445
20e26713
AH
4446 /* If we got invalid arguments bail out before generating bad rtl. */
4447 if (arg0 == error_mark_node
4448 || arg1 == error_mark_node
4449 || arg2 == error_mark_node)
9a171fcd 4450 return const0_rtx;
20e26713 4451
774b5662
DE
4452 if (icode == CODE_FOR_altivec_vsldoi_4sf
4453 || icode == CODE_FOR_altivec_vsldoi_4si
4454 || icode == CODE_FOR_altivec_vsldoi_8hi
4455 || icode == CODE_FOR_altivec_vsldoi_16qi)
b44140e7
AH
4456 {
4457 /* Only allow 4-bit unsigned literals. */
b44140e7
AH
4458 if (TREE_CODE (arg2) != INTEGER_CST
4459 || TREE_INT_CST_LOW (arg2) & ~0xf)
4460 {
4461 error ("argument 3 must be a 4-bit unsigned literal");
e3277ffb 4462 return const0_rtx;
b44140e7 4463 }
b44140e7
AH
4464 }
4465
c62f2db5 4466 if (target == 0
2212663f
DB
4467 || GET_MODE (target) != tmode
4468 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4469 target = gen_reg_rtx (tmode);
4470
4471 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4472 op0 = copy_to_mode_reg (mode0, op0);
4473 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4474 op1 = copy_to_mode_reg (mode1, op1);
4475 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
4476 op2 = copy_to_mode_reg (mode2, op2);
4477
4478 pat = GEN_FCN (icode) (target, op0, op1, op2);
4479 if (! pat)
4480 return 0;
4481 emit_insn (pat);
4482
4483 return target;
4484}
92898235 4485
3a9b8c7e 4486/* Expand the lvx builtins. */
0ac081f6 4487static rtx
3a9b8c7e 4488altivec_expand_ld_builtin (exp, target, expandedp)
0ac081f6
AH
4489 tree exp;
4490 rtx target;
92898235 4491 bool *expandedp;
0ac081f6 4492{
0ac081f6
AH
4493 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4494 tree arglist = TREE_OPERAND (exp, 1);
0ac081f6 4495 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
3a9b8c7e
AH
4496 tree arg0;
4497 enum machine_mode tmode, mode0;
7c3abc73 4498 rtx pat, op0;
3a9b8c7e 4499 enum insn_code icode;
92898235 4500
0ac081f6
AH
4501 switch (fcode)
4502 {
f18c054f
DB
4503 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
4504 icode = CODE_FOR_altivec_lvx_16qi;
3a9b8c7e 4505 break;
f18c054f
DB
4506 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
4507 icode = CODE_FOR_altivec_lvx_8hi;
3a9b8c7e
AH
4508 break;
4509 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
4510 icode = CODE_FOR_altivec_lvx_4si;
4511 break;
4512 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
4513 icode = CODE_FOR_altivec_lvx_4sf;
4514 break;
4515 default:
4516 *expandedp = false;
4517 return NULL_RTX;
4518 }
0ac081f6 4519
3a9b8c7e 4520 *expandedp = true;
f18c054f 4521
3a9b8c7e
AH
4522 arg0 = TREE_VALUE (arglist);
4523 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4524 tmode = insn_data[icode].operand[0].mode;
4525 mode0 = insn_data[icode].operand[1].mode;
f18c054f 4526
3a9b8c7e
AH
4527 if (target == 0
4528 || GET_MODE (target) != tmode
4529 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4530 target = gen_reg_rtx (tmode);
24408032 4531
3a9b8c7e
AH
4532 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4533 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
f18c054f 4534
3a9b8c7e
AH
4535 pat = GEN_FCN (icode) (target, op0);
4536 if (! pat)
4537 return 0;
4538 emit_insn (pat);
4539 return target;
4540}
f18c054f 4541
3a9b8c7e
AH
4542/* Expand the stvx builtins. */
4543static rtx
4544altivec_expand_st_builtin (exp, target, expandedp)
4545 tree exp;
7c3abc73 4546 rtx target ATTRIBUTE_UNUSED;
3a9b8c7e
AH
4547 bool *expandedp;
4548{
4549 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4550 tree arglist = TREE_OPERAND (exp, 1);
4551 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4552 tree arg0, arg1;
4553 enum machine_mode mode0, mode1;
7c3abc73 4554 rtx pat, op0, op1;
3a9b8c7e 4555 enum insn_code icode;
f18c054f 4556
3a9b8c7e
AH
4557 switch (fcode)
4558 {
4559 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
4560 icode = CODE_FOR_altivec_stvx_16qi;
4561 break;
4562 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
4563 icode = CODE_FOR_altivec_stvx_8hi;
4564 break;
4565 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
4566 icode = CODE_FOR_altivec_stvx_4si;
4567 break;
4568 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
4569 icode = CODE_FOR_altivec_stvx_4sf;
4570 break;
4571 default:
4572 *expandedp = false;
4573 return NULL_RTX;
4574 }
24408032 4575
3a9b8c7e
AH
4576 arg0 = TREE_VALUE (arglist);
4577 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4578 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4579 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4580 mode0 = insn_data[icode].operand[0].mode;
4581 mode1 = insn_data[icode].operand[1].mode;
f18c054f 4582
3a9b8c7e
AH
4583 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4584 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
4585 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
4586 op1 = copy_to_mode_reg (mode1, op1);
f18c054f 4587
3a9b8c7e
AH
4588 pat = GEN_FCN (icode) (op0, op1);
4589 if (pat)
4590 emit_insn (pat);
f18c054f 4591
3a9b8c7e
AH
4592 *expandedp = true;
4593 return NULL_RTX;
4594}
f18c054f 4595
3a9b8c7e
AH
4596/* Expand the dst builtins. */
4597static rtx
4598altivec_expand_dst_builtin (exp, target, expandedp)
4599 tree exp;
7c3abc73 4600 rtx target ATTRIBUTE_UNUSED;
3a9b8c7e
AH
4601 bool *expandedp;
4602{
4603 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4604 tree arglist = TREE_OPERAND (exp, 1);
4605 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4606 tree arg0, arg1, arg2;
4607 enum machine_mode mode0, mode1, mode2;
7c3abc73 4608 rtx pat, op0, op1, op2;
3a9b8c7e 4609 struct builtin_description *d;
a3170dc6 4610 size_t i;
f18c054f 4611
3a9b8c7e 4612 *expandedp = false;
f18c054f 4613
3a9b8c7e
AH
4614 /* Handle DST variants. */
4615 d = (struct builtin_description *) bdesc_dst;
4616 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
4617 if (d->code == fcode)
4618 {
4619 arg0 = TREE_VALUE (arglist);
4620 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4621 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4622 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4623 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4624 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4625 mode0 = insn_data[d->icode].operand[0].mode;
4626 mode1 = insn_data[d->icode].operand[1].mode;
4627 mode2 = insn_data[d->icode].operand[2].mode;
24408032 4628
3a9b8c7e
AH
4629 /* Invalid arguments, bail out before generating bad rtl. */
4630 if (arg0 == error_mark_node
4631 || arg1 == error_mark_node
4632 || arg2 == error_mark_node)
4633 return const0_rtx;
f18c054f 4634
3a9b8c7e
AH
4635 if (TREE_CODE (arg2) != INTEGER_CST
4636 || TREE_INT_CST_LOW (arg2) & ~0x3)
4637 {
4638 error ("argument to `%s' must be a 2-bit unsigned literal", d->name);
4639 return const0_rtx;
4640 }
f18c054f 4641
3a9b8c7e
AH
4642 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
4643 op0 = copy_to_mode_reg (mode0, op0);
4644 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
4645 op1 = copy_to_mode_reg (mode1, op1);
24408032 4646
3a9b8c7e
AH
4647 pat = GEN_FCN (d->icode) (op0, op1, op2);
4648 if (pat != 0)
4649 emit_insn (pat);
f18c054f 4650
3a9b8c7e
AH
4651 *expandedp = true;
4652 return NULL_RTX;
4653 }
f18c054f 4654
3a9b8c7e
AH
4655 return NULL_RTX;
4656}
24408032 4657
3a9b8c7e
AH
4658/* Expand the builtin in EXP and store the result in TARGET. Store
4659 true in *EXPANDEDP if we found a builtin to expand. */
4660static rtx
4661altivec_expand_builtin (exp, target, expandedp)
4662 tree exp;
4663 rtx target;
4664 bool *expandedp;
4665{
4666 struct builtin_description *d;
4667 struct builtin_description_predicates *dp;
4668 size_t i;
4669 enum insn_code icode;
4670 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4671 tree arglist = TREE_OPERAND (exp, 1);
7c3abc73
AH
4672 tree arg0;
4673 rtx op0, pat;
4674 enum machine_mode tmode, mode0;
3a9b8c7e 4675 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
0ac081f6 4676
3a9b8c7e
AH
4677 target = altivec_expand_ld_builtin (exp, target, expandedp);
4678 if (*expandedp)
4679 return target;
0ac081f6 4680
3a9b8c7e
AH
4681 target = altivec_expand_st_builtin (exp, target, expandedp);
4682 if (*expandedp)
4683 return target;
4684
4685 target = altivec_expand_dst_builtin (exp, target, expandedp);
4686 if (*expandedp)
4687 return target;
4688
4689 *expandedp = true;
95385cbb 4690
3a9b8c7e
AH
4691 switch (fcode)
4692 {
6525c0e7
AH
4693 case ALTIVEC_BUILTIN_STVX:
4694 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, arglist);
4695 case ALTIVEC_BUILTIN_STVEBX:
4696 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, arglist);
4697 case ALTIVEC_BUILTIN_STVEHX:
4698 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, arglist);
4699 case ALTIVEC_BUILTIN_STVEWX:
4700 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, arglist);
4701 case ALTIVEC_BUILTIN_STVXL:
4702 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, arglist);
3a9b8c7e 4703
95385cbb
AH
4704 case ALTIVEC_BUILTIN_MFVSCR:
4705 icode = CODE_FOR_altivec_mfvscr;
4706 tmode = insn_data[icode].operand[0].mode;
4707
4708 if (target == 0
4709 || GET_MODE (target) != tmode
4710 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4711 target = gen_reg_rtx (tmode);
4712
4713 pat = GEN_FCN (icode) (target);
0ac081f6
AH
4714 if (! pat)
4715 return 0;
4716 emit_insn (pat);
95385cbb
AH
4717 return target;
4718
4719 case ALTIVEC_BUILTIN_MTVSCR:
4720 icode = CODE_FOR_altivec_mtvscr;
4721 arg0 = TREE_VALUE (arglist);
4722 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4723 mode0 = insn_data[icode].operand[0].mode;
4724
4725 /* If we got invalid arguments bail out before generating bad rtl. */
4726 if (arg0 == error_mark_node)
9a171fcd 4727 return const0_rtx;
95385cbb
AH
4728
4729 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4730 op0 = copy_to_mode_reg (mode0, op0);
4731
4732 pat = GEN_FCN (icode) (op0);
4733 if (pat)
4734 emit_insn (pat);
4735 return NULL_RTX;
3a9b8c7e 4736
95385cbb
AH
4737 case ALTIVEC_BUILTIN_DSSALL:
4738 emit_insn (gen_altivec_dssall ());
4739 return NULL_RTX;
4740
4741 case ALTIVEC_BUILTIN_DSS:
4742 icode = CODE_FOR_altivec_dss;
4743 arg0 = TREE_VALUE (arglist);
4744 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4745 mode0 = insn_data[icode].operand[0].mode;
4746
4747 /* If we got invalid arguments bail out before generating bad rtl. */
4748 if (arg0 == error_mark_node)
9a171fcd 4749 return const0_rtx;
95385cbb 4750
b44140e7
AH
4751 if (TREE_CODE (arg0) != INTEGER_CST
4752 || TREE_INT_CST_LOW (arg0) & ~0x3)
4753 {
4754 error ("argument to dss must be a 2-bit unsigned literal");
9a171fcd 4755 return const0_rtx;
b44140e7
AH
4756 }
4757
95385cbb
AH
4758 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4759 op0 = copy_to_mode_reg (mode0, op0);
4760
4761 emit_insn (gen_altivec_dss (op0));
0ac081f6
AH
4762 return NULL_RTX;
4763 }
24408032 4764
100c4561
AH
4765 /* Expand abs* operations. */
4766 d = (struct builtin_description *) bdesc_abs;
ca7558fc 4767 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
100c4561
AH
4768 if (d->code == fcode)
4769 return altivec_expand_abs_builtin (d->icode, arglist, target);
4770
ae4b4a02
AH
4771 /* Expand the AltiVec predicates. */
4772 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
ca7558fc 4773 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
ae4b4a02
AH
4774 if (dp->code == fcode)
4775 return altivec_expand_predicate_builtin (dp->icode, dp->opcode, arglist, target);
4776
6525c0e7
AH
4777 /* LV* are funky. We initialized them differently. */
4778 switch (fcode)
4779 {
4780 case ALTIVEC_BUILTIN_LVSL:
92898235 4781 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvsl,
6525c0e7
AH
4782 arglist, target);
4783 case ALTIVEC_BUILTIN_LVSR:
92898235
AH
4784 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvsr,
4785 arglist, target);
6525c0e7 4786 case ALTIVEC_BUILTIN_LVEBX:
92898235
AH
4787 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvebx,
4788 arglist, target);
6525c0e7 4789 case ALTIVEC_BUILTIN_LVEHX:
92898235
AH
4790 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvehx,
4791 arglist, target);
6525c0e7 4792 case ALTIVEC_BUILTIN_LVEWX:
92898235
AH
4793 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvewx,
4794 arglist, target);
6525c0e7 4795 case ALTIVEC_BUILTIN_LVXL:
92898235
AH
4796 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvxl,
4797 arglist, target);
6525c0e7 4798 case ALTIVEC_BUILTIN_LVX:
92898235
AH
4799 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvx,
4800 arglist, target);
6525c0e7
AH
4801 default:
4802 break;
4803 /* Fall through. */
4804 }
95385cbb 4805
92898235 4806 *expandedp = false;
0ac081f6
AH
4807 return NULL_RTX;
4808}
4809
a3170dc6
AH
4810/* Binops that need to be initialized manually, but can be expanded
4811 automagically by rs6000_expand_binop_builtin. */
4812static struct builtin_description bdesc_2arg_spe[] =
4813{
4814 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
4815 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
4816 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
4817 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
4818 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
4819 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
4820 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
4821 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
4822 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
4823 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
4824 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
4825 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
4826 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
4827 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
4828 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
4829 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
4830 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
4831 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
4832 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
4833 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
4834 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
4835 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
4836};
4837
4838/* Expand the builtin in EXP and store the result in TARGET. Store
4839 true in *EXPANDEDP if we found a builtin to expand.
4840
4841 This expands the SPE builtins that are not simple unary and binary
4842 operations. */
4843static rtx
4844spe_expand_builtin (exp, target, expandedp)
4845 tree exp;
4846 rtx target;
4847 bool *expandedp;
4848{
4849 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4850 tree arglist = TREE_OPERAND (exp, 1);
4851 tree arg1, arg0;
4852 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4853 enum insn_code icode;
4854 enum machine_mode tmode, mode0;
4855 rtx pat, op0;
4856 struct builtin_description *d;
4857 size_t i;
4858
4859 *expandedp = true;
4860
4861 /* Syntax check for a 5-bit unsigned immediate. */
4862 switch (fcode)
4863 {
4864 case SPE_BUILTIN_EVSTDD:
4865 case SPE_BUILTIN_EVSTDH:
4866 case SPE_BUILTIN_EVSTDW:
4867 case SPE_BUILTIN_EVSTWHE:
4868 case SPE_BUILTIN_EVSTWHO:
4869 case SPE_BUILTIN_EVSTWWE:
4870 case SPE_BUILTIN_EVSTWWO:
4871 arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4872 if (TREE_CODE (arg1) != INTEGER_CST
4873 || TREE_INT_CST_LOW (arg1) & ~0x1f)
4874 {
4875 error ("argument 2 must be a 5-bit unsigned literal");
4876 return const0_rtx;
4877 }
4878 break;
4879 default:
4880 break;
4881 }
4882
4883 d = (struct builtin_description *) bdesc_2arg_spe;
4884 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
4885 if (d->code == fcode)
4886 return rs6000_expand_binop_builtin (d->icode, arglist, target);
4887
4888 d = (struct builtin_description *) bdesc_spe_predicates;
4889 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
4890 if (d->code == fcode)
4891 return spe_expand_predicate_builtin (d->icode, arglist, target);
4892
4893 d = (struct builtin_description *) bdesc_spe_evsel;
4894 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
4895 if (d->code == fcode)
4896 return spe_expand_evsel_builtin (d->icode, arglist, target);
4897
4898 switch (fcode)
4899 {
4900 case SPE_BUILTIN_EVSTDDX:
4901 return altivec_expand_stv_builtin (CODE_FOR_spe_evstddx, arglist);
4902 case SPE_BUILTIN_EVSTDHX:
4903 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdhx, arglist);
4904 case SPE_BUILTIN_EVSTDWX:
4905 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdwx, arglist);
4906 case SPE_BUILTIN_EVSTWHEX:
4907 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhex, arglist);
4908 case SPE_BUILTIN_EVSTWHOX:
4909 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhox, arglist);
4910 case SPE_BUILTIN_EVSTWWEX:
4911 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwex, arglist);
4912 case SPE_BUILTIN_EVSTWWOX:
4913 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwox, arglist);
4914 case SPE_BUILTIN_EVSTDD:
4915 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdd, arglist);
4916 case SPE_BUILTIN_EVSTDH:
4917 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdh, arglist);
4918 case SPE_BUILTIN_EVSTDW:
4919 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdw, arglist);
4920 case SPE_BUILTIN_EVSTWHE:
4921 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhe, arglist);
4922 case SPE_BUILTIN_EVSTWHO:
4923 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwho, arglist);
4924 case SPE_BUILTIN_EVSTWWE:
4925 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwe, arglist);
4926 case SPE_BUILTIN_EVSTWWO:
4927 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwo, arglist);
4928 case SPE_BUILTIN_MFSPEFSCR:
4929 icode = CODE_FOR_spe_mfspefscr;
4930 tmode = insn_data[icode].operand[0].mode;
4931
4932 if (target == 0
4933 || GET_MODE (target) != tmode
4934 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4935 target = gen_reg_rtx (tmode);
4936
4937 pat = GEN_FCN (icode) (target);
4938 if (! pat)
4939 return 0;
4940 emit_insn (pat);
4941 return target;
4942 case SPE_BUILTIN_MTSPEFSCR:
4943 icode = CODE_FOR_spe_mtspefscr;
4944 arg0 = TREE_VALUE (arglist);
4945 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4946 mode0 = insn_data[icode].operand[0].mode;
4947
4948 if (arg0 == error_mark_node)
4949 return const0_rtx;
4950
4951 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4952 op0 = copy_to_mode_reg (mode0, op0);
4953
4954 pat = GEN_FCN (icode) (op0);
4955 if (pat)
4956 emit_insn (pat);
4957 return NULL_RTX;
4958 default:
4959 break;
4960 }
4961
4962 *expandedp = false;
4963 return NULL_RTX;
4964}
4965
4966static rtx
4967spe_expand_predicate_builtin (icode, arglist, target)
4968 enum insn_code icode;
4969 tree arglist;
4970 rtx target;
4971{
4972 rtx pat, scratch, tmp;
4973 tree form = TREE_VALUE (arglist);
4974 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
4975 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4976 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4977 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4978 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4979 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4980 int form_int;
4981 enum rtx_code code;
4982
4983 if (TREE_CODE (form) != INTEGER_CST)
4984 {
4985 error ("argument 1 of __builtin_spe_predicate must be a constant");
4986 return const0_rtx;
4987 }
4988 else
4989 form_int = TREE_INT_CST_LOW (form);
4990
4991 if (mode0 != mode1)
4992 abort ();
4993
4994 if (arg0 == error_mark_node || arg1 == error_mark_node)
4995 return const0_rtx;
4996
4997 if (target == 0
4998 || GET_MODE (target) != SImode
4999 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
5000 target = gen_reg_rtx (SImode);
5001
5002 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
5003 op0 = copy_to_mode_reg (mode0, op0);
5004 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
5005 op1 = copy_to_mode_reg (mode1, op1);
5006
5007 scratch = gen_reg_rtx (CCmode);
5008
5009 pat = GEN_FCN (icode) (scratch, op0, op1);
5010 if (! pat)
5011 return const0_rtx;
5012 emit_insn (pat);
5013
5014 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
5015 _lower_. We use one compare, but look in different bits of the
5016 CR for each variant.
5017
5018 There are 2 elements in each SPE simd type (upper/lower). The CR
5019 bits are set as follows:
5020
5021 BIT0 | BIT 1 | BIT 2 | BIT 3
5022 U | L | (U | L) | (U & L)
5023
5024 So, for an "all" relationship, BIT 3 would be set.
5025 For an "any" relationship, BIT 2 would be set. Etc.
5026
5027 Following traditional nomenclature, these bits map to:
5028
5029 BIT0 | BIT 1 | BIT 2 | BIT 3
5030 LT | GT | EQ | OV
5031
5032 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
5033 */
5034
5035 switch (form_int)
5036 {
5037 /* All variant. OV bit. */
5038 case 0:
5039 /* We need to get to the OV bit, which is the ORDERED bit. We
5040 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
5041 that's ugly and will trigger a validate_condition_mode abort.
5042 So let's just use another pattern. */
5043 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
5044 return target;
5045 /* Any variant. EQ bit. */
5046 case 1:
5047 code = EQ;
5048 break;
5049 /* Upper variant. LT bit. */
5050 case 2:
5051 code = LT;
5052 break;
5053 /* Lower variant. GT bit. */
5054 case 3:
5055 code = GT;
5056 break;
5057 default:
5058 error ("argument 1 of __builtin_spe_predicate is out of range");
5059 return const0_rtx;
5060 }
5061
5062 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
5063 emit_move_insn (target, tmp);
5064
5065 return target;
5066}
5067
5068/* The evsel builtins look like this:
5069
5070 e = __builtin_spe_evsel_OP (a, b, c, d);
5071
5072 and work like this:
5073
5074 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
5075 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
5076*/
5077
5078static rtx
5079spe_expand_evsel_builtin (icode, arglist, target)
5080 enum insn_code icode;
5081 tree arglist;
5082 rtx target;
5083{
5084 rtx pat, scratch;
5085 tree arg0 = TREE_VALUE (arglist);
5086 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
5087 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
5088 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
5089 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
5090 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
5091 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
5092 rtx op3 = expand_expr (arg3, NULL_RTX, VOIDmode, 0);
5093 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
5094 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
5095
5096 if (mode0 != mode1)
5097 abort ();
5098
5099 if (arg0 == error_mark_node || arg1 == error_mark_node
5100 || arg2 == error_mark_node || arg3 == error_mark_node)
5101 return const0_rtx;
5102
5103 if (target == 0
5104 || GET_MODE (target) != mode0
5105 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
5106 target = gen_reg_rtx (mode0);
5107
5108 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
5109 op0 = copy_to_mode_reg (mode0, op0);
5110 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
5111 op1 = copy_to_mode_reg (mode0, op1);
5112 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
5113 op2 = copy_to_mode_reg (mode0, op2);
5114 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
5115 op3 = copy_to_mode_reg (mode0, op3);
5116
5117 /* Generate the compare. */
5118 scratch = gen_reg_rtx (CCmode);
5119 pat = GEN_FCN (icode) (scratch, op0, op1);
5120 if (! pat)
5121 return const0_rtx;
5122 emit_insn (pat);
5123
5124 if (mode0 == V2SImode)
5125 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
5126 else
5127 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
5128
5129 return target;
5130}
5131
0ac081f6
AH
5132/* Expand an expression EXP that calls a built-in function,
5133 with result going to TARGET if that's convenient
5134 (and in mode MODE if that's convenient).
5135 SUBTARGET may be used as the target for computing one of EXP's operands.
5136 IGNORE is nonzero if the value is to be ignored. */
5137
5138static rtx
5139rs6000_expand_builtin (exp, target, subtarget, mode, ignore)
5140 tree exp;
5141 rtx target;
00b960c7
AH
5142 rtx subtarget ATTRIBUTE_UNUSED;
5143 enum machine_mode mode ATTRIBUTE_UNUSED;
5144 int ignore ATTRIBUTE_UNUSED;
0ac081f6 5145{
92898235
AH
5146 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
5147 tree arglist = TREE_OPERAND (exp, 1);
5148 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
5149 struct builtin_description *d;
5150 size_t i;
5151 rtx ret;
5152 bool success;
5153
0ac081f6 5154 if (TARGET_ALTIVEC)
92898235
AH
5155 {
5156 ret = altivec_expand_builtin (exp, target, &success);
5157
a3170dc6
AH
5158 if (success)
5159 return ret;
5160 }
5161 if (TARGET_SPE)
5162 {
5163 ret = spe_expand_builtin (exp, target, &success);
5164
92898235
AH
5165 if (success)
5166 return ret;
5167 }
5168
0559cc77
DE
5169 if (TARGET_ALTIVEC || TARGET_SPE)
5170 {
5171 /* Handle simple unary operations. */
5172 d = (struct builtin_description *) bdesc_1arg;
5173 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
5174 if (d->code == fcode)
5175 return rs6000_expand_unop_builtin (d->icode, arglist, target);
5176
5177 /* Handle simple binary operations. */
5178 d = (struct builtin_description *) bdesc_2arg;
5179 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
5180 if (d->code == fcode)
5181 return rs6000_expand_binop_builtin (d->icode, arglist, target);
5182
5183 /* Handle simple ternary operations. */
5184 d = (struct builtin_description *) bdesc_3arg;
5185 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
5186 if (d->code == fcode)
5187 return rs6000_expand_ternop_builtin (d->icode, arglist, target);
5188 }
0ac081f6
AH
5189
5190 abort ();
92898235 5191 return NULL_RTX;
0ac081f6
AH
5192}
5193
5194static void
6fa3f289 5195rs6000_init_builtins ()
0ac081f6 5196{
a3170dc6
AH
5197 if (TARGET_SPE)
5198 spe_init_builtins ();
0ac081f6
AH
5199 if (TARGET_ALTIVEC)
5200 altivec_init_builtins ();
0559cc77
DE
5201 if (TARGET_ALTIVEC || TARGET_SPE)
5202 rs6000_common_init_builtins ();
0ac081f6
AH
5203}
5204
a3170dc6
AH
5205/* Search through a set of builtins and enable the mask bits.
5206 DESC is an array of builtins.
5207 SIZE is the totaly number of builtins.
5208 START is the builtin enum at which to start.
5209 END is the builtin enum at which to end. */
0ac081f6 5210static void
a3170dc6
AH
5211enable_mask_for_builtins (desc, size, start, end)
5212 struct builtin_description *desc;
5213 int size;
5214 enum rs6000_builtins start, end;
5215{
5216 int i;
5217
5218 for (i = 0; i < size; ++i)
5219 if (desc[i].code == start)
5220 break;
5221
5222 if (i == size)
5223 return;
5224
5225 for (; i < size; ++i)
5226 {
5227 /* Flip all the bits on. */
5228 desc[i].mask = target_flags;
5229 if (desc[i].code == end)
5230 break;
5231 }
5232}
5233
5234static void
b24c9d35 5235spe_init_builtins ()
0ac081f6 5236{
a3170dc6
AH
5237 tree endlink = void_list_node;
5238 tree puint_type_node = build_pointer_type (unsigned_type_node);
5239 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
5240 tree pv2si_type_node = build_pointer_type (V2SI_type_node);
ae4b4a02 5241 struct builtin_description *d;
0ac081f6
AH
5242 size_t i;
5243
a3170dc6
AH
5244 tree v2si_ftype_4_v2si
5245 = build_function_type
5246 (V2SI_type_node,
5247 tree_cons (NULL_TREE, V2SI_type_node,
5248 tree_cons (NULL_TREE, V2SI_type_node,
5249 tree_cons (NULL_TREE, V2SI_type_node,
5250 tree_cons (NULL_TREE, V2SI_type_node,
5251 endlink)))));
5252
5253 tree v2sf_ftype_4_v2sf
5254 = build_function_type
5255 (V2SF_type_node,
5256 tree_cons (NULL_TREE, V2SF_type_node,
5257 tree_cons (NULL_TREE, V2SF_type_node,
5258 tree_cons (NULL_TREE, V2SF_type_node,
5259 tree_cons (NULL_TREE, V2SF_type_node,
5260 endlink)))));
5261
5262 tree int_ftype_int_v2si_v2si
5263 = build_function_type
5264 (integer_type_node,
5265 tree_cons (NULL_TREE, integer_type_node,
5266 tree_cons (NULL_TREE, V2SI_type_node,
5267 tree_cons (NULL_TREE, V2SI_type_node,
5268 endlink))));
5269
5270 tree int_ftype_int_v2sf_v2sf
5271 = build_function_type
5272 (integer_type_node,
5273 tree_cons (NULL_TREE, integer_type_node,
5274 tree_cons (NULL_TREE, V2SF_type_node,
5275 tree_cons (NULL_TREE, V2SF_type_node,
5276 endlink))));
5277
5278 tree void_ftype_v2si_puint_int
5279 = build_function_type (void_type_node,
5280 tree_cons (NULL_TREE, V2SI_type_node,
5281 tree_cons (NULL_TREE, puint_type_node,
5282 tree_cons (NULL_TREE,
5283 integer_type_node,
5284 endlink))));
5285
5286 tree void_ftype_v2si_puint_char
5287 = build_function_type (void_type_node,
5288 tree_cons (NULL_TREE, V2SI_type_node,
5289 tree_cons (NULL_TREE, puint_type_node,
5290 tree_cons (NULL_TREE,
5291 char_type_node,
5292 endlink))));
5293
5294 tree void_ftype_v2si_pv2si_int
5295 = build_function_type (void_type_node,
5296 tree_cons (NULL_TREE, V2SI_type_node,
5297 tree_cons (NULL_TREE, pv2si_type_node,
5298 tree_cons (NULL_TREE,
5299 integer_type_node,
5300 endlink))));
5301
5302 tree void_ftype_v2si_pv2si_char
5303 = build_function_type (void_type_node,
5304 tree_cons (NULL_TREE, V2SI_type_node,
5305 tree_cons (NULL_TREE, pv2si_type_node,
5306 tree_cons (NULL_TREE,
5307 char_type_node,
5308 endlink))));
5309
5310 tree void_ftype_int
5311 = build_function_type (void_type_node,
5312 tree_cons (NULL_TREE, integer_type_node, endlink));
5313
5314 tree int_ftype_void
5315 = build_function_type (integer_type_node,
5316 tree_cons (NULL_TREE, void_type_node, endlink));
5317
5318 tree v2si_ftype_pv2si_int
5319 = build_function_type (V2SI_type_node,
5320 tree_cons (NULL_TREE, pv2si_type_node,
5321 tree_cons (NULL_TREE, integer_type_node,
5322 endlink)));
5323
5324 tree v2si_ftype_puint_int
5325 = build_function_type (V2SI_type_node,
5326 tree_cons (NULL_TREE, puint_type_node,
5327 tree_cons (NULL_TREE, integer_type_node,
5328 endlink)));
5329
5330 tree v2si_ftype_pushort_int
5331 = build_function_type (V2SI_type_node,
5332 tree_cons (NULL_TREE, pushort_type_node,
5333 tree_cons (NULL_TREE, integer_type_node,
5334 endlink)));
5335
5336 /* The initialization of the simple binary and unary builtins is
5337 done in rs6000_common_init_builtins, but we have to enable the
5338 mask bits here manually because we have run out of `target_flags'
5339 bits. We really need to redesign this mask business. */
5340
5341 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
5342 ARRAY_SIZE (bdesc_2arg),
5343 SPE_BUILTIN_EVADDW,
5344 SPE_BUILTIN_EVXOR);
5345 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
5346 ARRAY_SIZE (bdesc_1arg),
5347 SPE_BUILTIN_EVABS,
5348 SPE_BUILTIN_EVSUBFUSIAAW);
5349 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
5350 ARRAY_SIZE (bdesc_spe_predicates),
5351 SPE_BUILTIN_EVCMPEQ,
5352 SPE_BUILTIN_EVFSTSTLT);
5353 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
5354 ARRAY_SIZE (bdesc_spe_evsel),
5355 SPE_BUILTIN_EVSEL_CMPGTS,
5356 SPE_BUILTIN_EVSEL_FSTSTEQ);
5357
5358 /* Initialize irregular SPE builtins. */
5359
5360 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
5361 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
5362 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
5363 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
5364 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
5365 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
5366 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
5367 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
5368 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
5369 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
5370 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
5371 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
5372 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
5373 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
5374 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
5375 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
5376
5377 /* Loads. */
5378 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
5379 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
5380 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
5381 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
5382 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
5383 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
5384 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
5385 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
5386 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
5387 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
5388 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
5389 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
5390 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
5391 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
5392 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
5393 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
5394 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
5395 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
5396 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
5397 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
5398 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
5399 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
5400
5401 /* Predicates. */
5402 d = (struct builtin_description *) bdesc_spe_predicates;
5403 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
5404 {
5405 tree type;
5406
5407 switch (insn_data[d->icode].operand[1].mode)
5408 {
5409 case V2SImode:
5410 type = int_ftype_int_v2si_v2si;
5411 break;
5412 case V2SFmode:
5413 type = int_ftype_int_v2sf_v2sf;
5414 break;
5415 default:
5416 abort ();
5417 }
5418
5419 def_builtin (d->mask, d->name, type, d->code);
5420 }
5421
5422 /* Evsel predicates. */
5423 d = (struct builtin_description *) bdesc_spe_evsel;
5424 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
5425 {
5426 tree type;
5427
5428 switch (insn_data[d->icode].operand[1].mode)
5429 {
5430 case V2SImode:
5431 type = v2si_ftype_4_v2si;
5432 break;
5433 case V2SFmode:
5434 type = v2sf_ftype_4_v2sf;
5435 break;
5436 default:
5437 abort ();
5438 }
5439
5440 def_builtin (d->mask, d->name, type, d->code);
5441 }
5442}
5443
5444static void
b24c9d35 5445altivec_init_builtins ()
a3170dc6
AH
5446{
5447 struct builtin_description *d;
5448 struct builtin_description_predicates *dp;
5449 size_t i;
5450 tree pfloat_type_node = build_pointer_type (float_type_node);
5451 tree pint_type_node = build_pointer_type (integer_type_node);
5452 tree pshort_type_node = build_pointer_type (short_integer_type_node);
5453 tree pchar_type_node = build_pointer_type (char_type_node);
5454
5455 tree pvoid_type_node = build_pointer_type (void_type_node);
5456
0dbc3651
ZW
5457 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
5458 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
5459 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
5460 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
5461
5462 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
5463
a3170dc6
AH
5464 tree int_ftype_int_v4si_v4si
5465 = build_function_type_list (integer_type_node,
5466 integer_type_node, V4SI_type_node,
5467 V4SI_type_node, NULL_TREE);
0dbc3651
ZW
5468 tree v4sf_ftype_pcfloat
5469 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
a3170dc6 5470 tree void_ftype_pfloat_v4sf
b4de2f7d 5471 = build_function_type_list (void_type_node,
a3170dc6 5472 pfloat_type_node, V4SF_type_node, NULL_TREE);
0dbc3651
ZW
5473 tree v4si_ftype_pcint
5474 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
5475 tree void_ftype_pint_v4si
b4de2f7d
AH
5476 = build_function_type_list (void_type_node,
5477 pint_type_node, V4SI_type_node, NULL_TREE);
0dbc3651
ZW
5478 tree v8hi_ftype_pcshort
5479 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
f18c054f 5480 tree void_ftype_pshort_v8hi
b4de2f7d
AH
5481 = build_function_type_list (void_type_node,
5482 pshort_type_node, V8HI_type_node, NULL_TREE);
0dbc3651
ZW
5483 tree v16qi_ftype_pcchar
5484 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
f18c054f 5485 tree void_ftype_pchar_v16qi
b4de2f7d
AH
5486 = build_function_type_list (void_type_node,
5487 pchar_type_node, V16QI_type_node, NULL_TREE);
95385cbb 5488 tree void_ftype_v4si
b4de2f7d 5489 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
a3170dc6
AH
5490 tree v8hi_ftype_void
5491 = build_function_type (V8HI_type_node, void_list_node);
5492 tree void_ftype_void
5493 = build_function_type (void_type_node, void_list_node);
5494 tree void_ftype_qi
5495 = build_function_type_list (void_type_node, char_type_node, NULL_TREE);
0dbc3651
ZW
5496
5497 tree v16qi_ftype_int_pcvoid
a3170dc6 5498 = build_function_type_list (V16QI_type_node,
0dbc3651
ZW
5499 integer_type_node, pcvoid_type_node, NULL_TREE);
5500 tree v8hi_ftype_int_pcvoid
a3170dc6 5501 = build_function_type_list (V8HI_type_node,
0dbc3651
ZW
5502 integer_type_node, pcvoid_type_node, NULL_TREE);
5503 tree v4si_ftype_int_pcvoid
a3170dc6 5504 = build_function_type_list (V4SI_type_node,
0dbc3651
ZW
5505 integer_type_node, pcvoid_type_node, NULL_TREE);
5506
14b32f4e 5507 tree void_ftype_v4si_int_pvoid
b4de2f7d
AH
5508 = build_function_type_list (void_type_node,
5509 V4SI_type_node, integer_type_node,
5510 pvoid_type_node, NULL_TREE);
6525c0e7 5511 tree void_ftype_v16qi_int_pvoid
b4de2f7d
AH
5512 = build_function_type_list (void_type_node,
5513 V16QI_type_node, integer_type_node,
5514 pvoid_type_node, NULL_TREE);
6525c0e7 5515 tree void_ftype_v8hi_int_pvoid
b4de2f7d
AH
5516 = build_function_type_list (void_type_node,
5517 V8HI_type_node, integer_type_node,
5518 pvoid_type_node, NULL_TREE);
a3170dc6
AH
5519 tree int_ftype_int_v8hi_v8hi
5520 = build_function_type_list (integer_type_node,
5521 integer_type_node, V8HI_type_node,
5522 V8HI_type_node, NULL_TREE);
5523 tree int_ftype_int_v16qi_v16qi
5524 = build_function_type_list (integer_type_node,
5525 integer_type_node, V16QI_type_node,
5526 V16QI_type_node, NULL_TREE);
5527 tree int_ftype_int_v4sf_v4sf
5528 = build_function_type_list (integer_type_node,
5529 integer_type_node, V4SF_type_node,
5530 V4SF_type_node, NULL_TREE);
5531 tree v4si_ftype_v4si
5532 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
5533 tree v8hi_ftype_v8hi
5534 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
5535 tree v16qi_ftype_v16qi
5536 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
5537 tree v4sf_ftype_v4sf
5538 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
0dbc3651 5539 tree void_ftype_pcvoid_int_char
a3170dc6 5540 = build_function_type_list (void_type_node,
0dbc3651 5541 pcvoid_type_node, integer_type_node,
a3170dc6 5542 char_type_node, NULL_TREE);
0dbc3651
ZW
5543
5544 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
5545 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
5546 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
5547 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
5548 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
5549 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
5550 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
5551 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
5552 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
5553 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
5554 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
5555 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
5556 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
5557 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
5558 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
5559 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
a3170dc6
AH
5560 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
5561 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
5562 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
5563 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_qi, ALTIVEC_BUILTIN_DSS);
0dbc3651
ZW
5564 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVSL);
5565 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVSR);
5566 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVEBX);
5567 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVEHX);
5568 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVEWX);
5569 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVXL);
5570 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVX);
a3170dc6
AH
5571 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVX);
5572 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVEWX);
5573 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVXL);
5574 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_int_pvoid, ALTIVEC_BUILTIN_STVEBX);
5575 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_int_pvoid, ALTIVEC_BUILTIN_STVEHX);
5576
5577 /* Add the DST variants. */
5578 d = (struct builtin_description *) bdesc_dst;
5579 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
0dbc3651 5580 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_char, d->code);
a3170dc6
AH
5581
5582 /* Initialize the predicates. */
5583 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
5584 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
5585 {
5586 enum machine_mode mode1;
5587 tree type;
5588
5589 mode1 = insn_data[dp->icode].operand[1].mode;
5590
5591 switch (mode1)
5592 {
5593 case V4SImode:
5594 type = int_ftype_int_v4si_v4si;
5595 break;
5596 case V8HImode:
5597 type = int_ftype_int_v8hi_v8hi;
5598 break;
5599 case V16QImode:
5600 type = int_ftype_int_v16qi_v16qi;
5601 break;
5602 case V4SFmode:
5603 type = int_ftype_int_v4sf_v4sf;
5604 break;
5605 default:
5606 abort ();
5607 }
5608
5609 def_builtin (dp->mask, dp->name, type, dp->code);
5610 }
5611
5612 /* Initialize the abs* operators. */
5613 d = (struct builtin_description *) bdesc_abs;
5614 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
5615 {
5616 enum machine_mode mode0;
5617 tree type;
5618
5619 mode0 = insn_data[d->icode].operand[0].mode;
5620
5621 switch (mode0)
5622 {
5623 case V4SImode:
5624 type = v4si_ftype_v4si;
5625 break;
5626 case V8HImode:
5627 type = v8hi_ftype_v8hi;
5628 break;
5629 case V16QImode:
5630 type = v16qi_ftype_v16qi;
5631 break;
5632 case V4SFmode:
5633 type = v4sf_ftype_v4sf;
5634 break;
5635 default:
5636 abort ();
5637 }
5638
5639 def_builtin (d->mask, d->name, type, d->code);
5640 }
5641}
5642
5643static void
b24c9d35 5644rs6000_common_init_builtins ()
a3170dc6
AH
5645{
5646 struct builtin_description *d;
5647 size_t i;
5648
5649 tree v4sf_ftype_v4sf_v4sf_v16qi
5650 = build_function_type_list (V4SF_type_node,
5651 V4SF_type_node, V4SF_type_node,
5652 V16QI_type_node, NULL_TREE);
5653 tree v4si_ftype_v4si_v4si_v16qi
5654 = build_function_type_list (V4SI_type_node,
5655 V4SI_type_node, V4SI_type_node,
5656 V16QI_type_node, NULL_TREE);
5657 tree v8hi_ftype_v8hi_v8hi_v16qi
5658 = build_function_type_list (V8HI_type_node,
5659 V8HI_type_node, V8HI_type_node,
5660 V16QI_type_node, NULL_TREE);
5661 tree v16qi_ftype_v16qi_v16qi_v16qi
5662 = build_function_type_list (V16QI_type_node,
5663 V16QI_type_node, V16QI_type_node,
5664 V16QI_type_node, NULL_TREE);
5665 tree v4si_ftype_char
5666 = build_function_type_list (V4SI_type_node, char_type_node, NULL_TREE);
5667 tree v8hi_ftype_char
5668 = build_function_type_list (V8HI_type_node, char_type_node, NULL_TREE);
5669 tree v16qi_ftype_char
5670 = build_function_type_list (V16QI_type_node, char_type_node, NULL_TREE);
5671 tree v8hi_ftype_v16qi
5672 = build_function_type_list (V8HI_type_node, V16QI_type_node, NULL_TREE);
5673 tree v4sf_ftype_v4sf
5674 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
5675
5676 tree v2si_ftype_v2si_v2si
5677 = build_function_type_list (V2SI_type_node,
5678 V2SI_type_node, V2SI_type_node, NULL_TREE);
5679
5680 tree v2sf_ftype_v2sf_v2sf
5681 = build_function_type_list (V2SF_type_node,
5682 V2SF_type_node, V2SF_type_node, NULL_TREE);
5683
5684 tree v2si_ftype_int_int
5685 = build_function_type_list (V2SI_type_node,
5686 integer_type_node, integer_type_node,
5687 NULL_TREE);
5688
5689 tree v2si_ftype_v2si
5690 = build_function_type_list (V2SI_type_node, V2SI_type_node, NULL_TREE);
5691
5692 tree v2sf_ftype_v2sf
5693 = build_function_type_list (V2SF_type_node,
5694 V2SF_type_node, NULL_TREE);
5695
5696 tree v2sf_ftype_v2si
5697 = build_function_type_list (V2SF_type_node,
5698 V2SI_type_node, NULL_TREE);
5699
5700 tree v2si_ftype_v2sf
5701 = build_function_type_list (V2SI_type_node,
5702 V2SF_type_node, NULL_TREE);
5703
5704 tree v2si_ftype_v2si_char
5705 = build_function_type_list (V2SI_type_node,
5706 V2SI_type_node, char_type_node, NULL_TREE);
5707
5708 tree v2si_ftype_int_char
5709 = build_function_type_list (V2SI_type_node,
5710 integer_type_node, char_type_node, NULL_TREE);
5711
5712 tree v2si_ftype_char
5713 = build_function_type_list (V2SI_type_node, char_type_node, NULL_TREE);
5714
5715 tree int_ftype_int_int
5716 = build_function_type_list (integer_type_node,
5717 integer_type_node, integer_type_node,
5718 NULL_TREE);
95385cbb 5719
0ac081f6 5720 tree v4si_ftype_v4si_v4si
b4de2f7d
AH
5721 = build_function_type_list (V4SI_type_node,
5722 V4SI_type_node, V4SI_type_node, NULL_TREE);
617e0e1d 5723 tree v4sf_ftype_v4si_char
b4de2f7d
AH
5724 = build_function_type_list (V4SF_type_node,
5725 V4SI_type_node, char_type_node, NULL_TREE);
617e0e1d 5726 tree v4si_ftype_v4sf_char
b4de2f7d
AH
5727 = build_function_type_list (V4SI_type_node,
5728 V4SF_type_node, char_type_node, NULL_TREE);
2212663f 5729 tree v4si_ftype_v4si_char
b4de2f7d
AH
5730 = build_function_type_list (V4SI_type_node,
5731 V4SI_type_node, char_type_node, NULL_TREE);
2212663f 5732 tree v8hi_ftype_v8hi_char
b4de2f7d
AH
5733 = build_function_type_list (V8HI_type_node,
5734 V8HI_type_node, char_type_node, NULL_TREE);
2212663f 5735 tree v16qi_ftype_v16qi_char
b4de2f7d
AH
5736 = build_function_type_list (V16QI_type_node,
5737 V16QI_type_node, char_type_node, NULL_TREE);
24408032 5738 tree v16qi_ftype_v16qi_v16qi_char
b4de2f7d
AH
5739 = build_function_type_list (V16QI_type_node,
5740 V16QI_type_node, V16QI_type_node,
5741 char_type_node, NULL_TREE);
24408032 5742 tree v8hi_ftype_v8hi_v8hi_char
b4de2f7d
AH
5743 = build_function_type_list (V8HI_type_node,
5744 V8HI_type_node, V8HI_type_node,
5745 char_type_node, NULL_TREE);
24408032 5746 tree v4si_ftype_v4si_v4si_char
b4de2f7d
AH
5747 = build_function_type_list (V4SI_type_node,
5748 V4SI_type_node, V4SI_type_node,
5749 char_type_node, NULL_TREE);
24408032 5750 tree v4sf_ftype_v4sf_v4sf_char
b4de2f7d
AH
5751 = build_function_type_list (V4SF_type_node,
5752 V4SF_type_node, V4SF_type_node,
5753 char_type_node, NULL_TREE);
0ac081f6 5754 tree v4sf_ftype_v4sf_v4sf
b4de2f7d
AH
5755 = build_function_type_list (V4SF_type_node,
5756 V4SF_type_node, V4SF_type_node, NULL_TREE);
617e0e1d 5757 tree v4sf_ftype_v4sf_v4sf_v4si
b4de2f7d
AH
5758 = build_function_type_list (V4SF_type_node,
5759 V4SF_type_node, V4SF_type_node,
5760 V4SI_type_node, NULL_TREE);
2212663f 5761 tree v4sf_ftype_v4sf_v4sf_v4sf
b4de2f7d
AH
5762 = build_function_type_list (V4SF_type_node,
5763 V4SF_type_node, V4SF_type_node,
5764 V4SF_type_node, NULL_TREE);
617e0e1d 5765 tree v4si_ftype_v4si_v4si_v4si
b4de2f7d
AH
5766 = build_function_type_list (V4SI_type_node,
5767 V4SI_type_node, V4SI_type_node,
5768 V4SI_type_node, NULL_TREE);
0ac081f6 5769 tree v8hi_ftype_v8hi_v8hi
b4de2f7d
AH
5770 = build_function_type_list (V8HI_type_node,
5771 V8HI_type_node, V8HI_type_node, NULL_TREE);
2212663f 5772 tree v8hi_ftype_v8hi_v8hi_v8hi
b4de2f7d
AH
5773 = build_function_type_list (V8HI_type_node,
5774 V8HI_type_node, V8HI_type_node,
5775 V8HI_type_node, NULL_TREE);
2212663f 5776 tree v4si_ftype_v8hi_v8hi_v4si
b4de2f7d
AH
5777 = build_function_type_list (V4SI_type_node,
5778 V8HI_type_node, V8HI_type_node,
5779 V4SI_type_node, NULL_TREE);
2212663f 5780 tree v4si_ftype_v16qi_v16qi_v4si
b4de2f7d
AH
5781 = build_function_type_list (V4SI_type_node,
5782 V16QI_type_node, V16QI_type_node,
5783 V4SI_type_node, NULL_TREE);
0ac081f6 5784 tree v16qi_ftype_v16qi_v16qi
b4de2f7d
AH
5785 = build_function_type_list (V16QI_type_node,
5786 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5787 tree v4si_ftype_v4sf_v4sf
b4de2f7d
AH
5788 = build_function_type_list (V4SI_type_node,
5789 V4SF_type_node, V4SF_type_node, NULL_TREE);
0ac081f6 5790 tree v8hi_ftype_v16qi_v16qi
b4de2f7d
AH
5791 = build_function_type_list (V8HI_type_node,
5792 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5793 tree v4si_ftype_v8hi_v8hi
b4de2f7d
AH
5794 = build_function_type_list (V4SI_type_node,
5795 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 5796 tree v8hi_ftype_v4si_v4si
b4de2f7d
AH
5797 = build_function_type_list (V8HI_type_node,
5798 V4SI_type_node, V4SI_type_node, NULL_TREE);
0ac081f6 5799 tree v16qi_ftype_v8hi_v8hi
b4de2f7d
AH
5800 = build_function_type_list (V16QI_type_node,
5801 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 5802 tree v4si_ftype_v16qi_v4si
b4de2f7d
AH
5803 = build_function_type_list (V4SI_type_node,
5804 V16QI_type_node, V4SI_type_node, NULL_TREE);
fa066a23 5805 tree v4si_ftype_v16qi_v16qi
b4de2f7d
AH
5806 = build_function_type_list (V4SI_type_node,
5807 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5808 tree v4si_ftype_v8hi_v4si
b4de2f7d
AH
5809 = build_function_type_list (V4SI_type_node,
5810 V8HI_type_node, V4SI_type_node, NULL_TREE);
a3170dc6
AH
5811 tree v4si_ftype_v8hi
5812 = build_function_type_list (V4SI_type_node, V8HI_type_node, NULL_TREE);
5813 tree int_ftype_v4si_v4si
5814 = build_function_type_list (integer_type_node,
5815 V4SI_type_node, V4SI_type_node, NULL_TREE);
5816 tree int_ftype_v4sf_v4sf
5817 = build_function_type_list (integer_type_node,
5818 V4SF_type_node, V4SF_type_node, NULL_TREE);
5819 tree int_ftype_v16qi_v16qi
5820 = build_function_type_list (integer_type_node,
5821 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5822 tree int_ftype_v8hi_v8hi
b4de2f7d
AH
5823 = build_function_type_list (integer_type_node,
5824 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 5825
6f317ef3 5826 /* Add the simple ternary operators. */
2212663f 5827 d = (struct builtin_description *) bdesc_3arg;
ca7558fc 5828 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
2212663f
DB
5829 {
5830
5831 enum machine_mode mode0, mode1, mode2, mode3;
5832 tree type;
5833
0559cc77 5834 if (d->name == 0 || d->icode == CODE_FOR_nothing)
2212663f
DB
5835 continue;
5836
5837 mode0 = insn_data[d->icode].operand[0].mode;
5838 mode1 = insn_data[d->icode].operand[1].mode;
5839 mode2 = insn_data[d->icode].operand[2].mode;
5840 mode3 = insn_data[d->icode].operand[3].mode;
5841
5842 /* When all four are of the same mode. */
5843 if (mode0 == mode1 && mode1 == mode2 && mode2 == mode3)
5844 {
5845 switch (mode0)
5846 {
617e0e1d
DB
5847 case V4SImode:
5848 type = v4si_ftype_v4si_v4si_v4si;
5849 break;
2212663f
DB
5850 case V4SFmode:
5851 type = v4sf_ftype_v4sf_v4sf_v4sf;
5852 break;
5853 case V8HImode:
5854 type = v8hi_ftype_v8hi_v8hi_v8hi;
5855 break;
5856 case V16QImode:
5857 type = v16qi_ftype_v16qi_v16qi_v16qi;
5858 break;
5859 default:
5860 abort();
5861 }
5862 }
5863 else if (mode0 == mode1 && mode1 == mode2 && mode3 == V16QImode)
5864 {
5865 switch (mode0)
5866 {
5867 case V4SImode:
5868 type = v4si_ftype_v4si_v4si_v16qi;
5869 break;
5870 case V4SFmode:
5871 type = v4sf_ftype_v4sf_v4sf_v16qi;
5872 break;
5873 case V8HImode:
5874 type = v8hi_ftype_v8hi_v8hi_v16qi;
5875 break;
5876 case V16QImode:
5877 type = v16qi_ftype_v16qi_v16qi_v16qi;
5878 break;
5879 default:
5880 abort();
5881 }
5882 }
5883 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode
5884 && mode3 == V4SImode)
24408032 5885 type = v4si_ftype_v16qi_v16qi_v4si;
2212663f
DB
5886 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode
5887 && mode3 == V4SImode)
24408032 5888 type = v4si_ftype_v8hi_v8hi_v4si;
617e0e1d
DB
5889 else if (mode0 == V4SFmode && mode1 == V4SFmode && mode2 == V4SFmode
5890 && mode3 == V4SImode)
24408032
AH
5891 type = v4sf_ftype_v4sf_v4sf_v4si;
5892
5893 /* vchar, vchar, vchar, 4 bit literal. */
5894 else if (mode0 == V16QImode && mode1 == mode0 && mode2 == mode0
5895 && mode3 == QImode)
5896 type = v16qi_ftype_v16qi_v16qi_char;
5897
5898 /* vshort, vshort, vshort, 4 bit literal. */
5899 else if (mode0 == V8HImode && mode1 == mode0 && mode2 == mode0
5900 && mode3 == QImode)
5901 type = v8hi_ftype_v8hi_v8hi_char;
5902
5903 /* vint, vint, vint, 4 bit literal. */
5904 else if (mode0 == V4SImode && mode1 == mode0 && mode2 == mode0
5905 && mode3 == QImode)
5906 type = v4si_ftype_v4si_v4si_char;
5907
5908 /* vfloat, vfloat, vfloat, 4 bit literal. */
5909 else if (mode0 == V4SFmode && mode1 == mode0 && mode2 == mode0
5910 && mode3 == QImode)
5911 type = v4sf_ftype_v4sf_v4sf_char;
5912
2212663f
DB
5913 else
5914 abort ();
5915
5916 def_builtin (d->mask, d->name, type, d->code);
5917 }
5918
0ac081f6 5919 /* Add the simple binary operators. */
00b960c7 5920 d = (struct builtin_description *) bdesc_2arg;
ca7558fc 5921 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
0ac081f6
AH
5922 {
5923 enum machine_mode mode0, mode1, mode2;
5924 tree type;
5925
0559cc77 5926 if (d->name == 0 || d->icode == CODE_FOR_nothing)
0ac081f6
AH
5927 continue;
5928
5929 mode0 = insn_data[d->icode].operand[0].mode;
5930 mode1 = insn_data[d->icode].operand[1].mode;
5931 mode2 = insn_data[d->icode].operand[2].mode;
5932
5933 /* When all three operands are of the same mode. */
5934 if (mode0 == mode1 && mode1 == mode2)
5935 {
5936 switch (mode0)
5937 {
5938 case V4SFmode:
5939 type = v4sf_ftype_v4sf_v4sf;
5940 break;
5941 case V4SImode:
5942 type = v4si_ftype_v4si_v4si;
5943 break;
5944 case V16QImode:
5945 type = v16qi_ftype_v16qi_v16qi;
5946 break;
5947 case V8HImode:
5948 type = v8hi_ftype_v8hi_v8hi;
5949 break;
a3170dc6
AH
5950 case V2SImode:
5951 type = v2si_ftype_v2si_v2si;
5952 break;
5953 case V2SFmode:
5954 type = v2sf_ftype_v2sf_v2sf;
5955 break;
5956 case SImode:
5957 type = int_ftype_int_int;
5958 break;
0ac081f6
AH
5959 default:
5960 abort ();
5961 }
5962 }
5963
5964 /* A few other combos we really don't want to do manually. */
5965
5966 /* vint, vfloat, vfloat. */
5967 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
5968 type = v4si_ftype_v4sf_v4sf;
5969
5970 /* vshort, vchar, vchar. */
5971 else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
5972 type = v8hi_ftype_v16qi_v16qi;
5973
5974 /* vint, vshort, vshort. */
5975 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
5976 type = v4si_ftype_v8hi_v8hi;
5977
5978 /* vshort, vint, vint. */
5979 else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
5980 type = v8hi_ftype_v4si_v4si;
5981
5982 /* vchar, vshort, vshort. */
5983 else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
5984 type = v16qi_ftype_v8hi_v8hi;
5985
5986 /* vint, vchar, vint. */
5987 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
5988 type = v4si_ftype_v16qi_v4si;
5989
fa066a23
AH
5990 /* vint, vchar, vchar. */
5991 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode)
5992 type = v4si_ftype_v16qi_v16qi;
5993
0ac081f6
AH
5994 /* vint, vshort, vint. */
5995 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
5996 type = v4si_ftype_v8hi_v4si;
2212663f
DB
5997
5998 /* vint, vint, 5 bit literal. */
5999 else if (mode0 == V4SImode && mode1 == V4SImode && mode2 == QImode)
6000 type = v4si_ftype_v4si_char;
6001
6002 /* vshort, vshort, 5 bit literal. */
6003 else if (mode0 == V8HImode && mode1 == V8HImode && mode2 == QImode)
6004 type = v8hi_ftype_v8hi_char;
6005
6006 /* vchar, vchar, 5 bit literal. */
6007 else if (mode0 == V16QImode && mode1 == V16QImode && mode2 == QImode)
6008 type = v16qi_ftype_v16qi_char;
0ac081f6 6009
617e0e1d
DB
6010 /* vfloat, vint, 5 bit literal. */
6011 else if (mode0 == V4SFmode && mode1 == V4SImode && mode2 == QImode)
6012 type = v4sf_ftype_v4si_char;
6013
6014 /* vint, vfloat, 5 bit literal. */
6015 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == QImode)
6016 type = v4si_ftype_v4sf_char;
6017
a3170dc6
AH
6018 else if (mode0 == V2SImode && mode1 == SImode && mode2 == SImode)
6019 type = v2si_ftype_int_int;
6020
6021 else if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
6022 type = v2si_ftype_v2si_char;
6023
6024 else if (mode0 == V2SImode && mode1 == SImode && mode2 == QImode)
6025 type = v2si_ftype_int_char;
6026
0ac081f6
AH
6027 /* int, x, x. */
6028 else if (mode0 == SImode)
6029 {
6030 switch (mode1)
6031 {
6032 case V4SImode:
6033 type = int_ftype_v4si_v4si;
6034 break;
6035 case V4SFmode:
6036 type = int_ftype_v4sf_v4sf;
6037 break;
6038 case V16QImode:
6039 type = int_ftype_v16qi_v16qi;
6040 break;
6041 case V8HImode:
6042 type = int_ftype_v8hi_v8hi;
6043 break;
6044 default:
6045 abort ();
6046 }
6047 }
6048
6049 else
6050 abort ();
6051
2212663f
DB
6052 def_builtin (d->mask, d->name, type, d->code);
6053 }
24408032 6054
2212663f
DB
6055 /* Add the simple unary operators. */
6056 d = (struct builtin_description *) bdesc_1arg;
ca7558fc 6057 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
2212663f
DB
6058 {
6059 enum machine_mode mode0, mode1;
6060 tree type;
6061
0559cc77 6062 if (d->name == 0 || d->icode == CODE_FOR_nothing)
2212663f
DB
6063 continue;
6064
6065 mode0 = insn_data[d->icode].operand[0].mode;
6066 mode1 = insn_data[d->icode].operand[1].mode;
6067
6068 if (mode0 == V4SImode && mode1 == QImode)
6069 type = v4si_ftype_char;
6070 else if (mode0 == V8HImode && mode1 == QImode)
6071 type = v8hi_ftype_char;
6072 else if (mode0 == V16QImode && mode1 == QImode)
6073 type = v16qi_ftype_char;
617e0e1d
DB
6074 else if (mode0 == V4SFmode && mode1 == V4SFmode)
6075 type = v4sf_ftype_v4sf;
20e26713
AH
6076 else if (mode0 == V8HImode && mode1 == V16QImode)
6077 type = v8hi_ftype_v16qi;
6078 else if (mode0 == V4SImode && mode1 == V8HImode)
6079 type = v4si_ftype_v8hi;
a3170dc6
AH
6080 else if (mode0 == V2SImode && mode1 == V2SImode)
6081 type = v2si_ftype_v2si;
6082 else if (mode0 == V2SFmode && mode1 == V2SFmode)
6083 type = v2sf_ftype_v2sf;
6084 else if (mode0 == V2SFmode && mode1 == V2SImode)
6085 type = v2sf_ftype_v2si;
6086 else if (mode0 == V2SImode && mode1 == V2SFmode)
6087 type = v2si_ftype_v2sf;
6088 else if (mode0 == V2SImode && mode1 == QImode)
6089 type = v2si_ftype_char;
2212663f
DB
6090 else
6091 abort ();
6092
0ac081f6
AH
6093 def_builtin (d->mask, d->name, type, d->code);
6094 }
6095}
6096
35aff10b 6097\f
7e69e155
MM
6098/* Expand a block move operation, and return 1 if successful. Return 0
6099 if we should let the compiler generate normal code.
6100
6101 operands[0] is the destination
6102 operands[1] is the source
6103 operands[2] is the length
6104 operands[3] is the alignment */
6105
3933e0e1
MM
6106#define MAX_MOVE_REG 4
6107
7e69e155
MM
6108int
6109expand_block_move (operands)
6110 rtx operands[];
6111{
b6c9286a
MM
6112 rtx orig_dest = operands[0];
6113 rtx orig_src = operands[1];
7e69e155 6114 rtx bytes_rtx = operands[2];
7e69e155 6115 rtx align_rtx = operands[3];
3933e0e1 6116 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
5ee95df6 6117 int align;
3933e0e1
MM
6118 int bytes;
6119 int offset;
7e69e155
MM
6120 int move_bytes;
6121
3933e0e1 6122 /* If this is not a fixed size move, just call memcpy */
cc0d9ba8 6123 if (! constp)
3933e0e1
MM
6124 return 0;
6125
5ee95df6
FS
6126 /* If this is not a fixed size alignment, abort */
6127 if (GET_CODE (align_rtx) != CONST_INT)
6128 abort ();
6129 align = INTVAL (align_rtx);
6130
7e69e155 6131 /* Anything to move? */
3933e0e1
MM
6132 bytes = INTVAL (bytes_rtx);
6133 if (bytes <= 0)
7e69e155
MM
6134 return 1;
6135
ea9982a8 6136 /* store_one_arg depends on expand_block_move to handle at least the size of
6f317ef3 6137 reg_parm_stack_space. */
ea9982a8 6138 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
7e69e155
MM
6139 return 0;
6140
3933e0e1 6141 if (TARGET_STRING) /* string instructions are available */
7e69e155 6142 {
35aff10b 6143 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
7e69e155 6144 {
35aff10b
AM
6145 union {
6146 rtx (*movstrsi) PARAMS ((rtx, rtx, rtx, rtx));
6147 rtx (*mov) PARAMS ((rtx, rtx));
6148 } gen_func;
6149 enum machine_mode mode = BLKmode;
6150 rtx src, dest;
6151
3933e0e1 6152 if (bytes > 24 /* move up to 32 bytes at a time */
cc0d9ba8
DE
6153 && ! fixed_regs[5]
6154 && ! fixed_regs[6]
6155 && ! fixed_regs[7]
6156 && ! fixed_regs[8]
6157 && ! fixed_regs[9]
6158 && ! fixed_regs[10]
6159 && ! fixed_regs[11]
6160 && ! fixed_regs[12])
3933e0e1
MM
6161 {
6162 move_bytes = (bytes > 32) ? 32 : bytes;
35aff10b 6163 gen_func.movstrsi = gen_movstrsi_8reg;
3933e0e1
MM
6164 }
6165 else if (bytes > 16 /* move up to 24 bytes at a time */
f9562f27
DE
6166 && ! fixed_regs[5]
6167 && ! fixed_regs[6]
cc0d9ba8
DE
6168 && ! fixed_regs[7]
6169 && ! fixed_regs[8]
6170 && ! fixed_regs[9]
f9562f27 6171 && ! fixed_regs[10])
3933e0e1
MM
6172 {
6173 move_bytes = (bytes > 24) ? 24 : bytes;
35aff10b 6174 gen_func.movstrsi = gen_movstrsi_6reg;
3933e0e1
MM
6175 }
6176 else if (bytes > 8 /* move up to 16 bytes at a time */
f9562f27
DE
6177 && ! fixed_regs[5]
6178 && ! fixed_regs[6]
6179 && ! fixed_regs[7]
6180 && ! fixed_regs[8])
3933e0e1
MM
6181 {
6182 move_bytes = (bytes > 16) ? 16 : bytes;
35aff10b 6183 gen_func.movstrsi = gen_movstrsi_4reg;
3933e0e1 6184 }
acad7ed3 6185 else if (bytes >= 8 && TARGET_POWERPC64
a4f6c312 6186 /* 64-bit loads and stores require word-aligned
82e41834 6187 displacements. */
a4f6c312 6188 && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
acad7ed3
DE
6189 {
6190 move_bytes = 8;
35aff10b
AM
6191 mode = DImode;
6192 gen_func.mov = gen_movdi;
acad7ed3 6193 }
09a625f7 6194 else if (bytes > 4 && !TARGET_POWERPC64)
3933e0e1
MM
6195 { /* move up to 8 bytes at a time */
6196 move_bytes = (bytes > 8) ? 8 : bytes;
35aff10b 6197 gen_func.movstrsi = gen_movstrsi_2reg;
3933e0e1 6198 }
cc0d9ba8 6199 else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6200 { /* move 4 bytes */
6201 move_bytes = 4;
35aff10b
AM
6202 mode = SImode;
6203 gen_func.mov = gen_movsi;
3933e0e1 6204 }
cc0d9ba8 6205 else if (bytes == 2 && (align >= 2 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6206 { /* move 2 bytes */
6207 move_bytes = 2;
35aff10b
AM
6208 mode = HImode;
6209 gen_func.mov = gen_movhi;
3933e0e1
MM
6210 }
6211 else if (bytes == 1) /* move 1 byte */
6212 {
6213 move_bytes = 1;
35aff10b
AM
6214 mode = QImode;
6215 gen_func.mov = gen_movqi;
3933e0e1
MM
6216 }
6217 else
6218 { /* move up to 4 bytes at a time */
6219 move_bytes = (bytes > 4) ? 4 : bytes;
35aff10b 6220 gen_func.movstrsi = gen_movstrsi_1reg;
3933e0e1 6221 }
4c64a852 6222
35aff10b
AM
6223 src = adjust_address (orig_src, mode, offset);
6224 dest = adjust_address (orig_dest, mode, offset);
6225
6226 if (mode == BLKmode)
015892ee 6227 {
35aff10b
AM
6228 /* Move the address into scratch registers. The movstrsi
6229 patterns require zero offset. */
6230 if (!REG_P (XEXP (src, 0)))
cc0d9ba8 6231 {
35aff10b
AM
6232 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
6233 src = replace_equiv_address (src, src_reg);
cc0d9ba8 6234 }
35aff10b
AM
6235 set_mem_size (src, GEN_INT (move_bytes));
6236
6237 if (!REG_P (XEXP (dest, 0)))
cc0d9ba8 6238 {
35aff10b
AM
6239 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
6240 dest = replace_equiv_address (dest, dest_reg);
cc0d9ba8 6241 }
35aff10b
AM
6242 set_mem_size (dest, GEN_INT (move_bytes));
6243
6244 emit_insn ((*gen_func.movstrsi) (dest, src,
6245 GEN_INT (move_bytes & 31),
6246 align_rtx));
6247 }
6248 else
6249 {
6250 rtx tmp_reg = gen_reg_rtx (mode);
6251
6252 emit_insn ((*gen_func.mov) (tmp_reg, src));
6253 emit_insn ((*gen_func.mov) (dest, tmp_reg));
015892ee 6254 }
4c64a852 6255 }
3933e0e1
MM
6256 }
6257
6258 else /* string instructions not available */
6259 {
35aff10b
AM
6260 rtx stores[MAX_MOVE_REG];
6261 int num_reg = 0;
6262 int i;
6263
6264 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
7e69e155 6265 {
35aff10b
AM
6266 rtx (*gen_mov_func) PARAMS ((rtx, rtx));
6267 enum machine_mode mode;
6268 rtx src, dest, tmp_reg;
3933e0e1 6269
cc0d9ba8
DE
6270 /* Generate the appropriate load and store, saving the stores
6271 for later. */
6272 if (bytes >= 8 && TARGET_POWERPC64
a4f6c312
SS
6273 /* 64-bit loads and stores require word-aligned
6274 displacements. */
cc0d9ba8 6275 && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
b6c9286a
MM
6276 {
6277 move_bytes = 8;
35aff10b
AM
6278 mode = DImode;
6279 gen_mov_func = gen_movdi;
b6c9286a 6280 }
cc0d9ba8 6281 else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6282 {
6283 move_bytes = 4;
35aff10b
AM
6284 mode = SImode;
6285 gen_mov_func = gen_movsi;
3933e0e1 6286 }
cc0d9ba8 6287 else if (bytes >= 2 && (align >= 2 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6288 {
6289 move_bytes = 2;
35aff10b
AM
6290 mode = HImode;
6291 gen_mov_func = gen_movhi;
3933e0e1
MM
6292 }
6293 else
6294 {
6295 move_bytes = 1;
35aff10b
AM
6296 mode = QImode;
6297 gen_mov_func = gen_movqi;
3933e0e1
MM
6298 }
6299
35aff10b
AM
6300 src = adjust_address (orig_src, mode, offset);
6301 dest = adjust_address (orig_dest, mode, offset);
6302 tmp_reg = gen_reg_rtx (mode);
6303
6304 emit_insn ((*gen_mov_func) (tmp_reg, src));
6305 stores[num_reg++] = (*gen_mov_func) (dest, tmp_reg);
6306
3933e0e1
MM
6307 if (num_reg >= MAX_MOVE_REG)
6308 {
6309 for (i = 0; i < num_reg; i++)
6310 emit_insn (stores[i]);
6311 num_reg = 0;
7e69e155
MM
6312 }
6313 }
3933e0e1 6314
b6c9286a
MM
6315 for (i = 0; i < num_reg; i++)
6316 emit_insn (stores[i]);
7e69e155
MM
6317 }
6318
6319 return 1;
6320}
6321
9878760c
RK
6322\f
6323/* Return 1 if OP is a load multiple operation. It is known to be a
6324 PARALLEL and the first section will be tested. */
6325
6326int
6327load_multiple_operation (op, mode)
6328 rtx op;
296b8152 6329 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
6330{
6331 int count = XVECLEN (op, 0);
e2c953b6 6332 unsigned int dest_regno;
9878760c
RK
6333 rtx src_addr;
6334 int i;
6335
6336 /* Perform a quick check so we don't blow up below. */
6337 if (count <= 1
6338 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6339 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
6340 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
6341 return 0;
6342
6343 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6344 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
6345
6346 for (i = 1; i < count; i++)
6347 {
6348 rtx elt = XVECEXP (op, 0, i);
6349
6350 if (GET_CODE (elt) != SET
6351 || GET_CODE (SET_DEST (elt)) != REG
6352 || GET_MODE (SET_DEST (elt)) != SImode
6353 || REGNO (SET_DEST (elt)) != dest_regno + i
6354 || GET_CODE (SET_SRC (elt)) != MEM
6355 || GET_MODE (SET_SRC (elt)) != SImode
6356 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
6357 || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
6358 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
6359 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4)
6360 return 0;
6361 }
6362
6363 return 1;
6364}
6365
6366/* Similar, but tests for store multiple. Here, the second vector element
6367 is a CLOBBER. It will be tested later. */
6368
6369int
6370store_multiple_operation (op, mode)
6371 rtx op;
296b8152 6372 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
6373{
6374 int count = XVECLEN (op, 0) - 1;
e2c953b6 6375 unsigned int src_regno;
9878760c
RK
6376 rtx dest_addr;
6377 int i;
6378
6379 /* Perform a quick check so we don't blow up below. */
6380 if (count <= 1
6381 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6382 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
6383 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
6384 return 0;
6385
6386 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6387 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
6388
6389 for (i = 1; i < count; i++)
6390 {
6391 rtx elt = XVECEXP (op, 0, i + 1);
6392
6393 if (GET_CODE (elt) != SET
6394 || GET_CODE (SET_SRC (elt)) != REG
6395 || GET_MODE (SET_SRC (elt)) != SImode
6396 || REGNO (SET_SRC (elt)) != src_regno + i
6397 || GET_CODE (SET_DEST (elt)) != MEM
6398 || GET_MODE (SET_DEST (elt)) != SImode
6399 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
6400 || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
6401 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
6402 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4)
6403 return 0;
6404 }
6405
6406 return 1;
6407}
9ebbca7d 6408
9caa3eb2
DE
6409/* Return a string to perform a load_multiple operation.
6410 operands[0] is the vector.
6411 operands[1] is the source address.
6412 operands[2] is the first destination register. */
6413
6414const char *
6415rs6000_output_load_multiple (operands)
ebe637e3 6416 rtx operands[3];
9caa3eb2
DE
6417{
6418 /* We have to handle the case where the pseudo used to contain the address
6419 is assigned to one of the output registers. */
6420 int i, j;
6421 int words = XVECLEN (operands[0], 0);
6422 rtx xop[10];
6423
6424 if (XVECLEN (operands[0], 0) == 1)
6425 return "{l|lwz} %2,0(%1)";
6426
6427 for (i = 0; i < words; i++)
6428 if (refers_to_regno_p (REGNO (operands[2]) + i,
6429 REGNO (operands[2]) + i + 1, operands[1], 0))
6430 {
6431 if (i == words-1)
6432 {
6433 xop[0] = GEN_INT (4 * (words-1));
6434 xop[1] = operands[1];
6435 xop[2] = operands[2];
6436 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
6437 return "";
6438 }
6439 else if (i == 0)
6440 {
6441 xop[0] = GEN_INT (4 * (words-1));
6442 xop[1] = operands[1];
6443 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
6444 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);
6445 return "";
6446 }
6447 else
6448 {
6449 for (j = 0; j < words; j++)
6450 if (j != i)
6451 {
6452 xop[0] = GEN_INT (j * 4);
6453 xop[1] = operands[1];
6454 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
6455 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
6456 }
6457 xop[0] = GEN_INT (i * 4);
6458 xop[1] = operands[1];
6459 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
6460 return "";
6461 }
6462 }
6463
6464 return "{lsi|lswi} %2,%1,%N0";
6465}
6466
00b960c7
AH
6467/* Return 1 for a parallel vrsave operation. */
6468
6469int
6470vrsave_operation (op, mode)
6471 rtx op;
6472 enum machine_mode mode ATTRIBUTE_UNUSED;
6473{
6474 int count = XVECLEN (op, 0);
6475 unsigned int dest_regno, src_regno;
6476 int i;
6477
6478 if (count <= 1
6479 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6480 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
a004eb82 6481 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC_VOLATILE)
00b960c7
AH
6482 return 0;
6483
6484 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6485 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6486
6487 if (dest_regno != VRSAVE_REGNO
6488 && src_regno != VRSAVE_REGNO)
6489 return 0;
6490
6491 for (i = 1; i < count; i++)
6492 {
6493 rtx elt = XVECEXP (op, 0, i);
6494
9aa86737
AH
6495 if (GET_CODE (elt) != CLOBBER
6496 && GET_CODE (elt) != SET)
00b960c7
AH
6497 return 0;
6498 }
6499
6500 return 1;
6501}
6502
a4f6c312 6503/* Return 1 for an PARALLEL suitable for mtcrf. */
9ebbca7d
GK
6504
6505int
6506mtcrf_operation (op, mode)
6507 rtx op;
6508 enum machine_mode mode ATTRIBUTE_UNUSED;
6509{
6510 int count = XVECLEN (op, 0);
6511 int i;
9ebbca7d
GK
6512 rtx src_reg;
6513
6514 /* Perform a quick check so we don't blow up below. */
e35b9579
GK
6515 if (count < 1
6516 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6517 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC
6518 || XVECLEN (SET_SRC (XVECEXP (op, 0, 0)), 0) != 2)
9ebbca7d 6519 return 0;
e35b9579 6520 src_reg = XVECEXP (SET_SRC (XVECEXP (op, 0, 0)), 0, 0);
9ebbca7d
GK
6521
6522 if (GET_CODE (src_reg) != REG
6523 || GET_MODE (src_reg) != SImode
6524 || ! INT_REGNO_P (REGNO (src_reg)))
6525 return 0;
6526
e35b9579 6527 for (i = 0; i < count; i++)
9ebbca7d
GK
6528 {
6529 rtx exp = XVECEXP (op, 0, i);
6530 rtx unspec;
6531 int maskval;
6532
6533 if (GET_CODE (exp) != SET
6534 || GET_CODE (SET_DEST (exp)) != REG
6535 || GET_MODE (SET_DEST (exp)) != CCmode
6536 || ! CR_REGNO_P (REGNO (SET_DEST (exp))))
6537 return 0;
6538 unspec = SET_SRC (exp);
6539 maskval = 1 << (MAX_CR_REGNO - REGNO (SET_DEST (exp)));
9ebbca7d
GK
6540
6541 if (GET_CODE (unspec) != UNSPEC
6542 || XINT (unspec, 1) != 20
6543 || XVECLEN (unspec, 0) != 2
6544 || XVECEXP (unspec, 0, 0) != src_reg
6545 || GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT
6546 || INTVAL (XVECEXP (unspec, 0, 1)) != maskval)
6547 return 0;
6548 }
e35b9579 6549 return 1;
9ebbca7d
GK
6550}
6551
a4f6c312 6552/* Return 1 for an PARALLEL suitable for lmw. */
9ebbca7d
GK
6553
6554int
6555lmw_operation (op, mode)
6556 rtx op;
6557 enum machine_mode mode ATTRIBUTE_UNUSED;
6558{
6559 int count = XVECLEN (op, 0);
e2c953b6 6560 unsigned int dest_regno;
9ebbca7d 6561 rtx src_addr;
e2c953b6 6562 unsigned int base_regno;
9ebbca7d
GK
6563 HOST_WIDE_INT offset;
6564 int i;
6565
6566 /* Perform a quick check so we don't blow up below. */
6567 if (count <= 1
6568 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6569 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
6570 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
6571 return 0;
6572
6573 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6574 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
6575
6576 if (dest_regno > 31
e2c953b6 6577 || count != 32 - (int) dest_regno)
9ebbca7d
GK
6578 return 0;
6579
258bfae2 6580 if (LEGITIMATE_INDIRECT_ADDRESS_P (src_addr, 0))
9ebbca7d
GK
6581 {
6582 offset = 0;
6583 base_regno = REGNO (src_addr);
6584 if (base_regno == 0)
6585 return 0;
6586 }
258bfae2 6587 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, src_addr, 0))
9ebbca7d
GK
6588 {
6589 offset = INTVAL (XEXP (src_addr, 1));
6590 base_regno = REGNO (XEXP (src_addr, 0));
6591 }
6592 else
6593 return 0;
6594
6595 for (i = 0; i < count; i++)
6596 {
6597 rtx elt = XVECEXP (op, 0, i);
6598 rtx newaddr;
6599 rtx addr_reg;
6600 HOST_WIDE_INT newoffset;
6601
6602 if (GET_CODE (elt) != SET
6603 || GET_CODE (SET_DEST (elt)) != REG
6604 || GET_MODE (SET_DEST (elt)) != SImode
6605 || REGNO (SET_DEST (elt)) != dest_regno + i
6606 || GET_CODE (SET_SRC (elt)) != MEM
6607 || GET_MODE (SET_SRC (elt)) != SImode)
6608 return 0;
6609 newaddr = XEXP (SET_SRC (elt), 0);
258bfae2 6610 if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
9ebbca7d
GK
6611 {
6612 newoffset = 0;
6613 addr_reg = newaddr;
6614 }
258bfae2 6615 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
9ebbca7d
GK
6616 {
6617 addr_reg = XEXP (newaddr, 0);
6618 newoffset = INTVAL (XEXP (newaddr, 1));
6619 }
6620 else
6621 return 0;
6622 if (REGNO (addr_reg) != base_regno
6623 || newoffset != offset + 4 * i)
6624 return 0;
6625 }
6626
6627 return 1;
6628}
6629
a4f6c312 6630/* Return 1 for an PARALLEL suitable for stmw. */
9ebbca7d
GK
6631
6632int
6633stmw_operation (op, mode)
6634 rtx op;
6635 enum machine_mode mode ATTRIBUTE_UNUSED;
6636{
6637 int count = XVECLEN (op, 0);
e2c953b6 6638 unsigned int src_regno;
9ebbca7d 6639 rtx dest_addr;
e2c953b6 6640 unsigned int base_regno;
9ebbca7d
GK
6641 HOST_WIDE_INT offset;
6642 int i;
6643
6644 /* Perform a quick check so we don't blow up below. */
6645 if (count <= 1
6646 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6647 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
6648 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
6649 return 0;
6650
6651 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6652 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
6653
6654 if (src_regno > 31
e2c953b6 6655 || count != 32 - (int) src_regno)
9ebbca7d
GK
6656 return 0;
6657
258bfae2 6658 if (LEGITIMATE_INDIRECT_ADDRESS_P (dest_addr, 0))
9ebbca7d
GK
6659 {
6660 offset = 0;
6661 base_regno = REGNO (dest_addr);
6662 if (base_regno == 0)
6663 return 0;
6664 }
258bfae2 6665 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, dest_addr, 0))
9ebbca7d
GK
6666 {
6667 offset = INTVAL (XEXP (dest_addr, 1));
6668 base_regno = REGNO (XEXP (dest_addr, 0));
6669 }
6670 else
6671 return 0;
6672
6673 for (i = 0; i < count; i++)
6674 {
6675 rtx elt = XVECEXP (op, 0, i);
6676 rtx newaddr;
6677 rtx addr_reg;
6678 HOST_WIDE_INT newoffset;
6679
6680 if (GET_CODE (elt) != SET
6681 || GET_CODE (SET_SRC (elt)) != REG
6682 || GET_MODE (SET_SRC (elt)) != SImode
6683 || REGNO (SET_SRC (elt)) != src_regno + i
6684 || GET_CODE (SET_DEST (elt)) != MEM
6685 || GET_MODE (SET_DEST (elt)) != SImode)
6686 return 0;
6687 newaddr = XEXP (SET_DEST (elt), 0);
258bfae2 6688 if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
9ebbca7d
GK
6689 {
6690 newoffset = 0;
6691 addr_reg = newaddr;
6692 }
258bfae2 6693 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
9ebbca7d
GK
6694 {
6695 addr_reg = XEXP (newaddr, 0);
6696 newoffset = INTVAL (XEXP (newaddr, 1));
6697 }
6698 else
6699 return 0;
6700 if (REGNO (addr_reg) != base_regno
6701 || newoffset != offset + 4 * i)
6702 return 0;
6703 }
6704
6705 return 1;
6706}
9878760c 6707\f
a4f6c312
SS
6708/* A validation routine: say whether CODE, a condition code, and MODE
6709 match. The other alternatives either don't make sense or should
6710 never be generated. */
39a10a29 6711
39a10a29
GK
6712static void
6713validate_condition_mode (code, mode)
6714 enum rtx_code code;
6715 enum machine_mode mode;
6716{
6717 if (GET_RTX_CLASS (code) != '<'
6718 || GET_MODE_CLASS (mode) != MODE_CC)
6719 abort ();
6720
6721 /* These don't make sense. */
6722 if ((code == GT || code == LT || code == GE || code == LE)
6723 && mode == CCUNSmode)
6724 abort ();
6725
6726 if ((code == GTU || code == LTU || code == GEU || code == LEU)
6727 && mode != CCUNSmode)
6728 abort ();
6729
6730 if (mode != CCFPmode
6731 && (code == ORDERED || code == UNORDERED
6732 || code == UNEQ || code == LTGT
6733 || code == UNGT || code == UNLT
6734 || code == UNGE || code == UNLE))
a4f6c312 6735 abort ();
39a10a29 6736
de6c5979 6737 /* These should never be generated except for
ad72b533 6738 flag_unsafe_math_optimizations and flag_finite_math_only. */
39a10a29 6739 if (mode == CCFPmode
de6c5979 6740 && ! flag_unsafe_math_optimizations
ad72b533 6741 && ! flag_finite_math_only
39a10a29
GK
6742 && (code == LE || code == GE
6743 || code == UNEQ || code == LTGT
6744 || code == UNGT || code == UNLT))
6745 abort ();
6746
6747 /* These are invalid; the information is not there. */
6748 if (mode == CCEQmode
6749 && code != EQ && code != NE)
6750 abort ();
6751}
6752
9878760c
RK
6753/* Return 1 if OP is a comparison operation that is valid for a branch insn.
6754 We only check the opcode against the mode of the CC value here. */
6755
6756int
6757branch_comparison_operator (op, mode)
592696dd 6758 rtx op;
296b8152 6759 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
6760{
6761 enum rtx_code code = GET_CODE (op);
6762 enum machine_mode cc_mode;
6763
6764 if (GET_RTX_CLASS (code) != '<')
6765 return 0;
6766
6767 cc_mode = GET_MODE (XEXP (op, 0));
6768 if (GET_MODE_CLASS (cc_mode) != MODE_CC)
6769 return 0;
6770
39a10a29 6771 validate_condition_mode (code, cc_mode);
9878760c 6772
39a10a29
GK
6773 return 1;
6774}
6775
6776/* Return 1 if OP is a comparison operation that is valid for a branch
6777 insn and which is true if the corresponding bit in the CC register
6778 is set. */
6779
6780int
6781branch_positive_comparison_operator (op, mode)
592696dd 6782 rtx op;
39a10a29
GK
6783 enum machine_mode mode;
6784{
6785 enum rtx_code code;
6786
6787 if (! branch_comparison_operator (op, mode))
9878760c
RK
6788 return 0;
6789
39a10a29
GK
6790 code = GET_CODE (op);
6791 return (code == EQ || code == LT || code == GT
a3170dc6 6792 || (TARGET_SPE && TARGET_HARD_FLOAT && !TARGET_FPRS && code == NE)
39a10a29
GK
6793 || code == LTU || code == GTU
6794 || code == UNORDERED);
9878760c
RK
6795}
6796
6797/* Return 1 if OP is a comparison operation that is valid for an scc insn.
6798 We check the opcode against the mode of the CC value and disallow EQ or
6799 NE comparisons for integers. */
6800
6801int
6802scc_comparison_operator (op, mode)
592696dd 6803 rtx op;
9878760c
RK
6804 enum machine_mode mode;
6805{
6806 enum rtx_code code = GET_CODE (op);
6807 enum machine_mode cc_mode;
6808
6809 if (GET_MODE (op) != mode && mode != VOIDmode)
6810 return 0;
6811
6812 if (GET_RTX_CLASS (code) != '<')
6813 return 0;
6814
6815 cc_mode = GET_MODE (XEXP (op, 0));
6816 if (GET_MODE_CLASS (cc_mode) != MODE_CC)
6817 return 0;
6818
39a10a29 6819 validate_condition_mode (code, cc_mode);
9878760c 6820
39a10a29 6821 if (code == NE && cc_mode != CCFPmode)
c5defebb
RK
6822 return 0;
6823
9878760c
RK
6824 return 1;
6825}
e0cd0770
JC
6826
6827int
6828trap_comparison_operator (op, mode)
6829 rtx op;
6830 enum machine_mode mode;
6831{
6832 if (mode != VOIDmode && mode != GET_MODE (op))
6833 return 0;
39a10a29 6834 return GET_RTX_CLASS (GET_CODE (op)) == '<';
e0cd0770 6835}
dfbdccdb
GK
6836
6837int
6838boolean_operator (op, mode)
6839 rtx op;
6840 enum machine_mode mode ATTRIBUTE_UNUSED;
6841{
6842 enum rtx_code code = GET_CODE (op);
6843 return (code == AND || code == IOR || code == XOR);
6844}
1d328b19
GK
6845
6846int
6847boolean_or_operator (op, mode)
6848 rtx op;
6849 enum machine_mode mode ATTRIBUTE_UNUSED;
6850{
6851 enum rtx_code code = GET_CODE (op);
6852 return (code == IOR || code == XOR);
6853}
50a0b056
GK
6854
6855int
6856min_max_operator (op, mode)
6857 rtx op;
6858 enum machine_mode mode ATTRIBUTE_UNUSED;
6859{
6860 enum rtx_code code = GET_CODE (op);
6861 return (code == SMIN || code == SMAX || code == UMIN || code == UMAX);
6862}
9878760c
RK
6863\f
6864/* Return 1 if ANDOP is a mask that has no bits on that are not in the
6865 mask required to convert the result of a rotate insn into a shift
b1765bde 6866 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
9878760c
RK
6867
6868int
6869includes_lshift_p (shiftop, andop)
592696dd
SS
6870 rtx shiftop;
6871 rtx andop;
9878760c 6872{
e2c953b6
DE
6873 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
6874
6875 shift_mask <<= INTVAL (shiftop);
9878760c 6876
b1765bde 6877 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
9878760c
RK
6878}
6879
6880/* Similar, but for right shift. */
6881
6882int
6883includes_rshift_p (shiftop, andop)
592696dd
SS
6884 rtx shiftop;
6885 rtx andop;
9878760c 6886{
a7653a2c 6887 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
9878760c
RK
6888
6889 shift_mask >>= INTVAL (shiftop);
6890
b1765bde 6891 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
e2c953b6
DE
6892}
6893
c5059423
AM
6894/* Return 1 if ANDOP is a mask suitable for use with an rldic insn
6895 to perform a left shift. It must have exactly SHIFTOP least
6896 signifigant 0's, then one or more 1's, then zero or more 0's. */
e2c953b6
DE
6897
6898int
c5059423 6899includes_rldic_lshift_p (shiftop, andop)
592696dd
SS
6900 rtx shiftop;
6901 rtx andop;
e2c953b6 6902{
c5059423
AM
6903 if (GET_CODE (andop) == CONST_INT)
6904 {
02071907 6905 HOST_WIDE_INT c, lsb, shift_mask;
e2c953b6 6906
c5059423 6907 c = INTVAL (andop);
02071907 6908 if (c == 0 || c == ~0)
c5059423 6909 return 0;
e2c953b6 6910
02071907 6911 shift_mask = ~0;
c5059423
AM
6912 shift_mask <<= INTVAL (shiftop);
6913
6914 /* Find the least signifigant one bit. */
6915 lsb = c & -c;
6916
6917 /* It must coincide with the LSB of the shift mask. */
6918 if (-lsb != shift_mask)
6919 return 0;
e2c953b6 6920
c5059423
AM
6921 /* Invert to look for the next transition (if any). */
6922 c = ~c;
6923
6924 /* Remove the low group of ones (originally low group of zeros). */
6925 c &= -lsb;
6926
6927 /* Again find the lsb, and check we have all 1's above. */
6928 lsb = c & -c;
6929 return c == -lsb;
6930 }
6931 else if (GET_CODE (andop) == CONST_DOUBLE
6932 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
6933 {
02071907
AM
6934 HOST_WIDE_INT low, high, lsb;
6935 HOST_WIDE_INT shift_mask_low, shift_mask_high;
c5059423
AM
6936
6937 low = CONST_DOUBLE_LOW (andop);
6938 if (HOST_BITS_PER_WIDE_INT < 64)
6939 high = CONST_DOUBLE_HIGH (andop);
6940
6941 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
02071907 6942 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
c5059423
AM
6943 return 0;
6944
6945 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
6946 {
02071907 6947 shift_mask_high = ~0;
c5059423
AM
6948 if (INTVAL (shiftop) > 32)
6949 shift_mask_high <<= INTVAL (shiftop) - 32;
6950
6951 lsb = high & -high;
6952
6953 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
6954 return 0;
6955
6956 high = ~high;
6957 high &= -lsb;
6958
6959 lsb = high & -high;
6960 return high == -lsb;
6961 }
6962
02071907 6963 shift_mask_low = ~0;
c5059423
AM
6964 shift_mask_low <<= INTVAL (shiftop);
6965
6966 lsb = low & -low;
6967
6968 if (-lsb != shift_mask_low)
6969 return 0;
6970
6971 if (HOST_BITS_PER_WIDE_INT < 64)
6972 high = ~high;
6973 low = ~low;
6974 low &= -lsb;
6975
6976 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
6977 {
6978 lsb = high & -high;
6979 return high == -lsb;
6980 }
6981
6982 lsb = low & -low;
6983 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
6984 }
6985 else
6986 return 0;
6987}
e2c953b6 6988
c5059423
AM
6989/* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
6990 to perform a left shift. It must have SHIFTOP or more least
6991 signifigant 0's, with the remainder of the word 1's. */
e2c953b6 6992
c5059423
AM
6993int
6994includes_rldicr_lshift_p (shiftop, andop)
592696dd
SS
6995 rtx shiftop;
6996 rtx andop;
c5059423 6997{
e2c953b6 6998 if (GET_CODE (andop) == CONST_INT)
c5059423 6999 {
02071907 7000 HOST_WIDE_INT c, lsb, shift_mask;
c5059423 7001
02071907 7002 shift_mask = ~0;
c5059423
AM
7003 shift_mask <<= INTVAL (shiftop);
7004 c = INTVAL (andop);
7005
7006 /* Find the least signifigant one bit. */
7007 lsb = c & -c;
7008
7009 /* It must be covered by the shift mask.
a4f6c312 7010 This test also rejects c == 0. */
c5059423
AM
7011 if ((lsb & shift_mask) == 0)
7012 return 0;
7013
7014 /* Check we have all 1's above the transition, and reject all 1's. */
7015 return c == -lsb && lsb != 1;
7016 }
7017 else if (GET_CODE (andop) == CONST_DOUBLE
7018 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
7019 {
02071907 7020 HOST_WIDE_INT low, lsb, shift_mask_low;
c5059423
AM
7021
7022 low = CONST_DOUBLE_LOW (andop);
7023
7024 if (HOST_BITS_PER_WIDE_INT < 64)
7025 {
02071907 7026 HOST_WIDE_INT high, shift_mask_high;
c5059423
AM
7027
7028 high = CONST_DOUBLE_HIGH (andop);
7029
7030 if (low == 0)
7031 {
02071907 7032 shift_mask_high = ~0;
c5059423
AM
7033 if (INTVAL (shiftop) > 32)
7034 shift_mask_high <<= INTVAL (shiftop) - 32;
7035
7036 lsb = high & -high;
7037
7038 if ((lsb & shift_mask_high) == 0)
7039 return 0;
7040
7041 return high == -lsb;
7042 }
7043 if (high != ~0)
7044 return 0;
7045 }
7046
02071907 7047 shift_mask_low = ~0;
c5059423
AM
7048 shift_mask_low <<= INTVAL (shiftop);
7049
7050 lsb = low & -low;
7051
7052 if ((lsb & shift_mask_low) == 0)
7053 return 0;
7054
7055 return low == -lsb && lsb != 1;
7056 }
e2c953b6 7057 else
c5059423 7058 return 0;
9878760c 7059}
35068b43
RK
7060
7061/* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
7062 for lfq and stfq insns.
7063
7064 Note reg1 and reg2 *must* be hard registers. To be sure we will
7065 abort if we are passed pseudo registers. */
7066
7067int
7068registers_ok_for_quad_peep (reg1, reg2)
7069 rtx reg1, reg2;
7070{
7071 /* We might have been passed a SUBREG. */
7072 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
7073 return 0;
7074
7075 return (REGNO (reg1) == REGNO (reg2) - 1);
7076}
7077
a4f6c312
SS
7078/* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
7079 addr1 and addr2 must be in consecutive memory locations
7080 (addr2 == addr1 + 8). */
35068b43
RK
7081
7082int
7083addrs_ok_for_quad_peep (addr1, addr2)
592696dd
SS
7084 rtx addr1;
7085 rtx addr2;
35068b43 7086{
e2c953b6 7087 unsigned int reg1;
35068b43
RK
7088 int offset1;
7089
7090 /* Extract an offset (if used) from the first addr. */
7091 if (GET_CODE (addr1) == PLUS)
7092 {
7093 /* If not a REG, return zero. */
7094 if (GET_CODE (XEXP (addr1, 0)) != REG)
7095 return 0;
7096 else
7097 {
7098 reg1 = REGNO (XEXP (addr1, 0));
7099 /* The offset must be constant! */
7100 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
7101 return 0;
7102 offset1 = INTVAL (XEXP (addr1, 1));
7103 }
7104 }
7105 else if (GET_CODE (addr1) != REG)
7106 return 0;
7107 else
7108 {
7109 reg1 = REGNO (addr1);
7110 /* This was a simple (mem (reg)) expression. Offset is 0. */
7111 offset1 = 0;
7112 }
7113
acad7ed3 7114 /* Make sure the second address is a (mem (plus (reg) (const_int))). */
35068b43
RK
7115 if (GET_CODE (addr2) != PLUS)
7116 return 0;
7117
7118 if (GET_CODE (XEXP (addr2, 0)) != REG
7119 || GET_CODE (XEXP (addr2, 1)) != CONST_INT)
7120 return 0;
7121
7122 if (reg1 != REGNO (XEXP (addr2, 0)))
7123 return 0;
7124
7125 /* The offset for the second addr must be 8 more than the first addr. */
7126 if (INTVAL (XEXP (addr2, 1)) != offset1 + 8)
7127 return 0;
7128
7129 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
7130 instructions. */
7131 return 1;
7132}
9878760c
RK
7133\f
7134/* Return the register class of a scratch register needed to copy IN into
7135 or out of a register in CLASS in MODE. If it can be done directly,
7136 NO_REGS is returned. */
7137
7138enum reg_class
7139secondary_reload_class (class, mode, in)
7140 enum reg_class class;
296b8152 7141 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
7142 rtx in;
7143{
5accd822 7144 int regno;
9878760c 7145
46fad5b7
DJ
7146 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN && flag_pic))
7147 {
7148 /* We cannot copy a symbolic operand directly into anything
7149 other than BASE_REGS for TARGET_ELF. So indicate that a
7150 register from BASE_REGS is needed as an intermediate
7151 register.
7152
7153 On Darwin, pic addresses require a load from memory, which
7154 needs a base register. */
7155 if (class != BASE_REGS
7156 && (GET_CODE (in) == SYMBOL_REF
7157 || GET_CODE (in) == HIGH
7158 || GET_CODE (in) == LABEL_REF
7159 || GET_CODE (in) == CONST))
7160 return BASE_REGS;
7161 }
e7b7998a 7162
5accd822
DE
7163 if (GET_CODE (in) == REG)
7164 {
7165 regno = REGNO (in);
7166 if (regno >= FIRST_PSEUDO_REGISTER)
7167 {
7168 regno = true_regnum (in);
7169 if (regno >= FIRST_PSEUDO_REGISTER)
7170 regno = -1;
7171 }
7172 }
7173 else if (GET_CODE (in) == SUBREG)
7174 {
7175 regno = true_regnum (in);
7176 if (regno >= FIRST_PSEUDO_REGISTER)
7177 regno = -1;
7178 }
7179 else
7180 regno = -1;
7181
9878760c
RK
7182 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
7183 into anything. */
7184 if (class == GENERAL_REGS || class == BASE_REGS
7185 || (regno >= 0 && INT_REGNO_P (regno)))
7186 return NO_REGS;
7187
7188 /* Constants, memory, and FP registers can go into FP registers. */
7189 if ((regno == -1 || FP_REGNO_P (regno))
7190 && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
7191 return NO_REGS;
7192
0ac081f6
AH
7193 /* Memory, and AltiVec registers can go into AltiVec registers. */
7194 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
7195 && class == ALTIVEC_REGS)
7196 return NO_REGS;
7197
9878760c
RK
7198 /* We can copy among the CR registers. */
7199 if ((class == CR_REGS || class == CR0_REGS)
7200 && regno >= 0 && CR_REGNO_P (regno))
7201 return NO_REGS;
7202
7203 /* Otherwise, we need GENERAL_REGS. */
7204 return GENERAL_REGS;
7205}
7206\f
7207/* Given a comparison operation, return the bit number in CCR to test. We
7208 know this is a valid comparison.
7209
7210 SCC_P is 1 if this is for an scc. That means that %D will have been
7211 used instead of %C, so the bits will be in different places.
7212
b4ac57ab 7213 Return -1 if OP isn't a valid comparison for some reason. */
9878760c
RK
7214
7215int
7216ccr_bit (op, scc_p)
592696dd 7217 rtx op;
9878760c
RK
7218 int scc_p;
7219{
7220 enum rtx_code code = GET_CODE (op);
7221 enum machine_mode cc_mode;
7222 int cc_regnum;
7223 int base_bit;
9ebbca7d 7224 rtx reg;
9878760c
RK
7225
7226 if (GET_RTX_CLASS (code) != '<')
7227 return -1;
7228
9ebbca7d
GK
7229 reg = XEXP (op, 0);
7230
7231 if (GET_CODE (reg) != REG
7232 || ! CR_REGNO_P (REGNO (reg)))
7233 abort ();
7234
7235 cc_mode = GET_MODE (reg);
7236 cc_regnum = REGNO (reg);
7237 base_bit = 4 * (cc_regnum - CR0_REGNO);
9878760c 7238
39a10a29 7239 validate_condition_mode (code, cc_mode);
c5defebb 7240
9878760c
RK
7241 switch (code)
7242 {
7243 case NE:
a3170dc6
AH
7244 if (TARGET_SPE && TARGET_HARD_FLOAT && cc_mode == CCFPmode)
7245 return base_bit + 1;
9878760c
RK
7246 return scc_p ? base_bit + 3 : base_bit + 2;
7247 case EQ:
a3170dc6
AH
7248 if (TARGET_SPE && TARGET_HARD_FLOAT && cc_mode == CCFPmode)
7249 return base_bit + 1;
9878760c 7250 return base_bit + 2;
1c882ea4 7251 case GT: case GTU: case UNLE:
9878760c 7252 return base_bit + 1;
1c882ea4 7253 case LT: case LTU: case UNGE:
9878760c 7254 return base_bit;
1c882ea4
GK
7255 case ORDERED: case UNORDERED:
7256 return base_bit + 3;
9878760c
RK
7257
7258 case GE: case GEU:
39a10a29 7259 /* If scc, we will have done a cror to put the bit in the
9878760c
RK
7260 unordered position. So test that bit. For integer, this is ! LT
7261 unless this is an scc insn. */
39a10a29 7262 return scc_p ? base_bit + 3 : base_bit;
9878760c
RK
7263
7264 case LE: case LEU:
39a10a29 7265 return scc_p ? base_bit + 3 : base_bit + 1;
1c882ea4 7266
9878760c
RK
7267 default:
7268 abort ();
7269 }
7270}
1ff7789b 7271\f
8d30c4ee 7272/* Return the GOT register. */
1ff7789b
MM
7273
7274struct rtx_def *
7275rs6000_got_register (value)
5f59ecb7 7276 rtx value ATTRIBUTE_UNUSED;
1ff7789b 7277{
a4f6c312
SS
7278 /* The second flow pass currently (June 1999) can't update
7279 regs_ever_live without disturbing other parts of the compiler, so
7280 update it here to make the prolog/epilogue code happy. */
1db02437
FS
7281 if (no_new_pseudos && ! regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM])
7282 regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
1ff7789b 7283
8d30c4ee 7284 current_function_uses_pic_offset_table = 1;
3cb999d8 7285
1ff7789b
MM
7286 return pic_offset_table_rtx;
7287}
a7df97e6 7288\f
e2500fed
GK
7289/* Function to init struct machine_function.
7290 This will be called, via a pointer variable,
7291 from push_function_context. */
a7df97e6 7292
e2500fed
GK
7293static struct machine_function *
7294rs6000_init_machine_status ()
a7df97e6 7295{
e2500fed 7296 return ggc_alloc_cleared (sizeof (machine_function));
a7df97e6 7297}
9878760c 7298\f
0ba1b2ff
AM
7299/* These macros test for integers and extract the low-order bits. */
7300#define INT_P(X) \
7301((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
7302 && GET_MODE (X) == VOIDmode)
7303
7304#define INT_LOWPART(X) \
7305 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
7306
7307int
7308extract_MB (op)
7309 rtx op;
7310{
7311 int i;
7312 unsigned long val = INT_LOWPART (op);
7313
7314 /* If the high bit is zero, the value is the first 1 bit we find
7315 from the left. */
7316 if ((val & 0x80000000) == 0)
7317 {
7318 if ((val & 0xffffffff) == 0)
7319 abort ();
7320
7321 i = 1;
7322 while (((val <<= 1) & 0x80000000) == 0)
7323 ++i;
7324 return i;
7325 }
7326
7327 /* If the high bit is set and the low bit is not, or the mask is all
7328 1's, the value is zero. */
7329 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
7330 return 0;
7331
7332 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
7333 from the right. */
7334 i = 31;
7335 while (((val >>= 1) & 1) != 0)
7336 --i;
7337
7338 return i;
7339}
7340
7341int
7342extract_ME (op)
7343 rtx op;
7344{
7345 int i;
7346 unsigned long val = INT_LOWPART (op);
7347
7348 /* If the low bit is zero, the value is the first 1 bit we find from
7349 the right. */
7350 if ((val & 1) == 0)
7351 {
7352 if ((val & 0xffffffff) == 0)
7353 abort ();
7354
7355 i = 30;
7356 while (((val >>= 1) & 1) == 0)
7357 --i;
7358
7359 return i;
7360 }
7361
7362 /* If the low bit is set and the high bit is not, or the mask is all
7363 1's, the value is 31. */
7364 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
7365 return 31;
7366
7367 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
7368 from the left. */
7369 i = 0;
7370 while (((val <<= 1) & 0x80000000) != 0)
7371 ++i;
7372
7373 return i;
7374}
7375
9878760c
RK
7376/* Print an operand. Recognize special options, documented below. */
7377
38c1f2d7 7378#if TARGET_ELF
d9407988 7379#define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
8fbd2dc7 7380#define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
ba5e43aa
MM
7381#else
7382#define SMALL_DATA_RELOC "sda21"
8fbd2dc7 7383#define SMALL_DATA_REG 0
ba5e43aa
MM
7384#endif
7385
9878760c
RK
7386void
7387print_operand (file, x, code)
7388 FILE *file;
7389 rtx x;
9ebbca7d 7390 int code;
9878760c
RK
7391{
7392 int i;
a260abc9 7393 HOST_WIDE_INT val;
0ba1b2ff 7394 unsigned HOST_WIDE_INT uval;
9878760c
RK
7395
7396 switch (code)
7397 {
a8b3aeda 7398 case '.':
a85d226b
RK
7399 /* Write out an instruction after the call which may be replaced
7400 with glue code by the loader. This depends on the AIX version. */
7401 asm_fprintf (file, RS6000_CALL_GLUE);
a8b3aeda
RK
7402 return;
7403
81eace42
GK
7404 /* %a is output_address. */
7405
9854d9ed
RK
7406 case 'A':
7407 /* If X is a constant integer whose low-order 5 bits are zero,
7408 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
76229ac8 7409 in the AIX assembler where "sri" with a zero shift count
20e26713 7410 writes a trash instruction. */
9854d9ed 7411 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
76229ac8 7412 putc ('l', file);
9854d9ed 7413 else
76229ac8 7414 putc ('r', file);
9854d9ed
RK
7415 return;
7416
7417 case 'b':
e2c953b6
DE
7418 /* If constant, low-order 16 bits of constant, unsigned.
7419 Otherwise, write normally. */
7420 if (INT_P (x))
7421 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
7422 else
7423 print_operand (file, x, 0);
cad12a8d
RK
7424 return;
7425
a260abc9
DE
7426 case 'B':
7427 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
7428 for 64-bit mask direction. */
296b8152 7429 putc (((INT_LOWPART(x) & 1) == 0 ? 'r' : 'l'), file);
a238cd8b 7430 return;
a260abc9 7431
81eace42
GK
7432 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
7433 output_operand. */
7434
9854d9ed 7435 case 'D':
39a10a29
GK
7436 /* There used to be a comment for 'C' reading "This is an
7437 optional cror needed for certain floating-point
7438 comparisons. Otherwise write nothing." */
7439
9854d9ed
RK
7440 /* Similar, except that this is for an scc, so we must be able to
7441 encode the test in a single bit that is one. We do the above
7442 for any LE, GE, GEU, or LEU and invert the bit for NE. */
7443 if (GET_CODE (x) == LE || GET_CODE (x) == GE
7444 || GET_CODE (x) == LEU || GET_CODE (x) == GEU)
7445 {
9ebbca7d 7446 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
9854d9ed
RK
7447
7448 fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3,
7449 base_bit + 2,
7450 base_bit + (GET_CODE (x) == GE || GET_CODE (x) == GEU));
7451 }
7452
7453 else if (GET_CODE (x) == NE)
7454 {
9ebbca7d 7455 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
9854d9ed
RK
7456
7457 fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 3,
7458 base_bit + 2, base_bit + 2);
7459 }
a3170dc6
AH
7460 else if (TARGET_SPE && TARGET_HARD_FLOAT
7461 && GET_CODE (x) == EQ
7462 && GET_MODE (XEXP (x, 0)) == CCFPmode)
7463 {
7464 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
7465
7466 fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 1,
7467 base_bit + 1, base_bit + 1);
7468 }
9854d9ed
RK
7469 return;
7470
7471 case 'E':
39a10a29 7472 /* X is a CR register. Print the number of the EQ bit of the CR */
9854d9ed
RK
7473 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7474 output_operand_lossage ("invalid %%E value");
78fbdbf7 7475 else
39a10a29 7476 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
a85d226b 7477 return;
9854d9ed
RK
7478
7479 case 'f':
7480 /* X is a CR register. Print the shift count needed to move it
7481 to the high-order four bits. */
7482 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7483 output_operand_lossage ("invalid %%f value");
7484 else
9ebbca7d 7485 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
9854d9ed
RK
7486 return;
7487
7488 case 'F':
7489 /* Similar, but print the count for the rotate in the opposite
7490 direction. */
7491 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7492 output_operand_lossage ("invalid %%F value");
7493 else
9ebbca7d 7494 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
9854d9ed
RK
7495 return;
7496
7497 case 'G':
7498 /* X is a constant integer. If it is negative, print "m",
43aa4e05 7499 otherwise print "z". This is to make an aze or ame insn. */
9854d9ed
RK
7500 if (GET_CODE (x) != CONST_INT)
7501 output_operand_lossage ("invalid %%G value");
7502 else if (INTVAL (x) >= 0)
76229ac8 7503 putc ('z', file);
9854d9ed 7504 else
76229ac8 7505 putc ('m', file);
9854d9ed 7506 return;
e2c953b6 7507
9878760c 7508 case 'h':
a4f6c312
SS
7509 /* If constant, output low-order five bits. Otherwise, write
7510 normally. */
9878760c 7511 if (INT_P (x))
5f59ecb7 7512 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
9878760c
RK
7513 else
7514 print_operand (file, x, 0);
7515 return;
7516
64305719 7517 case 'H':
a4f6c312
SS
7518 /* If constant, output low-order six bits. Otherwise, write
7519 normally. */
64305719 7520 if (INT_P (x))
5f59ecb7 7521 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
64305719
DE
7522 else
7523 print_operand (file, x, 0);
7524 return;
7525
9854d9ed
RK
7526 case 'I':
7527 /* Print `i' if this is a constant, else nothing. */
9878760c 7528 if (INT_P (x))
76229ac8 7529 putc ('i', file);
9878760c
RK
7530 return;
7531
9854d9ed
RK
7532 case 'j':
7533 /* Write the bit number in CCR for jump. */
7534 i = ccr_bit (x, 0);
7535 if (i == -1)
7536 output_operand_lossage ("invalid %%j code");
9878760c 7537 else
9854d9ed 7538 fprintf (file, "%d", i);
9878760c
RK
7539 return;
7540
9854d9ed
RK
7541 case 'J':
7542 /* Similar, but add one for shift count in rlinm for scc and pass
7543 scc flag to `ccr_bit'. */
7544 i = ccr_bit (x, 1);
7545 if (i == -1)
7546 output_operand_lossage ("invalid %%J code");
7547 else
a0466a68
RK
7548 /* If we want bit 31, write a shift count of zero, not 32. */
7549 fprintf (file, "%d", i == 31 ? 0 : i + 1);
9878760c
RK
7550 return;
7551
9854d9ed
RK
7552 case 'k':
7553 /* X must be a constant. Write the 1's complement of the
7554 constant. */
9878760c 7555 if (! INT_P (x))
9854d9ed 7556 output_operand_lossage ("invalid %%k value");
e2c953b6
DE
7557 else
7558 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
9878760c
RK
7559 return;
7560
81eace42 7561 case 'K':
9ebbca7d
GK
7562 /* X must be a symbolic constant on ELF. Write an
7563 expression suitable for an 'addi' that adds in the low 16
7564 bits of the MEM. */
7565 if (GET_CODE (x) != CONST)
7566 {
7567 print_operand_address (file, x);
7568 fputs ("@l", file);
7569 }
7570 else
7571 {
7572 if (GET_CODE (XEXP (x, 0)) != PLUS
7573 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
7574 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
7575 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
53cd5d6c 7576 output_operand_lossage ("invalid %%K value");
9ebbca7d
GK
7577 print_operand_address (file, XEXP (XEXP (x, 0), 0));
7578 fputs ("@l", file);
ed8d2920
MM
7579 /* For GNU as, there must be a non-alphanumeric character
7580 between 'l' and the number. The '-' is added by
7581 print_operand() already. */
7582 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
7583 fputs ("+", file);
9ebbca7d
GK
7584 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
7585 }
81eace42
GK
7586 return;
7587
7588 /* %l is output_asm_label. */
9ebbca7d 7589
9854d9ed
RK
7590 case 'L':
7591 /* Write second word of DImode or DFmode reference. Works on register
7592 or non-indexed memory only. */
7593 if (GET_CODE (x) == REG)
5ebfb2ba 7594 fprintf (file, "%s", reg_names[REGNO (x) + 1]);
9854d9ed
RK
7595 else if (GET_CODE (x) == MEM)
7596 {
7597 /* Handle possible auto-increment. Since it is pre-increment and
1427100a 7598 we have already done it, we can just use an offset of word. */
9854d9ed
RK
7599 if (GET_CODE (XEXP (x, 0)) == PRE_INC
7600 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
ed8908e7
RK
7601 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
7602 UNITS_PER_WORD));
9854d9ed 7603 else
d7624dc0
RK
7604 output_address (XEXP (adjust_address_nv (x, SImode,
7605 UNITS_PER_WORD),
7606 0));
ed8908e7 7607
ba5e43aa 7608 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
7609 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7610 reg_names[SMALL_DATA_REG]);
9854d9ed 7611 }
9878760c 7612 return;
9854d9ed 7613
9878760c
RK
7614 case 'm':
7615 /* MB value for a mask operand. */
b1765bde 7616 if (! mask_operand (x, SImode))
9878760c
RK
7617 output_operand_lossage ("invalid %%m value");
7618
0ba1b2ff 7619 fprintf (file, "%d", extract_MB (x));
9878760c
RK
7620 return;
7621
7622 case 'M':
7623 /* ME value for a mask operand. */
b1765bde 7624 if (! mask_operand (x, SImode))
a260abc9 7625 output_operand_lossage ("invalid %%M value");
9878760c 7626
0ba1b2ff 7627 fprintf (file, "%d", extract_ME (x));
9878760c
RK
7628 return;
7629
81eace42
GK
7630 /* %n outputs the negative of its operand. */
7631
9878760c
RK
7632 case 'N':
7633 /* Write the number of elements in the vector times 4. */
7634 if (GET_CODE (x) != PARALLEL)
7635 output_operand_lossage ("invalid %%N value");
e2c953b6
DE
7636 else
7637 fprintf (file, "%d", XVECLEN (x, 0) * 4);
9878760c
RK
7638 return;
7639
7640 case 'O':
7641 /* Similar, but subtract 1 first. */
7642 if (GET_CODE (x) != PARALLEL)
1427100a 7643 output_operand_lossage ("invalid %%O value");
e2c953b6
DE
7644 else
7645 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
9878760c
RK
7646 return;
7647
9854d9ed
RK
7648 case 'p':
7649 /* X is a CONST_INT that is a power of two. Output the logarithm. */
7650 if (! INT_P (x)
2bfcf297 7651 || INT_LOWPART (x) < 0
9854d9ed
RK
7652 || (i = exact_log2 (INT_LOWPART (x))) < 0)
7653 output_operand_lossage ("invalid %%p value");
e2c953b6
DE
7654 else
7655 fprintf (file, "%d", i);
9854d9ed
RK
7656 return;
7657
9878760c
RK
7658 case 'P':
7659 /* The operand must be an indirect memory reference. The result
a4f6c312 7660 is the register number. */
9878760c
RK
7661 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
7662 || REGNO (XEXP (x, 0)) >= 32)
7663 output_operand_lossage ("invalid %%P value");
e2c953b6
DE
7664 else
7665 fprintf (file, "%d", REGNO (XEXP (x, 0)));
9878760c
RK
7666 return;
7667
dfbdccdb
GK
7668 case 'q':
7669 /* This outputs the logical code corresponding to a boolean
7670 expression. The expression may have one or both operands
39a10a29
GK
7671 negated (if one, only the first one). For condition register
7672 logical operations, it will also treat the negated
7673 CR codes as NOTs, but not handle NOTs of them. */
dfbdccdb 7674 {
63bc1d05 7675 const char *const *t = 0;
dfbdccdb
GK
7676 const char *s;
7677 enum rtx_code code = GET_CODE (x);
7678 static const char * const tbl[3][3] = {
7679 { "and", "andc", "nor" },
7680 { "or", "orc", "nand" },
7681 { "xor", "eqv", "xor" } };
7682
7683 if (code == AND)
7684 t = tbl[0];
7685 else if (code == IOR)
7686 t = tbl[1];
7687 else if (code == XOR)
7688 t = tbl[2];
7689 else
7690 output_operand_lossage ("invalid %%q value");
7691
7692 if (GET_CODE (XEXP (x, 0)) != NOT)
7693 s = t[0];
7694 else
7695 {
7696 if (GET_CODE (XEXP (x, 1)) == NOT)
7697 s = t[2];
7698 else
7699 s = t[1];
7700 }
7701
7702 fputs (s, file);
7703 }
7704 return;
7705
9854d9ed
RK
7706 case 'R':
7707 /* X is a CR register. Print the mask for `mtcrf'. */
7708 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7709 output_operand_lossage ("invalid %%R value");
7710 else
9ebbca7d 7711 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
9878760c 7712 return;
9854d9ed
RK
7713
7714 case 's':
7715 /* Low 5 bits of 32 - value */
7716 if (! INT_P (x))
7717 output_operand_lossage ("invalid %%s value");
e2c953b6
DE
7718 else
7719 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
9878760c 7720 return;
9854d9ed 7721
a260abc9 7722 case 'S':
0ba1b2ff 7723 /* PowerPC64 mask position. All 0's is excluded.
a260abc9
DE
7724 CONST_INT 32-bit mask is considered sign-extended so any
7725 transition must occur within the CONST_INT, not on the boundary. */
b1765bde 7726 if (! mask64_operand (x, DImode))
a260abc9
DE
7727 output_operand_lossage ("invalid %%S value");
7728
0ba1b2ff 7729 uval = INT_LOWPART (x);
a260abc9 7730
0ba1b2ff 7731 if (uval & 1) /* Clear Left */
a260abc9 7732 {
0ba1b2ff
AM
7733 uval &= ((unsigned HOST_WIDE_INT) 1 << 63 << 1) - 1;
7734 i = 64;
a260abc9 7735 }
0ba1b2ff 7736 else /* Clear Right */
a260abc9 7737 {
0ba1b2ff
AM
7738 uval = ~uval;
7739 uval &= ((unsigned HOST_WIDE_INT) 1 << 63 << 1) - 1;
7740 i = 63;
a260abc9 7741 }
0ba1b2ff
AM
7742 while (uval != 0)
7743 --i, uval >>= 1;
7744 if (i < 0)
7745 abort ();
7746 fprintf (file, "%d", i);
7747 return;
a260abc9 7748
a3170dc6
AH
7749 case 't':
7750 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
7751 if (GET_CODE (x) != REG || GET_MODE (x) != CCmode)
7752 abort ();
7753
7754 /* Bit 3 is OV bit. */
7755 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
7756
7757 /* If we want bit 31, write a shift count of zero, not 32. */
7758 fprintf (file, "%d", i == 31 ? 0 : i + 1);
7759 return;
7760
cccf3bdc
DE
7761 case 'T':
7762 /* Print the symbolic name of a branch target register. */
7763 if (GET_CODE (x) != REG || (REGNO (x) != LINK_REGISTER_REGNUM
7764 && REGNO (x) != COUNT_REGISTER_REGNUM))
7765 output_operand_lossage ("invalid %%T value");
e2c953b6 7766 else if (REGNO (x) == LINK_REGISTER_REGNUM)
cccf3bdc
DE
7767 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
7768 else
7769 fputs ("ctr", file);
7770 return;
7771
9854d9ed 7772 case 'u':
802a0058 7773 /* High-order 16 bits of constant for use in unsigned operand. */
9854d9ed
RK
7774 if (! INT_P (x))
7775 output_operand_lossage ("invalid %%u value");
e2c953b6
DE
7776 else
7777 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
7778 (INT_LOWPART (x) >> 16) & 0xffff);
9878760c
RK
7779 return;
7780
802a0058
MM
7781 case 'v':
7782 /* High-order 16 bits of constant for use in signed operand. */
7783 if (! INT_P (x))
7784 output_operand_lossage ("invalid %%v value");
e2c953b6 7785 else
134c32f6
DE
7786 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
7787 (INT_LOWPART (x) >> 16) & 0xffff);
7788 return;
802a0058 7789
9854d9ed
RK
7790 case 'U':
7791 /* Print `u' if this has an auto-increment or auto-decrement. */
7792 if (GET_CODE (x) == MEM
7793 && (GET_CODE (XEXP (x, 0)) == PRE_INC
7794 || GET_CODE (XEXP (x, 0)) == PRE_DEC))
76229ac8 7795 putc ('u', file);
9854d9ed 7796 return;
9878760c 7797
e0cd0770
JC
7798 case 'V':
7799 /* Print the trap code for this operand. */
7800 switch (GET_CODE (x))
7801 {
7802 case EQ:
7803 fputs ("eq", file); /* 4 */
7804 break;
7805 case NE:
7806 fputs ("ne", file); /* 24 */
7807 break;
7808 case LT:
7809 fputs ("lt", file); /* 16 */
7810 break;
7811 case LE:
7812 fputs ("le", file); /* 20 */
7813 break;
7814 case GT:
7815 fputs ("gt", file); /* 8 */
7816 break;
7817 case GE:
7818 fputs ("ge", file); /* 12 */
7819 break;
7820 case LTU:
7821 fputs ("llt", file); /* 2 */
7822 break;
7823 case LEU:
7824 fputs ("lle", file); /* 6 */
7825 break;
7826 case GTU:
7827 fputs ("lgt", file); /* 1 */
7828 break;
7829 case GEU:
7830 fputs ("lge", file); /* 5 */
7831 break;
7832 default:
7833 abort ();
7834 }
7835 break;
7836
9854d9ed
RK
7837 case 'w':
7838 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
7839 normally. */
7840 if (INT_P (x))
5f59ecb7
DE
7841 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
7842 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
9854d9ed
RK
7843 else
7844 print_operand (file, x, 0);
9878760c
RK
7845 return;
7846
9854d9ed 7847 case 'W':
e2c953b6 7848 /* MB value for a PowerPC64 rldic operand. */
e2c953b6
DE
7849 val = (GET_CODE (x) == CONST_INT
7850 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
7851
7852 if (val < 0)
7853 i = -1;
9854d9ed 7854 else
e2c953b6
DE
7855 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
7856 if ((val <<= 1) < 0)
7857 break;
7858
7859#if HOST_BITS_PER_WIDE_INT == 32
7860 if (GET_CODE (x) == CONST_INT && i >= 0)
7861 i += 32; /* zero-extend high-part was all 0's */
7862 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
7863 {
7864 val = CONST_DOUBLE_LOW (x);
7865
7866 if (val == 0)
a4f6c312 7867 abort ();
e2c953b6
DE
7868 else if (val < 0)
7869 --i;
7870 else
7871 for ( ; i < 64; i++)
7872 if ((val <<= 1) < 0)
7873 break;
7874 }
7875#endif
7876
7877 fprintf (file, "%d", i + 1);
9854d9ed 7878 return;
9878760c 7879
9854d9ed
RK
7880 case 'X':
7881 if (GET_CODE (x) == MEM
258bfae2 7882 && LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0), 0))
76229ac8 7883 putc ('x', file);
9854d9ed 7884 return;
9878760c 7885
9854d9ed
RK
7886 case 'Y':
7887 /* Like 'L', for third word of TImode */
7888 if (GET_CODE (x) == REG)
5ebfb2ba 7889 fprintf (file, "%s", reg_names[REGNO (x) + 2]);
9854d9ed 7890 else if (GET_CODE (x) == MEM)
9878760c 7891 {
9854d9ed
RK
7892 if (GET_CODE (XEXP (x, 0)) == PRE_INC
7893 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
a54d04b7 7894 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
9854d9ed 7895 else
d7624dc0 7896 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
ba5e43aa 7897 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
7898 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7899 reg_names[SMALL_DATA_REG]);
9878760c
RK
7900 }
7901 return;
9854d9ed 7902
9878760c 7903 case 'z':
b4ac57ab
RS
7904 /* X is a SYMBOL_REF. Write out the name preceded by a
7905 period and without any trailing data in brackets. Used for function
4d30c363
MM
7906 names. If we are configured for System V (or the embedded ABI) on
7907 the PowerPC, do not emit the period, since those systems do not use
7908 TOCs and the like. */
9878760c
RK
7909 if (GET_CODE (x) != SYMBOL_REF)
7910 abort ();
7911
b6c9286a
MM
7912 if (XSTR (x, 0)[0] != '.')
7913 {
7914 switch (DEFAULT_ABI)
7915 {
7916 default:
7917 abort ();
7918
7919 case ABI_AIX:
7920 putc ('.', file);
7921 break;
7922
7923 case ABI_V4:
7924 case ABI_AIX_NODESC:
ee890fe2 7925 case ABI_DARWIN:
b6c9286a 7926 break;
b6c9286a
MM
7927 }
7928 }
54ee9799
DE
7929#if TARGET_AIX
7930 RS6000_OUTPUT_BASENAME (file, XSTR (x, 0));
7931#else
9ebbca7d 7932 assemble_name (file, XSTR (x, 0));
54ee9799 7933#endif
9878760c
RK
7934 return;
7935
9854d9ed
RK
7936 case 'Z':
7937 /* Like 'L', for last word of TImode. */
7938 if (GET_CODE (x) == REG)
5ebfb2ba 7939 fprintf (file, "%s", reg_names[REGNO (x) + 3]);
9854d9ed
RK
7940 else if (GET_CODE (x) == MEM)
7941 {
7942 if (GET_CODE (XEXP (x, 0)) == PRE_INC
7943 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
a54d04b7 7944 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
9854d9ed 7945 else
d7624dc0 7946 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
ba5e43aa 7947 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
7948 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7949 reg_names[SMALL_DATA_REG]);
9854d9ed 7950 }
5c23c401 7951 return;
0ac081f6 7952
a3170dc6 7953 /* Print AltiVec or SPE memory operand. */
0ac081f6
AH
7954 case 'y':
7955 {
7956 rtx tmp;
7957
7958 if (GET_CODE (x) != MEM)
7959 abort ();
7960
7961 tmp = XEXP (x, 0);
7962
a3170dc6
AH
7963 if (TARGET_SPE)
7964 {
7965 /* Handle [reg]. */
7966 if (GET_CODE (tmp) == REG)
7967 {
7968 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
7969 break;
7970 }
7971 /* Handle [reg+UIMM]. */
7972 else if (GET_CODE (tmp) == PLUS &&
7973 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
7974 {
7975 int x;
7976
7977 if (GET_CODE (XEXP (tmp, 0)) != REG)
7978 abort ();
7979
7980 x = INTVAL (XEXP (tmp, 1));
7981 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
7982 break;
7983 }
7984
7985 /* Fall through. Must be [reg+reg]. */
7986 }
0ac081f6 7987 if (GET_CODE (tmp) == REG)
c62f2db5 7988 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
0ac081f6
AH
7989 else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
7990 {
7991 if (REGNO (XEXP (tmp, 0)) == 0)
7992 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
7993 reg_names[ REGNO (XEXP (tmp, 0)) ]);
7994 else
7995 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
7996 reg_names[ REGNO (XEXP (tmp, 1)) ]);
7997 }
7998 else
7999 abort ();
8000 break;
8001 }
9854d9ed 8002
9878760c
RK
8003 case 0:
8004 if (GET_CODE (x) == REG)
8005 fprintf (file, "%s", reg_names[REGNO (x)]);
8006 else if (GET_CODE (x) == MEM)
8007 {
8008 /* We need to handle PRE_INC and PRE_DEC here, since we need to
8009 know the width from the mode. */
8010 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
79ba6d34
MM
8011 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
8012 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
9878760c 8013 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
79ba6d34
MM
8014 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
8015 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
9878760c 8016 else
a54d04b7 8017 output_address (XEXP (x, 0));
9878760c
RK
8018 }
8019 else
a54d04b7 8020 output_addr_const (file, x);
a85d226b 8021 return;
9878760c
RK
8022
8023 default:
8024 output_operand_lossage ("invalid %%xn code");
8025 }
8026}
8027\f
8028/* Print the address of an operand. */
8029
8030void
8031print_operand_address (file, x)
8032 FILE *file;
592696dd 8033 rtx x;
9878760c
RK
8034{
8035 if (GET_CODE (x) == REG)
4697a36c 8036 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
9ebbca7d
GK
8037 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
8038 || GET_CODE (x) == LABEL_REF)
9878760c
RK
8039 {
8040 output_addr_const (file, x);
ba5e43aa 8041 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
8042 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
8043 reg_names[SMALL_DATA_REG]);
9ebbca7d 8044 else if (TARGET_TOC)
a4f6c312 8045 abort ();
9878760c
RK
8046 }
8047 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
8048 {
8049 if (REGNO (XEXP (x, 0)) == 0)
4697a36c
MM
8050 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
8051 reg_names[ REGNO (XEXP (x, 0)) ]);
9878760c 8052 else
4697a36c
MM
8053 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
8054 reg_names[ REGNO (XEXP (x, 1)) ]);
9878760c
RK
8055 }
8056 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
5f59ecb7
DE
8057 {
8058 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (XEXP (x, 1)));
8059 fprintf (file, "(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
8060 }
3cb999d8
DE
8061#if TARGET_ELF
8062 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
8063 && CONSTANT_P (XEXP (x, 1)))
4697a36c
MM
8064 {
8065 output_addr_const (file, XEXP (x, 1));
8066 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
8067 }
c859cda6
DJ
8068#endif
8069#if TARGET_MACHO
8070 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
8071 && CONSTANT_P (XEXP (x, 1)))
8072 {
8073 fprintf (file, "lo16(");
8074 output_addr_const (file, XEXP (x, 1));
8075 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
8076 }
3cb999d8 8077#endif
9ebbca7d
GK
8078 else if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
8079 {
2bfcf297 8080 if (TARGET_AIX && (!TARGET_ELF || !TARGET_MINIMAL_TOC))
9ebbca7d 8081 {
2bfcf297
DB
8082 rtx contains_minus = XEXP (x, 1);
8083 rtx minus, symref;
8084 const char *name;
9ebbca7d
GK
8085
8086 /* Find the (minus (sym) (toc)) buried in X, and temporarily
a4f6c312 8087 turn it into (sym) for output_addr_const. */
9ebbca7d
GK
8088 while (GET_CODE (XEXP (contains_minus, 0)) != MINUS)
8089 contains_minus = XEXP (contains_minus, 0);
8090
2bfcf297
DB
8091 minus = XEXP (contains_minus, 0);
8092 symref = XEXP (minus, 0);
8093 XEXP (contains_minus, 0) = symref;
8094 if (TARGET_ELF)
8095 {
8096 char *newname;
8097
8098 name = XSTR (symref, 0);
8099 newname = alloca (strlen (name) + sizeof ("@toc"));
8100 strcpy (newname, name);
8101 strcat (newname, "@toc");
8102 XSTR (symref, 0) = newname;
8103 }
8104 output_addr_const (file, XEXP (x, 1));
8105 if (TARGET_ELF)
8106 XSTR (symref, 0) = name;
9ebbca7d
GK
8107 XEXP (contains_minus, 0) = minus;
8108 }
8109 else
8110 output_addr_const (file, XEXP (x, 1));
8111
8112 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
8113 }
9878760c
RK
8114 else
8115 abort ();
8116}
8117\f
88cad84b 8118/* Target hook for assembling integer objects. The PowerPC version has
301d03af
RS
8119 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
8120 is defined. It also needs to handle DI-mode objects on 64-bit
8121 targets. */
8122
8123static bool
8124rs6000_assemble_integer (x, size, aligned_p)
8125 rtx x;
8126 unsigned int size;
8127 int aligned_p;
8128{
8129#ifdef RELOCATABLE_NEEDS_FIXUP
8130 /* Special handling for SI values. */
8131 if (size == 4 && aligned_p)
8132 {
8133 extern int in_toc_section PARAMS ((void));
8134 static int recurse = 0;
8135
8136 /* For -mrelocatable, we mark all addresses that need to be fixed up
8137 in the .fixup section. */
8138 if (TARGET_RELOCATABLE
8139 && !in_toc_section ()
8140 && !in_text_section ()
8141 && !recurse
8142 && GET_CODE (x) != CONST_INT
8143 && GET_CODE (x) != CONST_DOUBLE
8144 && CONSTANT_P (x))
8145 {
8146 char buf[256];
8147
8148 recurse = 1;
8149 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
8150 fixuplabelno++;
8151 ASM_OUTPUT_LABEL (asm_out_file, buf);
8152 fprintf (asm_out_file, "\t.long\t(");
8153 output_addr_const (asm_out_file, x);
8154 fprintf (asm_out_file, ")@fixup\n");
8155 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
8156 ASM_OUTPUT_ALIGN (asm_out_file, 2);
8157 fprintf (asm_out_file, "\t.long\t");
8158 assemble_name (asm_out_file, buf);
8159 fprintf (asm_out_file, "\n\t.previous\n");
8160 recurse = 0;
8161 return true;
8162 }
8163 /* Remove initial .'s to turn a -mcall-aixdesc function
8164 address into the address of the descriptor, not the function
8165 itself. */
8166 else if (GET_CODE (x) == SYMBOL_REF
8167 && XSTR (x, 0)[0] == '.'
8168 && DEFAULT_ABI == ABI_AIX)
8169 {
8170 const char *name = XSTR (x, 0);
8171 while (*name == '.')
8172 name++;
8173
8174 fprintf (asm_out_file, "\t.long\t%s\n", name);
8175 return true;
8176 }
8177 }
8178#endif /* RELOCATABLE_NEEDS_FIXUP */
8179 return default_assemble_integer (x, size, aligned_p);
8180}
93638d7a
AM
8181
8182#ifdef HAVE_GAS_HIDDEN
8183/* Emit an assembler directive to set symbol visibility for DECL to
8184 VISIBILITY_TYPE. */
8185
5add3202 8186static void
25fdb4dc 8187rs6000_assemble_visibility (decl, vis)
93638d7a 8188 tree decl;
25fdb4dc 8189 int vis;
93638d7a 8190{
93638d7a
AM
8191 /* Functions need to have their entry point symbol visibility set as
8192 well as their descriptor symbol visibility. */
8193 if (DEFAULT_ABI == ABI_AIX && TREE_CODE (decl) == FUNCTION_DECL)
8194 {
25fdb4dc
RH
8195 static const char * const visibility_types[] = {
8196 NULL, "internal", "hidden", "protected"
8197 };
8198
8199 const char *name, *type;
93638d7a
AM
8200
8201 name = ((* targetm.strip_name_encoding)
8202 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
25fdb4dc 8203 type = visibility_types[vis];
93638d7a 8204
25fdb4dc
RH
8205 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
8206 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
93638d7a 8207 }
25fdb4dc
RH
8208 else
8209 default_assemble_visibility (decl, vis);
93638d7a
AM
8210}
8211#endif
301d03af 8212\f
39a10a29
GK
8213enum rtx_code
8214rs6000_reverse_condition (mode, code)
8215 enum machine_mode mode;
8216 enum rtx_code code;
8217{
8218 /* Reversal of FP compares takes care -- an ordered compare
8219 becomes an unordered compare and vice versa. */
de40e1df 8220 if (mode == CCFPmode && !flag_unsafe_math_optimizations)
bab6226b 8221 return reverse_condition_maybe_unordered (code);
39a10a29 8222 else
bab6226b 8223 return reverse_condition (code);
39a10a29
GK
8224}
8225
39a10a29
GK
8226/* Generate a compare for CODE. Return a brand-new rtx that
8227 represents the result of the compare. */
a4f6c312 8228
39a10a29
GK
8229static rtx
8230rs6000_generate_compare (code)
8231 enum rtx_code code;
8232{
8233 enum machine_mode comp_mode;
8234 rtx compare_result;
8235
8236 if (rs6000_compare_fp_p)
8237 comp_mode = CCFPmode;
8238 else if (code == GTU || code == LTU
8239 || code == GEU || code == LEU)
8240 comp_mode = CCUNSmode;
8241 else
8242 comp_mode = CCmode;
8243
8244 /* First, the compare. */
8245 compare_result = gen_reg_rtx (comp_mode);
a3170dc6
AH
8246
8247 /* SPE FP compare instructions on the GPRs. Yuck! */
8248 if ((TARGET_SPE && TARGET_HARD_FLOAT) && rs6000_compare_fp_p)
8249 {
8250 rtx cmp, or1, or2, or_result, compare_result2;
8251
8252 switch (code)
8253 {
8254 case EQ:
8255 case UNEQ:
8256 case NE:
8257 case LTGT:
8258 cmp = flag_unsafe_math_optimizations
8259 ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
8260 rs6000_compare_op1)
8261 : gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
8262 rs6000_compare_op1);
8263 break;
8264 case GT:
8265 case GTU:
8266 case UNGT:
8267 case UNGE:
8268 case GE:
8269 case GEU:
8270 cmp = flag_unsafe_math_optimizations
8271 ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
8272 rs6000_compare_op1)
8273 : gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
8274 rs6000_compare_op1);
8275 break;
8276 case LT:
8277 case LTU:
8278 case UNLT:
8279 case UNLE:
8280 case LE:
8281 case LEU:
8282 cmp = flag_unsafe_math_optimizations
8283 ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
8284 rs6000_compare_op1)
8285 : gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
8286 rs6000_compare_op1);
8287 break;
8288 default:
8289 abort ();
8290 }
8291
8292 /* Synthesize LE and GE from LT/GT || EQ. */
8293 if (code == LE || code == GE || code == LEU || code == GEU)
8294 {
8295 /* Synthesize GE/LE frome GT/LT || EQ. */
8296
8297 emit_insn (cmp);
8298
8299 switch (code)
8300 {
8301 case LE: code = LT; break;
8302 case GE: code = GT; break;
8303 case LEU: code = LT; break;
8304 case GEU: code = GT; break;
8305 default: abort ();
8306 }
8307
8308 or1 = gen_reg_rtx (SImode);
8309 or2 = gen_reg_rtx (SImode);
8310 or_result = gen_reg_rtx (CCEQmode);
8311 compare_result2 = gen_reg_rtx (CCFPmode);
8312
8313 /* Do the EQ. */
8314 cmp = flag_unsafe_math_optimizations
8315 ? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
8316 rs6000_compare_op1)
8317 : gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0,
8318 rs6000_compare_op1);
8319 emit_insn (cmp);
8320
8321 /* The MC8540 FP compare instructions set the CR bits
8322 differently than other PPC compare instructions. For
8323 that matter, there is no generic test instruction, but a
8324 testgt, testlt, and testeq. For a true condition, bit 2
8325 is set (x1xx) in the CR. Following the traditional CR
8326 values:
8327
8328 LT GT EQ OV
8329 bit3 bit2 bit1 bit0
8330
8331 ... bit 2 would be a GT CR alias, so later on we
8332 look in the GT bits for the branch instructins.
8333 However, we must be careful to emit correct RTL in
8334 the meantime, so optimizations don't get confused. */
8335
8336 or1 = gen_rtx (NE, SImode, compare_result, const0_rtx);
8337 or2 = gen_rtx (NE, SImode, compare_result2, const0_rtx);
8338
8339 /* OR them together. */
8340 cmp = gen_rtx_SET (VOIDmode, or_result,
8341 gen_rtx_COMPARE (CCEQmode,
8342 gen_rtx_IOR (SImode, or1, or2),
8343 const_true_rtx));
8344 compare_result = or_result;
8345 code = EQ;
8346 }
8347 else
8348 {
8349 /* We only care about 1 bit (x1xx), so map everything to NE to
8350 maintain rtl sanity. We'll get to the right bit (x1xx) at
8351 code output time. */
8352 if (code == NE || code == LTGT)
8353 /* Do the inverse here because we have no cmpne
8354 instruction. We use the cmpeq instruction and expect
8355 to get a 0 instead. */
8356 code = EQ;
8357 else
8358 code = NE;
8359 }
8360
8361 emit_insn (cmp);
8362 }
8363 else
8364 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
8365 gen_rtx_COMPARE (comp_mode,
8366 rs6000_compare_op0,
8367 rs6000_compare_op1)));
39a10a29 8368
ca5adc63 8369 /* Some kinds of FP comparisons need an OR operation;
de6c5979 8370 except for flag_unsafe_math_optimizations we don't bother. */
39a10a29 8371 if (rs6000_compare_fp_p
de6c5979 8372 && ! flag_unsafe_math_optimizations
a3170dc6 8373 && ! (TARGET_HARD_FLOAT && TARGET_SPE)
39a10a29
GK
8374 && (code == LE || code == GE
8375 || code == UNEQ || code == LTGT
8376 || code == UNGT || code == UNLT))
8377 {
8378 enum rtx_code or1, or2;
8379 rtx or1_rtx, or2_rtx, compare2_rtx;
8380 rtx or_result = gen_reg_rtx (CCEQmode);
8381
8382 switch (code)
8383 {
8384 case LE: or1 = LT; or2 = EQ; break;
8385 case GE: or1 = GT; or2 = EQ; break;
8386 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
8387 case LTGT: or1 = LT; or2 = GT; break;
8388 case UNGT: or1 = UNORDERED; or2 = GT; break;
8389 case UNLT: or1 = UNORDERED; or2 = LT; break;
8390 default: abort ();
8391 }
8392 validate_condition_mode (or1, comp_mode);
8393 validate_condition_mode (or2, comp_mode);
8394 or1_rtx = gen_rtx (or1, SImode, compare_result, const0_rtx);
8395 or2_rtx = gen_rtx (or2, SImode, compare_result, const0_rtx);
8396 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
8397 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
8398 const_true_rtx);
8399 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
8400
8401 compare_result = or_result;
8402 code = EQ;
8403 }
8404
8405 validate_condition_mode (code, GET_MODE (compare_result));
8406
8407 return gen_rtx (code, VOIDmode, compare_result, const0_rtx);
8408}
8409
8410
8411/* Emit the RTL for an sCOND pattern. */
8412
8413void
8414rs6000_emit_sCOND (code, result)
8415 enum rtx_code code;
8416 rtx result;
8417{
8418 rtx condition_rtx;
8419 enum machine_mode op_mode;
8420
8421 condition_rtx = rs6000_generate_compare (code);
8422
8423 op_mode = GET_MODE (rs6000_compare_op0);
8424 if (op_mode == VOIDmode)
8425 op_mode = GET_MODE (rs6000_compare_op1);
8426
8427 if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p))
8428 {
8429 PUT_MODE (condition_rtx, DImode);
8430 convert_move (result, condition_rtx, 0);
8431 }
8432 else
8433 {
8434 PUT_MODE (condition_rtx, SImode);
8435 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
8436 }
8437}
8438
39a10a29
GK
8439/* Emit a branch of kind CODE to location LOC. */
8440
8441void
8442rs6000_emit_cbranch (code, loc)
8443 enum rtx_code code;
8444 rtx loc;
8445{
8446 rtx condition_rtx, loc_ref;
8447
8448 condition_rtx = rs6000_generate_compare (code);
8449 loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
8450 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
8451 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
8452 loc_ref, pc_rtx)));
8453}
8454
12a4e8c5
GK
8455/* Return the string to output a conditional branch to LABEL, which is
8456 the operand number of the label, or -1 if the branch is really a
8457 conditional return.
8458
8459 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
8460 condition code register and its mode specifies what kind of
8461 comparison we made.
8462
a0ab749a 8463 REVERSED is nonzero if we should reverse the sense of the comparison.
12a4e8c5
GK
8464
8465 INSN is the insn. */
8466
8467char *
8468output_cbranch (op, label, reversed, insn)
8469 rtx op;
8470 const char * label;
8471 int reversed;
8472 rtx insn;
8473{
8474 static char string[64];
8475 enum rtx_code code = GET_CODE (op);
8476 rtx cc_reg = XEXP (op, 0);
8477 enum machine_mode mode = GET_MODE (cc_reg);
8478 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
39a10a29 8479 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
12a4e8c5
GK
8480 int really_reversed = reversed ^ need_longbranch;
8481 char *s = string;
8482 const char *ccode;
8483 const char *pred;
8484 rtx note;
8485
39a10a29
GK
8486 validate_condition_mode (code, mode);
8487
8488 /* Work out which way this really branches. We could use
8489 reverse_condition_maybe_unordered here always but this
8490 makes the resulting assembler clearer. */
12a4e8c5 8491 if (really_reversed)
de40e1df
DJ
8492 {
8493 /* Reversal of FP compares takes care -- an ordered compare
8494 becomes an unordered compare and vice versa. */
8495 if (mode == CCFPmode)
8496 code = reverse_condition_maybe_unordered (code);
8497 else
8498 code = reverse_condition (code);
8499 }
12a4e8c5 8500
a3170dc6
AH
8501 if ((TARGET_SPE && TARGET_HARD_FLOAT) && mode == CCFPmode)
8502 {
8503 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
8504 to the GT bit. */
8505 if (code == EQ)
8506 /* Opposite of GT. */
8507 code = UNLE;
8508 else if (code == NE)
8509 code = GT;
8510 else
8511 abort ();
8512 }
8513
39a10a29 8514 switch (code)
12a4e8c5
GK
8515 {
8516 /* Not all of these are actually distinct opcodes, but
8517 we distinguish them for clarity of the resulting assembler. */
50a0b056
GK
8518 case NE: case LTGT:
8519 ccode = "ne"; break;
8520 case EQ: case UNEQ:
8521 ccode = "eq"; break;
8522 case GE: case GEU:
8523 ccode = "ge"; break;
8524 case GT: case GTU: case UNGT:
8525 ccode = "gt"; break;
8526 case LE: case LEU:
8527 ccode = "le"; break;
8528 case LT: case LTU: case UNLT:
8529 ccode = "lt"; break;
12a4e8c5
GK
8530 case UNORDERED: ccode = "un"; break;
8531 case ORDERED: ccode = "nu"; break;
8532 case UNGE: ccode = "nl"; break;
8533 case UNLE: ccode = "ng"; break;
8534 default:
a4f6c312 8535 abort ();
12a4e8c5
GK
8536 }
8537
94a54f47
GK
8538 /* Maybe we have a guess as to how likely the branch is.
8539 The old mnemonics don't have a way to specify this information. */
f4857b9b 8540 pred = "";
12a4e8c5
GK
8541 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
8542 if (note != NULL_RTX)
8543 {
8544 /* PROB is the difference from 50%. */
8545 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
f4857b9b
AM
8546 bool always_hint = rs6000_cpu != PROCESSOR_POWER4;
8547
8548 /* Only hint for highly probable/improbable branches on newer
8549 cpus as static prediction overrides processor dynamic
8550 prediction. For older cpus we may as well always hint, but
8551 assume not taken for branches that are very close to 50% as a
8552 mispredicted taken branch is more expensive than a
8553 mispredicted not-taken branch. */
8554 if (always_hint
8555 || abs (prob) > REG_BR_PROB_BASE / 100 * 48)
8556 {
8557 if (abs (prob) > REG_BR_PROB_BASE / 20
8558 && ((prob > 0) ^ need_longbranch))
8559 pred = "+";
8560 else
8561 pred = "-";
8562 }
12a4e8c5 8563 }
12a4e8c5
GK
8564
8565 if (label == NULL)
94a54f47 8566 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
12a4e8c5 8567 else
94a54f47 8568 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
12a4e8c5 8569
37c67319
GK
8570 /* We need to escape any '%' characters in the reg_names string.
8571 Assume they'd only be the first character... */
8572 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
8573 *s++ = '%';
94a54f47 8574 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
12a4e8c5
GK
8575
8576 if (label != NULL)
8577 {
8578 /* If the branch distance was too far, we may have to use an
8579 unconditional branch to go the distance. */
8580 if (need_longbranch)
44518ddd 8581 s += sprintf (s, ",$+8\n\tb %s", label);
12a4e8c5
GK
8582 else
8583 s += sprintf (s, ",%s", label);
8584 }
8585
8586 return string;
8587}
50a0b056
GK
8588
8589/* Emit a conditional move: move TRUE_COND to DEST if OP of the
8590 operands of the last comparison is nonzero/true, FALSE_COND if it
8591 is zero/false. Return 0 if the hardware has no such operation. */
a4f6c312 8592
50a0b056
GK
8593int
8594rs6000_emit_cmove (dest, op, true_cond, false_cond)
8595 rtx dest;
8596 rtx op;
8597 rtx true_cond;
8598 rtx false_cond;
8599{
8600 enum rtx_code code = GET_CODE (op);
8601 rtx op0 = rs6000_compare_op0;
8602 rtx op1 = rs6000_compare_op1;
8603 REAL_VALUE_TYPE c1;
3148ad6d
DJ
8604 enum machine_mode compare_mode = GET_MODE (op0);
8605 enum machine_mode result_mode = GET_MODE (dest);
50a0b056
GK
8606 rtx temp;
8607
3148ad6d 8608 /* These modes should always match. */
a3170dc6
AH
8609 if (GET_MODE (op1) != compare_mode
8610 /* In the isel case however, we can use a compare immediate, so
8611 op1 may be a small constant. */
8612 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
3148ad6d 8613 return 0;
178c3eff 8614 if (GET_MODE (true_cond) != result_mode)
3148ad6d 8615 return 0;
178c3eff 8616 if (GET_MODE (false_cond) != result_mode)
3148ad6d
DJ
8617 return 0;
8618
50a0b056
GK
8619 /* First, work out if the hardware can do this at all, or
8620 if it's too slow... */
50a0b056 8621 if (! rs6000_compare_fp_p)
a3170dc6
AH
8622 {
8623 if (TARGET_ISEL)
8624 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
8625 return 0;
8626 }
50a0b056
GK
8627
8628 /* Eliminate half of the comparisons by switching operands, this
8629 makes the remaining code simpler. */
8630 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
8631 || code == LTGT || code == LT)
8632 {
8633 code = reverse_condition_maybe_unordered (code);
8634 temp = true_cond;
8635 true_cond = false_cond;
8636 false_cond = temp;
8637 }
8638
8639 /* UNEQ and LTGT take four instructions for a comparison with zero,
8640 it'll probably be faster to use a branch here too. */
8641 if (code == UNEQ)
8642 return 0;
8643
8644 if (GET_CODE (op1) == CONST_DOUBLE)
8645 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
8646
8647 /* We're going to try to implement comparions by performing
8648 a subtract, then comparing against zero. Unfortunately,
8649 Inf - Inf is NaN which is not zero, and so if we don't
27d30956 8650 know that the operand is finite and the comparison
50a0b056
GK
8651 would treat EQ different to UNORDERED, we can't do it. */
8652 if (! flag_unsafe_math_optimizations
8653 && code != GT && code != UNGE
045572c7 8654 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
50a0b056
GK
8655 /* Constructs of the form (a OP b ? a : b) are safe. */
8656 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
8657 || (! rtx_equal_p (op0, true_cond)
8658 && ! rtx_equal_p (op1, true_cond))))
8659 return 0;
8660 /* At this point we know we can use fsel. */
8661
8662 /* Reduce the comparison to a comparison against zero. */
3148ad6d 8663 temp = gen_reg_rtx (compare_mode);
50a0b056 8664 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d 8665 gen_rtx_MINUS (compare_mode, op0, op1)));
50a0b056 8666 op0 = temp;
3148ad6d 8667 op1 = CONST0_RTX (compare_mode);
50a0b056
GK
8668
8669 /* If we don't care about NaNs we can reduce some of the comparisons
8670 down to faster ones. */
8671 if (flag_unsafe_math_optimizations)
8672 switch (code)
8673 {
8674 case GT:
8675 code = LE;
8676 temp = true_cond;
8677 true_cond = false_cond;
8678 false_cond = temp;
8679 break;
8680 case UNGE:
8681 code = GE;
8682 break;
8683 case UNEQ:
8684 code = EQ;
8685 break;
8686 default:
8687 break;
8688 }
8689
8690 /* Now, reduce everything down to a GE. */
8691 switch (code)
8692 {
8693 case GE:
8694 break;
8695
8696 case LE:
3148ad6d
DJ
8697 temp = gen_reg_rtx (compare_mode);
8698 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
8699 op0 = temp;
8700 break;
8701
8702 case ORDERED:
3148ad6d
DJ
8703 temp = gen_reg_rtx (compare_mode);
8704 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
50a0b056
GK
8705 op0 = temp;
8706 break;
8707
8708 case EQ:
3148ad6d 8709 temp = gen_reg_rtx (compare_mode);
50a0b056 8710 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d
DJ
8711 gen_rtx_NEG (compare_mode,
8712 gen_rtx_ABS (compare_mode, op0))));
50a0b056
GK
8713 op0 = temp;
8714 break;
8715
8716 case UNGE:
3148ad6d 8717 temp = gen_reg_rtx (result_mode);
50a0b056 8718 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d 8719 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
8720 gen_rtx_GE (VOIDmode,
8721 op0, op1),
8722 true_cond, false_cond)));
8723 false_cond = temp;
8724 true_cond = false_cond;
8725
3148ad6d
DJ
8726 temp = gen_reg_rtx (compare_mode);
8727 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
8728 op0 = temp;
8729 break;
8730
8731 case GT:
3148ad6d 8732 temp = gen_reg_rtx (result_mode);
50a0b056 8733 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d 8734 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
8735 gen_rtx_GE (VOIDmode,
8736 op0, op1),
8737 true_cond, false_cond)));
8738 true_cond = temp;
8739 false_cond = true_cond;
8740
3148ad6d
DJ
8741 temp = gen_reg_rtx (compare_mode);
8742 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
8743 op0 = temp;
8744 break;
8745
8746 default:
8747 abort ();
8748 }
8749
8750 emit_insn (gen_rtx_SET (VOIDmode, dest,
3148ad6d 8751 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
8752 gen_rtx_GE (VOIDmode,
8753 op0, op1),
8754 true_cond, false_cond)));
8755 return 1;
8756}
8757
a3170dc6
AH
8758/* Same as above, but for ints (isel). */
8759
8760static int
8761rs6000_emit_int_cmove (dest, op, true_cond, false_cond)
8762 rtx dest;
8763 rtx op;
8764 rtx true_cond;
8765 rtx false_cond;
8766{
8767 rtx condition_rtx, cr;
8768
8769 /* All isel implementations thus far are 32-bits. */
8770 if (GET_MODE (rs6000_compare_op0) != SImode)
8771 return 0;
8772
8773 /* We still have to do the compare, because isel doesn't do a
8774 compare, it just looks at the CRx bits set by a previous compare
8775 instruction. */
8776 condition_rtx = rs6000_generate_compare (GET_CODE (op));
8777 cr = XEXP (condition_rtx, 0);
8778
8779 if (GET_MODE (cr) == CCmode)
8780 emit_insn (gen_isel_signed (dest, condition_rtx,
8781 true_cond, false_cond, cr));
8782 else
8783 emit_insn (gen_isel_unsigned (dest, condition_rtx,
8784 true_cond, false_cond, cr));
8785
8786 return 1;
8787}
8788
8789const char *
8790output_isel (operands)
8791 rtx *operands;
8792{
8793 enum rtx_code code;
8794
8795 code = GET_CODE (operands[1]);
8796 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
8797 {
8798 PUT_CODE (operands[1], reverse_condition (code));
8799 return "isel %0,%3,%2,%j1";
8800 }
8801 else
8802 return "isel %0,%2,%3,%j1";
8803}
8804
50a0b056
GK
8805void
8806rs6000_emit_minmax (dest, code, op0, op1)
8807 rtx dest;
8808 enum rtx_code code;
8809 rtx op0;
8810 rtx op1;
8811{
8812 enum machine_mode mode = GET_MODE (op0);
5dc8d536 8813 enum rtx_code c;
50a0b056 8814 rtx target;
5dc8d536
AH
8815
8816 if (code == SMAX || code == SMIN)
8817 c = GE;
8818 else
8819 c = GEU;
8820
50a0b056 8821 if (code == SMAX || code == UMAX)
5dc8d536 8822 target = emit_conditional_move (dest, c, op0, op1, mode,
50a0b056
GK
8823 op0, op1, mode, 0);
8824 else
5dc8d536 8825 target = emit_conditional_move (dest, c, op0, op1, mode,
50a0b056
GK
8826 op1, op0, mode, 0);
8827 if (target == NULL_RTX)
8828 abort ();
8829 if (target != dest)
8830 emit_move_insn (dest, target);
8831}
12a4e8c5 8832\f
a4f6c312
SS
8833/* This page contains routines that are used to determine what the
8834 function prologue and epilogue code will do and write them out. */
9878760c 8835
a4f6c312
SS
8836/* Return the first fixed-point register that is required to be
8837 saved. 32 if none. */
9878760c
RK
8838
8839int
8840first_reg_to_save ()
8841{
8842 int first_reg;
8843
8844 /* Find lowest numbered live register. */
8845 for (first_reg = 13; first_reg <= 31; first_reg++)
a38d360d
GK
8846 if (regs_ever_live[first_reg]
8847 && (! call_used_regs[first_reg]
1db02437 8848 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
f607bc57
ZW
8849 && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
8850 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)))))
9878760c
RK
8851 break;
8852
ee890fe2 8853#if TARGET_MACHO
93638d7a
AM
8854 if (flag_pic
8855 && current_function_uses_pic_offset_table
8856 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
1db02437 8857 return RS6000_PIC_OFFSET_TABLE_REGNUM;
ee890fe2
SS
8858#endif
8859
9878760c
RK
8860 return first_reg;
8861}
8862
8863/* Similar, for FP regs. */
8864
8865int
8866first_fp_reg_to_save ()
8867{
8868 int first_reg;
8869
8870 /* Find lowest numbered live register. */
8871 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
8872 if (regs_ever_live[first_reg])
8873 break;
8874
8875 return first_reg;
8876}
00b960c7
AH
8877
8878/* Similar, for AltiVec regs. */
8879
8880static int
8881first_altivec_reg_to_save ()
8882{
8883 int i;
8884
8885 /* Stack frame remains as is unless we are in AltiVec ABI. */
8886 if (! TARGET_ALTIVEC_ABI)
8887 return LAST_ALTIVEC_REGNO + 1;
8888
8889 /* Find lowest numbered live register. */
8890 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
8891 if (regs_ever_live[i])
8892 break;
8893
8894 return i;
8895}
8896
8897/* Return a 32-bit mask of the AltiVec registers we need to set in
8898 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
8899 the 32-bit word is 0. */
8900
8901static unsigned int
8902compute_vrsave_mask ()
8903{
8904 unsigned int i, mask = 0;
8905
8906 /* First, find out if we use _any_ altivec registers. */
8907 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
8908 if (regs_ever_live[i])
8909 mask |= ALTIVEC_REG_BIT (i);
8910
8911 if (mask == 0)
8912 return mask;
8913
8914 /* Next, add all registers that are call-clobbered. We do this
8915 because post-reload register optimizers such as regrename_optimize
8916 may choose to use them. They never change the register class
8917 chosen by reload, so cannot create new uses of altivec registers
8918 if there were none before, so the early exit above is safe. */
8919 /* ??? Alternately, we could define HARD_REGNO_RENAME_OK to disallow
8920 altivec registers not saved in the mask, which might well make the
8921 adjustments below more effective in eliding the save/restore of
8922 VRSAVE in small functions. */
8923 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
8924 if (call_used_regs[i])
8925 mask |= ALTIVEC_REG_BIT (i);
8926
8927 /* Next, remove the argument registers from the set. These must
8928 be in the VRSAVE mask set by the caller, so we don't need to add
8929 them in again. More importantly, the mask we compute here is
8930 used to generate CLOBBERs in the set_vrsave insn, and we do not
8931 wish the argument registers to die. */
8932 for (i = cfun->args_info.vregno; i >= ALTIVEC_ARG_MIN_REG; --i)
8933 mask &= ~ALTIVEC_REG_BIT (i);
8934
8935 /* Similarly, remove the return value from the set. */
8936 {
8937 bool yes = false;
8938 diddle_return_value (is_altivec_return_reg, &yes);
8939 if (yes)
8940 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
8941 }
8942
8943 return mask;
8944}
8945
8946static void
8947is_altivec_return_reg (reg, xyes)
8948 rtx reg;
8949 void *xyes;
8950{
8951 bool *yes = (bool *) xyes;
8952 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
8953 *yes = true;
8954}
8955
4697a36c
MM
8956\f
8957/* Calculate the stack information for the current function. This is
8958 complicated by having two separate calling sequences, the AIX calling
8959 sequence and the V.4 calling sequence.
8960
592696dd 8961 AIX (and Darwin/Mac OS X) stack frames look like:
a260abc9 8962 32-bit 64-bit
4697a36c 8963 SP----> +---------------------------------------+
a260abc9 8964 | back chain to caller | 0 0
4697a36c 8965 +---------------------------------------+
a260abc9 8966 | saved CR | 4 8 (8-11)
4697a36c 8967 +---------------------------------------+
a260abc9 8968 | saved LR | 8 16
4697a36c 8969 +---------------------------------------+
a260abc9 8970 | reserved for compilers | 12 24
4697a36c 8971 +---------------------------------------+
a260abc9 8972 | reserved for binders | 16 32
4697a36c 8973 +---------------------------------------+
a260abc9 8974 | saved TOC pointer | 20 40
4697a36c 8975 +---------------------------------------+
a260abc9 8976 | Parameter save area (P) | 24 48
4697a36c 8977 +---------------------------------------+
a260abc9 8978 | Alloca space (A) | 24+P etc.
802a0058 8979 +---------------------------------------+
a7df97e6 8980 | Local variable space (L) | 24+P+A
4697a36c 8981 +---------------------------------------+
a7df97e6 8982 | Float/int conversion temporary (X) | 24+P+A+L
4697a36c 8983 +---------------------------------------+
00b960c7
AH
8984 | Save area for AltiVec registers (W) | 24+P+A+L+X
8985 +---------------------------------------+
8986 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
8987 +---------------------------------------+
8988 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
4697a36c 8989 +---------------------------------------+
00b960c7
AH
8990 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
8991 +---------------------------------------+
8992 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
4697a36c
MM
8993 +---------------------------------------+
8994 old SP->| back chain to caller's caller |
8995 +---------------------------------------+
8996
5376a30c
KR
8997 The required alignment for AIX configurations is two words (i.e., 8
8998 or 16 bytes).
8999
9000
4697a36c
MM
9001 V.4 stack frames look like:
9002
9003 SP----> +---------------------------------------+
9004 | back chain to caller | 0
9005 +---------------------------------------+
5eb387b8 9006 | caller's saved LR | 4
4697a36c
MM
9007 +---------------------------------------+
9008 | Parameter save area (P) | 8
9009 +---------------------------------------+
a7df97e6
MM
9010 | Alloca space (A) | 8+P
9011 +---------------------------------------+
9012 | Varargs save area (V) | 8+P+A
9013 +---------------------------------------+
9014 | Local variable space (L) | 8+P+A+V
9015 +---------------------------------------+
9016 | Float/int conversion temporary (X) | 8+P+A+V+L
4697a36c 9017 +---------------------------------------+
00b960c7
AH
9018 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
9019 +---------------------------------------+
9020 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
9021 +---------------------------------------+
9022 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
9023 +---------------------------------------+
a3170dc6
AH
9024 | SPE: area for 64-bit GP registers |
9025 +---------------------------------------+
9026 | SPE alignment padding |
9027 +---------------------------------------+
00b960c7 9028 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
a7df97e6 9029 +---------------------------------------+
00b960c7 9030 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
a7df97e6 9031 +---------------------------------------+
00b960c7 9032 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
4697a36c
MM
9033 +---------------------------------------+
9034 old SP->| back chain to caller's caller |
9035 +---------------------------------------+
b6c9286a 9036
5376a30c
KR
9037 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
9038 given. (But note below and in sysv4.h that we require only 8 and
9039 may round up the size of our stack frame anyways. The historical
9040 reason is early versions of powerpc-linux which didn't properly
9041 align the stack at program startup. A happy side-effect is that
9042 -mno-eabi libraries can be used with -meabi programs.)
9043
5376a30c
KR
9044 The EABI configuration defaults to the V.4 layout, unless
9045 -mcall-aix is used, in which case the AIX layout is used. However,
9046 the stack alignment requirements may differ. If -mno-eabi is not
9047 given, the required stack alignment is 8 bytes; if -mno-eabi is
9048 given, the required alignment is 16 bytes. (But see V.4 comment
9049 above.) */
4697a36c 9050
61b2fbe7
MM
9051#ifndef ABI_STACK_BOUNDARY
9052#define ABI_STACK_BOUNDARY STACK_BOUNDARY
9053#endif
9054
4697a36c
MM
9055rs6000_stack_t *
9056rs6000_stack_info ()
9057{
9058 static rs6000_stack_t info, zero_info;
9059 rs6000_stack_t *info_ptr = &info;
9ebbca7d 9060 int reg_size = TARGET_POWERPC64 ? 8 : 4;
24d304eb 9061 enum rs6000_abi abi;
83720594 9062 int ehrd_size;
b6c9286a 9063 int total_raw_size;
4697a36c 9064
a4f6c312 9065 /* Zero all fields portably. */
4697a36c
MM
9066 info = zero_info;
9067
a4f6c312 9068 /* Select which calling sequence. */
b6c9286a 9069 info_ptr->abi = abi = DEFAULT_ABI;
9878760c 9070
a4f6c312 9071 /* Calculate which registers need to be saved & save area size. */
4697a36c 9072 info_ptr->first_gp_reg_save = first_reg_to_save ();
1db02437 9073 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
906fb125 9074 even if it currently looks like we won't. */
2bfcf297 9075 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
f607bc57
ZW
9076 || (flag_pic == 1 && abi == ABI_V4)
9077 || (flag_pic && abi == ABI_DARWIN))
1db02437
FS
9078 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
9079 info_ptr->gp_size = reg_size * (32 - RS6000_PIC_OFFSET_TABLE_REGNUM);
906fb125
GK
9080 else
9081 info_ptr->gp_size = reg_size * (32 - info_ptr->first_gp_reg_save);
4697a36c 9082
a3170dc6
AH
9083 /* For the SPE, we have an additional upper 32-bits on each GPR.
9084 Ideally we should save the entire 64-bits only when the upper
9085 half is used in SIMD instructions. Since we only record
9086 registers live (not the size they are used in), this proves
9087 difficult because we'd have to traverse the instruction chain at
9088 the right time, taking reload into account. This is a real pain,
9089 so we opt to save the GPRs in 64-bits always. Anyone overly
9090 concerned with frame size can fix this. ;-).
9091
9092 So... since we save all GPRs (except the SP) in 64-bits, the
9093 traditional GP save area will be empty. */
9094 if (TARGET_SPE_ABI)
9095 info_ptr->gp_size = 0;
9096
4697a36c
MM
9097 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
9098 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
9099
00b960c7
AH
9100 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
9101 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
9102 - info_ptr->first_altivec_reg_save);
9103
592696dd 9104 /* Does this function call anything? */
71f123ca
FS
9105 info_ptr->calls_p = (! current_function_is_leaf
9106 || cfun->machine->ra_needs_full_frame);
b6c9286a 9107
a4f6c312 9108 /* Determine if we need to save the link register. */
71f123ca 9109 if (rs6000_ra_ever_killed ()
70f4f91c 9110 || (DEFAULT_ABI == ABI_AIX && current_function_profile)
4697a36c
MM
9111#ifdef TARGET_RELOCATABLE
9112 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
9113#endif
9114 || (info_ptr->first_fp_reg_save != 64
9115 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
00b960c7 9116 || info_ptr->first_altivec_reg_save <= LAST_ALTIVEC_REGNO
24d304eb 9117 || (abi == ABI_V4 && current_function_calls_alloca)
a4f6c312
SS
9118 || (DEFAULT_ABI == ABI_DARWIN
9119 && flag_pic
9120 && current_function_uses_pic_offset_table)
4697a36c
MM
9121 || info_ptr->calls_p)
9122 {
9123 info_ptr->lr_save_p = 1;
9ebbca7d 9124 regs_ever_live[LINK_REGISTER_REGNUM] = 1;
4697a36c
MM
9125 }
9126
9ebbca7d
GK
9127 /* Determine if we need to save the condition code registers. */
9128 if (regs_ever_live[CR2_REGNO]
9129 || regs_ever_live[CR3_REGNO]
9130 || regs_ever_live[CR4_REGNO])
4697a36c
MM
9131 {
9132 info_ptr->cr_save_p = 1;
f607bc57 9133 if (abi == ABI_V4)
4697a36c
MM
9134 info_ptr->cr_size = reg_size;
9135 }
9136
83720594
RH
9137 /* If the current function calls __builtin_eh_return, then we need
9138 to allocate stack space for registers that will hold data for
9139 the exception handler. */
9140 if (current_function_calls_eh_return)
9141 {
9142 unsigned int i;
9143 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
9144 continue;
a3170dc6
AH
9145
9146 /* SPE saves EH registers in 64-bits. */
9147 ehrd_size = i * (TARGET_SPE_ABI ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
83720594
RH
9148 }
9149 else
9150 ehrd_size = 0;
9151
592696dd 9152 /* Determine various sizes. */
4697a36c
MM
9153 info_ptr->reg_size = reg_size;
9154 info_ptr->fixed_size = RS6000_SAVE_AREA;
9155 info_ptr->varargs_size = RS6000_VARARGS_AREA;
189e03e3 9156 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
a4f6c312
SS
9157 info_ptr->parm_size = RS6000_ALIGN (current_function_outgoing_args_size,
9158 8);
00b960c7 9159
a3170dc6
AH
9160 if (TARGET_SPE_ABI)
9161 info_ptr->spe_gp_size = 8 * (32 - info_ptr->first_gp_reg_save);
9162 else
9163 info_ptr->spe_gp_size = 0;
9164
08b57fb3 9165 if (TARGET_ALTIVEC_ABI && TARGET_ALTIVEC_VRSAVE)
00b960c7
AH
9166 {
9167 info_ptr->vrsave_mask = compute_vrsave_mask ();
9168 info_ptr->vrsave_size = info_ptr->vrsave_mask ? 4 : 0;
9169 }
9170 else
9171 {
9172 info_ptr->vrsave_mask = 0;
9173 info_ptr->vrsave_size = 0;
9174 }
b6c9286a 9175
592696dd 9176 /* Calculate the offsets. */
24d304eb 9177 switch (abi)
4697a36c 9178 {
b6c9286a 9179 case ABI_NONE:
24d304eb 9180 default:
b6c9286a
MM
9181 abort ();
9182
9183 case ABI_AIX:
9184 case ABI_AIX_NODESC:
ee890fe2 9185 case ABI_DARWIN:
b6c9286a
MM
9186 info_ptr->fp_save_offset = - info_ptr->fp_size;
9187 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
00b960c7
AH
9188
9189 if (TARGET_ALTIVEC_ABI)
9190 {
9191 info_ptr->vrsave_save_offset
9192 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
9193
9194 /* Align stack so vector save area is on a quadword boundary. */
9195 if (info_ptr->altivec_size != 0)
9196 info_ptr->altivec_padding_size
9197 = 16 - (-info_ptr->vrsave_save_offset % 16);
9198 else
9199 info_ptr->altivec_padding_size = 0;
9200
9201 info_ptr->altivec_save_offset
9202 = info_ptr->vrsave_save_offset
9203 - info_ptr->altivec_padding_size
9204 - info_ptr->altivec_size;
9205
9206 /* Adjust for AltiVec case. */
9207 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
9208 }
9209 else
9210 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
a260abc9
DE
9211 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
9212 info_ptr->lr_save_offset = 2*reg_size;
24d304eb
RK
9213 break;
9214
9215 case ABI_V4:
b6c9286a
MM
9216 info_ptr->fp_save_offset = - info_ptr->fp_size;
9217 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
a7df97e6 9218 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
00b960c7 9219
a3170dc6
AH
9220 if (TARGET_SPE_ABI)
9221 {
9222 /* Align stack so SPE GPR save area is aligned on a
9223 double-word boundary. */
9224 if (info_ptr->spe_gp_size != 0)
9225 info_ptr->spe_padding_size
9226 = 8 - (-info_ptr->cr_save_offset % 8);
9227 else
9228 info_ptr->spe_padding_size = 0;
9229
9230 info_ptr->spe_gp_save_offset
9231 = info_ptr->cr_save_offset
9232 - info_ptr->spe_padding_size
9233 - info_ptr->spe_gp_size;
9234
9235 /* Adjust for SPE case. */
9236 info_ptr->toc_save_offset
9237 = info_ptr->spe_gp_save_offset - info_ptr->toc_size;
9238 }
9239 else if (TARGET_ALTIVEC_ABI)
00b960c7
AH
9240 {
9241 info_ptr->vrsave_save_offset
9242 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
9243
9244 /* Align stack so vector save area is on a quadword boundary. */
9245 if (info_ptr->altivec_size != 0)
9246 info_ptr->altivec_padding_size
9247 = 16 - (-info_ptr->vrsave_save_offset % 16);
9248 else
9249 info_ptr->altivec_padding_size = 0;
9250
9251 info_ptr->altivec_save_offset
9252 = info_ptr->vrsave_save_offset
9253 - info_ptr->altivec_padding_size
9254 - info_ptr->altivec_size;
9255
9256 /* Adjust for AltiVec case. */
9257 info_ptr->toc_save_offset
9258 = info_ptr->altivec_save_offset - info_ptr->toc_size;
9259 }
9260 else
9261 info_ptr->toc_save_offset = info_ptr->cr_save_offset - info_ptr->toc_size;
83720594 9262 info_ptr->ehrd_offset = info_ptr->toc_save_offset - ehrd_size;
b6c9286a
MM
9263 info_ptr->lr_save_offset = reg_size;
9264 break;
4697a36c
MM
9265 }
9266
00b960c7
AH
9267 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
9268 + info_ptr->gp_size
9269 + info_ptr->altivec_size
9270 + info_ptr->altivec_padding_size
9271 + info_ptr->vrsave_size
a3170dc6
AH
9272 + info_ptr->spe_gp_size
9273 + info_ptr->spe_padding_size
00b960c7
AH
9274 + ehrd_size
9275 + info_ptr->cr_size
9276 + info_ptr->lr_size
9277 + info_ptr->vrsave_size
9278 + info_ptr->toc_size,
9279 (TARGET_ALTIVEC_ABI || ABI_DARWIN)
9280 ? 16 : 8);
9281
ff381587
MM
9282 total_raw_size = (info_ptr->vars_size
9283 + info_ptr->parm_size
ff381587
MM
9284 + info_ptr->save_size
9285 + info_ptr->varargs_size
9286 + info_ptr->fixed_size);
9287
a4f6c312
SS
9288 info_ptr->total_size =
9289 RS6000_ALIGN (total_raw_size, ABI_STACK_BOUNDARY / BITS_PER_UNIT);
ff381587
MM
9290
9291 /* Determine if we need to allocate any stack frame:
9292
a4f6c312
SS
9293 For AIX we need to push the stack if a frame pointer is needed
9294 (because the stack might be dynamically adjusted), if we are
9295 debugging, if we make calls, or if the sum of fp_save, gp_save,
9296 and local variables are more than the space needed to save all
9297 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
9298 + 18*8 = 288 (GPR13 reserved).
ff381587 9299
a4f6c312
SS
9300 For V.4 we don't have the stack cushion that AIX uses, but assume
9301 that the debugger can handle stackless frames. */
ff381587
MM
9302
9303 if (info_ptr->calls_p)
9304 info_ptr->push_p = 1;
9305
f607bc57 9306 else if (abi == ABI_V4)
e72247f4 9307 info_ptr->push_p = total_raw_size > info_ptr->fixed_size;
ff381587
MM
9308
9309 else
9310 info_ptr->push_p = (frame_pointer_needed
ee890fe2 9311 || (abi != ABI_DARWIN && write_symbols != NO_DEBUG)
ff381587 9312 || ((total_raw_size - info_ptr->fixed_size)
bfc79d3b 9313 > (TARGET_32BIT ? 220 : 288)));
ff381587 9314
a4f6c312 9315 /* Zero offsets if we're not saving those registers. */
8dda1a21 9316 if (info_ptr->fp_size == 0)
4697a36c
MM
9317 info_ptr->fp_save_offset = 0;
9318
8dda1a21 9319 if (info_ptr->gp_size == 0)
4697a36c
MM
9320 info_ptr->gp_save_offset = 0;
9321
00b960c7
AH
9322 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
9323 info_ptr->altivec_save_offset = 0;
9324
9325 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
9326 info_ptr->vrsave_save_offset = 0;
9327
a3170dc6
AH
9328 if (! TARGET_SPE_ABI || info_ptr->spe_gp_size == 0)
9329 info_ptr->spe_gp_save_offset = 0;
9330
c81fc13e 9331 if (! info_ptr->lr_save_p)
4697a36c
MM
9332 info_ptr->lr_save_offset = 0;
9333
c81fc13e 9334 if (! info_ptr->cr_save_p)
4697a36c
MM
9335 info_ptr->cr_save_offset = 0;
9336
c81fc13e 9337 if (! info_ptr->toc_save_p)
b6c9286a
MM
9338 info_ptr->toc_save_offset = 0;
9339
4697a36c
MM
9340 return info_ptr;
9341}
9342
9343void
9344debug_stack_info (info)
9345 rs6000_stack_t *info;
9878760c 9346{
d330fd93 9347 const char *abi_string;
24d304eb 9348
c81fc13e 9349 if (! info)
4697a36c
MM
9350 info = rs6000_stack_info ();
9351
9352 fprintf (stderr, "\nStack information for function %s:\n",
9353 ((current_function_decl && DECL_NAME (current_function_decl))
9354 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
9355 : "<unknown>"));
9356
24d304eb
RK
9357 switch (info->abi)
9358 {
b6c9286a
MM
9359 default: abi_string = "Unknown"; break;
9360 case ABI_NONE: abi_string = "NONE"; break;
f607bc57 9361 case ABI_AIX:
b6c9286a 9362 case ABI_AIX_NODESC: abi_string = "AIX"; break;
ee890fe2 9363 case ABI_DARWIN: abi_string = "Darwin"; break;
b6c9286a 9364 case ABI_V4: abi_string = "V.4"; break;
24d304eb
RK
9365 }
9366
9367 fprintf (stderr, "\tABI = %5s\n", abi_string);
9368
00b960c7
AH
9369 if (TARGET_ALTIVEC_ABI)
9370 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
9371
a3170dc6
AH
9372 if (TARGET_SPE_ABI)
9373 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
9374
4697a36c
MM
9375 if (info->first_gp_reg_save != 32)
9376 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
9377
9378 if (info->first_fp_reg_save != 64)
9379 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
9878760c 9380
00b960c7
AH
9381 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
9382 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
9383 info->first_altivec_reg_save);
9384
4697a36c
MM
9385 if (info->lr_save_p)
9386 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
9878760c 9387
4697a36c
MM
9388 if (info->cr_save_p)
9389 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
9390
b6c9286a
MM
9391 if (info->toc_save_p)
9392 fprintf (stderr, "\ttoc_save_p = %5d\n", info->toc_save_p);
9393
00b960c7
AH
9394 if (info->vrsave_mask)
9395 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
9396
4697a36c
MM
9397 if (info->push_p)
9398 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
9399
9400 if (info->calls_p)
9401 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
9402
4697a36c
MM
9403 if (info->gp_save_offset)
9404 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
9405
9406 if (info->fp_save_offset)
9407 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
9408
00b960c7
AH
9409 if (info->altivec_save_offset)
9410 fprintf (stderr, "\taltivec_save_offset = %5d\n",
9411 info->altivec_save_offset);
9412
a3170dc6
AH
9413 if (info->spe_gp_save_offset)
9414 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
9415 info->spe_gp_save_offset);
9416
00b960c7
AH
9417 if (info->vrsave_save_offset)
9418 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
9419 info->vrsave_save_offset);
9420
4697a36c
MM
9421 if (info->lr_save_offset)
9422 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
9423
9424 if (info->cr_save_offset)
9425 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
9426
b6c9286a
MM
9427 if (info->toc_save_offset)
9428 fprintf (stderr, "\ttoc_save_offset = %5d\n", info->toc_save_offset);
9429
4697a36c
MM
9430 if (info->varargs_save_offset)
9431 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
9432
9433 if (info->total_size)
9434 fprintf (stderr, "\ttotal_size = %5d\n", info->total_size);
9435
9436 if (info->varargs_size)
9437 fprintf (stderr, "\tvarargs_size = %5d\n", info->varargs_size);
9438
9439 if (info->vars_size)
9440 fprintf (stderr, "\tvars_size = %5d\n", info->vars_size);
9441
9442 if (info->parm_size)
9443 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
9444
9445 if (info->fixed_size)
9446 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
9447
9448 if (info->gp_size)
9449 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
9450
a3170dc6
AH
9451 if (info->spe_gp_size)
9452 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
9453
4697a36c
MM
9454 if (info->fp_size)
9455 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
9456
00b960c7
AH
9457 if (info->altivec_size)
9458 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
9459
9460 if (info->vrsave_size)
9461 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
9462
9463 if (info->altivec_padding_size)
9464 fprintf (stderr, "\taltivec_padding_size= %5d\n",
9465 info->altivec_padding_size);
9466
a3170dc6
AH
9467 if (info->spe_padding_size)
9468 fprintf (stderr, "\tspe_padding_size = %5d\n",
9469 info->spe_padding_size);
9470
a4f6c312 9471 if (info->lr_size)
ed947a96 9472 fprintf (stderr, "\tlr_size = %5d\n", info->lr_size);
b6c9286a 9473
4697a36c
MM
9474 if (info->cr_size)
9475 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
9476
a4f6c312 9477 if (info->toc_size)
b6c9286a
MM
9478 fprintf (stderr, "\ttoc_size = %5d\n", info->toc_size);
9479
4697a36c
MM
9480 if (info->save_size)
9481 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
9482
9483 if (info->reg_size != 4)
9484 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
9485
9486 fprintf (stderr, "\n");
9878760c 9487}
71f123ca
FS
9488
9489rtx
9490rs6000_return_addr (count, frame)
9491 int count;
9492 rtx frame;
9493{
a4f6c312
SS
9494 /* Currently we don't optimize very well between prolog and body
9495 code and for PIC code the code can be actually quite bad, so
9496 don't try to be too clever here. */
f585a356 9497 if (count != 0 || flag_pic != 0)
71f123ca
FS
9498 {
9499 cfun->machine->ra_needs_full_frame = 1;
8ac61af7
RK
9500
9501 return
9502 gen_rtx_MEM
9503 (Pmode,
9504 memory_address
9505 (Pmode,
9506 plus_constant (copy_to_reg
9507 (gen_rtx_MEM (Pmode,
9508 memory_address (Pmode, frame))),
9509 RETURN_ADDRESS_OFFSET)));
71f123ca
FS
9510 }
9511
9e2f7ec7 9512 return get_hard_reg_initial_val (Pmode, LINK_REGISTER_REGNUM);
71f123ca
FS
9513}
9514
5e1bf043
DJ
9515/* Say whether a function is a candidate for sibcall handling or not.
9516 We do not allow indirect calls to be optimized into sibling calls.
9517 Also, we can't do it if there are any vector parameters; there's
9518 nowhere to put the VRsave code so it works; note that functions with
9519 vector parameters are required to have a prototype, so the argument
9520 type info must be available here. (The tail recursion case can work
9521 with vector parameters, but there's no way to distinguish here.) */
4977bab6
ZW
9522static bool
9523rs6000_function_ok_for_sibcall (decl, exp)
9524 tree decl;
9525 tree exp ATTRIBUTE_UNUSED;
5e1bf043
DJ
9526{
9527 tree type;
4977bab6 9528 if (decl)
5e1bf043
DJ
9529 {
9530 if (TARGET_ALTIVEC_VRSAVE)
9531 {
4977bab6 9532 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
5e1bf043
DJ
9533 type; type = TREE_CHAIN (type))
9534 {
c15b529f 9535 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
4977bab6 9536 return false;
5e1bf043
DJ
9537 }
9538 }
9539 if (DEFAULT_ABI == ABI_DARWIN
4977bab6 9540 || (*targetm.binds_local_p) (decl))
2bcc50d0 9541 {
4977bab6 9542 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
2bcc50d0
AM
9543
9544 if (!lookup_attribute ("longcall", attr_list)
9545 || lookup_attribute ("shortcall", attr_list))
4977bab6 9546 return true;
2bcc50d0 9547 }
5e1bf043 9548 }
4977bab6 9549 return false;
5e1bf043
DJ
9550}
9551
71f123ca
FS
9552static int
9553rs6000_ra_ever_killed ()
9554{
9555 rtx top;
5e1bf043
DJ
9556 rtx reg;
9557 rtx insn;
71f123ca 9558
3961e8fe
RH
9559 /* Irritatingly, there are two kinds of thunks -- those created with
9560 TARGET_ASM_OUTPUT_MI_THUNK and those with DECL_THUNK_P that go
9561 through the regular part of the compiler. This is a very hacky
9562 way to tell them apart. */
9563 if (current_function_is_thunk && !no_new_pseudos)
71f123ca 9564 return 0;
eb0424da 9565
36f7e964
AH
9566 /* regs_ever_live has LR marked as used if any sibcalls are present,
9567 but this should not force saving and restoring in the
9568 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
9569 clobbers LR, so that is inappropriate. */
9570
5e1bf043
DJ
9571 /* Also, the prologue can generate a store into LR that
9572 doesn't really count, like this:
36f7e964 9573
5e1bf043
DJ
9574 move LR->R0
9575 bcl to set PIC register
9576 move LR->R31
9577 move R0->LR
36f7e964
AH
9578
9579 When we're called from the epilogue, we need to avoid counting
9580 this as a store. */
5e1bf043 9581
71f123ca
FS
9582 push_topmost_sequence ();
9583 top = get_insns ();
9584 pop_topmost_sequence ();
5e1bf043 9585 reg = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
71f123ca 9586
5e1bf043
DJ
9587 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
9588 {
9589 if (INSN_P (insn))
9590 {
9591 if (FIND_REG_INC_NOTE (insn, reg))
9592 return 1;
9593 else if (GET_CODE (insn) == CALL_INSN
c15b529f 9594 && !SIBLING_CALL_P (insn))
5e1bf043 9595 return 1;
36f7e964
AH
9596 else if (set_of (reg, insn) != NULL_RTX
9597 && !prologue_epilogue_contains (insn))
5e1bf043
DJ
9598 return 1;
9599 }
9600 }
9601 return 0;
71f123ca 9602}
4697a36c 9603\f
8cd8f856
GK
9604/* Add a REG_MAYBE_DEAD note to the insn. */
9605static void
9606rs6000_maybe_dead (insn)
9607 rtx insn;
9608{
9609 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,
9610 const0_rtx,
9611 REG_NOTES (insn));
9612}
9613
9ebbca7d 9614/* Emit instructions needed to load the TOC register.
c7ca610e 9615 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
9ebbca7d 9616 a constant pool; or for SVR4 -fpic. */
c7ca610e
RK
9617
9618void
9ebbca7d
GK
9619rs6000_emit_load_toc_table (fromprolog)
9620 int fromprolog;
c7ca610e 9621{
9ebbca7d 9622 rtx dest;
1db02437 9623 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
c7ca610e 9624
20b71b17
AM
9625 if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
9626 {
9627 rtx temp = (fromprolog
9628 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
9629 : gen_reg_rtx (Pmode));
9630 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_pic_si (temp)));
9631 rs6000_maybe_dead (emit_move_insn (dest, temp));
9632 }
9633 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
9634 {
9635 char buf[30];
9636 rtx tempLR = (fromprolog
9637 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
9638 : gen_reg_rtx (Pmode));
9639 rtx temp0 = (fromprolog
9640 ? gen_rtx_REG (Pmode, 0)
9641 : gen_reg_rtx (Pmode));
9642 rtx symF;
9643
9644 /* possibly create the toc section */
9645 if (! toc_initialized)
38c1f2d7 9646 {
20b71b17
AM
9647 toc_section ();
9648 function_section (current_function_decl);
38c1f2d7 9649 }
9ebbca7d 9650
20b71b17
AM
9651 if (fromprolog)
9652 {
9653 rtx symL;
38c1f2d7 9654
20b71b17
AM
9655 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
9656 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9ebbca7d 9657
20b71b17
AM
9658 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
9659 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9660
9661 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1 (tempLR,
9662 symF)));
9663 rs6000_maybe_dead (emit_move_insn (dest, tempLR));
9664 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest,
9665 symL,
9666 symF)));
9ebbca7d
GK
9667 }
9668 else
20b71b17
AM
9669 {
9670 rtx tocsym;
9671 static int reload_toc_labelno = 0;
9672
9673 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
9674
9675 ASM_GENERATE_INTERNAL_LABEL (buf, "LCG", reload_toc_labelno++);
9676 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9677
9678 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1b (tempLR,
9679 symF,
9680 tocsym)));
9681 rs6000_maybe_dead (emit_move_insn (dest, tempLR));
9682 rs6000_maybe_dead (emit_move_insn (temp0,
9683 gen_rtx_MEM (Pmode, dest)));
9684 }
9685 rs6000_maybe_dead (emit_insn (gen_addsi3 (dest, temp0, dest)));
9ebbca7d 9686 }
20b71b17
AM
9687 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
9688 {
9689 /* This is for AIX code running in non-PIC ELF32. */
9690 char buf[30];
9691 rtx realsym;
9692 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
9693 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9694
9695 rs6000_maybe_dead (emit_insn (gen_elf_high (dest, realsym)));
9696 rs6000_maybe_dead (emit_insn (gen_elf_low (dest, dest, realsym)));
9697 }
9698 else if (DEFAULT_ABI == ABI_AIX)
9ebbca7d
GK
9699 {
9700 if (TARGET_32BIT)
20b71b17 9701 rs6000_maybe_dead (emit_insn (gen_load_toc_aix_si (dest)));
9ebbca7d 9702 else
20b71b17 9703 rs6000_maybe_dead (emit_insn (gen_load_toc_aix_di (dest)));
9ebbca7d 9704 }
20b71b17
AM
9705 else
9706 abort ();
9ebbca7d
GK
9707}
9708
9709int
9710get_TOC_alias_set ()
9711{
9712 static int set = -1;
9713 if (set == -1)
9714 set = new_alias_set ();
9715 return set;
9716}
9717
9718/* This retuns nonzero if the current function uses the TOC. This is
9719 determined by the presence of (unspec ... 7), which is generated by
9720 the various load_toc_* patterns. */
a4f6c312 9721
9ebbca7d
GK
9722int
9723uses_TOC ()
9724{
9725 rtx insn;
38c1f2d7 9726
9ebbca7d 9727 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2c3c49de 9728 if (INSN_P (insn))
9ebbca7d
GK
9729 {
9730 rtx pat = PATTERN (insn);
9731 int i;
9732
8cd8f856 9733 if (GET_CODE (pat) == PARALLEL)
9ebbca7d
GK
9734 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
9735 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == UNSPEC
9736 && XINT (XVECEXP (PATTERN (insn), 0, i), 1) == 7)
9737 return 1;
38c1f2d7 9738 }
9ebbca7d
GK
9739 return 0;
9740}
38c1f2d7 9741
9ebbca7d 9742rtx
a4f6c312 9743create_TOC_reference (symbol)
9ebbca7d
GK
9744 rtx symbol;
9745{
a8a05998
ZW
9746 return gen_rtx_PLUS (Pmode,
9747 gen_rtx_REG (Pmode, TOC_REGISTER),
9748 gen_rtx_CONST (Pmode,
9749 gen_rtx_MINUS (Pmode, symbol,
b999aaeb 9750 gen_rtx_SYMBOL_REF (Pmode, toc_label_name))));
9ebbca7d 9751}
38c1f2d7 9752
9ebbca7d
GK
9753#if TARGET_AIX
9754/* __throw will restore its own return address to be the same as the
9755 return address of the function that the throw is being made to.
9756 This is unfortunate, because we want to check the original
9757 return address to see if we need to restore the TOC.
9758 So we have to squirrel it away here.
9759 This is used only in compiling __throw and __rethrow.
c7ca610e 9760
9ebbca7d
GK
9761 Most of this code should be removed by CSE. */
9762static rtx insn_after_throw;
c7ca610e 9763
a4f6c312 9764/* This does the saving... */
9ebbca7d
GK
9765void
9766rs6000_aix_emit_builtin_unwind_init ()
9767{
9768 rtx mem;
9769 rtx stack_top = gen_reg_rtx (Pmode);
9770 rtx opcode_addr = gen_reg_rtx (Pmode);
9771
9772 insn_after_throw = gen_reg_rtx (SImode);
9773
9774 mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
9775 emit_move_insn (stack_top, mem);
9776
9777 mem = gen_rtx_MEM (Pmode,
9778 gen_rtx_PLUS (Pmode, stack_top,
9779 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
9780 emit_move_insn (opcode_addr, mem);
9781 emit_move_insn (insn_after_throw, gen_rtx_MEM (SImode, opcode_addr));
c7ca610e
RK
9782}
9783
a4f6c312
SS
9784/* Emit insns to _restore_ the TOC register, at runtime (specifically
9785 in _eh.o). Only used on AIX.
9ebbca7d
GK
9786
9787 The idea is that on AIX, function calls look like this:
9788 bl somefunction-trampoline
9789 lwz r2,20(sp)
9790
a4f6c312 9791 and later,
9ebbca7d
GK
9792 somefunction-trampoline:
9793 stw r2,20(sp)
9794 ... load function address in the count register ...
9795 bctr
9796 or like this, if the linker determines that this is not a cross-module call
9797 and so the TOC need not be restored:
9798 bl somefunction
9799 nop
9800 or like this, if the compiler could determine that this is not a
9801 cross-module call:
9802 bl somefunction
9803 now, the tricky bit here is that register 2 is saved and restored
9804 by the _linker_, so we can't readily generate debugging information
9805 for it. So we need to go back up the call chain looking at the
9806 insns at return addresses to see which calls saved the TOC register
9807 and so see where it gets restored from.
9808
9809 Oh, and all this gets done in RTL inside the eh_epilogue pattern,
9810 just before the actual epilogue.
9811
9812 On the bright side, this incurs no space or time overhead unless an
9813 exception is thrown, except for the extra code in libgcc.a.
9814
9815 The parameter STACKSIZE is a register containing (at runtime)
9816 the amount to be popped off the stack in addition to the stack frame
9817 of this routine (which will be __throw or __rethrow, and so is
9818 guaranteed to have a stack frame). */
a4f6c312 9819
9ebbca7d
GK
9820void
9821rs6000_emit_eh_toc_restore (stacksize)
9822 rtx stacksize;
9823{
9824 rtx top_of_stack;
9825 rtx bottom_of_stack = gen_reg_rtx (Pmode);
9826 rtx tocompare = gen_reg_rtx (SImode);
9827 rtx opcode = gen_reg_rtx (SImode);
9828 rtx opcode_addr = gen_reg_rtx (Pmode);
9829 rtx mem;
9830 rtx loop_start = gen_label_rtx ();
9831 rtx no_toc_restore_needed = gen_label_rtx ();
9832 rtx loop_exit = gen_label_rtx ();
9833
9834 mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
ba4828e0 9835 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
9836 emit_move_insn (bottom_of_stack, mem);
9837
9838 top_of_stack = expand_binop (Pmode, add_optab,
9839 bottom_of_stack, stacksize,
9840 NULL_RTX, 1, OPTAB_WIDEN);
9841
2496c7bd
LB
9842 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
9843 : 0xE8410028, SImode));
9ebbca7d
GK
9844
9845 if (insn_after_throw == NULL_RTX)
a4f6c312 9846 abort ();
9ebbca7d
GK
9847 emit_move_insn (opcode, insn_after_throw);
9848
6496a589 9849 emit_note (NULL, NOTE_INSN_LOOP_BEG);
9ebbca7d
GK
9850 emit_label (loop_start);
9851
9852 do_compare_rtx_and_jump (opcode, tocompare, NE, 1,
06f4e019 9853 SImode, NULL_RTX, NULL_RTX,
9ebbca7d
GK
9854 no_toc_restore_needed);
9855
9856 mem = gen_rtx_MEM (Pmode,
9857 gen_rtx_PLUS (Pmode, bottom_of_stack,
9858 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
9859 emit_move_insn (gen_rtx_REG (Pmode, 2), mem);
9860
9861 emit_label (no_toc_restore_needed);
9862 do_compare_rtx_and_jump (top_of_stack, bottom_of_stack, EQ, 1,
06f4e019 9863 Pmode, NULL_RTX, NULL_RTX,
9ebbca7d
GK
9864 loop_exit);
9865
9866 mem = gen_rtx_MEM (Pmode, bottom_of_stack);
ba4828e0 9867 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
9868 emit_move_insn (bottom_of_stack, mem);
9869
9870 mem = gen_rtx_MEM (Pmode,
9871 gen_rtx_PLUS (Pmode, bottom_of_stack,
9872 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
9873 emit_move_insn (opcode_addr, mem);
9874 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
9875
6496a589 9876 emit_note (NULL, NOTE_INSN_LOOP_CONT);
9ebbca7d 9877 emit_jump (loop_start);
6496a589 9878 emit_note (NULL, NOTE_INSN_LOOP_END);
9ebbca7d
GK
9879 emit_label (loop_exit);
9880}
9881#endif /* TARGET_AIX */
38c1f2d7 9882\f
ba4828e0
RK
9883/* This ties together stack memory (MEM with an alias set of
9884 rs6000_sr_alias_set) and the change to the stack pointer. */
9885
9ebbca7d
GK
9886static void
9887rs6000_emit_stack_tie ()
9888{
ba4828e0
RK
9889 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
9890
9891 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
9892 emit_insn (gen_stack_tie (mem));
9893}
38c1f2d7 9894
9ebbca7d
GK
9895/* Emit the correct code for allocating stack space, as insns.
9896 If COPY_R12, make sure a copy of the old frame is left in r12.
9897 The generated code may use hard register 0 as a temporary. */
9898
9899static void
9900rs6000_emit_allocate_stack (size, copy_r12)
9901 HOST_WIDE_INT size;
38c1f2d7
MM
9902 int copy_r12;
9903{
9ebbca7d
GK
9904 rtx insn;
9905 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
9906 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
9907 rtx todec = GEN_INT (-size);
a157febd
GK
9908
9909 if (current_function_limit_stack)
9910 {
9911 if (REG_P (stack_limit_rtx)
9912 && REGNO (stack_limit_rtx) > 1
9913 && REGNO (stack_limit_rtx) <= 31)
9914 {
9ebbca7d
GK
9915 emit_insn (Pmode == SImode
9916 ? gen_addsi3 (tmp_reg,
9917 stack_limit_rtx,
9918 GEN_INT (size))
9919 : gen_adddi3 (tmp_reg,
9920 stack_limit_rtx,
9921 GEN_INT (size)));
9922
9923 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
9924 const0_rtx));
a157febd
GK
9925 }
9926 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
9ebbca7d 9927 && TARGET_32BIT
f607bc57 9928 && DEFAULT_ABI == ABI_V4)
a157febd 9929 {
9ebbca7d
GK
9930 rtx toload = gen_rtx_CONST (VOIDmode,
9931 gen_rtx_PLUS (Pmode,
9932 stack_limit_rtx,
9933 GEN_INT (size)));
9934
9935 emit_insn (gen_elf_high (tmp_reg, toload));
9936 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
9937 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
9938 const0_rtx));
a157febd
GK
9939 }
9940 else
9941 warning ("stack limit expression is not supported");
9942 }
9943
9ebbca7d
GK
9944 if (copy_r12 || ! TARGET_UPDATE)
9945 emit_move_insn (gen_rtx_REG (Pmode, 12), stack_reg);
9946
38c1f2d7
MM
9947 if (TARGET_UPDATE)
9948 {
9ebbca7d 9949 if (size > 32767)
38c1f2d7 9950 {
9ebbca7d
GK
9951 /* Need a note here so that try_split doesn't get confused. */
9952 if (get_last_insn() == NULL_RTX)
9953 emit_note (0, NOTE_INSN_DELETED);
9954 insn = emit_move_insn (tmp_reg, todec);
9955 try_split (PATTERN (insn), insn, 0);
9956 todec = tmp_reg;
38c1f2d7 9957 }
9ebbca7d
GK
9958
9959 if (Pmode == SImode)
9960 insn = emit_insn (gen_movsi_update (stack_reg, stack_reg,
9961 todec, stack_reg));
9962 else
9963 insn = emit_insn (gen_movdi_update (stack_reg, stack_reg,
9964 todec, stack_reg));
38c1f2d7
MM
9965 }
9966 else
9967 {
9ebbca7d
GK
9968 if (Pmode == SImode)
9969 insn = emit_insn (gen_addsi3 (stack_reg, stack_reg, todec));
38c1f2d7 9970 else
9ebbca7d
GK
9971 insn = emit_insn (gen_adddi3 (stack_reg, stack_reg, todec));
9972 emit_move_insn (gen_rtx_MEM (Pmode, stack_reg),
9973 gen_rtx_REG (Pmode, 12));
9974 }
9975
9976 RTX_FRAME_RELATED_P (insn) = 1;
9977 REG_NOTES (insn) =
9978 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
9979 gen_rtx_SET (VOIDmode, stack_reg,
9980 gen_rtx_PLUS (Pmode, stack_reg,
9981 GEN_INT (-size))),
9982 REG_NOTES (insn));
9983}
9984
9aa86737
AH
9985/* Add a RTX_FRAME_RELATED note so that dwarf2out_frame_debug_expr
9986 knows that:
9987
9988 (mem (plus (blah) (regXX)))
9989
9990 is really:
9991
9992 (mem (plus (blah) (const VALUE_OF_REGXX))). */
9993
9994static void
9995altivec_frame_fixup (insn, reg, val)
9996 rtx insn, reg;
9997 HOST_WIDE_INT val;
9998{
9999 rtx real;
10000
10001 real = copy_rtx (PATTERN (insn));
10002
10003 real = replace_rtx (real, reg, GEN_INT (val));
10004
10005 RTX_FRAME_RELATED_P (insn) = 1;
10006 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
10007 real,
10008 REG_NOTES (insn));
10009}
10010
a4f6c312
SS
10011/* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
10012 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
10013 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
10014 deduce these equivalences by itself so it wasn't necessary to hold
10015 its hand so much. */
9ebbca7d
GK
10016
10017static void
10018rs6000_frame_related (insn, reg, val, reg2, rreg)
10019 rtx insn;
10020 rtx reg;
10021 HOST_WIDE_INT val;
10022 rtx reg2;
10023 rtx rreg;
10024{
10025 rtx real, temp;
10026
e56c4463
JL
10027 /* copy_rtx will not make unique copies of registers, so we need to
10028 ensure we don't have unwanted sharing here. */
10029 if (reg == reg2)
10030 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
10031
10032 if (reg == rreg)
10033 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
10034
9ebbca7d
GK
10035 real = copy_rtx (PATTERN (insn));
10036
89e7058f
AH
10037 if (reg2 != NULL_RTX)
10038 real = replace_rtx (real, reg2, rreg);
10039
9ebbca7d
GK
10040 real = replace_rtx (real, reg,
10041 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
10042 STACK_POINTER_REGNUM),
10043 GEN_INT (val)));
10044
10045 /* We expect that 'real' is either a SET or a PARALLEL containing
10046 SETs (and possibly other stuff). In a PARALLEL, all the SETs
10047 are important so they all have to be marked RTX_FRAME_RELATED_P. */
10048
10049 if (GET_CODE (real) == SET)
10050 {
10051 rtx set = real;
10052
10053 temp = simplify_rtx (SET_SRC (set));
10054 if (temp)
10055 SET_SRC (set) = temp;
10056 temp = simplify_rtx (SET_DEST (set));
10057 if (temp)
10058 SET_DEST (set) = temp;
10059 if (GET_CODE (SET_DEST (set)) == MEM)
38c1f2d7 10060 {
9ebbca7d
GK
10061 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
10062 if (temp)
10063 XEXP (SET_DEST (set), 0) = temp;
38c1f2d7 10064 }
38c1f2d7 10065 }
9ebbca7d
GK
10066 else if (GET_CODE (real) == PARALLEL)
10067 {
10068 int i;
10069 for (i = 0; i < XVECLEN (real, 0); i++)
10070 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
10071 {
10072 rtx set = XVECEXP (real, 0, i);
10073
10074 temp = simplify_rtx (SET_SRC (set));
10075 if (temp)
10076 SET_SRC (set) = temp;
10077 temp = simplify_rtx (SET_DEST (set));
10078 if (temp)
10079 SET_DEST (set) = temp;
10080 if (GET_CODE (SET_DEST (set)) == MEM)
10081 {
10082 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
10083 if (temp)
10084 XEXP (SET_DEST (set), 0) = temp;
10085 }
10086 RTX_FRAME_RELATED_P (set) = 1;
10087 }
10088 }
10089 else
a4f6c312 10090 abort ();
9ebbca7d 10091
9ebbca7d
GK
10092 RTX_FRAME_RELATED_P (insn) = 1;
10093 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
10094 real,
10095 REG_NOTES (insn));
38c1f2d7
MM
10096}
10097
00b960c7
AH
10098/* Returns an insn that has a vrsave set operation with the
10099 appropriate CLOBBERs. */
10100
10101static rtx
9aa86737 10102generate_set_vrsave (reg, info, epiloguep)
00b960c7
AH
10103 rtx reg;
10104 rs6000_stack_t *info;
9aa86737 10105 int epiloguep;
00b960c7
AH
10106{
10107 int nclobs, i;
10108 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
a004eb82 10109 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
00b960c7 10110
a004eb82
AH
10111 clobs[0]
10112 = gen_rtx_SET (VOIDmode,
10113 vrsave,
10114 gen_rtx_UNSPEC_VOLATILE (SImode,
10115 gen_rtvec (2, reg, vrsave),
10116 30));
00b960c7
AH
10117
10118 nclobs = 1;
10119
9aa86737
AH
10120 /* We need to clobber the registers in the mask so the scheduler
10121 does not move sets to VRSAVE before sets of AltiVec registers.
10122
10123 However, if the function receives nonlocal gotos, reload will set
10124 all call saved registers live. We will end up with:
10125
10126 (set (reg 999) (mem))
10127 (parallel [ (set (reg vrsave) (unspec blah))
10128 (clobber (reg 999))])
10129
10130 The clobber will cause the store into reg 999 to be dead, and
10131 flow will attempt to delete an epilogue insn. In this case, we
10132 need an unspec use/set of the register. */
00b960c7
AH
10133
10134 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
10135 if (info->vrsave_mask != 0 && ALTIVEC_REG_BIT (i) != 0)
9aa86737
AH
10136 {
10137 if (!epiloguep || call_used_regs [i])
10138 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
10139 gen_rtx_REG (V4SImode, i));
10140 else
10141 {
10142 rtx reg = gen_rtx_REG (V4SImode, i);
9aa86737
AH
10143
10144 clobs[nclobs++]
a004eb82
AH
10145 = gen_rtx_SET (VOIDmode,
10146 reg,
10147 gen_rtx_UNSPEC (V4SImode,
10148 gen_rtvec (1, reg), 27));
9aa86737
AH
10149 }
10150 }
00b960c7
AH
10151
10152 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
10153
10154 for (i = 0; i < nclobs; ++i)
10155 XVECEXP (insn, 0, i) = clobs[i];
10156
10157 return insn;
10158}
10159
89e7058f
AH
10160/* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
10161 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
10162
10163static void
10164emit_frame_save (frame_reg, frame_ptr, mode, regno, offset, total_size)
10165 rtx frame_reg;
10166 rtx frame_ptr;
10167 enum machine_mode mode;
10168 unsigned int regno;
10169 int offset;
10170 int total_size;
10171{
10172 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
10173 rtx replacea, replaceb;
10174
10175 int_rtx = GEN_INT (offset);
10176
10177 /* Some cases that need register indexed addressing. */
10178 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
a3170dc6
AH
10179 || (TARGET_SPE_ABI
10180 && SPE_VECTOR_MODE (mode)
10181 && !SPE_CONST_OFFSET_OK (offset)))
89e7058f
AH
10182 {
10183 /* Whomever calls us must make sure r11 is available in the
10184 flow path of instructions in the prologue. */
10185 offset_rtx = gen_rtx_REG (Pmode, 11);
10186 emit_move_insn (offset_rtx, int_rtx);
10187
10188 replacea = offset_rtx;
10189 replaceb = int_rtx;
10190 }
10191 else
10192 {
10193 offset_rtx = int_rtx;
10194 replacea = NULL_RTX;
10195 replaceb = NULL_RTX;
10196 }
10197
10198 reg = gen_rtx_REG (mode, regno);
10199 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
10200 mem = gen_rtx_MEM (mode, addr);
10201 set_mem_alias_set (mem, rs6000_sr_alias_set);
10202
10203 insn = emit_move_insn (mem, reg);
10204
10205 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
10206}
10207
a3170dc6
AH
10208/* Emit an offset memory reference suitable for a frame store, while
10209 converting to a valid addressing mode. */
10210
10211static rtx
10212gen_frame_mem_offset (mode, reg, offset)
10213 enum machine_mode mode;
10214 rtx reg;
10215 int offset;
10216{
10217 rtx int_rtx, offset_rtx;
10218
10219 int_rtx = GEN_INT (offset);
10220
10221 if (TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
10222 {
10223 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
10224 emit_move_insn (offset_rtx, int_rtx);
10225 }
10226 else
10227 offset_rtx = int_rtx;
10228
10229 return gen_rtx_MEM (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
10230}
10231
9ebbca7d
GK
10232/* Emit function prologue as insns. */
10233
9878760c 10234void
83720594 10235rs6000_emit_prologue ()
9878760c 10236{
4697a36c 10237 rs6000_stack_t *info = rs6000_stack_info ();
9ebbca7d
GK
10238 enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
10239 int reg_size = TARGET_POWERPC64 ? 8 : 4;
10240 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
10241 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
10242 rtx frame_reg_rtx = sp_reg_rtx;
10243 rtx cr_save_rtx = NULL;
10244 rtx insn;
10245 int saving_FPRs_inline;
10246 int using_store_multiple;
10247 HOST_WIDE_INT sp_offset = 0;
10248
a3170dc6
AH
10249 if (TARGET_SPE_ABI)
10250 {
10251 reg_mode = V2SImode;
10252 reg_size = 8;
10253 }
10254
9ebbca7d 10255 using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
a3170dc6 10256 && !TARGET_SPE_ABI
9ebbca7d
GK
10257 && info->first_gp_reg_save < 31);
10258 saving_FPRs_inline = (info->first_fp_reg_save == 64
10259 || FP_SAVE_INLINE (info->first_fp_reg_save));
10260
10261 /* For V.4, update stack before we do any saving and set back pointer. */
f607bc57 10262 if (info->push_p && DEFAULT_ABI == ABI_V4)
9ebbca7d
GK
10263 {
10264 if (info->total_size < 32767)
10265 sp_offset = info->total_size;
10266 else
10267 frame_reg_rtx = frame_ptr_rtx;
10268 rs6000_emit_allocate_stack (info->total_size,
10269 (frame_reg_rtx != sp_reg_rtx
10270 && (info->cr_save_p
10271 || info->lr_save_p
10272 || info->first_fp_reg_save < 64
10273 || info->first_gp_reg_save < 32
10274 )));
10275 if (frame_reg_rtx != sp_reg_rtx)
10276 rs6000_emit_stack_tie ();
10277 }
10278
9aa86737
AH
10279 /* Save AltiVec registers if needed. */
10280 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
10281 {
10282 int i;
10283
10284 /* There should be a non inline version of this, for when we
10285 are saving lots of vector registers. */
10286 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
10287 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
10288 {
10289 rtx areg, savereg, mem;
10290 int offset;
10291
10292 offset = info->altivec_save_offset + sp_offset
10293 + 16 * (i - info->first_altivec_reg_save);
10294
10295 savereg = gen_rtx_REG (V4SImode, i);
10296
10297 areg = gen_rtx_REG (Pmode, 0);
10298 emit_move_insn (areg, GEN_INT (offset));
10299
10300 /* AltiVec addressing mode is [reg+reg]. */
10301 mem = gen_rtx_MEM (V4SImode,
10302 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
10303
10304 set_mem_alias_set (mem, rs6000_sr_alias_set);
10305
10306 insn = emit_move_insn (mem, savereg);
10307
10308 altivec_frame_fixup (insn, areg, offset);
10309 }
10310 }
10311
10312 /* VRSAVE is a bit vector representing which AltiVec registers
10313 are used. The OS uses this to determine which vector
10314 registers to save on a context switch. We need to save
10315 VRSAVE on the stack frame, add whatever AltiVec registers we
10316 used in this function, and do the corresponding magic in the
10317 epilogue. */
10318
10319 if (TARGET_ALTIVEC && info->vrsave_mask != 0)
10320 {
a004eb82 10321 rtx reg, mem, vrsave;
9aa86737
AH
10322 int offset;
10323
10324 /* Get VRSAVE onto a GPR. */
10325 reg = gen_rtx_REG (SImode, 12);
a004eb82 10326 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
b188f760
AH
10327 if (TARGET_MACHO)
10328 emit_insn (gen_get_vrsave_internal (reg));
10329 else
10330 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
9aa86737
AH
10331
10332 /* Save VRSAVE. */
10333 offset = info->vrsave_save_offset + sp_offset;
10334 mem
10335 = gen_rtx_MEM (SImode,
10336 gen_rtx_PLUS (Pmode, frame_reg_rtx, GEN_INT (offset)));
10337 set_mem_alias_set (mem, rs6000_sr_alias_set);
10338 insn = emit_move_insn (mem, reg);
10339
10340 /* Include the registers in the mask. */
10341 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
10342
10343 insn = emit_insn (generate_set_vrsave (reg, info, 0));
10344 }
10345
9ebbca7d
GK
10346 /* If we use the link register, get it into r0. */
10347 if (info->lr_save_p)
71f123ca 10348 emit_move_insn (gen_rtx_REG (Pmode, 0),
9ebbca7d
GK
10349 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10350
10351 /* If we need to save CR, put it into r12. */
10352 if (info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
10353 {
10354 cr_save_rtx = gen_rtx_REG (SImode, 12);
10355 emit_insn (gen_movesi_from_cr (cr_save_rtx));
10356 }
10357
a4f6c312
SS
10358 /* Do any required saving of fpr's. If only one or two to save, do
10359 it ourselves. Otherwise, call function. */
9ebbca7d
GK
10360 if (saving_FPRs_inline)
10361 {
10362 int i;
10363 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10364 if ((regs_ever_live[info->first_fp_reg_save+i]
10365 && ! call_used_regs[info->first_fp_reg_save+i]))
89e7058f
AH
10366 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, DFmode,
10367 info->first_fp_reg_save + i,
10368 info->fp_save_offset + sp_offset + 8 * i,
10369 info->total_size);
9ebbca7d
GK
10370 }
10371 else if (info->first_fp_reg_save != 64)
10372 {
10373 int i;
10374 char rname[30];
520a57c8 10375 const char *alloc_rname;
9ebbca7d
GK
10376 rtvec p;
10377 p = rtvec_alloc (2 + 64 - info->first_fp_reg_save);
10378
10379 RTVEC_ELT (p, 0) = gen_rtx_CLOBBER (VOIDmode,
10380 gen_rtx_REG (Pmode,
10381 LINK_REGISTER_REGNUM));
10382 sprintf (rname, "%s%d%s", SAVE_FP_PREFIX,
10383 info->first_fp_reg_save - 32, SAVE_FP_SUFFIX);
a8a05998 10384 alloc_rname = ggc_strdup (rname);
9ebbca7d
GK
10385 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
10386 gen_rtx_SYMBOL_REF (Pmode,
10387 alloc_rname));
10388 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10389 {
10390 rtx addr, reg, mem;
10391 reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
10392 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10393 GEN_INT (info->fp_save_offset
10394 + sp_offset + 8*i));
10395 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 10396 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10397
10398 RTVEC_ELT (p, i + 2) = gen_rtx_SET (VOIDmode, mem, reg);
10399 }
10400 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
10401 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10402 NULL_RTX, NULL_RTX);
10403 }
b6c9286a 10404
9ebbca7d
GK
10405 /* Save GPRs. This is done as a PARALLEL if we are using
10406 the store-multiple instructions. */
10407 if (using_store_multiple)
b6c9286a 10408 {
308c142a 10409 rtvec p;
9ebbca7d
GK
10410 int i;
10411 p = rtvec_alloc (32 - info->first_gp_reg_save);
9ebbca7d
GK
10412 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
10413 {
10414 rtx addr, reg, mem;
10415 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
10416 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10417 GEN_INT (info->gp_save_offset
10418 + sp_offset
10419 + reg_size * i));
10420 mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0 10421 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10422
10423 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
10424 }
10425 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
10426 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10427 NULL_RTX, NULL_RTX);
b6c9286a
MM
10428 }
10429 else
10430 {
9ebbca7d
GK
10431 int i;
10432 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
10433 if ((regs_ever_live[info->first_gp_reg_save+i]
10434 && ! call_used_regs[info->first_gp_reg_save+i])
1db02437 10435 || (i+info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
f607bc57
ZW
10436 && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10437 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
a3170dc6
AH
10438 {
10439 rtx addr, reg, mem;
10440 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
10441
10442 if (TARGET_SPE_ABI)
10443 {
10444 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
10445 rtx b;
10446
10447 if (!SPE_CONST_OFFSET_OK (offset))
10448 {
10449 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
10450 emit_move_insn (b, GEN_INT (offset));
10451 }
10452 else
10453 b = GEN_INT (offset);
10454
10455 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
10456 mem = gen_rtx_MEM (V2SImode, addr);
10457 set_mem_alias_set (mem, rs6000_sr_alias_set);
10458 insn = emit_move_insn (mem, reg);
10459
10460 if (GET_CODE (b) == CONST_INT)
10461 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10462 NULL_RTX, NULL_RTX);
10463 else
10464 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10465 b, GEN_INT (offset));
10466 }
10467 else
10468 {
10469 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10470 GEN_INT (info->gp_save_offset
10471 + sp_offset
10472 + reg_size * i));
10473 mem = gen_rtx_MEM (reg_mode, addr);
10474 set_mem_alias_set (mem, rs6000_sr_alias_set);
10475
10476 insn = emit_move_insn (mem, reg);
10477 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10478 NULL_RTX, NULL_RTX);
10479 }
10480 }
9ebbca7d
GK
10481 }
10482
83720594
RH
10483 /* ??? There's no need to emit actual instructions here, but it's the
10484 easiest way to get the frame unwind information emitted. */
10485 if (current_function_calls_eh_return)
10486 {
78e1b90d
DE
10487 unsigned int i, regno;
10488
83720594
RH
10489 for (i = 0; ; ++i)
10490 {
83720594
RH
10491 regno = EH_RETURN_DATA_REGNO (i);
10492 if (regno == INVALID_REGNUM)
10493 break;
10494
89e7058f
AH
10495 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
10496 info->ehrd_offset + sp_offset
10497 + reg_size * (int) i,
10498 info->total_size);
83720594
RH
10499 }
10500 }
10501
9ebbca7d
GK
10502 /* Save lr if we used it. */
10503 if (info->lr_save_p)
10504 {
10505 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10506 GEN_INT (info->lr_save_offset + sp_offset));
10507 rtx reg = gen_rtx_REG (Pmode, 0);
10508 rtx mem = gen_rtx_MEM (Pmode, addr);
10509 /* This should not be of rs6000_sr_alias_set, because of
10510 __builtin_return_address. */
10511
10512 insn = emit_move_insn (mem, reg);
10513 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10514 reg, gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10515 }
10516
10517 /* Save CR if we use any that must be preserved. */
10518 if (info->cr_save_p)
10519 {
10520 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10521 GEN_INT (info->cr_save_offset + sp_offset));
10522 rtx mem = gen_rtx_MEM (SImode, addr);
ba4828e0
RK
10523
10524 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10525
10526 /* If r12 was used to hold the original sp, copy cr into r0 now
10527 that it's free. */
10528 if (REGNO (frame_reg_rtx) == 12)
10529 {
10530 cr_save_rtx = gen_rtx_REG (SImode, 0);
10531 emit_insn (gen_movesi_from_cr (cr_save_rtx));
10532 }
10533 insn = emit_move_insn (mem, cr_save_rtx);
10534
10535 /* Now, there's no way that dwarf2out_frame_debug_expr is going
10536 to understand '(unspec:SI [(reg:CC 68) ...] 19)'. But that's
10537 OK. All we have to do is specify that _one_ condition code
10538 register is saved in this stack slot. The thrower's epilogue
a1dc9455
FS
10539 will then restore all the call-saved registers.
10540 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
9ebbca7d 10541 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
a1dc9455 10542 cr_save_rtx, gen_rtx_REG (SImode, CR2_REGNO));
9ebbca7d
GK
10543 }
10544
10545 /* Update stack and set back pointer unless this is V.4,
10546 for which it was done previously. */
f607bc57 10547 if (info->push_p && DEFAULT_ABI != ABI_V4)
9ebbca7d
GK
10548 rs6000_emit_allocate_stack (info->total_size, FALSE);
10549
10550 /* Set frame pointer, if needed. */
10551 if (frame_pointer_needed)
10552 {
a3170dc6 10553 insn = emit_move_insn (gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM),
9ebbca7d
GK
10554 sp_reg_rtx);
10555 RTX_FRAME_RELATED_P (insn) = 1;
b6c9286a 10556 }
9878760c 10557
1db02437 10558 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
9ebbca7d 10559 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
f607bc57 10560 || (DEFAULT_ABI == ABI_V4 && flag_pic == 1
1db02437 10561 && regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM]))
9ebbca7d
GK
10562 {
10563 /* If emit_load_toc_table will use the link register, we need to save
10564 it. We use R11 for this purpose because emit_load_toc_table
10565 can use register 0. This allows us to use a plain 'blr' to return
10566 from the procedure more often. */
d5fa86ba
GK
10567 int save_LR_around_toc_setup = (TARGET_ELF && flag_pic != 0
10568 && ! info->lr_save_p
10569 && EXIT_BLOCK_PTR->pred != NULL);
9ebbca7d
GK
10570 if (save_LR_around_toc_setup)
10571 emit_move_insn (gen_rtx_REG (Pmode, 11),
10572 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10573
10574 rs6000_emit_load_toc_table (TRUE);
10575
10576 if (save_LR_around_toc_setup)
10577 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
10578 gen_rtx_REG (Pmode, 11));
10579 }
ee890fe2 10580
fcce224d 10581#if TARGET_MACHO
ee890fe2
SS
10582 if (DEFAULT_ABI == ABI_DARWIN
10583 && flag_pic && current_function_uses_pic_offset_table)
10584 {
10585 rtx dest = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
f51eee6a
GK
10586 char *picbase = machopic_function_base_name ();
10587 rtx src = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (picbase, -1));
ee890fe2 10588
f51eee6a 10589 rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (dest, src)));
ee890fe2
SS
10590
10591 rs6000_maybe_dead (
1db02437 10592 emit_move_insn (gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM),
ee890fe2
SS
10593 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)));
10594 }
fcce224d 10595#endif
9ebbca7d
GK
10596}
10597
9ebbca7d 10598/* Write function prologue. */
a4f6c312 10599
08c148a8
NB
10600static void
10601rs6000_output_function_prologue (file, size)
9ebbca7d 10602 FILE *file;
08c148a8 10603 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
9ebbca7d
GK
10604{
10605 rs6000_stack_t *info = rs6000_stack_info ();
10606
4697a36c
MM
10607 if (TARGET_DEBUG_STACK)
10608 debug_stack_info (info);
9878760c 10609
a4f6c312
SS
10610 /* Write .extern for any function we will call to save and restore
10611 fp values. */
10612 if (info->first_fp_reg_save < 64
10613 && !FP_SAVE_INLINE (info->first_fp_reg_save))
4d30c363 10614 fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
4697a36c 10615 SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX,
a4f6c312
SS
10616 RESTORE_FP_PREFIX, info->first_fp_reg_save - 32,
10617 RESTORE_FP_SUFFIX);
9878760c 10618
c764f757
RK
10619 /* Write .extern for AIX common mode routines, if needed. */
10620 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
10621 {
f6709c70
JW
10622 fputs ("\t.extern __mulh\n", file);
10623 fputs ("\t.extern __mull\n", file);
10624 fputs ("\t.extern __divss\n", file);
10625 fputs ("\t.extern __divus\n", file);
10626 fputs ("\t.extern __quoss\n", file);
10627 fputs ("\t.extern __quous\n", file);
c764f757
RK
10628 common_mode_defined = 1;
10629 }
9878760c 10630
9ebbca7d 10631 if (! HAVE_prologue)
979721f8 10632 {
9ebbca7d 10633 start_sequence ();
9dda4cc8 10634
a4f6c312
SS
10635 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
10636 the "toplevel" insn chain. */
9ebbca7d
GK
10637 emit_note (0, NOTE_INSN_DELETED);
10638 rs6000_emit_prologue ();
10639 emit_note (0, NOTE_INSN_DELETED);
178c3eff
DJ
10640
10641 /* Expand INSN_ADDRESSES so final() doesn't crash. */
10642 {
10643 rtx insn;
10644 unsigned addr = 0;
10645 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
10646 {
10647 INSN_ADDRESSES_NEW (insn, addr);
10648 addr += 4;
10649 }
10650 }
9dda4cc8 10651
9ebbca7d 10652 if (TARGET_DEBUG_STACK)
a4f6c312
SS
10653 debug_rtx_list (get_insns (), 100);
10654 final (get_insns (), file, FALSE, FALSE);
9ebbca7d 10655 end_sequence ();
979721f8
MM
10656 }
10657
9ebbca7d
GK
10658 rs6000_pic_labelno++;
10659}
10660
10661/* Emit function epilogue as insns.
9878760c 10662
9ebbca7d
GK
10663 At present, dwarf2out_frame_debug_expr doesn't understand
10664 register restores, so we don't bother setting RTX_FRAME_RELATED_P
10665 anywhere in the epilogue. Most of the insns below would in any case
10666 need special notes to explain where r11 is in relation to the stack. */
9878760c 10667
9ebbca7d 10668void
83720594 10669rs6000_emit_epilogue (sibcall)
9ebbca7d
GK
10670 int sibcall;
10671{
10672 rs6000_stack_t *info;
10673 int restoring_FPRs_inline;
10674 int using_load_multiple;
10675 int using_mfcr_multiple;
10676 int use_backchain_to_restore_sp;
10677 int sp_offset = 0;
10678 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
10679 rtx frame_reg_rtx = sp_reg_rtx;
10680 enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
10681 int reg_size = TARGET_POWERPC64 ? 8 : 4;
10682 int i;
10683
a3170dc6
AH
10684 if (TARGET_SPE_ABI)
10685 {
10686 reg_mode = V2SImode;
10687 reg_size = 8;
10688 }
10689
9ebbca7d
GK
10690 info = rs6000_stack_info ();
10691 using_load_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
a3170dc6 10692 && !TARGET_SPE_ABI
9ebbca7d
GK
10693 && info->first_gp_reg_save < 31);
10694 restoring_FPRs_inline = (sibcall
83720594 10695 || current_function_calls_eh_return
9ebbca7d
GK
10696 || info->first_fp_reg_save == 64
10697 || FP_SAVE_INLINE (info->first_fp_reg_save));
10698 use_backchain_to_restore_sp = (frame_pointer_needed
10699 || current_function_calls_alloca
10700 || info->total_size > 32767);
10701 using_mfcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
10702 || rs6000_cpu == PROCESSOR_PPC603
10703 || rs6000_cpu == PROCESSOR_PPC750
10704 || optimize_size);
10705
10706 /* If we have a frame pointer, a call to alloca, or a large stack
10707 frame, restore the old stack pointer using the backchain. Otherwise,
10708 we know what size to update it with. */
10709 if (use_backchain_to_restore_sp)
bacbde18 10710 {
9ebbca7d
GK
10711 /* Under V.4, don't reset the stack pointer until after we're done
10712 loading the saved registers. */
f607bc57 10713 if (DEFAULT_ABI == ABI_V4)
9ebbca7d 10714 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
4697a36c 10715
9ebbca7d
GK
10716 emit_move_insn (frame_reg_rtx,
10717 gen_rtx_MEM (Pmode, sp_reg_rtx));
10718
bacbde18 10719 }
9ebbca7d 10720 else if (info->push_p)
85638c0d 10721 {
f607bc57 10722 if (DEFAULT_ABI == ABI_V4)
9ebbca7d
GK
10723 sp_offset = info->total_size;
10724 else
10725 {
10726 emit_insn (TARGET_32BIT
10727 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
10728 GEN_INT (info->total_size))
10729 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
10730 GEN_INT (info->total_size)));
10731 }
85638c0d 10732 }
9ebbca7d 10733
9aa86737
AH
10734 /* Restore AltiVec registers if needed. */
10735 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
10736 {
10737 int i;
10738
10739 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
10740 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
10741 {
10742 rtx addr, areg, mem;
10743
10744 areg = gen_rtx_REG (Pmode, 0);
10745 emit_move_insn
10746 (areg, GEN_INT (info->altivec_save_offset
10747 + sp_offset
10748 + 16 * (i - info->first_altivec_reg_save)));
10749
10750 /* AltiVec addressing mode is [reg+reg]. */
10751 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
10752 mem = gen_rtx_MEM (V4SImode, addr);
10753 set_mem_alias_set (mem, rs6000_sr_alias_set);
10754
10755 emit_move_insn (gen_rtx_REG (V4SImode, i), mem);
10756 }
10757 }
10758
10759 /* Restore VRSAVE if needed. */
10760 if (TARGET_ALTIVEC_ABI && info->vrsave_mask != 0)
10761 {
10762 rtx addr, mem, reg;
10763
10764 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10765 GEN_INT (info->vrsave_save_offset + sp_offset));
10766 mem = gen_rtx_MEM (SImode, addr);
10767 set_mem_alias_set (mem, rs6000_sr_alias_set);
10768 reg = gen_rtx_REG (SImode, 12);
10769 emit_move_insn (reg, mem);
10770
10771 emit_insn (generate_set_vrsave (reg, info, 1));
10772 }
10773
9ebbca7d
GK
10774 /* Get the old lr if we saved it. */
10775 if (info->lr_save_p)
b6c9286a 10776 {
a3170dc6
AH
10777 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
10778 info->lr_save_offset + sp_offset);
ba4828e0
RK
10779
10780 set_mem_alias_set (mem, rs6000_sr_alias_set);
b6c9286a 10781
9ebbca7d 10782 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
b6c9286a 10783 }
9ebbca7d
GK
10784
10785 /* Get the old cr if we saved it. */
10786 if (info->cr_save_p)
10787 {
10788 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10789 GEN_INT (info->cr_save_offset + sp_offset));
10790 rtx mem = gen_rtx_MEM (SImode, addr);
ba4828e0
RK
10791
10792 set_mem_alias_set (mem, rs6000_sr_alias_set);
b6c9286a 10793
9ebbca7d
GK
10794 emit_move_insn (gen_rtx_REG (SImode, 12), mem);
10795 }
10796
10797 /* Set LR here to try to overlap restores below. */
4697a36c 10798 if (info->lr_save_p)
9ebbca7d
GK
10799 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
10800 gen_rtx_REG (Pmode, 0));
10801
83720594
RH
10802 /* Load exception handler data registers, if needed. */
10803 if (current_function_calls_eh_return)
10804 {
78e1b90d
DE
10805 unsigned int i, regno;
10806
83720594
RH
10807 for (i = 0; ; ++i)
10808 {
a3170dc6 10809 rtx mem;
83720594
RH
10810
10811 regno = EH_RETURN_DATA_REGNO (i);
10812 if (regno == INVALID_REGNUM)
10813 break;
10814
a3170dc6
AH
10815 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
10816 info->ehrd_offset + sp_offset
10817 + reg_size * (int) i);
ba4828e0 10818 set_mem_alias_set (mem, rs6000_sr_alias_set);
83720594
RH
10819
10820 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
10821 }
10822 }
9ebbca7d
GK
10823
10824 /* Restore GPRs. This is done as a PARALLEL if we are using
10825 the load-multiple instructions. */
10826 if (using_load_multiple)
979721f8 10827 {
9ebbca7d
GK
10828 rtvec p;
10829 p = rtvec_alloc (32 - info->first_gp_reg_save);
10830 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
979721f8 10831 {
9ebbca7d
GK
10832 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10833 GEN_INT (info->gp_save_offset
10834 + sp_offset
10835 + reg_size * i));
10836 rtx mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0
RK
10837
10838 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10839
10840 RTVEC_ELT (p, i) =
10841 gen_rtx_SET (VOIDmode,
10842 gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
10843 mem);
979721f8 10844 }
9ebbca7d 10845 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
979721f8 10846 }
9ebbca7d
GK
10847 else
10848 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
10849 if ((regs_ever_live[info->first_gp_reg_save+i]
10850 && ! call_used_regs[info->first_gp_reg_save+i])
1db02437 10851 || (i+info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
f607bc57
ZW
10852 && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10853 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
9ebbca7d
GK
10854 {
10855 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10856 GEN_INT (info->gp_save_offset
10857 + sp_offset
10858 + reg_size * i));
10859 rtx mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0 10860
a3170dc6
AH
10861 /* Restore 64-bit quantities for SPE. */
10862 if (TARGET_SPE_ABI)
10863 {
10864 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
10865 rtx b;
10866
10867 if (!SPE_CONST_OFFSET_OK (offset))
10868 {
10869 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
10870 emit_move_insn (b, GEN_INT (offset));
10871 }
10872 else
10873 b = GEN_INT (offset);
10874
10875 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
10876 mem = gen_rtx_MEM (V2SImode, addr);
10877 }
10878
ba4828e0 10879 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10880
10881 emit_move_insn (gen_rtx_REG (reg_mode,
a3170dc6 10882 info->first_gp_reg_save + i), mem);
9ebbca7d 10883 }
9878760c 10884
9ebbca7d
GK
10885 /* Restore fpr's if we need to do it without calling a function. */
10886 if (restoring_FPRs_inline)
10887 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10888 if ((regs_ever_live[info->first_fp_reg_save+i]
10889 && ! call_used_regs[info->first_fp_reg_save+i]))
10890 {
10891 rtx addr, mem;
10892 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10893 GEN_INT (info->fp_save_offset
10894 + sp_offset
a4f6c312 10895 + 8 * i));
9ebbca7d 10896 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 10897 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10898
10899 emit_move_insn (gen_rtx_REG (DFmode,
10900 info->first_fp_reg_save + i),
10901 mem);
10902 }
8d30c4ee 10903
9ebbca7d
GK
10904 /* If we saved cr, restore it here. Just those that were used. */
10905 if (info->cr_save_p)
979721f8 10906 {
9ebbca7d 10907 rtx r12_rtx = gen_rtx_REG (SImode, 12);
e35b9579 10908 int count = 0;
9ebbca7d
GK
10909
10910 if (using_mfcr_multiple)
979721f8 10911 {
9ebbca7d
GK
10912 for (i = 0; i < 8; i++)
10913 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
e35b9579 10914 count++;
9ebbca7d 10915 if (count == 0)
e35b9579
GK
10916 abort ();
10917 }
10918
10919 if (using_mfcr_multiple && count > 1)
10920 {
10921 rtvec p;
10922 int ndx;
9ebbca7d 10923
e35b9579 10924 p = rtvec_alloc (count);
9ebbca7d 10925
e35b9579 10926 ndx = 0;
9ebbca7d
GK
10927 for (i = 0; i < 8; i++)
10928 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
10929 {
10930 rtvec r = rtvec_alloc (2);
10931 RTVEC_ELT (r, 0) = r12_rtx;
10932 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
e35b9579 10933 RTVEC_ELT (p, ndx) =
9ebbca7d
GK
10934 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
10935 gen_rtx_UNSPEC (CCmode, r, 20));
e35b9579 10936 ndx++;
9ebbca7d
GK
10937 }
10938 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
e35b9579
GK
10939 if (ndx != count)
10940 abort ();
979721f8
MM
10941 }
10942 else
9ebbca7d
GK
10943 for (i = 0; i < 8; i++)
10944 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
979721f8 10945 {
9ebbca7d
GK
10946 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
10947 CR0_REGNO+i),
10948 r12_rtx));
979721f8 10949 }
979721f8
MM
10950 }
10951
9ebbca7d
GK
10952 /* If this is V.4, unwind the stack pointer after all of the loads
10953 have been done. We need to emit a block here so that sched
10954 doesn't decide to move the sp change before the register restores
10955 (which may not have any obvious dependency on the stack). This
10956 doesn't hurt performance, because there is no scheduling that can
10957 be done after this point. */
f607bc57 10958 if (DEFAULT_ABI == ABI_V4)
b6c9286a 10959 {
9ebbca7d
GK
10960 if (frame_reg_rtx != sp_reg_rtx)
10961 rs6000_emit_stack_tie ();
b6c9286a 10962
9ebbca7d 10963 if (use_backchain_to_restore_sp)
b6c9286a 10964 {
9ebbca7d 10965 emit_move_insn (sp_reg_rtx, frame_reg_rtx);
b6c9286a 10966 }
9ebbca7d 10967 else if (sp_offset != 0)
13f1623b 10968 {
9ebbca7d
GK
10969 emit_insn (Pmode == SImode
10970 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
10971 GEN_INT (sp_offset))
10972 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
10973 GEN_INT (sp_offset)));
13f1623b 10974 }
9ebbca7d 10975 }
b6c9286a 10976
83720594
RH
10977 if (current_function_calls_eh_return)
10978 {
10979 rtx sa = EH_RETURN_STACKADJ_RTX;
10980 emit_insn (Pmode == SImode
10981 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, sa)
10982 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx, sa));
10983 }
10984
9ebbca7d
GK
10985 if (!sibcall)
10986 {
10987 rtvec p;
10988 if (! restoring_FPRs_inline)
10989 p = rtvec_alloc (3 + 64 - info->first_fp_reg_save);
10990 else
10991 p = rtvec_alloc (2);
b6c9286a 10992
e35b9579
GK
10993 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
10994 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
9ebbca7d
GK
10995 gen_rtx_REG (Pmode,
10996 LINK_REGISTER_REGNUM));
9ebbca7d
GK
10997
10998 /* If we have to restore more than two FP registers, branch to the
10999 restore function. It will return to our caller. */
11000 if (! restoring_FPRs_inline)
11001 {
11002 int i;
11003 char rname[30];
520a57c8 11004 const char *alloc_rname;
979721f8 11005
9ebbca7d
GK
11006 sprintf (rname, "%s%d%s", RESTORE_FP_PREFIX,
11007 info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
a8a05998 11008 alloc_rname = ggc_strdup (rname);
9ebbca7d
GK
11009 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode,
11010 gen_rtx_SYMBOL_REF (Pmode,
11011 alloc_rname));
b6c9286a 11012
9ebbca7d
GK
11013 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
11014 {
11015 rtx addr, mem;
11016 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
11017 GEN_INT (info->fp_save_offset + 8*i));
11018 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 11019 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
11020
11021 RTVEC_ELT (p, i+3) =
11022 gen_rtx_SET (VOIDmode,
11023 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
11024 mem);
b6c9286a
MM
11025 }
11026 }
9ebbca7d
GK
11027
11028 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
3daf36a4 11029 }
9878760c
RK
11030}
11031
11032/* Write function epilogue. */
11033
08c148a8
NB
11034static void
11035rs6000_output_function_epilogue (file, size)
9878760c 11036 FILE *file;
08c148a8 11037 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
9878760c 11038{
4697a36c 11039 rs6000_stack_t *info = rs6000_stack_info ();
9878760c 11040
9ebbca7d 11041 if (! HAVE_epilogue)
9878760c 11042 {
9ebbca7d
GK
11043 rtx insn = get_last_insn ();
11044 /* If the last insn was a BARRIER, we don't have to write anything except
11045 the trace table. */
11046 if (GET_CODE (insn) == NOTE)
11047 insn = prev_nonnote_insn (insn);
11048 if (insn == 0 || GET_CODE (insn) != BARRIER)
4697a36c 11049 {
9ebbca7d
GK
11050 /* This is slightly ugly, but at least we don't have two
11051 copies of the epilogue-emitting code. */
11052 start_sequence ();
11053
11054 /* A NOTE_INSN_DELETED is supposed to be at the start
11055 and end of the "toplevel" insn chain. */
11056 emit_note (0, NOTE_INSN_DELETED);
11057 rs6000_emit_epilogue (FALSE);
11058 emit_note (0, NOTE_INSN_DELETED);
11059
178c3eff
DJ
11060 /* Expand INSN_ADDRESSES so final() doesn't crash. */
11061 {
11062 rtx insn;
11063 unsigned addr = 0;
11064 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
11065 {
11066 INSN_ADDRESSES_NEW (insn, addr);
11067 addr += 4;
11068 }
11069 }
11070
9ebbca7d 11071 if (TARGET_DEBUG_STACK)
a4f6c312
SS
11072 debug_rtx_list (get_insns (), 100);
11073 final (get_insns (), file, FALSE, FALSE);
9ebbca7d 11074 end_sequence ();
4697a36c 11075 }
9878760c 11076 }
b4ac57ab 11077
9b30bae2 11078 /* Output a traceback table here. See /usr/include/sys/debug.h for info
314fc5a9
ILT
11079 on its format.
11080
11081 We don't output a traceback table if -finhibit-size-directive was
11082 used. The documentation for -finhibit-size-directive reads
11083 ``don't output a @code{.size} assembler directive, or anything
11084 else that would cause trouble if the function is split in the
11085 middle, and the two halves are placed at locations far apart in
11086 memory.'' The traceback table has this property, since it
11087 includes the offset from the start of the function to the
4d30c363
MM
11088 traceback table itself.
11089
11090 System V.4 Powerpc's (and the embedded ABI derived from it) use a
b6c9286a 11091 different traceback table. */
57ac7be9
AM
11092 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
11093 && rs6000_traceback != traceback_none)
9b30bae2 11094 {
69c75916 11095 const char *fname = NULL;
3ac88239 11096 const char *language_string = lang_hooks.name;
6041bf2f 11097 int fixed_parms = 0, float_parms = 0, parm_info = 0;
314fc5a9 11098 int i;
57ac7be9
AM
11099 int optional_tbtab;
11100
11101 if (rs6000_traceback == traceback_full)
11102 optional_tbtab = 1;
11103 else if (rs6000_traceback == traceback_part)
11104 optional_tbtab = 0;
11105 else
11106 optional_tbtab = !optimize_size && !TARGET_ELF;
314fc5a9 11107
69c75916
AM
11108 if (optional_tbtab)
11109 {
11110 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
11111 while (*fname == '.') /* V.4 encodes . in the name */
11112 fname++;
11113
11114 /* Need label immediately before tbtab, so we can compute
11115 its offset from the function start. */
11116 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
11117 ASM_OUTPUT_LABEL (file, fname);
11118 }
314fc5a9
ILT
11119
11120 /* The .tbtab pseudo-op can only be used for the first eight
11121 expressions, since it can't handle the possibly variable
11122 length fields that follow. However, if you omit the optional
11123 fields, the assembler outputs zeros for all optional fields
11124 anyways, giving each variable length field is minimum length
11125 (as defined in sys/debug.h). Thus we can not use the .tbtab
11126 pseudo-op at all. */
11127
11128 /* An all-zero word flags the start of the tbtab, for debuggers
11129 that have to find it by searching forward from the entry
11130 point or from the current pc. */
19d2d16f 11131 fputs ("\t.long 0\n", file);
314fc5a9
ILT
11132
11133 /* Tbtab format type. Use format type 0. */
19d2d16f 11134 fputs ("\t.byte 0,", file);
314fc5a9
ILT
11135
11136 /* Language type. Unfortunately, there doesn't seem to be any
11137 official way to get this info, so we use language_string. C
11138 is 0. C++ is 9. No number defined for Obj-C, so use the
9517ead8 11139 value for C for now. There is no official value for Java,
6f573ff9 11140 although IBM appears to be using 13. There is no official value
f710504c 11141 for Chill, so we've chosen 44 pseudo-randomly. */
314fc5a9 11142 if (! strcmp (language_string, "GNU C")
e2c953b6 11143 || ! strcmp (language_string, "GNU Objective-C"))
314fc5a9
ILT
11144 i = 0;
11145 else if (! strcmp (language_string, "GNU F77"))
11146 i = 1;
11147 else if (! strcmp (language_string, "GNU Ada"))
11148 i = 3;
8b83775b 11149 else if (! strcmp (language_string, "GNU Pascal"))
314fc5a9
ILT
11150 i = 2;
11151 else if (! strcmp (language_string, "GNU C++"))
11152 i = 9;
9517ead8
AG
11153 else if (! strcmp (language_string, "GNU Java"))
11154 i = 13;
6f573ff9
JL
11155 else if (! strcmp (language_string, "GNU CHILL"))
11156 i = 44;
314fc5a9
ILT
11157 else
11158 abort ();
11159 fprintf (file, "%d,", i);
11160
11161 /* 8 single bit fields: global linkage (not set for C extern linkage,
11162 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
11163 from start of procedure stored in tbtab, internal function, function
11164 has controlled storage, function has no toc, function uses fp,
11165 function logs/aborts fp operations. */
11166 /* Assume that fp operations are used if any fp reg must be saved. */
6041bf2f
DE
11167 fprintf (file, "%d,",
11168 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
314fc5a9
ILT
11169
11170 /* 6 bitfields: function is interrupt handler, name present in
11171 proc table, function calls alloca, on condition directives
11172 (controls stack walks, 3 bits), saves condition reg, saves
11173 link reg. */
11174 /* The `function calls alloca' bit seems to be set whenever reg 31 is
11175 set up as a frame pointer, even when there is no alloca call. */
11176 fprintf (file, "%d,",
6041bf2f
DE
11177 ((optional_tbtab << 6)
11178 | ((optional_tbtab & frame_pointer_needed) << 5)
11179 | (info->cr_save_p << 1)
11180 | (info->lr_save_p)));
314fc5a9 11181
6041bf2f 11182 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
314fc5a9
ILT
11183 (6 bits). */
11184 fprintf (file, "%d,",
4697a36c 11185 (info->push_p << 7) | (64 - info->first_fp_reg_save));
314fc5a9
ILT
11186
11187 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
11188 fprintf (file, "%d,", (32 - first_reg_to_save ()));
11189
6041bf2f
DE
11190 if (optional_tbtab)
11191 {
11192 /* Compute the parameter info from the function decl argument
11193 list. */
11194 tree decl;
11195 int next_parm_info_bit = 31;
314fc5a9 11196
6041bf2f
DE
11197 for (decl = DECL_ARGUMENTS (current_function_decl);
11198 decl; decl = TREE_CHAIN (decl))
11199 {
11200 rtx parameter = DECL_INCOMING_RTL (decl);
11201 enum machine_mode mode = GET_MODE (parameter);
314fc5a9 11202
6041bf2f
DE
11203 if (GET_CODE (parameter) == REG)
11204 {
11205 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
11206 {
11207 int bits;
11208
11209 float_parms++;
11210
11211 if (mode == SFmode)
11212 bits = 0x2;
fcce224d 11213 else if (mode == DFmode || mode == TFmode)
6041bf2f
DE
11214 bits = 0x3;
11215 else
11216 abort ();
11217
11218 /* If only one bit will fit, don't or in this entry. */
11219 if (next_parm_info_bit > 0)
11220 parm_info |= (bits << (next_parm_info_bit - 1));
11221 next_parm_info_bit -= 2;
11222 }
11223 else
11224 {
11225 fixed_parms += ((GET_MODE_SIZE (mode)
11226 + (UNITS_PER_WORD - 1))
11227 / UNITS_PER_WORD);
11228 next_parm_info_bit -= 1;
11229 }
11230 }
11231 }
11232 }
314fc5a9
ILT
11233
11234 /* Number of fixed point parameters. */
11235 /* This is actually the number of words of fixed point parameters; thus
11236 an 8 byte struct counts as 2; and thus the maximum value is 8. */
11237 fprintf (file, "%d,", fixed_parms);
11238
11239 /* 2 bitfields: number of floating point parameters (7 bits), parameters
11240 all on stack. */
11241 /* This is actually the number of fp registers that hold parameters;
11242 and thus the maximum value is 13. */
11243 /* Set parameters on stack bit if parameters are not in their original
11244 registers, regardless of whether they are on the stack? Xlc
11245 seems to set the bit when not optimizing. */
11246 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
11247
6041bf2f
DE
11248 if (! optional_tbtab)
11249 return;
11250
314fc5a9
ILT
11251 /* Optional fields follow. Some are variable length. */
11252
11253 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
11254 11 double float. */
11255 /* There is an entry for each parameter in a register, in the order that
11256 they occur in the parameter list. Any intervening arguments on the
11257 stack are ignored. If the list overflows a long (max possible length
11258 34 bits) then completely leave off all elements that don't fit. */
11259 /* Only emit this long if there was at least one parameter. */
11260 if (fixed_parms || float_parms)
11261 fprintf (file, "\t.long %d\n", parm_info);
11262
11263 /* Offset from start of code to tb table. */
19d2d16f 11264 fputs ("\t.long ", file);
314fc5a9 11265 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
54ee9799
DE
11266#if TARGET_AIX
11267 RS6000_OUTPUT_BASENAME (file, fname);
11268#else
9ebbca7d 11269 assemble_name (file, fname);
54ee9799 11270#endif
19d2d16f 11271 fputs ("-.", file);
54ee9799
DE
11272#if TARGET_AIX
11273 RS6000_OUTPUT_BASENAME (file, fname);
11274#else
9ebbca7d 11275 assemble_name (file, fname);
54ee9799 11276#endif
19d2d16f 11277 putc ('\n', file);
314fc5a9
ILT
11278
11279 /* Interrupt handler mask. */
11280 /* Omit this long, since we never set the interrupt handler bit
11281 above. */
11282
11283 /* Number of CTL (controlled storage) anchors. */
11284 /* Omit this long, since the has_ctl bit is never set above. */
11285
11286 /* Displacement into stack of each CTL anchor. */
11287 /* Omit this list of longs, because there are no CTL anchors. */
11288
11289 /* Length of function name. */
69c75916
AM
11290 if (*fname == '*')
11291 ++fname;
296b8152 11292 fprintf (file, "\t.short %d\n", (int) strlen (fname));
314fc5a9
ILT
11293
11294 /* Function name. */
11295 assemble_string (fname, strlen (fname));
11296
11297 /* Register for alloca automatic storage; this is always reg 31.
11298 Only emit this if the alloca bit was set above. */
11299 if (frame_pointer_needed)
19d2d16f 11300 fputs ("\t.byte 31\n", file);
b1765bde
DE
11301
11302 fputs ("\t.align 2\n", file);
9b30bae2 11303 }
9878760c 11304}
17167fd8 11305\f
a4f6c312
SS
11306/* A C compound statement that outputs the assembler code for a thunk
11307 function, used to implement C++ virtual function calls with
11308 multiple inheritance. The thunk acts as a wrapper around a virtual
11309 function, adjusting the implicit object parameter before handing
11310 control off to the real function.
11311
11312 First, emit code to add the integer DELTA to the location that
11313 contains the incoming first argument. Assume that this argument
11314 contains a pointer, and is the one used to pass the `this' pointer
11315 in C++. This is the incoming argument *before* the function
11316 prologue, e.g. `%o0' on a sparc. The addition must preserve the
11317 values of all other incoming arguments.
17167fd8
MM
11318
11319 After the addition, emit code to jump to FUNCTION, which is a
a4f6c312
SS
11320 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
11321 not touch the return address. Hence returning from FUNCTION will
11322 return to whoever called the current `thunk'.
17167fd8 11323
a4f6c312
SS
11324 The effect must be as if FUNCTION had been called directly with the
11325 adjusted first argument. This macro is responsible for emitting
11326 all of the code for a thunk function; output_function_prologue()
11327 and output_function_epilogue() are not invoked.
17167fd8 11328
a4f6c312
SS
11329 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
11330 been extracted from it.) It might possibly be useful on some
11331 targets, but probably not.
17167fd8 11332
a4f6c312
SS
11333 If you do not define this macro, the target-independent code in the
11334 C++ frontend will generate a less efficient heavyweight thunk that
11335 calls FUNCTION instead of jumping to it. The generic approach does
11336 not support varargs. */
17167fd8 11337
3961e8fe
RH
11338static void
11339rs6000_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function)
17167fd8 11340 FILE *file;
d330fd93 11341 tree thunk_fndecl ATTRIBUTE_UNUSED;
eb0424da 11342 HOST_WIDE_INT delta;
3961e8fe 11343 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
17167fd8
MM
11344 tree function;
11345{
a4f6c312
SS
11346 const char *this_reg =
11347 reg_names[ aggregate_value_p (TREE_TYPE (TREE_TYPE (function))) ? 4 : 3 ];
d330fd93 11348 const char *prefix;
3cce094d 11349 const char *fname;
d330fd93 11350 const char *r0 = reg_names[0];
d330fd93
KG
11351 const char *toc = reg_names[2];
11352 const char *schain = reg_names[11];
11353 const char *r12 = reg_names[12];
17167fd8
MM
11354 char buf[512];
11355 static int labelno = 0;
11356
a4f6c312 11357 /* Small constants that can be done by one add instruction. */
17167fd8
MM
11358 if (delta >= -32768 && delta <= 32767)
11359 {
22b4a3b0 11360 if (! TARGET_NEW_MNEMONICS)
eb0424da 11361 fprintf (file, "\tcal %s,%d(%s)\n", this_reg, (int) delta, this_reg);
17167fd8 11362 else
eb0424da 11363 fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, (int) delta);
17167fd8
MM
11364 }
11365
56a7189a
AM
11366 /* 64-bit constants. If "int" is 32 bits, we'll never hit this abort. */
11367 else if (TARGET_64BIT && (delta < -2147483647 - 1 || delta > 2147483647))
11368 abort ();
11369
a4f6c312 11370 /* Large constants that can be done by one addis instruction. */
56a7189a 11371 else if ((delta & 0xffff) == 0)
17167fd8 11372 asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
eb0424da 11373 (int) (delta >> 16));
17167fd8
MM
11374
11375 /* 32-bit constants that can be done by an add and addis instruction. */
56a7189a 11376 else
17167fd8 11377 {
a4f6c312
SS
11378 /* Break into two pieces, propagating the sign bit from the low
11379 word to the upper word. */
56a7189a
AM
11380 int delta_low = ((delta & 0xffff) ^ 0x8000) - 0x8000;
11381 int delta_high = (delta - delta_low) >> 16;
17167fd8
MM
11382
11383 asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
11384 delta_high);
11385
22b4a3b0 11386 if (! TARGET_NEW_MNEMONICS)
17167fd8
MM
11387 fprintf (file, "\tcal %s,%d(%s)\n", this_reg, delta_low, this_reg);
11388 else
11389 fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, delta_low);
11390 }
11391
17167fd8
MM
11392 /* Get the prefix in front of the names. */
11393 switch (DEFAULT_ABI)
11394 {
11395 default:
11396 abort ();
11397
11398 case ABI_AIX:
11399 prefix = ".";
11400 break;
11401
11402 case ABI_V4:
11403 case ABI_AIX_NODESC:
2d173d20 11404 case ABI_DARWIN:
17167fd8
MM
11405 prefix = "";
11406 break;
17167fd8
MM
11407 }
11408
11409 /* If the function is compiled in this module, jump to it directly.
11410 Otherwise, load up its address and jump to it. */
11411
11412 fname = XSTR (XEXP (DECL_RTL (function), 0), 0);
42820a49 11413
9ebbca7d 11414 if (current_file_function_operand (XEXP (DECL_RTL (function), 0), VOIDmode)
a5c76ee6
ZW
11415 && (! lookup_attribute ("longcall",
11416 TYPE_ATTRIBUTES (TREE_TYPE (function)))
11417 || lookup_attribute ("shortcall",
11418 TYPE_ATTRIBUTES (TREE_TYPE (function)))))
17167fd8
MM
11419 {
11420 fprintf (file, "\tb %s", prefix);
11421 assemble_name (file, fname);
22b4a3b0 11422 if (DEFAULT_ABI == ABI_V4 && flag_pic) fputs ("@local", file);
949ea356 11423 putc ('\n', file);
17167fd8
MM
11424 }
11425
11426 else
11427 {
11428 switch (DEFAULT_ABI)
11429 {
11430 default:
17167fd8
MM
11431 abort ();
11432
11433 case ABI_AIX:
11434 /* Set up a TOC entry for the function. */
11435 ASM_GENERATE_INTERNAL_LABEL (buf, "Lthunk", labelno);
11436 toc_section ();
4977bab6 11437 (*targetm.asm_out.internal_label) (file, "Lthunk", labelno);
17167fd8
MM
11438 labelno++;
11439
fa9b5c6b
DE
11440 if (TARGET_MINIMAL_TOC)
11441 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
11442 else
11443 {
11444 fputs ("\t.tc ", file);
11445 assemble_name (file, fname);
11446 fputs ("[TC],", file);
11447 }
11448 assemble_name (file, fname);
17167fd8 11449 putc ('\n', file);
3961e8fe 11450 function_section (current_function_decl);
468e8dba
DE
11451 if (TARGET_MINIMAL_TOC)
11452 asm_fprintf (file, (TARGET_32BIT)
11453 ? "\t{l|lwz} %s,%s(%s)\n" : "\tld %s,%s(%s)\n", r12,
11454 TARGET_ELF ? ".LCTOC0@toc" : ".LCTOC..1", toc);
d2574c50 11455 asm_fprintf (file, (TARGET_32BIT) ? "\t{l|lwz} %s," : "\tld %s,", r12);
17167fd8 11456 assemble_name (file, buf);
468e8dba
DE
11457 if (TARGET_ELF && TARGET_MINIMAL_TOC)
11458 fputs ("-(.LCTOC1)", file);
11459 asm_fprintf (file, "(%s)\n", TARGET_MINIMAL_TOC ? r12 : toc);
17167fd8
MM
11460 asm_fprintf (file,
11461 (TARGET_32BIT) ? "\t{l|lwz} %s,0(%s)\n" : "\tld %s,0(%s)\n",
11462 r0, r12);
11463
11464 asm_fprintf (file,
11465 (TARGET_32BIT) ? "\t{l|lwz} %s,4(%s)\n" : "\tld %s,8(%s)\n",
11466 toc, r12);
11467
11468 asm_fprintf (file, "\tmtctr %s\n", r0);
11469 asm_fprintf (file,
11470 (TARGET_32BIT) ? "\t{l|lwz} %s,8(%s)\n" : "\tld %s,16(%s)\n",
11471 schain, r12);
11472
11473 asm_fprintf (file, "\tbctr\n");
11474 break;
11475
9ebbca7d 11476 case ABI_AIX_NODESC:
17167fd8 11477 case ABI_V4:
22b4a3b0
FS
11478 fprintf (file, "\tb %s", prefix);
11479 assemble_name (file, fname);
11480 if (flag_pic) fputs ("@plt", file);
949ea356 11481 putc ('\n', file);
22b4a3b0 11482 break;
ee890fe2
SS
11483
11484#if TARGET_MACHO
11485 case ABI_DARWIN:
11486 fprintf (file, "\tb %s", prefix);
11487 if (flag_pic && !machopic_name_defined_p (fname))
11488 assemble_name (file, machopic_stub_name (fname));
11489 else
11490 assemble_name (file, fname);
11491 putc ('\n', file);
11492 break;
11493#endif
9ebbca7d
GK
11494 }
11495 }
11496}
9ebbca7d
GK
11497\f
11498/* A quick summary of the various types of 'constant-pool tables'
11499 under PowerPC:
11500
11501 Target Flags Name One table per
11502 AIX (none) AIX TOC object file
11503 AIX -mfull-toc AIX TOC object file
11504 AIX -mminimal-toc AIX minimal TOC translation unit
11505 SVR4/EABI (none) SVR4 SDATA object file
11506 SVR4/EABI -fpic SVR4 pic object file
11507 SVR4/EABI -fPIC SVR4 PIC translation unit
11508 SVR4/EABI -mrelocatable EABI TOC function
11509 SVR4/EABI -maix AIX TOC object file
11510 SVR4/EABI -maix -mminimal-toc
11511 AIX minimal TOC translation unit
11512
11513 Name Reg. Set by entries contains:
11514 made by addrs? fp? sum?
11515
11516 AIX TOC 2 crt0 as Y option option
11517 AIX minimal TOC 30 prolog gcc Y Y option
11518 SVR4 SDATA 13 crt0 gcc N Y N
11519 SVR4 pic 30 prolog ld Y not yet N
11520 SVR4 PIC 30 prolog gcc Y option option
11521 EABI TOC 30 prolog gcc Y option option
11522
11523*/
11524
11525/* Hash table stuff for keeping track of TOC entries. */
11526
11527struct toc_hash_struct
11528{
11529 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
11530 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
11531 rtx key;
a9098fd0 11532 enum machine_mode key_mode;
9ebbca7d
GK
11533 int labelno;
11534};
17167fd8 11535
9ebbca7d
GK
11536static htab_t toc_hash_table;
11537
11538/* Hash functions for the hash table. */
11539
11540static unsigned
11541rs6000_hash_constant (k)
11542 rtx k;
11543{
46b33600
RH
11544 enum rtx_code code = GET_CODE (k);
11545 enum machine_mode mode = GET_MODE (k);
11546 unsigned result = (code << 3) ^ mode;
11547 const char *format;
11548 int flen, fidx;
9ebbca7d 11549
46b33600
RH
11550 format = GET_RTX_FORMAT (code);
11551 flen = strlen (format);
11552 fidx = 0;
9ebbca7d 11553
46b33600
RH
11554 switch (code)
11555 {
11556 case LABEL_REF:
11557 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
11558
11559 case CONST_DOUBLE:
11560 if (mode != VOIDmode)
11561 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
11562 flen = 2;
11563 break;
11564
11565 case CODE_LABEL:
11566 fidx = 3;
11567 break;
11568
11569 default:
11570 break;
11571 }
9ebbca7d
GK
11572
11573 for (; fidx < flen; fidx++)
11574 switch (format[fidx])
11575 {
11576 case 's':
11577 {
11578 unsigned i, len;
11579 const char *str = XSTR (k, fidx);
11580 len = strlen (str);
11581 result = result * 613 + len;
11582 for (i = 0; i < len; i++)
11583 result = result * 613 + (unsigned) str[i];
17167fd8
MM
11584 break;
11585 }
9ebbca7d
GK
11586 case 'u':
11587 case 'e':
11588 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
11589 break;
11590 case 'i':
11591 case 'n':
11592 result = result * 613 + (unsigned) XINT (k, fidx);
11593 break;
11594 case 'w':
11595 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
11596 result = result * 613 + (unsigned) XWINT (k, fidx);
11597 else
11598 {
11599 size_t i;
11600 for (i = 0; i < sizeof(HOST_WIDE_INT)/sizeof(unsigned); i++)
11601 result = result * 613 + (unsigned) (XWINT (k, fidx)
11602 >> CHAR_BIT * i);
11603 }
11604 break;
11605 default:
a4f6c312 11606 abort ();
9ebbca7d 11607 }
46b33600 11608
9ebbca7d
GK
11609 return result;
11610}
11611
11612static unsigned
11613toc_hash_function (hash_entry)
11614 const void * hash_entry;
11615{
a9098fd0
GK
11616 const struct toc_hash_struct *thc =
11617 (const struct toc_hash_struct *) hash_entry;
11618 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
9ebbca7d
GK
11619}
11620
11621/* Compare H1 and H2 for equivalence. */
11622
11623static int
11624toc_hash_eq (h1, h2)
11625 const void * h1;
11626 const void * h2;
11627{
11628 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
11629 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
11630
a9098fd0
GK
11631 if (((const struct toc_hash_struct *) h1)->key_mode
11632 != ((const struct toc_hash_struct *) h2)->key_mode)
11633 return 0;
11634
5692c7bc 11635 return rtx_equal_p (r1, r2);
9ebbca7d
GK
11636}
11637
11638/* Mark the hash table-entry HASH_ENTRY. */
11639
11640static int
11641toc_hash_mark_entry (hash_slot, unused)
2eba1afa 11642 void ** hash_slot;
9ebbca7d
GK
11643 void * unused ATTRIBUTE_UNUSED;
11644{
11645 const struct toc_hash_struct * hash_entry =
11646 *(const struct toc_hash_struct **) hash_slot;
11647 rtx r = hash_entry->key;
11648 ggc_set_mark (hash_entry);
a4f6c312 11649 /* For CODE_LABELS, we don't want to drag in the whole insn chain... */
9ebbca7d
GK
11650 if (GET_CODE (r) == LABEL_REF)
11651 {
11652 ggc_set_mark (r);
11653 ggc_set_mark (XEXP (r, 0));
11654 }
11655 else
11656 ggc_mark_rtx (r);
11657 return 1;
11658}
11659
11660/* Mark all the elements of the TOC hash-table *HT. */
11661
11662static void
11663toc_hash_mark_table (vht)
11664 void *vht;
11665{
11666 htab_t *ht = vht;
11667
11668 htab_traverse (*ht, toc_hash_mark_entry, (void *)0);
17167fd8
MM
11669}
11670
28e510bd
MM
11671/* These are the names given by the C++ front-end to vtables, and
11672 vtable-like objects. Ideally, this logic should not be here;
11673 instead, there should be some programmatic way of inquiring as
11674 to whether or not an object is a vtable. */
11675
11676#define VTABLE_NAME_P(NAME) \
11677 (strncmp ("_vt.", name, strlen("_vt.")) == 0 \
11678 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
11679 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
11680 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
11681
11682void
11683rs6000_output_symbol_ref (file, x)
11684 FILE *file;
11685 rtx x;
11686{
11687 /* Currently C++ toc references to vtables can be emitted before it
11688 is decided whether the vtable is public or private. If this is
11689 the case, then the linker will eventually complain that there is
11690 a reference to an unknown section. Thus, for vtables only,
11691 we emit the TOC reference to reference the symbol and not the
11692 section. */
11693 const char *name = XSTR (x, 0);
54ee9799
DE
11694
11695 if (VTABLE_NAME_P (name))
11696 {
11697 RS6000_OUTPUT_BASENAME (file, name);
11698 }
11699 else
11700 assemble_name (file, name);
28e510bd
MM
11701}
11702
a4f6c312
SS
11703/* Output a TOC entry. We derive the entry name from what is being
11704 written. */
9878760c
RK
11705
11706void
a9098fd0 11707output_toc (file, x, labelno, mode)
9878760c
RK
11708 FILE *file;
11709 rtx x;
11710 int labelno;
a9098fd0 11711 enum machine_mode mode;
9878760c
RK
11712{
11713 char buf[256];
3cce094d 11714 const char *name = buf;
ec940faa 11715 const char *real_name;
9878760c
RK
11716 rtx base = x;
11717 int offset = 0;
11718
4697a36c
MM
11719 if (TARGET_NO_TOC)
11720 abort ();
11721
9ebbca7d
GK
11722 /* When the linker won't eliminate them, don't output duplicate
11723 TOC entries (this happens on AIX if there is any kind of TOC,
1f8f4a0b
MM
11724 and on SVR4 under -fPIC or -mrelocatable). */
11725 if (TARGET_TOC)
9ebbca7d
GK
11726 {
11727 struct toc_hash_struct *h;
11728 void * * found;
11729
11730 h = ggc_alloc (sizeof (*h));
11731 h->key = x;
a9098fd0 11732 h->key_mode = mode;
9ebbca7d
GK
11733 h->labelno = labelno;
11734
11735 found = htab_find_slot (toc_hash_table, h, 1);
11736 if (*found == NULL)
11737 *found = h;
11738 else /* This is indeed a duplicate.
11739 Set this label equal to that label. */
11740 {
11741 fputs ("\t.set ", file);
11742 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
11743 fprintf (file, "%d,", labelno);
11744 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
11745 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
11746 found)->labelno));
11747 return;
11748 }
11749 }
11750
11751 /* If we're going to put a double constant in the TOC, make sure it's
11752 aligned properly when strict alignment is on. */
ff1720ed
RK
11753 if (GET_CODE (x) == CONST_DOUBLE
11754 && STRICT_ALIGNMENT
a9098fd0 11755 && GET_MODE_BITSIZE (mode) >= 64
ff1720ed
RK
11756 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
11757 ASM_OUTPUT_ALIGN (file, 3);
11758 }
11759
4977bab6 11760 (*targetm.asm_out.internal_label) (file, "LC", labelno);
9878760c 11761
37c37a57
RK
11762 /* Handle FP constants specially. Note that if we have a minimal
11763 TOC, things we put here aren't actually in the TOC, so we can allow
11764 FP constants. */
fcce224d
DE
11765 if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == TFmode)
11766 {
11767 REAL_VALUE_TYPE rv;
11768 long k[4];
11769
11770 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
11771 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
11772
11773 if (TARGET_64BIT)
11774 {
11775 if (TARGET_MINIMAL_TOC)
11776 fputs (DOUBLE_INT_ASM_OP, file);
11777 else
11778 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
11779 k[0] & 0xffffffff, k[1] & 0xffffffff,
11780 k[2] & 0xffffffff, k[3] & 0xffffffff);
11781 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
11782 k[0] & 0xffffffff, k[1] & 0xffffffff,
11783 k[2] & 0xffffffff, k[3] & 0xffffffff);
11784 return;
11785 }
11786 else
11787 {
11788 if (TARGET_MINIMAL_TOC)
11789 fputs ("\t.long ", file);
11790 else
11791 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
11792 k[0] & 0xffffffff, k[1] & 0xffffffff,
11793 k[2] & 0xffffffff, k[3] & 0xffffffff);
11794 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
11795 k[0] & 0xffffffff, k[1] & 0xffffffff,
11796 k[2] & 0xffffffff, k[3] & 0xffffffff);
11797 return;
11798 }
11799 }
11800 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
9878760c 11801 {
042259f2
DE
11802 REAL_VALUE_TYPE rv;
11803 long k[2];
0adc764e 11804
042259f2
DE
11805 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
11806 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
31bfaa0b 11807
13ded975
DE
11808 if (TARGET_64BIT)
11809 {
11810 if (TARGET_MINIMAL_TOC)
2bfcf297 11811 fputs (DOUBLE_INT_ASM_OP, file);
13ded975 11812 else
2f0552b6
AM
11813 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
11814 k[0] & 0xffffffff, k[1] & 0xffffffff);
11815 fprintf (file, "0x%lx%08lx\n",
11816 k[0] & 0xffffffff, k[1] & 0xffffffff);
13ded975
DE
11817 return;
11818 }
1875cc88 11819 else
13ded975
DE
11820 {
11821 if (TARGET_MINIMAL_TOC)
2bfcf297 11822 fputs ("\t.long ", file);
13ded975 11823 else
2f0552b6
AM
11824 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
11825 k[0] & 0xffffffff, k[1] & 0xffffffff);
11826 fprintf (file, "0x%lx,0x%lx\n",
11827 k[0] & 0xffffffff, k[1] & 0xffffffff);
13ded975
DE
11828 return;
11829 }
9878760c 11830 }
a9098fd0 11831 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
9878760c 11832 {
042259f2
DE
11833 REAL_VALUE_TYPE rv;
11834 long l;
9878760c 11835
042259f2
DE
11836 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
11837 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
11838
31bfaa0b
DE
11839 if (TARGET_64BIT)
11840 {
11841 if (TARGET_MINIMAL_TOC)
2bfcf297 11842 fputs (DOUBLE_INT_ASM_OP, file);
31bfaa0b 11843 else
2f0552b6
AM
11844 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
11845 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
31bfaa0b
DE
11846 return;
11847 }
042259f2 11848 else
31bfaa0b
DE
11849 {
11850 if (TARGET_MINIMAL_TOC)
2bfcf297 11851 fputs ("\t.long ", file);
31bfaa0b 11852 else
2f0552b6
AM
11853 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
11854 fprintf (file, "0x%lx\n", l & 0xffffffff);
31bfaa0b
DE
11855 return;
11856 }
042259f2 11857 }
f176e826 11858 else if (GET_MODE (x) == VOIDmode
a9098fd0 11859 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
042259f2 11860 {
e2c953b6 11861 unsigned HOST_WIDE_INT low;
042259f2
DE
11862 HOST_WIDE_INT high;
11863
11864 if (GET_CODE (x) == CONST_DOUBLE)
11865 {
11866 low = CONST_DOUBLE_LOW (x);
11867 high = CONST_DOUBLE_HIGH (x);
11868 }
11869 else
11870#if HOST_BITS_PER_WIDE_INT == 32
11871 {
11872 low = INTVAL (x);
0858c623 11873 high = (low & 0x80000000) ? ~0 : 0;
042259f2
DE
11874 }
11875#else
11876 {
0858c623 11877 low = INTVAL (x) & 0xffffffff;
042259f2
DE
11878 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
11879 }
11880#endif
9878760c 11881
a9098fd0
GK
11882 /* TOC entries are always Pmode-sized, but since this
11883 is a bigendian machine then if we're putting smaller
11884 integer constants in the TOC we have to pad them.
11885 (This is still a win over putting the constants in
11886 a separate constant pool, because then we'd have
02a4ec28
FS
11887 to have both a TOC entry _and_ the actual constant.)
11888
11889 For a 32-bit target, CONST_INT values are loaded and shifted
11890 entirely within `low' and can be stored in one TOC entry. */
11891
11892 if (TARGET_64BIT && POINTER_SIZE < GET_MODE_BITSIZE (mode))
a9098fd0 11893 abort ();/* It would be easy to make this work, but it doesn't now. */
02a4ec28
FS
11894
11895 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
fb52d8de
AM
11896 {
11897#if HOST_BITS_PER_WIDE_INT == 32
11898 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
11899 POINTER_SIZE, &low, &high, 0);
11900#else
11901 low |= high << 32;
11902 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
11903 high = (HOST_WIDE_INT) low >> 32;
11904 low &= 0xffffffff;
11905#endif
11906 }
a9098fd0 11907
13ded975
DE
11908 if (TARGET_64BIT)
11909 {
11910 if (TARGET_MINIMAL_TOC)
2bfcf297 11911 fputs (DOUBLE_INT_ASM_OP, file);
13ded975 11912 else
2f0552b6
AM
11913 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
11914 (long) high & 0xffffffff, (long) low & 0xffffffff);
11915 fprintf (file, "0x%lx%08lx\n",
11916 (long) high & 0xffffffff, (long) low & 0xffffffff);
13ded975
DE
11917 return;
11918 }
1875cc88 11919 else
13ded975 11920 {
02a4ec28
FS
11921 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
11922 {
11923 if (TARGET_MINIMAL_TOC)
2bfcf297 11924 fputs ("\t.long ", file);
02a4ec28 11925 else
2bfcf297 11926 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
2f0552b6
AM
11927 (long) high & 0xffffffff, (long) low & 0xffffffff);
11928 fprintf (file, "0x%lx,0x%lx\n",
11929 (long) high & 0xffffffff, (long) low & 0xffffffff);
02a4ec28 11930 }
13ded975 11931 else
02a4ec28
FS
11932 {
11933 if (TARGET_MINIMAL_TOC)
2bfcf297 11934 fputs ("\t.long ", file);
02a4ec28 11935 else
2f0552b6
AM
11936 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
11937 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
02a4ec28 11938 }
13ded975
DE
11939 return;
11940 }
9878760c
RK
11941 }
11942
11943 if (GET_CODE (x) == CONST)
11944 {
2bfcf297
DB
11945 if (GET_CODE (XEXP (x, 0)) != PLUS)
11946 abort ();
11947
9878760c
RK
11948 base = XEXP (XEXP (x, 0), 0);
11949 offset = INTVAL (XEXP (XEXP (x, 0), 1));
11950 }
11951
11952 if (GET_CODE (base) == SYMBOL_REF)
11953 name = XSTR (base, 0);
11954 else if (GET_CODE (base) == LABEL_REF)
11955 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (base, 0)));
11956 else if (GET_CODE (base) == CODE_LABEL)
11957 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
11958 else
11959 abort ();
11960
772c5265 11961 real_name = (*targetm.strip_name_encoding) (name);
1875cc88 11962 if (TARGET_MINIMAL_TOC)
2bfcf297 11963 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
1875cc88
JW
11964 else
11965 {
b6c9286a 11966 fprintf (file, "\t.tc %s", real_name);
9878760c 11967
1875cc88
JW
11968 if (offset < 0)
11969 fprintf (file, ".N%d", - offset);
11970 else if (offset)
11971 fprintf (file, ".P%d", offset);
9878760c 11972
19d2d16f 11973 fputs ("[TC],", file);
1875cc88 11974 }
581bc4de
MM
11975
11976 /* Currently C++ toc references to vtables can be emitted before it
11977 is decided whether the vtable is public or private. If this is
11978 the case, then the linker will eventually complain that there is
11979 a TOC reference to an unknown section. Thus, for vtables only,
11980 we emit the TOC reference to reference the symbol and not the
11981 section. */
28e510bd 11982 if (VTABLE_NAME_P (name))
581bc4de 11983 {
54ee9799 11984 RS6000_OUTPUT_BASENAME (file, name);
581bc4de
MM
11985 if (offset < 0)
11986 fprintf (file, "%d", offset);
11987 else if (offset > 0)
11988 fprintf (file, "+%d", offset);
11989 }
11990 else
11991 output_addr_const (file, x);
19d2d16f 11992 putc ('\n', file);
9878760c
RK
11993}
11994\f
11995/* Output an assembler pseudo-op to write an ASCII string of N characters
11996 starting at P to FILE.
11997
11998 On the RS/6000, we have to do this using the .byte operation and
11999 write out special characters outside the quoted string.
12000 Also, the assembler is broken; very long strings are truncated,
a4f6c312 12001 so we must artificially break them up early. */
9878760c
RK
12002
12003void
12004output_ascii (file, p, n)
12005 FILE *file;
d330fd93 12006 const char *p;
9878760c
RK
12007 int n;
12008{
12009 char c;
12010 int i, count_string;
d330fd93
KG
12011 const char *for_string = "\t.byte \"";
12012 const char *for_decimal = "\t.byte ";
12013 const char *to_close = NULL;
9878760c
RK
12014
12015 count_string = 0;
12016 for (i = 0; i < n; i++)
12017 {
12018 c = *p++;
12019 if (c >= ' ' && c < 0177)
12020 {
12021 if (for_string)
12022 fputs (for_string, file);
12023 putc (c, file);
12024
12025 /* Write two quotes to get one. */
12026 if (c == '"')
12027 {
12028 putc (c, file);
12029 ++count_string;
12030 }
12031
12032 for_string = NULL;
12033 for_decimal = "\"\n\t.byte ";
12034 to_close = "\"\n";
12035 ++count_string;
12036
12037 if (count_string >= 512)
12038 {
12039 fputs (to_close, file);
12040
12041 for_string = "\t.byte \"";
12042 for_decimal = "\t.byte ";
12043 to_close = NULL;
12044 count_string = 0;
12045 }
12046 }
12047 else
12048 {
12049 if (for_decimal)
12050 fputs (for_decimal, file);
12051 fprintf (file, "%d", c);
12052
12053 for_string = "\n\t.byte \"";
12054 for_decimal = ", ";
12055 to_close = "\n";
12056 count_string = 0;
12057 }
12058 }
12059
12060 /* Now close the string if we have written one. Then end the line. */
12061 if (to_close)
9ebbca7d 12062 fputs (to_close, file);
9878760c
RK
12063}
12064\f
12065/* Generate a unique section name for FILENAME for a section type
12066 represented by SECTION_DESC. Output goes into BUF.
12067
12068 SECTION_DESC can be any string, as long as it is different for each
12069 possible section type.
12070
12071 We name the section in the same manner as xlc. The name begins with an
12072 underscore followed by the filename (after stripping any leading directory
11e5fe42
RK
12073 names) with the last period replaced by the string SECTION_DESC. If
12074 FILENAME does not contain a period, SECTION_DESC is appended to the end of
12075 the name. */
9878760c
RK
12076
12077void
12078rs6000_gen_section_name (buf, filename, section_desc)
12079 char **buf;
9ebbca7d
GK
12080 const char *filename;
12081 const char *section_desc;
9878760c 12082{
9ebbca7d 12083 const char *q, *after_last_slash, *last_period = 0;
9878760c
RK
12084 char *p;
12085 int len;
9878760c
RK
12086
12087 after_last_slash = filename;
12088 for (q = filename; *q; q++)
11e5fe42
RK
12089 {
12090 if (*q == '/')
12091 after_last_slash = q + 1;
12092 else if (*q == '.')
12093 last_period = q;
12094 }
9878760c 12095
11e5fe42 12096 len = strlen (after_last_slash) + strlen (section_desc) + 2;
6d9f628e 12097 *buf = (char *) xmalloc (len);
9878760c
RK
12098
12099 p = *buf;
12100 *p++ = '_';
12101
12102 for (q = after_last_slash; *q; q++)
12103 {
11e5fe42 12104 if (q == last_period)
9878760c
RK
12105 {
12106 strcpy (p, section_desc);
12107 p += strlen (section_desc);
9878760c
RK
12108 }
12109
e9a780ec 12110 else if (ISALNUM (*q))
9878760c
RK
12111 *p++ = *q;
12112 }
12113
11e5fe42 12114 if (last_period == 0)
9878760c
RK
12115 strcpy (p, section_desc);
12116 else
12117 *p = '\0';
12118}
e165f3f0 12119\f
a4f6c312 12120/* Emit profile function. */
411707f4 12121
411707f4
CC
12122void
12123output_profile_hook (labelno)
57ac7be9 12124 int labelno ATTRIBUTE_UNUSED;
411707f4 12125{
8480e480
CC
12126 if (DEFAULT_ABI == ABI_AIX)
12127 {
57ac7be9
AM
12128#ifdef NO_PROFILE_COUNTERS
12129 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0);
12130#else
8480e480 12131 char buf[30];
40501e5f 12132 const char *label_name;
8480e480 12133 rtx fun;
411707f4 12134
8480e480 12135 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
772c5265 12136 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
8480e480 12137 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
411707f4 12138
8480e480
CC
12139 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1,
12140 fun, Pmode);
57ac7be9 12141#endif
8480e480 12142 }
ee890fe2
SS
12143 else if (DEFAULT_ABI == ABI_DARWIN)
12144 {
d5fa86ba 12145 const char *mcount_name = RS6000_MCOUNT;
ee890fe2
SS
12146 int caller_addr_regno = LINK_REGISTER_REGNUM;
12147
12148 /* Be conservative and always set this, at least for now. */
12149 current_function_uses_pic_offset_table = 1;
12150
12151#if TARGET_MACHO
12152 /* For PIC code, set up a stub and collect the caller's address
12153 from r0, which is where the prologue puts it. */
12154 if (flag_pic)
12155 {
12156 mcount_name = machopic_stub_name (mcount_name);
12157 if (current_function_uses_pic_offset_table)
12158 caller_addr_regno = 0;
12159 }
12160#endif
12161 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
12162 0, VOIDmode, 1,
12163 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
12164 }
411707f4
CC
12165}
12166
a4f6c312 12167/* Write function profiler code. */
e165f3f0
RK
12168
12169void
12170output_function_profiler (file, labelno)
12171 FILE *file;
12172 int labelno;
12173{
3daf36a4 12174 char buf[100];
09eeeacb 12175 int save_lr = 8;
e165f3f0 12176
3daf36a4 12177 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
38c1f2d7 12178 switch (DEFAULT_ABI)
3daf36a4 12179 {
38c1f2d7
MM
12180 default:
12181 abort ();
12182
12183 case ABI_V4:
09eeeacb
AM
12184 save_lr = 4;
12185 /* Fall through. */
12186
38c1f2d7 12187 case ABI_AIX_NODESC:
09eeeacb
AM
12188 if (!TARGET_32BIT)
12189 {
12190 warning ("no profiling of 64-bit code for this ABI");
12191 return;
12192 }
38c1f2d7
MM
12193 fprintf (file, "\tmflr %s\n", reg_names[0]);
12194 if (flag_pic == 1)
12195 {
dfdfa60f 12196 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
09eeeacb
AM
12197 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12198 reg_names[0], save_lr, reg_names[1]);
17167fd8 12199 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
dfdfa60f 12200 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
38c1f2d7 12201 assemble_name (file, buf);
17167fd8 12202 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
38c1f2d7 12203 }
9ebbca7d 12204 else if (flag_pic > 1)
38c1f2d7 12205 {
09eeeacb
AM
12206 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12207 reg_names[0], save_lr, reg_names[1]);
9ebbca7d
GK
12208 /* Now, we need to get the address of the label. */
12209 fputs ("\tbl 1f\n\t.long ", file);
034e84c4 12210 assemble_name (file, buf);
9ebbca7d
GK
12211 fputs ("-.\n1:", file);
12212 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
12213 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
12214 reg_names[0], reg_names[11]);
12215 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
12216 reg_names[0], reg_names[0], reg_names[11]);
38c1f2d7 12217 }
38c1f2d7
MM
12218 else
12219 {
17167fd8 12220 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
38c1f2d7 12221 assemble_name (file, buf);
dfdfa60f 12222 fputs ("@ha\n", file);
09eeeacb
AM
12223 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12224 reg_names[0], save_lr, reg_names[1]);
a260abc9 12225 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
38c1f2d7 12226 assemble_name (file, buf);
17167fd8 12227 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
38c1f2d7
MM
12228 }
12229
09eeeacb
AM
12230 if (current_function_needs_context && DEFAULT_ABI == ABI_AIX_NODESC)
12231 {
12232 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12233 reg_names[STATIC_CHAIN_REGNUM],
12234 12, reg_names[1]);
12235 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
12236 asm_fprintf (file, "\t{l|lwz} %s,%d(%s)\n",
12237 reg_names[STATIC_CHAIN_REGNUM],
12238 12, reg_names[1]);
12239 }
12240 else
12241 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
12242 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
38c1f2d7
MM
12243 break;
12244
12245 case ABI_AIX:
ee890fe2 12246 case ABI_DARWIN:
a4f6c312 12247 /* Don't do anything, done in output_profile_hook (). */
38c1f2d7
MM
12248 break;
12249 }
e165f3f0 12250}
a251ffd0
TG
12251
12252/* Adjust the cost of a scheduling dependency. Return the new cost of
12253 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
12254
c237e94a 12255static int
a06faf84 12256rs6000_adjust_cost (insn, link, dep_insn, cost)
a251ffd0
TG
12257 rtx insn;
12258 rtx link;
296b8152 12259 rtx dep_insn ATTRIBUTE_UNUSED;
a251ffd0
TG
12260 int cost;
12261{
12262 if (! recog_memoized (insn))
12263 return 0;
12264
12265 if (REG_NOTE_KIND (link) != 0)
12266 return 0;
12267
12268 if (REG_NOTE_KIND (link) == 0)
12269 {
ed947a96
DJ
12270 /* Data dependency; DEP_INSN writes a register that INSN reads
12271 some cycles later. */
12272 switch (get_attr_type (insn))
12273 {
12274 case TYPE_JMPREG:
309323c2 12275 /* Tell the first scheduling pass about the latency between
ed947a96
DJ
12276 a mtctr and bctr (and mtlr and br/blr). The first
12277 scheduling pass will not know about this latency since
12278 the mtctr instruction, which has the latency associated
12279 to it, will be generated by reload. */
309323c2 12280 return TARGET_POWER ? 5 : 4;
ed947a96
DJ
12281 case TYPE_BRANCH:
12282 /* Leave some extra cycles between a compare and its
12283 dependent branch, to inhibit expensive mispredicts. */
309323c2
DE
12284 if ((rs6000_cpu_attr == CPU_PPC603
12285 || rs6000_cpu_attr == CPU_PPC604
12286 || rs6000_cpu_attr == CPU_PPC604E
12287 || rs6000_cpu_attr == CPU_PPC620
12288 || rs6000_cpu_attr == CPU_PPC630
12289 || rs6000_cpu_attr == CPU_PPC750
12290 || rs6000_cpu_attr == CPU_PPC7400
12291 || rs6000_cpu_attr == CPU_PPC7450
12292 || rs6000_cpu_attr == CPU_POWER4)
ed947a96
DJ
12293 && recog_memoized (dep_insn)
12294 && (INSN_CODE (dep_insn) >= 0)
12295 && (get_attr_type (dep_insn) == TYPE_COMPARE
12296 || get_attr_type (dep_insn) == TYPE_DELAYED_COMPARE
12297 || get_attr_type (dep_insn) == TYPE_FPCOMPARE
12298 || get_attr_type (dep_insn) == TYPE_CR_LOGICAL))
12299 return cost + 2;
12300 default:
12301 break;
12302 }
a251ffd0
TG
12303 /* Fall out to return default cost. */
12304 }
12305
12306 return cost;
12307}
b6c9286a 12308
a4f6c312
SS
12309/* A C statement (sans semicolon) to update the integer scheduling
12310 priority INSN_PRIORITY (INSN). Reduce the priority to execute the
12311 INSN earlier, increase the priority to execute INSN later. Do not
12312 define this macro if you do not need to adjust the scheduling
12313 priorities of insns. */
bef84347 12314
c237e94a 12315static int
bef84347 12316rs6000_adjust_priority (insn, priority)
d330fd93 12317 rtx insn ATTRIBUTE_UNUSED;
bef84347
VM
12318 int priority;
12319{
a4f6c312
SS
12320 /* On machines (like the 750) which have asymmetric integer units,
12321 where one integer unit can do multiply and divides and the other
12322 can't, reduce the priority of multiply/divide so it is scheduled
12323 before other integer operations. */
bef84347
VM
12324
12325#if 0
2c3c49de 12326 if (! INSN_P (insn))
bef84347
VM
12327 return priority;
12328
12329 if (GET_CODE (PATTERN (insn)) == USE)
12330 return priority;
12331
12332 switch (rs6000_cpu_attr) {
12333 case CPU_PPC750:
12334 switch (get_attr_type (insn))
12335 {
12336 default:
12337 break;
12338
12339 case TYPE_IMUL:
12340 case TYPE_IDIV:
3cb999d8
DE
12341 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
12342 priority, priority);
bef84347
VM
12343 if (priority >= 0 && priority < 0x01000000)
12344 priority >>= 3;
12345 break;
12346 }
12347 }
12348#endif
12349
12350 return priority;
12351}
12352
a4f6c312
SS
12353/* Return how many instructions the machine can issue per cycle. */
12354
c237e94a
ZW
12355static int
12356rs6000_issue_rate ()
b6c9286a
MM
12357{
12358 switch (rs6000_cpu_attr) {
3cb999d8
DE
12359 case CPU_RIOS1: /* ? */
12360 case CPU_RS64A:
12361 case CPU_PPC601: /* ? */
ed947a96 12362 case CPU_PPC7450:
3cb999d8 12363 return 3;
b6c9286a 12364 case CPU_PPC603:
bef84347 12365 case CPU_PPC750:
ed947a96 12366 case CPU_PPC7400:
bef84347 12367 return 2;
3cb999d8 12368 case CPU_RIOS2:
b6c9286a 12369 case CPU_PPC604:
19684119 12370 case CPU_PPC604E:
b6c9286a 12371 case CPU_PPC620:
3cb999d8 12372 case CPU_PPC630:
309323c2 12373 case CPU_POWER4:
b6c9286a
MM
12374 return 4;
12375 default:
12376 return 1;
12377 }
12378}
12379
b6c9286a 12380\f
b6c9286a
MM
12381/* Length in units of the trampoline for entering a nested function. */
12382
12383int
12384rs6000_trampoline_size ()
12385{
12386 int ret = 0;
12387
12388 switch (DEFAULT_ABI)
12389 {
12390 default:
12391 abort ();
12392
12393 case ABI_AIX:
8f802bfb 12394 ret = (TARGET_32BIT) ? 12 : 24;
b6c9286a
MM
12395 break;
12396
4dabc42d 12397 case ABI_DARWIN:
b6c9286a
MM
12398 case ABI_V4:
12399 case ABI_AIX_NODESC:
03a7e1a5 12400 ret = (TARGET_32BIT) ? 40 : 48;
b6c9286a 12401 break;
b6c9286a
MM
12402 }
12403
12404 return ret;
12405}
12406
12407/* Emit RTL insns to initialize the variable parts of a trampoline.
12408 FNADDR is an RTX for the address of the function's pure code.
12409 CXT is an RTX for the static chain value for the function. */
12410
12411void
12412rs6000_initialize_trampoline (addr, fnaddr, cxt)
12413 rtx addr;
12414 rtx fnaddr;
12415 rtx cxt;
12416{
ac2a93a1 12417 enum machine_mode pmode = Pmode;
8bd04c56
MM
12418 int regsize = (TARGET_32BIT) ? 4 : 8;
12419 rtx ctx_reg = force_reg (pmode, cxt);
b6c9286a
MM
12420
12421 switch (DEFAULT_ABI)
12422 {
12423 default:
12424 abort ();
12425
8bd04c56 12426/* Macros to shorten the code expansions below. */
39403d82 12427#define MEM_DEREF(addr) gen_rtx_MEM (pmode, memory_address (pmode, addr))
c5c76735
JL
12428#define MEM_PLUS(addr,offset) \
12429 gen_rtx_MEM (pmode, memory_address (pmode, plus_constant (addr, offset)))
7c59dc5d 12430
b6c9286a
MM
12431 /* Under AIX, just build the 3 word function descriptor */
12432 case ABI_AIX:
8bd04c56
MM
12433 {
12434 rtx fn_reg = gen_reg_rtx (pmode);
12435 rtx toc_reg = gen_reg_rtx (pmode);
12436 emit_move_insn (fn_reg, MEM_DEREF (fnaddr));
1cb18e3c 12437 emit_move_insn (toc_reg, MEM_PLUS (fnaddr, regsize));
8bd04c56
MM
12438 emit_move_insn (MEM_DEREF (addr), fn_reg);
12439 emit_move_insn (MEM_PLUS (addr, regsize), toc_reg);
12440 emit_move_insn (MEM_PLUS (addr, 2*regsize), ctx_reg);
12441 }
b6c9286a
MM
12442 break;
12443
4dabc42d
TC
12444 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
12445 case ABI_DARWIN:
b6c9286a
MM
12446 case ABI_V4:
12447 case ABI_AIX_NODESC:
39403d82 12448 emit_library_call (gen_rtx_SYMBOL_REF (SImode, "__trampoline_setup"),
eaf1bcf1
MM
12449 FALSE, VOIDmode, 4,
12450 addr, pmode,
12451 GEN_INT (rs6000_trampoline_size ()), SImode,
12452 fnaddr, pmode,
12453 ctx_reg, pmode);
b6c9286a 12454 break;
b6c9286a
MM
12455 }
12456
12457 return;
12458}
7509c759
MM
12459
12460\f
91d231cb 12461/* Table of valid machine attributes. */
a4f6c312 12462
91d231cb 12463const struct attribute_spec rs6000_attribute_table[] =
7509c759 12464{
91d231cb 12465 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
a5c76ee6
ZW
12466 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
12467 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
12468 { NULL, 0, 0, false, false, false, NULL }
91d231cb 12469};
7509c759 12470
a5c76ee6
ZW
12471/* Handle a "longcall" or "shortcall" attribute; arguments as in
12472 struct attribute_spec.handler. */
a4f6c312 12473
91d231cb
JM
12474static tree
12475rs6000_handle_longcall_attribute (node, name, args, flags, no_add_attrs)
12476 tree *node;
12477 tree name;
12478 tree args ATTRIBUTE_UNUSED;
12479 int flags ATTRIBUTE_UNUSED;
12480 bool *no_add_attrs;
12481{
12482 if (TREE_CODE (*node) != FUNCTION_TYPE
12483 && TREE_CODE (*node) != FIELD_DECL
12484 && TREE_CODE (*node) != TYPE_DECL)
12485 {
12486 warning ("`%s' attribute only applies to functions",
12487 IDENTIFIER_POINTER (name));
12488 *no_add_attrs = true;
12489 }
6a4cee5f 12490
91d231cb 12491 return NULL_TREE;
7509c759
MM
12492}
12493
a5c76ee6
ZW
12494/* Set longcall attributes on all functions declared when
12495 rs6000_default_long_calls is true. */
12496static void
12497rs6000_set_default_type_attributes (type)
12498 tree type;
12499{
12500 if (rs6000_default_long_calls
12501 && (TREE_CODE (type) == FUNCTION_TYPE
12502 || TREE_CODE (type) == METHOD_TYPE))
12503 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
12504 NULL_TREE,
12505 TYPE_ATTRIBUTES (type));
12506}
12507
3cb999d8
DE
12508/* Return a reference suitable for calling a function with the
12509 longcall attribute. */
a4f6c312 12510
6a4cee5f
MM
12511struct rtx_def *
12512rs6000_longcall_ref (call_ref)
12513 rtx call_ref;
12514{
d330fd93 12515 const char *call_name;
6a4cee5f
MM
12516 tree node;
12517
12518 if (GET_CODE (call_ref) != SYMBOL_REF)
12519 return call_ref;
12520
12521 /* System V adds '.' to the internal name, so skip them. */
12522 call_name = XSTR (call_ref, 0);
12523 if (*call_name == '.')
12524 {
12525 while (*call_name == '.')
12526 call_name++;
12527
12528 node = get_identifier (call_name);
39403d82 12529 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
6a4cee5f
MM
12530 }
12531
12532 return force_reg (Pmode, call_ref);
12533}
12534
7509c759 12535\f
b64a1b53
RH
12536#ifdef USING_ELFOS_H
12537
7509c759
MM
12538/* A C statement or statements to switch to the appropriate section
12539 for output of RTX in mode MODE. You can assume that RTX is some
12540 kind of constant in RTL. The argument MODE is redundant except in
12541 the case of a `const_int' rtx. Select the section by calling
12542 `text_section' or one of the alternatives for other sections.
12543
12544 Do not define this macro if you put all constants in the read-only
12545 data section. */
12546
b64a1b53
RH
12547static void
12548rs6000_elf_select_rtx_section (mode, x, align)
a9098fd0 12549 enum machine_mode mode;
7509c759 12550 rtx x;
b64a1b53 12551 unsigned HOST_WIDE_INT align;
7509c759 12552{
a9098fd0 12553 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
7509c759 12554 toc_section ();
7509c759 12555 else
b64a1b53 12556 default_elf_select_rtx_section (mode, x, align);
7509c759
MM
12557}
12558
12559/* A C statement or statements to switch to the appropriate
12560 section for output of DECL. DECL is either a `VAR_DECL' node
12561 or a constant of some sort. RELOC indicates whether forming
12562 the initial value of DECL requires link-time relocations. */
12563
ae46c4e0
RH
12564static void
12565rs6000_elf_select_section (decl, reloc, align)
7509c759
MM
12566 tree decl;
12567 int reloc;
0e5dbd9b 12568 unsigned HOST_WIDE_INT align;
7509c759 12569{
0e5dbd9b
DE
12570 default_elf_select_section_1 (decl, reloc, align,
12571 flag_pic || DEFAULT_ABI == ABI_AIX);
63019373
GK
12572}
12573
12574/* A C statement to build up a unique section name, expressed as a
12575 STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
12576 RELOC indicates whether the initial value of EXP requires
12577 link-time relocations. If you do not define this macro, GCC will use
12578 the symbol name prefixed by `.' as the section name. Note - this
f5143c46 12579 macro can now be called for uninitialized data items as well as
4912a07c 12580 initialized data and functions. */
63019373 12581
ae46c4e0
RH
12582static void
12583rs6000_elf_unique_section (decl, reloc)
63019373
GK
12584 tree decl;
12585 int reloc;
12586{
0e5dbd9b
DE
12587 default_unique_section_1 (decl, reloc,
12588 flag_pic || DEFAULT_ABI == ABI_AIX);
7509c759 12589}
d9407988
MM
12590
12591\f
d9407988
MM
12592/* If we are referencing a function that is static or is known to be
12593 in this file, make the SYMBOL_REF special. We can use this to indicate
12594 that we can branch to this function without emitting a no-op after the
9ebbca7d 12595 call. For real AIX calling sequences, we also replace the
d9407988
MM
12596 function name with the real name (1 or 2 leading .'s), rather than
12597 the function descriptor name. This saves a lot of overriding code
a260abc9 12598 to read the prefixes. */
d9407988 12599
fb49053f
RH
12600static void
12601rs6000_elf_encode_section_info (decl, first)
d9407988 12602 tree decl;
b2003250 12603 int first;
d9407988 12604{
b2003250
RH
12605 if (!first)
12606 return;
12607
d9407988
MM
12608 if (TREE_CODE (decl) == FUNCTION_DECL)
12609 {
12610 rtx sym_ref = XEXP (DECL_RTL (decl), 0);
b629ba0c 12611 if ((*targetm.binds_local_p) (decl))
d9407988
MM
12612 SYMBOL_REF_FLAG (sym_ref) = 1;
12613
9ebbca7d 12614 if (DEFAULT_ABI == ABI_AIX)
d9407988 12615 {
ff669a6c
RH
12616 size_t len1 = (DEFAULT_ABI == ABI_AIX) ? 1 : 2;
12617 size_t len2 = strlen (XSTR (sym_ref, 0));
520a57c8 12618 char *str = alloca (len1 + len2 + 1);
ff669a6c
RH
12619 str[0] = '.';
12620 str[1] = '.';
12621 memcpy (str + len1, XSTR (sym_ref, 0), len2 + 1);
12622
520a57c8 12623 XSTR (sym_ref, 0) = ggc_alloc_string (str, len1 + len2);
d9407988
MM
12624 }
12625 }
12626 else if (rs6000_sdata != SDATA_NONE
f607bc57 12627 && DEFAULT_ABI == ABI_V4
d9407988
MM
12628 && TREE_CODE (decl) == VAR_DECL)
12629 {
12630 int size = int_size_in_bytes (TREE_TYPE (decl));
12631 tree section_name = DECL_SECTION_NAME (decl);
d330fd93 12632 const char *name = (char *)0;
d9407988
MM
12633 int len = 0;
12634
12635 if (section_name)
12636 {
12637 if (TREE_CODE (section_name) == STRING_CST)
12638 {
12639 name = TREE_STRING_POINTER (section_name);
12640 len = TREE_STRING_LENGTH (section_name);
12641 }
12642 else
12643 abort ();
12644 }
12645
12646 if ((size > 0 && size <= g_switch_value)
12647 || (name
5f59ecb7 12648 && ((len == sizeof (".sdata") - 1
3cb999d8 12649 && strcmp (name, ".sdata") == 0)
5f59ecb7 12650 || (len == sizeof (".sdata2") - 1
3cb999d8 12651 && strcmp (name, ".sdata2") == 0)
5f59ecb7 12652 || (len == sizeof (".sbss") - 1
3cb999d8 12653 && strcmp (name, ".sbss") == 0)
5f59ecb7 12654 || (len == sizeof (".sbss2") - 1
3cb999d8 12655 && strcmp (name, ".sbss2") == 0)
5f59ecb7 12656 || (len == sizeof (".PPC.EMB.sdata0") - 1
3cb999d8 12657 && strcmp (name, ".PPC.EMB.sdata0") == 0)
5f59ecb7 12658 || (len == sizeof (".PPC.EMB.sbss0") - 1
3cb999d8 12659 && strcmp (name, ".PPC.EMB.sbss0") == 0))))
d9407988
MM
12660 {
12661 rtx sym_ref = XEXP (DECL_RTL (decl), 0);
ff669a6c 12662 size_t len = strlen (XSTR (sym_ref, 0));
88c1e412 12663 char *str = alloca (len + 2);
ff669a6c 12664
ff669a6c
RH
12665 str[0] = '@';
12666 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
88c1e412 12667 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
d9407988
MM
12668 }
12669 }
12670}
12671
772c5265
RH
12672static const char *
12673rs6000_elf_strip_name_encoding (str)
12674 const char *str;
12675{
12676 while (*str == '*' || *str == '@')
12677 str++;
12678 return str;
12679}
12680
0e5dbd9b
DE
12681static bool
12682rs6000_elf_in_small_data_p (decl)
12683 tree decl;
12684{
12685 if (rs6000_sdata == SDATA_NONE)
12686 return false;
12687
12688 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
12689 {
12690 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
12691 if (strcmp (section, ".sdata") == 0
12692 || strcmp (section, ".sdata2") == 0
12693 || strcmp (section, ".sbss") == 0)
12694 return true;
12695 }
12696 else
12697 {
12698 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
12699
12700 if (size > 0
12701 && size <= g_switch_value
12702 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
12703 return true;
12704 }
12705
12706 return false;
12707}
12708
b91da81f 12709#endif /* USING_ELFOS_H */
000034eb 12710
a6c2a102 12711\f
000034eb 12712/* Return a REG that occurs in ADDR with coefficient 1.
02441cd6
JL
12713 ADDR can be effectively incremented by incrementing REG.
12714
12715 r0 is special and we must not select it as an address
12716 register by this routine since our caller will try to
12717 increment the returned register via an "la" instruction. */
000034eb
DE
12718
12719struct rtx_def *
12720find_addr_reg (addr)
12721 rtx addr;
12722{
12723 while (GET_CODE (addr) == PLUS)
12724 {
02441cd6
JL
12725 if (GET_CODE (XEXP (addr, 0)) == REG
12726 && REGNO (XEXP (addr, 0)) != 0)
000034eb 12727 addr = XEXP (addr, 0);
02441cd6
JL
12728 else if (GET_CODE (XEXP (addr, 1)) == REG
12729 && REGNO (XEXP (addr, 1)) != 0)
000034eb
DE
12730 addr = XEXP (addr, 1);
12731 else if (CONSTANT_P (XEXP (addr, 0)))
12732 addr = XEXP (addr, 1);
12733 else if (CONSTANT_P (XEXP (addr, 1)))
12734 addr = XEXP (addr, 0);
12735 else
12736 abort ();
12737 }
02441cd6 12738 if (GET_CODE (addr) == REG && REGNO (addr) != 0)
000034eb
DE
12739 return addr;
12740 abort ();
12741}
12742
a6c2a102
DE
12743void
12744rs6000_fatal_bad_address (op)
12745 rtx op;
12746{
12747 fatal_insn ("bad address", op);
12748}
c8023011
MM
12749
12750/* Called to register all of our global variables with the garbage
12751 collector. */
12752
12753static void
12754rs6000_add_gc_roots ()
12755{
9ebbca7d
GK
12756 toc_hash_table = htab_create (1021, toc_hash_function, toc_hash_eq, NULL);
12757 ggc_add_root (&toc_hash_table, 1, sizeof (toc_hash_table),
12758 toc_hash_mark_table);
ee890fe2
SS
12759}
12760
12761#if TARGET_MACHO
12762
12763#if 0
12764/* Returns 1 if OP is either a symbol reference or a sum of a symbol
12765 reference and a constant. */
12766
12767int
12768symbolic_operand (op)
592696dd 12769 rtx op;
ee890fe2
SS
12770{
12771 switch (GET_CODE (op))
12772 {
12773 case SYMBOL_REF:
12774 case LABEL_REF:
12775 return 1;
12776 case CONST:
12777 op = XEXP (op, 0);
12778 return (GET_CODE (op) == SYMBOL_REF ||
12779 (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
12780 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
12781 && GET_CODE (XEXP (op, 1)) == CONST_INT);
12782 default:
12783 return 0;
12784 }
c8023011 12785}
ee890fe2
SS
12786#endif
12787
12788#ifdef RS6000_LONG_BRANCH
12789
12790static tree stub_list = 0;
12791
12792/* ADD_COMPILER_STUB adds the compiler generated stub for handling
12793 procedure calls to the linked list. */
12794
12795void
12796add_compiler_stub (label_name, function_name, line_number)
12797 tree label_name;
12798 tree function_name;
12799 int line_number;
12800{
12801 tree stub = build_tree_list (function_name, label_name);
12802 TREE_TYPE (stub) = build_int_2 (line_number, 0);
12803 TREE_CHAIN (stub) = stub_list;
12804 stub_list = stub;
12805}
12806
12807#define STUB_LABEL_NAME(STUB) TREE_VALUE (STUB)
12808#define STUB_FUNCTION_NAME(STUB) TREE_PURPOSE (STUB)
12809#define STUB_LINE_NUMBER(STUB) TREE_INT_CST_LOW (TREE_TYPE (STUB))
12810
a4f6c312
SS
12811/* OUTPUT_COMPILER_STUB outputs the compiler generated stub for
12812 handling procedure calls from the linked list and initializes the
12813 linked list. */
ee890fe2 12814
a4f6c312
SS
12815void
12816output_compiler_stub ()
ee890fe2
SS
12817{
12818 char tmp_buf[256];
12819 char label_buf[256];
308c142a 12820 tree stub;
ee890fe2
SS
12821
12822 if (!flag_pic)
12823 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
12824 {
12825 fprintf (asm_out_file,
12826 "%s:\n", IDENTIFIER_POINTER(STUB_LABEL_NAME(stub)));
12827
12828#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
12829 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
12830 fprintf (asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER(stub));
12831#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
12832
12833 if (IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))[0] == '*')
12834 strcpy (label_buf,
12835 IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))+1);
12836 else
12837 {
12838 label_buf[0] = '_';
12839 strcpy (label_buf+1,
12840 IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub)));
12841 }
12842
12843 strcpy (tmp_buf, "lis r12,hi16(");
12844 strcat (tmp_buf, label_buf);
12845 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
12846 strcat (tmp_buf, label_buf);
12847 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
12848 output_asm_insn (tmp_buf, 0);
12849
12850#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
12851 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
12852 fprintf(asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER (stub));
12853#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
12854 }
12855
12856 stub_list = 0;
12857}
12858
12859/* NO_PREVIOUS_DEF checks in the link list whether the function name is
12860 already there or not. */
12861
a4f6c312
SS
12862int
12863no_previous_def (function_name)
ee890fe2
SS
12864 tree function_name;
12865{
12866 tree stub;
12867 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
12868 if (function_name == STUB_FUNCTION_NAME (stub))
12869 return 0;
12870 return 1;
12871}
12872
12873/* GET_PREV_LABEL gets the label name from the previous definition of
12874 the function. */
12875
a4f6c312
SS
12876tree
12877get_prev_label (function_name)
ee890fe2
SS
12878 tree function_name;
12879{
12880 tree stub;
12881 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
12882 if (function_name == STUB_FUNCTION_NAME (stub))
12883 return STUB_LABEL_NAME (stub);
12884 return 0;
12885}
12886
12887/* INSN is either a function call or a millicode call. It may have an
12888 unconditional jump in its delay slot.
12889
12890 CALL_DEST is the routine we are calling. */
12891
12892char *
12893output_call (insn, call_dest, operand_number)
12894 rtx insn;
12895 rtx call_dest;
12896 int operand_number;
12897{
12898 static char buf[256];
12899 if (GET_CODE (call_dest) == SYMBOL_REF && TARGET_LONG_BRANCH && !flag_pic)
12900 {
12901 tree labelname;
12902 tree funname = get_identifier (XSTR (call_dest, 0));
12903
12904 if (no_previous_def (funname))
12905 {
308c142a 12906 int line_number = 0;
ee890fe2
SS
12907 rtx label_rtx = gen_label_rtx ();
12908 char *label_buf, temp_buf[256];
12909 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
12910 CODE_LABEL_NUMBER (label_rtx));
12911 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
12912 labelname = get_identifier (label_buf);
12913 for (; insn && GET_CODE (insn) != NOTE; insn = PREV_INSN (insn));
12914 if (insn)
12915 line_number = NOTE_LINE_NUMBER (insn);
12916 add_compiler_stub (labelname, funname, line_number);
12917 }
12918 else
12919 labelname = get_prev_label (funname);
12920
12921 sprintf (buf, "jbsr %%z%d,%.246s",
12922 operand_number, IDENTIFIER_POINTER (labelname));
12923 return buf;
12924 }
12925 else
12926 {
12927 sprintf (buf, "bl %%z%d", operand_number);
12928 return buf;
12929 }
12930}
12931
12932#endif /* RS6000_LONG_BRANCH */
12933
12934#define GEN_LOCAL_LABEL_FOR_SYMBOL(BUF,SYMBOL,LENGTH,N) \
12935 do { \
83182544 12936 const char *const symbol_ = (SYMBOL); \
ee890fe2
SS
12937 char *buffer_ = (BUF); \
12938 if (symbol_[0] == '"') \
12939 { \
12940 sprintf(buffer_, "\"L%d$%s", (N), symbol_+1); \
12941 } \
12942 else if (name_needs_quotes(symbol_)) \
12943 { \
12944 sprintf(buffer_, "\"L%d$%s\"", (N), symbol_); \
12945 } \
12946 else \
12947 { \
12948 sprintf(buffer_, "L%d$%s", (N), symbol_); \
12949 } \
12950 } while (0)
12951
12952
12953/* Generate PIC and indirect symbol stubs. */
12954
12955void
12956machopic_output_stub (file, symb, stub)
12957 FILE *file;
12958 const char *symb, *stub;
12959{
12960 unsigned int length;
a4f6c312
SS
12961 char *symbol_name, *lazy_ptr_name;
12962 char *local_label_0;
ee890fe2
SS
12963 static int label = 0;
12964
df56a27f 12965 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
772c5265 12966 symb = (*targetm.strip_name_encoding) (symb);
df56a27f 12967
ee890fe2
SS
12968 label += 1;
12969
ee890fe2
SS
12970 length = strlen (symb);
12971 symbol_name = alloca (length + 32);
12972 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
12973
12974 lazy_ptr_name = alloca (length + 32);
12975 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
12976
12977 local_label_0 = alloca (length + 32);
12978 GEN_LOCAL_LABEL_FOR_SYMBOL (local_label_0, symb, length, 0);
12979
ee890fe2
SS
12980 if (flag_pic == 2)
12981 machopic_picsymbol_stub_section ();
12982 else
12983 machopic_symbol_stub_section ();
12984
12985 fprintf (file, "%s:\n", stub);
12986 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
12987
12988 if (flag_pic == 2)
12989 {
12990 fprintf (file, "\tmflr r0\n");
12991 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
12992 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
12993 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
12994 lazy_ptr_name, local_label_0);
12995 fprintf (file, "\tmtlr r0\n");
12996 fprintf (file, "\tlwz r12,lo16(%s-%s)(r11)\n",
12997 lazy_ptr_name, local_label_0);
12998 fprintf (file, "\tmtctr r12\n");
12999 fprintf (file, "\taddi r11,r11,lo16(%s-%s)\n",
13000 lazy_ptr_name, local_label_0);
13001 fprintf (file, "\tbctr\n");
13002 }
13003 else
13004 fprintf (file, "non-pure not supported\n");
13005
13006 machopic_lazy_symbol_ptr_section ();
13007 fprintf (file, "%s:\n", lazy_ptr_name);
13008 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
13009 fprintf (file, "\t.long dyld_stub_binding_helper\n");
13010}
13011
13012/* Legitimize PIC addresses. If the address is already
13013 position-independent, we return ORIG. Newly generated
13014 position-independent addresses go into a reg. This is REG if non
13015 zero, otherwise we allocate register(s) as necessary. */
13016
c859cda6 13017#define SMALL_INT(X) ((unsigned) (INTVAL(X) + 0x8000) < 0x10000)
ee890fe2
SS
13018
13019rtx
13020rs6000_machopic_legitimize_pic_address (orig, mode, reg)
13021 rtx orig;
13022 enum machine_mode mode;
13023 rtx reg;
13024{
13025 rtx base, offset;
13026
13027 if (reg == NULL && ! reload_in_progress && ! reload_completed)
13028 reg = gen_reg_rtx (Pmode);
13029
13030 if (GET_CODE (orig) == CONST)
13031 {
13032 if (GET_CODE (XEXP (orig, 0)) == PLUS
13033 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
13034 return orig;
13035
13036 if (GET_CODE (XEXP (orig, 0)) == PLUS)
13037 {
a4f6c312
SS
13038 base =
13039 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
13040 Pmode, reg);
13041 offset =
13042 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
13043 Pmode, reg);
ee890fe2
SS
13044 }
13045 else
13046 abort ();
13047
13048 if (GET_CODE (offset) == CONST_INT)
13049 {
13050 if (SMALL_INT (offset))
ed8908e7 13051 return plus_constant (base, INTVAL (offset));
ee890fe2
SS
13052 else if (! reload_in_progress && ! reload_completed)
13053 offset = force_reg (Pmode, offset);
13054 else
c859cda6
DJ
13055 {
13056 rtx mem = force_const_mem (Pmode, orig);
13057 return machopic_legitimize_pic_address (mem, Pmode, reg);
13058 }
ee890fe2
SS
13059 }
13060 return gen_rtx (PLUS, Pmode, base, offset);
13061 }
13062
13063 /* Fall back on generic machopic code. */
13064 return machopic_legitimize_pic_address (orig, mode, reg);
13065}
13066
13067/* This is just a placeholder to make linking work without having to
13068 add this to the generic Darwin EXTRA_SECTIONS. If -mcall-aix is
13069 ever needed for Darwin (not too likely!) this would have to get a
13070 real definition. */
13071
13072void
13073toc_section ()
13074{
13075}
13076
13077#endif /* TARGET_MACHO */
7c262518
RH
13078
13079#if TARGET_ELF
13080static unsigned int
13081rs6000_elf_section_type_flags (decl, name, reloc)
13082 tree decl;
13083 const char *name;
13084 int reloc;
13085{
5add3202
DE
13086 unsigned int flags
13087 = default_section_type_flags_1 (decl, name, reloc,
13088 flag_pic || DEFAULT_ABI == ABI_AIX);
7c262518 13089
270fc29b
RH
13090 if (TARGET_RELOCATABLE)
13091 flags |= SECTION_WRITE;
7c262518 13092
d0101753 13093 return flags;
7c262518 13094}
d9f6800d
RH
13095
13096/* Record an element in the table of global constructors. SYMBOL is
13097 a SYMBOL_REF of the function to be called; PRIORITY is a number
13098 between 0 and MAX_INIT_PRIORITY.
13099
13100 This differs from default_named_section_asm_out_constructor in
13101 that we have special handling for -mrelocatable. */
13102
13103static void
13104rs6000_elf_asm_out_constructor (symbol, priority)
13105 rtx symbol;
13106 int priority;
13107{
13108 const char *section = ".ctors";
13109 char buf[16];
13110
13111 if (priority != DEFAULT_INIT_PRIORITY)
13112 {
13113 sprintf (buf, ".ctors.%.5u",
13114 /* Invert the numbering so the linker puts us in the proper
13115 order; constructors are run from right to left, and the
13116 linker sorts in increasing order. */
13117 MAX_INIT_PRIORITY - priority);
13118 section = buf;
13119 }
13120
715bdd29
RH
13121 named_section_flags (section, SECTION_WRITE);
13122 assemble_align (POINTER_SIZE);
d9f6800d
RH
13123
13124 if (TARGET_RELOCATABLE)
13125 {
13126 fputs ("\t.long (", asm_out_file);
13127 output_addr_const (asm_out_file, symbol);
13128 fputs (")@fixup\n", asm_out_file);
13129 }
13130 else
c8af3574 13131 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
d9f6800d
RH
13132}
13133
13134static void
13135rs6000_elf_asm_out_destructor (symbol, priority)
13136 rtx symbol;
13137 int priority;
13138{
13139 const char *section = ".dtors";
13140 char buf[16];
13141
13142 if (priority != DEFAULT_INIT_PRIORITY)
13143 {
13144 sprintf (buf, ".dtors.%.5u",
13145 /* Invert the numbering so the linker puts us in the proper
13146 order; constructors are run from right to left, and the
13147 linker sorts in increasing order. */
13148 MAX_INIT_PRIORITY - priority);
13149 section = buf;
13150 }
13151
715bdd29
RH
13152 named_section_flags (section, SECTION_WRITE);
13153 assemble_align (POINTER_SIZE);
d9f6800d
RH
13154
13155 if (TARGET_RELOCATABLE)
13156 {
13157 fputs ("\t.long (", asm_out_file);
13158 output_addr_const (asm_out_file, symbol);
13159 fputs (")@fixup\n", asm_out_file);
13160 }
13161 else
c8af3574 13162 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
d9f6800d 13163}
7c262518
RH
13164#endif
13165
cbaaba19 13166#if TARGET_XCOFF
7c262518 13167static void
b275d088
DE
13168rs6000_xcoff_asm_globalize_label (stream, name)
13169 FILE *stream;
13170 const char *name;
13171{
13172 fputs (GLOBAL_ASM_OP, stream);
13173 RS6000_OUTPUT_BASENAME (stream, name);
13174 putc ('\n', stream);
13175}
13176
13177static void
13178rs6000_xcoff_asm_named_section (name, flags)
7c262518 13179 const char *name;
0e5dbd9b 13180 unsigned int flags;
7c262518 13181{
0e5dbd9b
DE
13182 int smclass;
13183 static const char * const suffix[3] = { "PR", "RO", "RW" };
13184
13185 if (flags & SECTION_CODE)
13186 smclass = 0;
13187 else if (flags & SECTION_WRITE)
13188 smclass = 2;
13189 else
13190 smclass = 1;
13191
5b5198f7 13192 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
0e5dbd9b 13193 (flags & SECTION_CODE) ? "." : "",
5b5198f7 13194 name, suffix[smclass], flags & SECTION_ENTSIZE);
7c262518 13195}
ae46c4e0
RH
13196
13197static void
0e5dbd9b
DE
13198rs6000_xcoff_select_section (decl, reloc, align)
13199 tree decl;
ae46c4e0
RH
13200 int reloc;
13201 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
13202{
5add3202 13203 if (decl_readonly_section_1 (decl, reloc, 1))
ae46c4e0 13204 {
0e5dbd9b 13205 if (TREE_PUBLIC (decl))
ae46c4e0
RH
13206 read_only_data_section ();
13207 else
13208 read_only_private_data_section ();
13209 }
13210 else
13211 {
0e5dbd9b 13212 if (TREE_PUBLIC (decl))
ae46c4e0
RH
13213 data_section ();
13214 else
13215 private_data_section ();
13216 }
13217}
13218
13219static void
13220rs6000_xcoff_unique_section (decl, reloc)
13221 tree decl;
772c5265 13222 int reloc ATTRIBUTE_UNUSED;
ae46c4e0
RH
13223{
13224 const char *name;
ae46c4e0 13225
5b5198f7
DE
13226 /* Use select_section for private and uninitialized data. */
13227 if (!TREE_PUBLIC (decl)
13228 || DECL_COMMON (decl)
0e5dbd9b
DE
13229 || DECL_INITIAL (decl) == NULL_TREE
13230 || DECL_INITIAL (decl) == error_mark_node
13231 || (flag_zero_initialized_in_bss
13232 && initializer_zerop (DECL_INITIAL (decl))))
13233 return;
13234
13235 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
13236 name = (*targetm.strip_name_encoding) (name);
13237 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
ae46c4e0 13238}
b64a1b53 13239
fb49053f
RH
13240/* Select section for constant in constant pool.
13241
13242 On RS/6000, all constants are in the private read-only data area.
13243 However, if this is being placed in the TOC it must be output as a
13244 toc entry. */
13245
b64a1b53
RH
13246static void
13247rs6000_xcoff_select_rtx_section (mode, x, align)
13248 enum machine_mode mode;
13249 rtx x;
13250 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
13251{
13252 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
13253 toc_section ();
13254 else
13255 read_only_private_data_section ();
13256}
772c5265
RH
13257
13258/* Remove any trailing [DS] or the like from the symbol name. */
13259
13260static const char *
13261rs6000_xcoff_strip_name_encoding (name)
13262 const char *name;
13263{
13264 size_t len;
13265 if (*name == '*')
13266 name++;
13267 len = strlen (name);
13268 if (name[len - 1] == ']')
13269 return ggc_alloc_string (name, len - 4);
13270 else
13271 return name;
13272}
13273
5add3202
DE
13274/* Section attributes. AIX is always PIC. */
13275
13276static unsigned int
13277rs6000_xcoff_section_type_flags (decl, name, reloc)
13278 tree decl;
13279 const char *name;
13280 int reloc;
13281{
5b5198f7
DE
13282 unsigned int align;
13283 unsigned int flags = default_section_type_flags_1 (decl, name, reloc, 1);
13284
13285 /* Align to at least UNIT size. */
13286 if (flags & SECTION_CODE)
13287 align = MIN_UNITS_PER_WORD;
13288 else
13289 /* Increase alignment of large objects if not already stricter. */
13290 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
13291 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
13292 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
13293
13294 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
5add3202
DE
13295}
13296
cbaaba19 13297#endif /* TARGET_XCOFF */
fb49053f 13298
0e5dbd9b 13299/* Note that this is also used for PPC64 Linux. */
fb49053f
RH
13300
13301static void
13302rs6000_xcoff_encode_section_info (decl, first)
13303 tree decl;
13304 int first ATTRIBUTE_UNUSED;
13305{
13306 if (TREE_CODE (decl) == FUNCTION_DECL
b629ba0c 13307 && (*targetm.binds_local_p) (decl))
fb49053f
RH
13308 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
13309}
0e5dbd9b
DE
13310
13311/* Cross-module name binding. For AIX and PPC64 Linux, which always are
13312 PIC, use private copy of flag_pic. */
13313
2bcc50d0 13314static bool
0e5dbd9b
DE
13315rs6000_binds_local_p (decl)
13316 tree decl;
13317{
5add3202 13318 return default_binds_local_p_1 (decl, flag_pic || rs6000_flag_pic);
0e5dbd9b 13319}
34bb030a
DE
13320
13321/* A C expression returning the cost of moving data from a register of class
13322 CLASS1 to one of CLASS2. */
13323
13324int
13325rs6000_register_move_cost (mode, from, to)
13326 enum machine_mode mode;
13327 enum reg_class from, to;
13328{
13329 /* Moves from/to GENERAL_REGS. */
13330 if (reg_classes_intersect_p (to, GENERAL_REGS)
13331 || reg_classes_intersect_p (from, GENERAL_REGS))
13332 {
13333 if (! reg_classes_intersect_p (to, GENERAL_REGS))
13334 from = to;
13335
13336 if (from == FLOAT_REGS || from == ALTIVEC_REGS)
13337 return (rs6000_memory_move_cost (mode, from, 0)
13338 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
13339
13340/* It's more expensive to move CR_REGS than CR0_REGS because of the shift...*/
13341 else if (from == CR_REGS)
13342 return 4;
13343
13344 else
13345/* A move will cost one instruction per GPR moved. */
13346 return 2 * HARD_REGNO_NREGS (0, mode);
13347 }
13348
13349/* Moving between two similar registers is just one instruction. */
13350 else if (reg_classes_intersect_p (to, from))
13351 return mode == TFmode ? 4 : 2;
13352
13353/* Everything else has to go through GENERAL_REGS. */
13354 else
13355 return (rs6000_register_move_cost (mode, GENERAL_REGS, to)
13356 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
13357}
13358
13359/* A C expressions returning the cost of moving data of MODE from a register to
13360 or from memory. */
13361
13362int
13363rs6000_memory_move_cost (mode, class, in)
13364 enum machine_mode mode;
13365 enum reg_class class;
13366 int in ATTRIBUTE_UNUSED;
13367{
13368 if (reg_classes_intersect_p (class, GENERAL_REGS))
13369 return 4 * HARD_REGNO_NREGS (0, mode);
13370 else if (reg_classes_intersect_p (class, FLOAT_REGS))
13371 return 4 * HARD_REGNO_NREGS (32, mode);
13372 else if (reg_classes_intersect_p (class, ALTIVEC_REGS))
13373 return 4 * HARD_REGNO_NREGS (FIRST_ALTIVEC_REGNO, mode);
13374 else
13375 return 4 + rs6000_register_move_cost (mode, class, GENERAL_REGS);
13376}
13377