]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/rs6000/rs6000.c
s390.md (mulsidi3): Set both subregs of the multiword register.
[thirdparty/gcc.git] / gcc / config / rs6000 / rs6000.c
CommitLineData
9878760c 1/* Subroutines used for code generation on IBM RS/6000.
9ebbca7d 2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
95385cbb 3 2000, 2001, 2002 Free Software Foundation, Inc.
fab3bcc3 4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
9878760c
RK
5
6This file is part of GNU CC.
7
8GNU CC is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2, or (at your option)
11any later version.
12
13GNU CC is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GNU CC; see the file COPYING. If not, write to
c15c9075
RK
20the Free Software Foundation, 59 Temple Place - Suite 330,
21Boston, MA 02111-1307, USA. */
9878760c 22
956d6950 23#include "config.h"
c4d38ccb 24#include "system.h"
9878760c
RK
25#include "rtl.h"
26#include "regs.h"
27#include "hard-reg-set.h"
28#include "real.h"
29#include "insn-config.h"
30#include "conditions.h"
9878760c
RK
31#include "insn-attr.h"
32#include "flags.h"
33#include "recog.h"
9878760c 34#include "obstack.h"
9b30bae2 35#include "tree.h"
dfafc897 36#include "expr.h"
2fc1c679 37#include "optabs.h"
2a430ec1 38#include "except.h"
a7df97e6 39#include "function.h"
296b8152 40#include "output.h"
d5fa86ba 41#include "basic-block.h"
d0101753 42#include "integrate.h"
296b8152 43#include "toplev.h"
c8023011 44#include "ggc.h"
9ebbca7d
GK
45#include "hashtab.h"
46#include "tm_p.h"
672a6f42
NB
47#include "target.h"
48#include "target-def.h"
3ac88239 49#include "langhooks.h"
24ea750e 50#include "reload.h"
9b30bae2 51
7509c759
MM
52#ifndef TARGET_NO_PROTOTYPE
53#define TARGET_NO_PROTOTYPE 0
54#endif
55
9878760c
RK
56#define min(A,B) ((A) < (B) ? (A) : (B))
57#define max(A,B) ((A) > (B) ? (A) : (B))
58
5248c961
RK
59/* Target cpu type */
60
61enum processor_type rs6000_cpu;
8e3f41e7
MM
62struct rs6000_cpu_select rs6000_select[3] =
63{
815cdc52
MM
64 /* switch name, tune arch */
65 { (const char *)0, "--with-cpu=", 1, 1 },
66 { (const char *)0, "-mcpu=", 1, 1 },
67 { (const char *)0, "-mtune=", 1, 0 },
8e3f41e7 68};
5248c961 69
6fa3f289
ZW
70/* Size of long double */
71const char *rs6000_long_double_size_string;
72int rs6000_long_double_type_size;
73
74/* Whether -mabi=altivec has appeared */
75int rs6000_altivec_abi;
76
c764f757
RK
77/* Set to non-zero once AIX common-mode calls have been defined. */
78static int common_mode_defined;
c81bebd7 79
9878760c
RK
80/* Save information from a "cmpxx" operation until the branch or scc is
81 emitted. */
9878760c
RK
82rtx rs6000_compare_op0, rs6000_compare_op1;
83int rs6000_compare_fp_p;
874a0744 84
874a0744
MM
85/* Label number of label created for -mrelocatable, to call to so we can
86 get the address of the GOT section */
87int rs6000_pic_labelno;
c81bebd7 88
b91da81f 89#ifdef USING_ELFOS_H
c81bebd7 90/* Which abi to adhere to */
815cdc52 91const char *rs6000_abi_name = RS6000_ABI_NAME;
d9407988
MM
92
93/* Semantics of the small data area */
94enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
95
96/* Which small data model to use */
815cdc52 97const char *rs6000_sdata_name = (char *)0;
9ebbca7d
GK
98
99/* Counter for labels which are to be placed in .fixup. */
100int fixuplabelno = 0;
874a0744 101#endif
4697a36c 102
b6c9286a
MM
103/* ABI enumeration available for subtarget to use. */
104enum rs6000_abi rs6000_current_abi;
105
0ac081f6
AH
106/* ABI string from -mabi= option. */
107const char *rs6000_abi_string;
108
38c1f2d7 109/* Debug flags */
815cdc52 110const char *rs6000_debug_name;
38c1f2d7
MM
111int rs6000_debug_stack; /* debug stack applications */
112int rs6000_debug_arg; /* debug argument handling */
113
114/* Flag to say the TOC is initialized */
115int toc_initialized;
9ebbca7d 116char toc_label_name[10];
38c1f2d7 117
9ebbca7d
GK
118/* Alias set for saves and restores from the rs6000 stack. */
119static int rs6000_sr_alias_set;
c8023011 120
9ebbca7d
GK
121static void rs6000_add_gc_roots PARAMS ((void));
122static int num_insns_constant_wide PARAMS ((HOST_WIDE_INT));
123static rtx expand_block_move_mem PARAMS ((enum machine_mode, rtx, rtx));
39a10a29
GK
124static void validate_condition_mode
125 PARAMS ((enum rtx_code, enum machine_mode));
126static rtx rs6000_generate_compare PARAMS ((enum rtx_code));
e50f5f3d 127static void rs6000_maybe_dead PARAMS ((rtx));
9ebbca7d
GK
128static void rs6000_emit_stack_tie PARAMS ((void));
129static void rs6000_frame_related PARAMS ((rtx, rtx, HOST_WIDE_INT, rtx, rtx));
130static void rs6000_emit_allocate_stack PARAMS ((HOST_WIDE_INT, int));
131static unsigned rs6000_hash_constant PARAMS ((rtx));
132static unsigned toc_hash_function PARAMS ((const void *));
133static int toc_hash_eq PARAMS ((const void *, const void *));
2eba1afa 134static int toc_hash_mark_entry PARAMS ((void **, void *));
9ebbca7d
GK
135static void toc_hash_mark_table PARAMS ((void *));
136static int constant_pool_expr_1 PARAMS ((rtx, int *, int *));
6fee9e99
NC
137static void rs6000_free_machine_status PARAMS ((struct function *));
138static void rs6000_init_machine_status PARAMS ((struct function *));
301d03af 139static bool rs6000_assemble_integer PARAMS ((rtx, unsigned int, int));
71f123ca 140static int rs6000_ra_ever_killed PARAMS ((void));
91d231cb
JM
141static tree rs6000_handle_longcall_attribute PARAMS ((tree *, tree, tree, int, bool *));
142const struct attribute_spec rs6000_attribute_table[];
08c148a8
NB
143static void rs6000_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
144static void rs6000_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
2bfcf297
DB
145static rtx rs6000_emit_set_long_const PARAMS ((rtx,
146 HOST_WIDE_INT, HOST_WIDE_INT));
7c262518
RH
147#if TARGET_ELF
148static unsigned int rs6000_elf_section_type_flags PARAMS ((tree, const char *,
149 int));
d9f6800d
RH
150static void rs6000_elf_asm_out_constructor PARAMS ((rtx, int));
151static void rs6000_elf_asm_out_destructor PARAMS ((rtx, int));
7c262518
RH
152#endif
153#ifdef OBJECT_FORMAT_COFF
715bdd29 154static void xcoff_asm_named_section PARAMS ((const char *, unsigned int));
7c262518 155#endif
c237e94a
ZW
156static int rs6000_adjust_cost PARAMS ((rtx, rtx, rtx, int));
157static int rs6000_adjust_priority PARAMS ((rtx, int));
158static int rs6000_issue_rate PARAMS ((void));
159
6fa3f289 160static void rs6000_init_builtins PARAMS ((void));
0ac081f6
AH
161static void altivec_init_builtins PARAMS ((void));
162static rtx rs6000_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
00b960c7 163static rtx altivec_expand_builtin PARAMS ((tree, rtx));
2212663f 164static rtx altivec_expand_unop_builtin PARAMS ((enum insn_code, tree, rtx));
0ac081f6 165static rtx altivec_expand_binop_builtin PARAMS ((enum insn_code, tree, rtx));
100c4561 166static rtx altivec_expand_abs_builtin PARAMS ((enum insn_code, tree, rtx));
ae4b4a02 167static rtx altivec_expand_predicate_builtin PARAMS ((enum insn_code, const char *, tree, rtx));
2212663f 168static rtx altivec_expand_ternop_builtin PARAMS ((enum insn_code, tree, rtx));
6525c0e7 169static rtx altivec_expand_stv_builtin PARAMS ((enum insn_code, tree));
0ac081f6 170static void rs6000_parse_abi_options PARAMS ((void));
00b960c7
AH
171static int first_altivec_reg_to_save PARAMS ((void));
172static unsigned int compute_vrsave_mask PARAMS ((void));
173static void is_altivec_return_reg PARAMS ((rtx, void *));
174int vrsave_operation PARAMS ((rtx, enum machine_mode));
9aa86737
AH
175static rtx generate_set_vrsave PARAMS ((rtx, rs6000_stack_t *, int));
176static void altivec_frame_fixup PARAMS ((rtx, rtx, HOST_WIDE_INT));
69ef87e2 177static int easy_vector_constant PARAMS ((rtx));
c81bebd7
MM
178\f
179/* Default register names. */
180char rs6000_reg_names[][8] =
181{
802a0058
MM
182 "0", "1", "2", "3", "4", "5", "6", "7",
183 "8", "9", "10", "11", "12", "13", "14", "15",
184 "16", "17", "18", "19", "20", "21", "22", "23",
185 "24", "25", "26", "27", "28", "29", "30", "31",
186 "0", "1", "2", "3", "4", "5", "6", "7",
187 "8", "9", "10", "11", "12", "13", "14", "15",
188 "16", "17", "18", "19", "20", "21", "22", "23",
189 "24", "25", "26", "27", "28", "29", "30", "31",
190 "mq", "lr", "ctr","ap",
191 "0", "1", "2", "3", "4", "5", "6", "7",
0ac081f6
AH
192 "xer",
193 /* AltiVec registers. */
0cd5e3a1
AH
194 "0", "1", "2", "3", "4", "5", "6", "7",
195 "8", "9", "10", "11", "12", "13", "14", "15",
196 "16", "17", "18", "19", "20", "21", "22", "23",
197 "24", "25", "26", "27", "28", "29", "30", "31",
0ac081f6 198 "vrsave"
c81bebd7
MM
199};
200
201#ifdef TARGET_REGNAMES
8b60264b 202static const char alt_reg_names[][8] =
c81bebd7 203{
802a0058
MM
204 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
205 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
206 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
207 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
208 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
209 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
210 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
211 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
212 "mq", "lr", "ctr", "ap",
213 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
0ac081f6
AH
214 "xer",
215 /* AltiVec registers. */
216 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
217 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
218 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
219 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
76a773f3 220 "vrsave"
c81bebd7
MM
221};
222#endif
9878760c 223\f
daf11973
MM
224#ifndef MASK_STRICT_ALIGN
225#define MASK_STRICT_ALIGN 0
226#endif
672a6f42
NB
227\f
228/* Initialize the GCC target structure. */
91d231cb
JM
229#undef TARGET_ATTRIBUTE_TABLE
230#define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
daf11973 231
301d03af
RS
232#undef TARGET_ASM_ALIGNED_DI_OP
233#define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
234
235/* Default unaligned ops are only provided for ELF. Find the ops needed
236 for non-ELF systems. */
237#ifndef OBJECT_FORMAT_ELF
238#ifdef OBJECT_FORMAT_COFF
ae6c1efd 239/* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
301d03af
RS
240 64-bit targets. */
241#undef TARGET_ASM_UNALIGNED_HI_OP
242#define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
243#undef TARGET_ASM_UNALIGNED_SI_OP
244#define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
245#undef TARGET_ASM_UNALIGNED_DI_OP
246#define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
247#else
248/* For Darwin. */
249#undef TARGET_ASM_UNALIGNED_HI_OP
250#define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
251#undef TARGET_ASM_UNALIGNED_SI_OP
252#define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
253#endif
254#endif
255
256/* This hook deals with fixups for relocatable code and DI-mode objects
257 in 64-bit code. */
258#undef TARGET_ASM_INTEGER
259#define TARGET_ASM_INTEGER rs6000_assemble_integer
260
08c148a8
NB
261#undef TARGET_ASM_FUNCTION_PROLOGUE
262#define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
263#undef TARGET_ASM_FUNCTION_EPILOGUE
264#define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
265
7c262518
RH
266#if TARGET_ELF
267#undef TARGET_SECTION_TYPE_FLAGS
268#define TARGET_SECTION_TYPE_FLAGS rs6000_elf_section_type_flags
269#endif
270
c237e94a
ZW
271#undef TARGET_SCHED_ISSUE_RATE
272#define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
273#undef TARGET_SCHED_ADJUST_COST
274#define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
275#undef TARGET_SCHED_ADJUST_PRIORITY
276#define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
277
0ac081f6
AH
278#undef TARGET_INIT_BUILTINS
279#define TARGET_INIT_BUILTINS rs6000_init_builtins
280
281#undef TARGET_EXPAND_BUILTIN
282#define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
283
00b960c7
AH
284/* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
285#define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
286
f6897b10 287struct gcc_target targetm = TARGET_INITIALIZER;
672a6f42 288\f
5248c961
RK
289/* Override command line options. Mostly we process the processor
290 type and sometimes adjust other TARGET_ options. */
291
292void
8e3f41e7 293rs6000_override_options (default_cpu)
d330fd93 294 const char *default_cpu;
5248c961 295{
c4d38ccb 296 size_t i, j;
8e3f41e7 297 struct rs6000_cpu_select *ptr;
5248c961 298
85638c0d
RK
299 /* Simplify the entries below by making a mask for any POWER
300 variant and any PowerPC variant. */
301
938937d8 302#define POWER_MASKS (MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING)
68c49ffa
RK
303#define POWERPC_MASKS (MASK_POWERPC | MASK_PPC_GPOPT \
304 | MASK_PPC_GFXOPT | MASK_POWERPC64)
305#define POWERPC_OPT_MASKS (MASK_PPC_GPOPT | MASK_PPC_GFXOPT)
85638c0d 306
5248c961
RK
307 static struct ptt
308 {
8b60264b
KG
309 const char *const name; /* Canonical processor name. */
310 const enum processor_type processor; /* Processor type enum value. */
311 const int target_enable; /* Target flags to enable. */
312 const int target_disable; /* Target flags to disable. */
313 } const processor_target_table[]
cf27b467
MM
314 = {{"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS,
315 POWER_MASKS | POWERPC_MASKS},
db7f1e43 316 {"power", PROCESSOR_POWER,
938937d8 317 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43 318 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
8e3f41e7
MM
319 {"power2", PROCESSOR_POWER,
320 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
321 POWERPC_MASKS | MASK_NEW_MNEMONICS},
c71791e0
DE
322 {"power3", PROCESSOR_PPC630,
323 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
324 POWER_MASKS | MASK_PPC_GPOPT},
db7f1e43
RK
325 {"powerpc", PROCESSOR_POWERPC,
326 MASK_POWERPC | MASK_NEW_MNEMONICS,
68c49ffa 327 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
3cb999d8
DE
328 {"powerpc64", PROCESSOR_POWERPC64,
329 MASK_POWERPC | MASK_POWERPC64 | MASK_NEW_MNEMONICS,
330 POWER_MASKS | POWERPC_OPT_MASKS},
db7f1e43 331 {"rios", PROCESSOR_RIOS1,
938937d8 332 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
333 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
334 {"rios1", PROCESSOR_RIOS1,
938937d8 335 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
336 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
337 {"rsc", PROCESSOR_PPC601,
938937d8 338 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
339 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
340 {"rsc1", PROCESSOR_PPC601,
938937d8 341 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
342 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
343 {"rios2", PROCESSOR_RIOS2,
938937d8 344 MASK_POWER | MASK_MULTIPLE | MASK_STRING | MASK_POWER2,
db7f1e43 345 POWERPC_MASKS | MASK_NEW_MNEMONICS},
3cb999d8
DE
346 {"rs64a", PROCESSOR_RS64A,
347 MASK_POWERPC | MASK_NEW_MNEMONICS,
348 POWER_MASKS | POWERPC_OPT_MASKS},
a3a1dbf6
MM
349 {"401", PROCESSOR_PPC403,
350 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
351 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
49a0b204 352 {"403", PROCESSOR_PPC403,
daf11973 353 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS | MASK_STRICT_ALIGN,
49a0b204 354 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
d7a5e253
DE
355 {"405", PROCESSOR_PPC405,
356 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
357 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
cf27b467
MM
358 {"505", PROCESSOR_MPCCORE,
359 MASK_POWERPC | MASK_NEW_MNEMONICS,
360 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
5248c961 361 {"601", PROCESSOR_PPC601,
938937d8 362 MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_MULTIPLE | MASK_STRING,
68c49ffa 363 MASK_POWER2 | POWERPC_OPT_MASKS | MASK_POWERPC64},
1ec26da6 364 {"602", PROCESSOR_PPC603,
cf27b467
MM
365 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
366 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
5248c961 367 {"603", PROCESSOR_PPC603,
68c49ffa
RK
368 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
369 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
b6c9286a
MM
370 {"603e", PROCESSOR_PPC603,
371 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
372 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
b5370a88 373 {"ec603e", PROCESSOR_PPC603,
a3a1dbf6
MM
374 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
375 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
5248c961 376 {"604", PROCESSOR_PPC604,
b6c9286a
MM
377 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
378 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
cac8ce95 379 {"604e", PROCESSOR_PPC604e,
07e6159a
MM
380 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
381 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
b6c9286a 382 {"620", PROCESSOR_PPC620,
68c49ffa 383 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
a260abc9 384 POWER_MASKS | MASK_PPC_GPOPT},
3cb999d8
DE
385 {"630", PROCESSOR_PPC630,
386 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
387 POWER_MASKS | MASK_PPC_GPOPT},
bef84347
VM
388 {"740", PROCESSOR_PPC750,
389 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
390 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
391 {"750", PROCESSOR_PPC750,
392 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
393 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
a4f6c312
SS
394 {"7400", PROCESSOR_PPC7400,
395 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
396 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
397 {"7450", PROCESSOR_PPC7450,
398 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
399 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
07e6159a
MM
400 {"801", PROCESSOR_MPCCORE,
401 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
402 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
cf27b467
MM
403 {"821", PROCESSOR_MPCCORE,
404 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
405 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
07e6159a
MM
406 {"823", PROCESSOR_MPCCORE,
407 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
408 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
cf27b467
MM
409 {"860", PROCESSOR_MPCCORE,
410 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
411 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}};
5248c961 412
ca7558fc 413 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
5248c961 414
a4f6c312
SS
415 /* Save current -mmultiple/-mno-multiple status. */
416 int multiple = TARGET_MULTIPLE;
417 /* Save current -mstring/-mno-string status. */
418 int string = TARGET_STRING;
8a61d227 419
a4f6c312 420 /* Identify the processor type. */
8e3f41e7 421 rs6000_select[0].string = default_cpu;
3cb999d8 422 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
8e3f41e7 423
b6a1cbae 424 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
5248c961 425 {
8e3f41e7
MM
426 ptr = &rs6000_select[i];
427 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
5248c961 428 {
8e3f41e7
MM
429 for (j = 0; j < ptt_size; j++)
430 if (! strcmp (ptr->string, processor_target_table[j].name))
431 {
432 if (ptr->set_tune_p)
433 rs6000_cpu = processor_target_table[j].processor;
434
435 if (ptr->set_arch_p)
436 {
437 target_flags |= processor_target_table[j].target_enable;
438 target_flags &= ~processor_target_table[j].target_disable;
439 }
440 break;
441 }
442
4406229e 443 if (j == ptt_size)
8e3f41e7 444 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
5248c961
RK
445 }
446 }
8a61d227 447
a4f6c312
SS
448 /* If we are optimizing big endian systems for space, use the store
449 multiple instructions. */
ef792183
MM
450 if (BYTES_BIG_ENDIAN && optimize_size)
451 target_flags |= MASK_MULTIPLE;
452
8a61d227
MM
453 /* If -mmultiple or -mno-multiple was explicitly used, don't
454 override with the processor default */
455 if (TARGET_MULTIPLE_SET)
456 target_flags = (target_flags & ~MASK_MULTIPLE) | multiple;
7e69e155 457
a4f6c312
SS
458 /* If -mstring or -mno-string was explicitly used, don't override
459 with the processor default. */
938937d8 460 if (TARGET_STRING_SET)
1f5515bf 461 target_flags = (target_flags & ~MASK_STRING) | string;
938937d8 462
a4f6c312
SS
463 /* Don't allow -mmultiple or -mstring on little endian systems
464 unless the cpu is a 750, because the hardware doesn't support the
465 instructions used in little endian mode, and causes an alignment
466 trap. The 750 does not cause an alignment trap (except when the
467 target is unaligned). */
bef84347 468
bfc79d3b 469 if (! BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
7e69e155
MM
470 {
471 if (TARGET_MULTIPLE)
472 {
473 target_flags &= ~MASK_MULTIPLE;
474 if (TARGET_MULTIPLE_SET)
475 warning ("-mmultiple is not supported on little endian systems");
476 }
477
478 if (TARGET_STRING)
479 {
480 target_flags &= ~MASK_STRING;
938937d8
MM
481 if (TARGET_STRING_SET)
482 warning ("-mstring is not supported on little endian systems");
7e69e155
MM
483 }
484 }
3933e0e1 485
3774b567 486 if (flag_pic && DEFAULT_ABI == ABI_AIX && extra_warnings)
a260abc9 487 {
2bfcf297 488 warning ("-f%s ignored (all code is position independent)",
a260abc9
DE
489 (flag_pic > 1) ? "PIC" : "pic");
490 flag_pic = 0;
491 }
492
2bfcf297 493#ifdef XCOFF_DEBUGGING_INFO
9861b0c9 494 if (flag_function_sections && (write_symbols != NO_DEBUG)
2bfcf297 495 && DEFAULT_ABI == ABI_AIX)
9861b0c9
DE
496 {
497 warning ("-ffunction-sections disabled on AIX when debugging");
498 flag_function_sections = 0;
499 }
500
501 if (flag_data_sections && (DEFAULT_ABI == ABI_AIX))
502 {
503 warning ("-fdata-sections not supported on AIX");
504 flag_data_sections = 0;
505 }
2bfcf297 506#endif
9861b0c9 507
38c1f2d7
MM
508 /* Set debug flags */
509 if (rs6000_debug_name)
510 {
bfc79d3b 511 if (! strcmp (rs6000_debug_name, "all"))
38c1f2d7 512 rs6000_debug_stack = rs6000_debug_arg = 1;
bfc79d3b 513 else if (! strcmp (rs6000_debug_name, "stack"))
38c1f2d7 514 rs6000_debug_stack = 1;
bfc79d3b 515 else if (! strcmp (rs6000_debug_name, "arg"))
38c1f2d7
MM
516 rs6000_debug_arg = 1;
517 else
c725bd79 518 error ("unknown -mdebug-%s switch", rs6000_debug_name);
38c1f2d7
MM
519 }
520
6fa3f289
ZW
521 /* Set size of long double */
522 rs6000_long_double_type_size = 64;
523 if (rs6000_long_double_size_string)
524 {
525 char *tail;
526 int size = strtol (rs6000_long_double_size_string, &tail, 10);
527 if (*tail != '\0' || (size != 64 && size != 128))
528 error ("Unknown switch -mlong-double-%s",
529 rs6000_long_double_size_string);
530 else
531 rs6000_long_double_type_size = size;
532 }
533
0ac081f6
AH
534 /* Handle -mabi= options. */
535 rs6000_parse_abi_options ();
536
c81bebd7 537#ifdef TARGET_REGNAMES
a4f6c312
SS
538 /* If the user desires alternate register names, copy in the
539 alternate names now. */
c81bebd7 540 if (TARGET_REGNAMES)
4e135bdd 541 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
c81bebd7
MM
542#endif
543
3933e0e1
MM
544#ifdef SUBTARGET_OVERRIDE_OPTIONS
545 SUBTARGET_OVERRIDE_OPTIONS;
546#endif
10baca6b
AH
547#ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
548 SUBSUBTARGET_OVERRIDE_OPTIONS;
549#endif
c8023011 550
6fa3f289
ZW
551 /* Set TARGET_AIX_STRUCT_RET last, after the ABI is determined.
552 If -maix-struct-return or -msvr4-struct-return was explicitly
553 used, don't override with the ABI default. */
554 if (!(target_flags & MASK_AIX_STRUCT_RET_SET))
555 {
556 if (DEFAULT_ABI == ABI_V4 && !DRAFT_V4_STRUCT_RET)
557 target_flags = (target_flags & ~MASK_AIX_STRUCT_RET);
558 else
559 target_flags |= MASK_AIX_STRUCT_RET;
560 }
561
c8023011
MM
562 /* Register global variables with the garbage collector. */
563 rs6000_add_gc_roots ();
9ebbca7d
GK
564
565 /* Allocate an alias set for register saves & restores from stack. */
566 rs6000_sr_alias_set = new_alias_set ();
567
568 if (TARGET_TOC)
569 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
71f123ca 570
301d03af
RS
571 /* We can only guarantee the availability of DI pseudo-ops when
572 assembling for 64-bit targets. */
ae6c1efd 573 if (!TARGET_64BIT)
301d03af
RS
574 {
575 targetm.asm_out.aligned_op.di = NULL;
576 targetm.asm_out.unaligned_op.di = NULL;
577 }
578
71f123ca
FS
579 /* Arrange to save and restore machine status around nested functions. */
580 init_machine_status = rs6000_init_machine_status;
71f123ca 581 free_machine_status = rs6000_free_machine_status;
5248c961 582}
5accd822 583
0ac081f6 584/* Handle -mabi= options. */
00b960c7
AH
585static void
586rs6000_parse_abi_options ()
0ac081f6
AH
587{
588 if (rs6000_abi_string == 0)
589 return;
590 else if (! strcmp (rs6000_abi_string, "altivec"))
6fa3f289 591 rs6000_altivec_abi = 1;
76a773f3
AH
592 else if (! strcmp (rs6000_abi_string, "no-altivec"))
593 rs6000_altivec_abi = 0;
0ac081f6 594 else
c725bd79 595 error ("unknown ABI specified: '%s'", rs6000_abi_string);
0ac081f6
AH
596}
597
5accd822
DE
598void
599optimization_options (level, size)
e2c953b6 600 int level ATTRIBUTE_UNUSED;
5accd822
DE
601 int size ATTRIBUTE_UNUSED;
602{
5accd822 603}
3cfa4909
MM
604\f
605/* Do anything needed at the start of the asm file. */
606
607void
608rs6000_file_start (file, default_cpu)
609 FILE *file;
d330fd93 610 const char *default_cpu;
3cfa4909 611{
c4d38ccb 612 size_t i;
3cfa4909 613 char buffer[80];
d330fd93 614 const char *start = buffer;
3cfa4909
MM
615 struct rs6000_cpu_select *ptr;
616
617 if (flag_verbose_asm)
618 {
619 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
620 rs6000_select[0].string = default_cpu;
621
b6a1cbae 622 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3cfa4909
MM
623 {
624 ptr = &rs6000_select[i];
625 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
626 {
627 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
628 start = "";
629 }
630 }
631
b91da81f 632#ifdef USING_ELFOS_H
3cfa4909
MM
633 switch (rs6000_sdata)
634 {
635 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
636 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
637 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
638 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
639 }
640
641 if (rs6000_sdata && g_switch_value)
642 {
643 fprintf (file, "%s -G %d", start, g_switch_value);
644 start = "";
645 }
646#endif
647
648 if (*start == '\0')
949ea356 649 putc ('\n', file);
3cfa4909
MM
650 }
651}
652
24d304eb
RK
653\f
654/* Create a CONST_DOUBLE from a string. */
655
656struct rtx_def *
657rs6000_float_const (string, mode)
d330fd93 658 const char *string;
24d304eb
RK
659 enum machine_mode mode;
660{
ca5adc63
GK
661 REAL_VALUE_TYPE value;
662 value = REAL_VALUE_ATOF (string, mode);
24d304eb
RK
663 return immed_real_const_1 (value, mode);
664}
5248c961 665\f
9878760c
RK
666/* Return non-zero if this function is known to have a null epilogue. */
667
668int
669direct_return ()
670{
4697a36c
MM
671 if (reload_completed)
672 {
673 rs6000_stack_t *info = rs6000_stack_info ();
674
675 if (info->first_gp_reg_save == 32
676 && info->first_fp_reg_save == 64
00b960c7 677 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
c81fc13e
DE
678 && ! info->lr_save_p
679 && ! info->cr_save_p
00b960c7 680 && info->vrsave_mask == 0
c81fc13e 681 && ! info->push_p)
4697a36c
MM
682 return 1;
683 }
684
685 return 0;
9878760c
RK
686}
687
688/* Returns 1 always. */
689
690int
691any_operand (op, mode)
592696dd 692 rtx op ATTRIBUTE_UNUSED;
296b8152 693 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
694{
695 return 1;
696}
697
a4f6c312 698/* Returns 1 if op is the count register. */
38c1f2d7 699int
a4f6c312 700count_register_operand (op, mode)
592696dd 701 rtx op;
296b8152 702 enum machine_mode mode ATTRIBUTE_UNUSED;
b6c9286a
MM
703{
704 if (GET_CODE (op) != REG)
705 return 0;
706
707 if (REGNO (op) == COUNT_REGISTER_REGNUM)
708 return 1;
709
710 if (REGNO (op) > FIRST_PSEUDO_REGISTER)
711 return 1;
712
713 return 0;
714}
715
0ec4e2a8
AH
716/* Returns 1 if op is an altivec register. */
717int
718altivec_register_operand (op, mode)
719 rtx op;
720 enum machine_mode mode ATTRIBUTE_UNUSED;
721{
722
723 return (register_operand (op, mode)
724 && (GET_CODE (op) != REG
725 || REGNO (op) > FIRST_PSEUDO_REGISTER
726 || ALTIVEC_REGNO_P (REGNO (op))));
727}
728
38c1f2d7 729int
a4f6c312 730xer_operand (op, mode)
592696dd 731 rtx op;
296b8152 732 enum machine_mode mode ATTRIBUTE_UNUSED;
802a0058
MM
733{
734 if (GET_CODE (op) != REG)
735 return 0;
736
9ebbca7d 737 if (XER_REGNO_P (REGNO (op)))
802a0058
MM
738 return 1;
739
802a0058
MM
740 return 0;
741}
742
c859cda6 743/* Return 1 if OP is a signed 8-bit constant. Int multiplication
6f317ef3 744 by such constants completes more quickly. */
c859cda6
DJ
745
746int
747s8bit_cint_operand (op, mode)
748 rtx op;
749 enum machine_mode mode ATTRIBUTE_UNUSED;
750{
751 return ( GET_CODE (op) == CONST_INT
752 && (INTVAL (op) >= -128 && INTVAL (op) <= 127));
753}
754
9878760c
RK
755/* Return 1 if OP is a constant that can fit in a D field. */
756
757int
758short_cint_operand (op, mode)
592696dd 759 rtx op;
296b8152 760 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 761{
5f59ecb7
DE
762 return (GET_CODE (op) == CONST_INT
763 && CONST_OK_FOR_LETTER_P (INTVAL (op), 'I'));
9878760c
RK
764}
765
5519a4f9 766/* Similar for an unsigned D field. */
9878760c
RK
767
768int
769u_short_cint_operand (op, mode)
592696dd 770 rtx op;
296b8152 771 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 772{
19684119 773 return (GET_CODE (op) == CONST_INT
c1f11548 774 && CONST_OK_FOR_LETTER_P (INTVAL (op) & GET_MODE_MASK (mode), 'K'));
9878760c
RK
775}
776
dcfedcd0
RK
777/* Return 1 if OP is a CONST_INT that cannot fit in a signed D field. */
778
779int
780non_short_cint_operand (op, mode)
592696dd 781 rtx op;
296b8152 782 enum machine_mode mode ATTRIBUTE_UNUSED;
dcfedcd0
RK
783{
784 return (GET_CODE (op) == CONST_INT
a7653a2c 785 && (unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) >= 0x10000);
dcfedcd0
RK
786}
787
2bfcf297
DB
788/* Returns 1 if OP is a CONST_INT that is a positive value
789 and an exact power of 2. */
790
791int
792exact_log2_cint_operand (op, mode)
592696dd 793 rtx op;
2bfcf297
DB
794 enum machine_mode mode ATTRIBUTE_UNUSED;
795{
796 return (GET_CODE (op) == CONST_INT
797 && INTVAL (op) > 0
798 && exact_log2 (INTVAL (op)) >= 0);
799}
800
9878760c
RK
801/* Returns 1 if OP is a register that is not special (i.e., not MQ,
802 ctr, or lr). */
803
804int
cd2b37d9 805gpc_reg_operand (op, mode)
592696dd 806 rtx op;
9878760c
RK
807 enum machine_mode mode;
808{
809 return (register_operand (op, mode)
802a0058 810 && (GET_CODE (op) != REG
9ebbca7d
GK
811 || (REGNO (op) >= ARG_POINTER_REGNUM
812 && !XER_REGNO_P (REGNO (op)))
813 || REGNO (op) < MQ_REGNO));
9878760c
RK
814}
815
816/* Returns 1 if OP is either a pseudo-register or a register denoting a
817 CR field. */
818
819int
820cc_reg_operand (op, mode)
592696dd 821 rtx op;
9878760c
RK
822 enum machine_mode mode;
823{
824 return (register_operand (op, mode)
825 && (GET_CODE (op) != REG
826 || REGNO (op) >= FIRST_PSEUDO_REGISTER
827 || CR_REGNO_P (REGNO (op))));
828}
829
815cdc52
MM
830/* Returns 1 if OP is either a pseudo-register or a register denoting a
831 CR field that isn't CR0. */
832
833int
834cc_reg_not_cr0_operand (op, mode)
592696dd 835 rtx op;
815cdc52
MM
836 enum machine_mode mode;
837{
838 return (register_operand (op, mode)
839 && (GET_CODE (op) != REG
840 || REGNO (op) >= FIRST_PSEUDO_REGISTER
841 || CR_REGNO_NOT_CR0_P (REGNO (op))));
842}
843
a4f6c312
SS
844/* Returns 1 if OP is either a constant integer valid for a D-field or
845 a non-special register. If a register, it must be in the proper
846 mode unless MODE is VOIDmode. */
9878760c
RK
847
848int
849reg_or_short_operand (op, mode)
592696dd 850 rtx op;
9878760c
RK
851 enum machine_mode mode;
852{
f5a28898 853 return short_cint_operand (op, mode) || gpc_reg_operand (op, mode);
9878760c
RK
854}
855
a4f6c312
SS
856/* Similar, except check if the negation of the constant would be
857 valid for a D-field. */
9878760c
RK
858
859int
860reg_or_neg_short_operand (op, mode)
592696dd 861 rtx op;
9878760c
RK
862 enum machine_mode mode;
863{
864 if (GET_CODE (op) == CONST_INT)
865 return CONST_OK_FOR_LETTER_P (INTVAL (op), 'P');
866
cd2b37d9 867 return gpc_reg_operand (op, mode);
9878760c
RK
868}
869
768070a0
TR
870/* Returns 1 if OP is either a constant integer valid for a DS-field or
871 a non-special register. If a register, it must be in the proper
872 mode unless MODE is VOIDmode. */
873
874int
875reg_or_aligned_short_operand (op, mode)
876 rtx op;
877 enum machine_mode mode;
878{
879 if (gpc_reg_operand (op, mode))
880 return 1;
881 else if (short_cint_operand (op, mode) && !(INTVAL (op) & 3))
882 return 1;
883
884 return 0;
885}
886
887
a4f6c312
SS
888/* Return 1 if the operand is either a register or an integer whose
889 high-order 16 bits are zero. */
9878760c
RK
890
891int
892reg_or_u_short_operand (op, mode)
592696dd 893 rtx op;
9878760c
RK
894 enum machine_mode mode;
895{
e675f625 896 return u_short_cint_operand (op, mode) || gpc_reg_operand (op, mode);
9878760c
RK
897}
898
899/* Return 1 is the operand is either a non-special register or ANY
900 constant integer. */
901
902int
903reg_or_cint_operand (op, mode)
592696dd 904 rtx op;
9878760c
RK
905 enum machine_mode mode;
906{
a4f6c312 907 return (GET_CODE (op) == CONST_INT || gpc_reg_operand (op, mode));
f6bf7de2
DE
908}
909
910/* Return 1 is the operand is either a non-special register or ANY
911 32-bit signed constant integer. */
912
913int
914reg_or_arith_cint_operand (op, mode)
592696dd 915 rtx op;
f6bf7de2
DE
916 enum machine_mode mode;
917{
a4f6c312
SS
918 return (gpc_reg_operand (op, mode)
919 || (GET_CODE (op) == CONST_INT
f6bf7de2 920#if HOST_BITS_PER_WIDE_INT != 32
a4f6c312
SS
921 && ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80000000)
922 < (unsigned HOST_WIDE_INT) 0x100000000ll)
f6bf7de2 923#endif
a4f6c312 924 ));
9878760c
RK
925}
926
2bfcf297
DB
927/* Return 1 is the operand is either a non-special register or a 32-bit
928 signed constant integer valid for 64-bit addition. */
929
930int
931reg_or_add_cint64_operand (op, mode)
592696dd 932 rtx op;
2bfcf297
DB
933 enum machine_mode mode;
934{
a4f6c312
SS
935 return (gpc_reg_operand (op, mode)
936 || (GET_CODE (op) == CONST_INT
a65c591c 937#if HOST_BITS_PER_WIDE_INT == 32
a4f6c312 938 && INTVAL (op) < 0x7fff8000
a65c591c 939#else
a4f6c312
SS
940 && ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80008000)
941 < 0x100000000ll)
2bfcf297 942#endif
a4f6c312 943 ));
2bfcf297
DB
944}
945
946/* Return 1 is the operand is either a non-special register or a 32-bit
947 signed constant integer valid for 64-bit subtraction. */
948
949int
950reg_or_sub_cint64_operand (op, mode)
592696dd 951 rtx op;
2bfcf297
DB
952 enum machine_mode mode;
953{
a4f6c312
SS
954 return (gpc_reg_operand (op, mode)
955 || (GET_CODE (op) == CONST_INT
a65c591c 956#if HOST_BITS_PER_WIDE_INT == 32
a4f6c312 957 && (- INTVAL (op)) < 0x7fff8000
a65c591c 958#else
a4f6c312
SS
959 && ((unsigned HOST_WIDE_INT) ((- INTVAL (op)) + 0x80008000)
960 < 0x100000000ll)
2bfcf297 961#endif
a4f6c312 962 ));
2bfcf297
DB
963}
964
9ebbca7d
GK
965/* Return 1 is the operand is either a non-special register or ANY
966 32-bit unsigned constant integer. */
967
968int
1d328b19 969reg_or_logical_cint_operand (op, mode)
592696dd 970 rtx op;
9ebbca7d
GK
971 enum machine_mode mode;
972{
1d328b19
GK
973 if (GET_CODE (op) == CONST_INT)
974 {
975 if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT)
976 {
977 if (GET_MODE_BITSIZE (mode) <= 32)
a4f6c312 978 abort ();
1d328b19
GK
979
980 if (INTVAL (op) < 0)
981 return 0;
982 }
983
984 return ((INTVAL (op) & GET_MODE_MASK (mode)
0858c623 985 & (~ (unsigned HOST_WIDE_INT) 0xffffffff)) == 0);
1d328b19
GK
986 }
987 else if (GET_CODE (op) == CONST_DOUBLE)
988 {
989 if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
990 || mode != DImode)
a4f6c312 991 abort ();
1d328b19
GK
992
993 return CONST_DOUBLE_HIGH (op) == 0;
994 }
995 else
996 return gpc_reg_operand (op, mode);
9ebbca7d
GK
997}
998
51d3e7d6 999/* Return 1 if the operand is an operand that can be loaded via the GOT. */
766a866c
MM
1000
1001int
1002got_operand (op, mode)
592696dd 1003 rtx op;
296b8152 1004 enum machine_mode mode ATTRIBUTE_UNUSED;
766a866c
MM
1005{
1006 return (GET_CODE (op) == SYMBOL_REF
1007 || GET_CODE (op) == CONST
1008 || GET_CODE (op) == LABEL_REF);
1009}
1010
38c1f2d7
MM
1011/* Return 1 if the operand is a simple references that can be loaded via
1012 the GOT (labels involving addition aren't allowed). */
1013
1014int
1015got_no_const_operand (op, mode)
592696dd 1016 rtx op;
296b8152 1017 enum machine_mode mode ATTRIBUTE_UNUSED;
38c1f2d7
MM
1018{
1019 return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF);
1020}
1021
4e74d8ec
MM
1022/* Return the number of instructions it takes to form a constant in an
1023 integer register. */
1024
1025static int
1026num_insns_constant_wide (value)
1027 HOST_WIDE_INT value;
1028{
1029 /* signed constant loadable with {cal|addi} */
5f59ecb7 1030 if (CONST_OK_FOR_LETTER_P (value, 'I'))
0865c631
GK
1031 return 1;
1032
4e74d8ec 1033 /* constant loadable with {cau|addis} */
5f59ecb7 1034 else if (CONST_OK_FOR_LETTER_P (value, 'L'))
4e74d8ec
MM
1035 return 1;
1036
5f59ecb7 1037#if HOST_BITS_PER_WIDE_INT == 64
c81fc13e 1038 else if (TARGET_POWERPC64)
4e74d8ec 1039 {
a65c591c
DE
1040 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
1041 HOST_WIDE_INT high = value >> 31;
4e74d8ec 1042
a65c591c 1043 if (high == 0 || high == -1)
4e74d8ec
MM
1044 return 2;
1045
a65c591c 1046 high >>= 1;
4e74d8ec 1047
a65c591c 1048 if (low == 0)
4e74d8ec 1049 return num_insns_constant_wide (high) + 1;
4e74d8ec
MM
1050 else
1051 return (num_insns_constant_wide (high)
e396202a 1052 + num_insns_constant_wide (low) + 1);
4e74d8ec
MM
1053 }
1054#endif
1055
1056 else
1057 return 2;
1058}
1059
1060int
1061num_insns_constant (op, mode)
1062 rtx op;
1063 enum machine_mode mode;
1064{
4e74d8ec 1065 if (GET_CODE (op) == CONST_INT)
0d30d435
DE
1066 {
1067#if HOST_BITS_PER_WIDE_INT == 64
4e2c1c44
DE
1068 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
1069 && mask64_operand (op, mode))
0d30d435
DE
1070 return 2;
1071 else
1072#endif
1073 return num_insns_constant_wide (INTVAL (op));
1074 }
4e74d8ec 1075
6fc48950
MM
1076 else if (GET_CODE (op) == CONST_DOUBLE && mode == SFmode)
1077 {
1078 long l;
1079 REAL_VALUE_TYPE rv;
1080
1081 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1082 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
e72247f4 1083 return num_insns_constant_wide ((HOST_WIDE_INT) l);
6fc48950
MM
1084 }
1085
47ad8c61 1086 else if (GET_CODE (op) == CONST_DOUBLE)
4e74d8ec 1087 {
47ad8c61
MM
1088 HOST_WIDE_INT low;
1089 HOST_WIDE_INT high;
1090 long l[2];
1091 REAL_VALUE_TYPE rv;
1092 int endian = (WORDS_BIG_ENDIAN == 0);
4e74d8ec 1093
47ad8c61
MM
1094 if (mode == VOIDmode || mode == DImode)
1095 {
1096 high = CONST_DOUBLE_HIGH (op);
1097 low = CONST_DOUBLE_LOW (op);
1098 }
1099 else
1100 {
1101 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1102 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
1103 high = l[endian];
1104 low = l[1 - endian];
1105 }
4e74d8ec 1106
47ad8c61
MM
1107 if (TARGET_32BIT)
1108 return (num_insns_constant_wide (low)
1109 + num_insns_constant_wide (high));
4e74d8ec
MM
1110
1111 else
47ad8c61 1112 {
e72247f4 1113 if (high == 0 && low >= 0)
47ad8c61
MM
1114 return num_insns_constant_wide (low);
1115
e72247f4 1116 else if (high == -1 && low < 0)
47ad8c61
MM
1117 return num_insns_constant_wide (low);
1118
a260abc9
DE
1119 else if (mask64_operand (op, mode))
1120 return 2;
1121
47ad8c61
MM
1122 else if (low == 0)
1123 return num_insns_constant_wide (high) + 1;
1124
1125 else
1126 return (num_insns_constant_wide (high)
1127 + num_insns_constant_wide (low) + 1);
1128 }
4e74d8ec
MM
1129 }
1130
1131 else
1132 abort ();
1133}
1134
a4f6c312
SS
1135/* Return 1 if the operand is a CONST_DOUBLE and it can be put into a
1136 register with one instruction per word. We only do this if we can
1137 safely read CONST_DOUBLE_{LOW,HIGH}. */
9878760c
RK
1138
1139int
1140easy_fp_constant (op, mode)
592696dd
SS
1141 rtx op;
1142 enum machine_mode mode;
9878760c 1143{
9878760c
RK
1144 if (GET_CODE (op) != CONST_DOUBLE
1145 || GET_MODE (op) != mode
4e74d8ec 1146 || (GET_MODE_CLASS (mode) != MODE_FLOAT && mode != DImode))
9878760c
RK
1147 return 0;
1148
a4f6c312 1149 /* Consider all constants with -msoft-float to be easy. */
4e74d8ec 1150 if (TARGET_SOFT_FLOAT && mode != DImode)
b6c9286a
MM
1151 return 1;
1152
a4f6c312 1153 /* If we are using V.4 style PIC, consider all constants to be hard. */
f607bc57 1154 if (flag_pic && DEFAULT_ABI == ABI_V4)
a7273471
MM
1155 return 0;
1156
5ae4759c 1157#ifdef TARGET_RELOCATABLE
a4f6c312
SS
1158 /* Similarly if we are using -mrelocatable, consider all constants
1159 to be hard. */
5ae4759c
MM
1160 if (TARGET_RELOCATABLE)
1161 return 0;
1162#endif
1163
042259f2
DE
1164 if (mode == DFmode)
1165 {
1166 long k[2];
1167 REAL_VALUE_TYPE rv;
1168
1169 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1170 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
9878760c 1171
a65c591c
DE
1172 return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1
1173 && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1);
042259f2 1174 }
4e74d8ec
MM
1175
1176 else if (mode == SFmode)
042259f2
DE
1177 {
1178 long l;
1179 REAL_VALUE_TYPE rv;
1180
1181 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1182 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
9878760c 1183
4e74d8ec 1184 return num_insns_constant_wide (l) == 1;
042259f2 1185 }
4e74d8ec 1186
a260abc9 1187 else if (mode == DImode)
c81fc13e 1188 return ((TARGET_POWERPC64
a260abc9
DE
1189 && GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_LOW (op) == 0)
1190 || (num_insns_constant (op, DImode) <= 2));
4e74d8ec 1191
a9098fd0
GK
1192 else if (mode == SImode)
1193 return 1;
4e74d8ec
MM
1194 else
1195 abort ();
9878760c 1196}
8f75773e 1197
69ef87e2
AH
1198/* Return 1 if the operand is a CONST_INT and can be put into a
1199 register with one instruction. */
1200
1201static int
1202easy_vector_constant (op)
1203 rtx op;
1204{
1205 rtx elt;
1206 int units, i;
1207
1208 if (GET_CODE (op) != CONST_VECTOR)
1209 return 0;
1210
1211 units = CONST_VECTOR_NUNITS (op);
1212
1213 /* We can generate 0 easily. Look for that. */
1214 for (i = 0; i < units; ++i)
1215 {
1216 elt = CONST_VECTOR_ELT (op, i);
1217
1218 /* We could probably simplify this by just checking for equality
1219 with CONST0_RTX for the current mode, but let's be safe
1220 instead. */
1221
98ef3137
JJ
1222 switch (GET_CODE (elt))
1223 {
1224 case CONST_INT:
1225 if (INTVAL (elt) != 0)
1226 return 0;
1227 break;
1228 case CONST_DOUBLE:
1229 if (CONST_DOUBLE_LOW (elt) != 0 || CONST_DOUBLE_HIGH (elt) != 0)
1230 return 0;
1231 break;
1232 default:
1233 return 0;
1234 }
69ef87e2
AH
1235 }
1236
1237 /* We could probably generate a few other constants trivially, but
1238 gcc doesn't generate them yet. FIXME later. */
98ef3137 1239 return 1;
69ef87e2
AH
1240}
1241
1242/* Return 1 if the operand is the constant 0. This works for scalars
1243 as well as vectors. */
1244int
1245zero_constant (op, mode)
1246 rtx op;
1247 enum machine_mode mode;
1248{
1249 return op == CONST0_RTX (mode);
1250}
1251
50a0b056
GK
1252/* Return 1 if the operand is 0.0. */
1253int
1254zero_fp_constant (op, mode)
592696dd
SS
1255 rtx op;
1256 enum machine_mode mode;
50a0b056
GK
1257{
1258 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
1259}
1260
a4f6c312
SS
1261/* Return 1 if the operand is in volatile memory. Note that during
1262 the RTL generation phase, memory_operand does not return TRUE for
b6c9286a
MM
1263 volatile memory references. So this function allows us to
1264 recognize volatile references where its safe. */
1265
1266int
1267volatile_mem_operand (op, mode)
592696dd 1268 rtx op;
b6c9286a
MM
1269 enum machine_mode mode;
1270{
1271 if (GET_CODE (op) != MEM)
1272 return 0;
1273
1274 if (!MEM_VOLATILE_P (op))
1275 return 0;
1276
1277 if (mode != GET_MODE (op))
1278 return 0;
1279
1280 if (reload_completed)
1281 return memory_operand (op, mode);
1282
1283 if (reload_in_progress)
1284 return strict_memory_address_p (mode, XEXP (op, 0));
1285
1286 return memory_address_p (mode, XEXP (op, 0));
1287}
1288
97f6e72f 1289/* Return 1 if the operand is an offsettable memory operand. */
914c2e77
RK
1290
1291int
97f6e72f 1292offsettable_mem_operand (op, mode)
592696dd 1293 rtx op;
914c2e77
RK
1294 enum machine_mode mode;
1295{
97f6e72f 1296 return ((GET_CODE (op) == MEM)
677a9668 1297 && offsettable_address_p (reload_completed || reload_in_progress,
97f6e72f 1298 mode, XEXP (op, 0)));
914c2e77
RK
1299}
1300
9878760c
RK
1301/* Return 1 if the operand is either an easy FP constant (see above) or
1302 memory. */
1303
1304int
1305mem_or_easy_const_operand (op, mode)
592696dd 1306 rtx op;
9878760c
RK
1307 enum machine_mode mode;
1308{
1309 return memory_operand (op, mode) || easy_fp_constant (op, mode);
1310}
1311
1312/* Return 1 if the operand is either a non-special register or an item
5f59ecb7 1313 that can be used as the operand of a `mode' add insn. */
9878760c
RK
1314
1315int
1316add_operand (op, mode)
592696dd 1317 rtx op;
9878760c
RK
1318 enum machine_mode mode;
1319{
2bfcf297 1320 if (GET_CODE (op) == CONST_INT)
e72247f4
DE
1321 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
1322 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
2bfcf297
DB
1323
1324 return gpc_reg_operand (op, mode);
9878760c
RK
1325}
1326
dcfedcd0
RK
1327/* Return 1 if OP is a constant but not a valid add_operand. */
1328
1329int
1330non_add_cint_operand (op, mode)
592696dd 1331 rtx op;
296b8152 1332 enum machine_mode mode ATTRIBUTE_UNUSED;
dcfedcd0
RK
1333{
1334 return (GET_CODE (op) == CONST_INT
e72247f4
DE
1335 && !CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
1336 && !CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
dcfedcd0
RK
1337}
1338
9878760c
RK
1339/* Return 1 if the operand is a non-special register or a constant that
1340 can be used as the operand of an OR or XOR insn on the RS/6000. */
1341
1342int
1343logical_operand (op, mode)
592696dd 1344 rtx op;
9878760c
RK
1345 enum machine_mode mode;
1346{
40501e5f 1347 HOST_WIDE_INT opl, oph;
1d328b19 1348
dfbdccdb
GK
1349 if (gpc_reg_operand (op, mode))
1350 return 1;
1d328b19 1351
dfbdccdb 1352 if (GET_CODE (op) == CONST_INT)
40501e5f
AM
1353 {
1354 opl = INTVAL (op) & GET_MODE_MASK (mode);
1355
1356#if HOST_BITS_PER_WIDE_INT <= 32
1357 if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT && opl < 0)
1358 return 0;
1359#endif
1360 }
dfbdccdb
GK
1361 else if (GET_CODE (op) == CONST_DOUBLE)
1362 {
1d328b19 1363 if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
40501e5f 1364 abort ();
1d328b19
GK
1365
1366 opl = CONST_DOUBLE_LOW (op);
1367 oph = CONST_DOUBLE_HIGH (op);
40501e5f 1368 if (oph != 0)
38886f37 1369 return 0;
dfbdccdb
GK
1370 }
1371 else
1372 return 0;
1d328b19 1373
40501e5f
AM
1374 return ((opl & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0
1375 || (opl & ~ (unsigned HOST_WIDE_INT) 0xffff0000) == 0);
9878760c
RK
1376}
1377
dcfedcd0 1378/* Return 1 if C is a constant that is not a logical operand (as
1d328b19 1379 above), but could be split into one. */
dcfedcd0
RK
1380
1381int
1382non_logical_cint_operand (op, mode)
592696dd 1383 rtx op;
5f59ecb7 1384 enum machine_mode mode;
dcfedcd0 1385{
dfbdccdb 1386 return ((GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE)
1d328b19
GK
1387 && ! logical_operand (op, mode)
1388 && reg_or_logical_cint_operand (op, mode));
dcfedcd0
RK
1389}
1390
19ba8161 1391/* Return 1 if C is a constant that can be encoded in a 32-bit mask on the
9878760c
RK
1392 RS/6000. It is if there are no more than two 1->0 or 0->1 transitions.
1393 Reject all ones and all zeros, since these should have been optimized
1394 away and confuse the making of MB and ME. */
1395
1396int
19ba8161 1397mask_operand (op, mode)
592696dd 1398 rtx op;
19ba8161 1399 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 1400{
02071907 1401 HOST_WIDE_INT c, lsb;
9878760c 1402
19ba8161
DE
1403 if (GET_CODE (op) != CONST_INT)
1404 return 0;
1405
1406 c = INTVAL (op);
1407
57deb3a1
AM
1408 /* Fail in 64-bit mode if the mask wraps around because the upper
1409 32-bits of the mask will all be 1s, contrary to GCC's internal view. */
1410 if (TARGET_POWERPC64 && (c & 0x80000001) == 0x80000001)
1411 return 0;
1412
c5059423
AM
1413 /* We don't change the number of transitions by inverting,
1414 so make sure we start with the LS bit zero. */
1415 if (c & 1)
1416 c = ~c;
1417
1418 /* Reject all zeros or all ones. */
1419 if (c == 0)
9878760c
RK
1420 return 0;
1421
c5059423
AM
1422 /* Find the first transition. */
1423 lsb = c & -c;
1424
1425 /* Invert to look for a second transition. */
1426 c = ~c;
9878760c 1427
c5059423
AM
1428 /* Erase first transition. */
1429 c &= -lsb;
9878760c 1430
c5059423
AM
1431 /* Find the second transition (if any). */
1432 lsb = c & -c;
1433
1434 /* Match if all the bits above are 1's (or c is zero). */
1435 return c == -lsb;
9878760c
RK
1436}
1437
a260abc9
DE
1438/* Return 1 if the operand is a constant that is a PowerPC64 mask.
1439 It is if there are no more than one 1->0 or 0->1 transitions.
1440 Reject all ones and all zeros, since these should have been optimized
1441 away and confuse the making of MB and ME. */
9878760c
RK
1442
1443int
a260abc9 1444mask64_operand (op, mode)
592696dd 1445 rtx op;
a260abc9
DE
1446 enum machine_mode mode;
1447{
1448 if (GET_CODE (op) == CONST_INT)
1449 {
02071907 1450 HOST_WIDE_INT c, lsb;
a260abc9 1451
c5059423
AM
1452 /* We don't change the number of transitions by inverting,
1453 so make sure we start with the LS bit zero. */
1454 c = INTVAL (op);
1455 if (c & 1)
1456 c = ~c;
a260abc9 1457
c5059423
AM
1458 /* Reject all zeros or all ones. */
1459 if (c == 0)
e2c953b6
DE
1460 return 0;
1461
c5059423
AM
1462 /* Find the transition, and check that all bits above are 1's. */
1463 lsb = c & -c;
1464 return c == -lsb;
e2c953b6 1465 }
a260abc9
DE
1466 else if (GET_CODE (op) == CONST_DOUBLE
1467 && (mode == VOIDmode || mode == DImode))
1468 {
02071907 1469 HOST_WIDE_INT low, high, lsb;
a260abc9 1470
c5059423
AM
1471 if (HOST_BITS_PER_WIDE_INT < 64)
1472 high = CONST_DOUBLE_HIGH (op);
a260abc9 1473
c5059423
AM
1474 low = CONST_DOUBLE_LOW (op);
1475 if (low & 1)
1476 {
1477 if (HOST_BITS_PER_WIDE_INT < 64)
1478 high = ~high;
1479 low = ~low;
1480 }
a260abc9 1481
c5059423
AM
1482 if (low == 0)
1483 {
1484 if (HOST_BITS_PER_WIDE_INT >= 64 || high == 0)
1485 return 0;
a260abc9 1486
c5059423
AM
1487 lsb = high & -high;
1488 return high == -lsb;
1489 }
a260abc9 1490
c5059423
AM
1491 lsb = low & -low;
1492 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
a260abc9
DE
1493 }
1494 else
1495 return 0;
1496}
1497
1498/* Return 1 if the operand is either a non-special register or a constant
1499 that can be used as the operand of a PowerPC64 logical AND insn. */
1500
1501int
1502and64_operand (op, mode)
592696dd 1503 rtx op;
9878760c
RK
1504 enum machine_mode mode;
1505{
a4f6c312 1506 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
52d3af72
DE
1507 return (gpc_reg_operand (op, mode) || mask64_operand (op, mode));
1508
1509 return (logical_operand (op, mode) || mask64_operand (op, mode));
9878760c
RK
1510}
1511
a260abc9
DE
1512/* Return 1 if the operand is either a non-special register or a
1513 constant that can be used as the operand of an RS/6000 logical AND insn. */
dcfedcd0
RK
1514
1515int
a260abc9 1516and_operand (op, mode)
592696dd 1517 rtx op;
a260abc9 1518 enum machine_mode mode;
dcfedcd0 1519{
a4f6c312 1520 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
52d3af72
DE
1521 return (gpc_reg_operand (op, mode) || mask_operand (op, mode));
1522
1523 return (logical_operand (op, mode) || mask_operand (op, mode));
dcfedcd0
RK
1524}
1525
9878760c
RK
1526/* Return 1 if the operand is a general register or memory operand. */
1527
1528int
1529reg_or_mem_operand (op, mode)
592696dd
SS
1530 rtx op;
1531 enum machine_mode mode;
9878760c 1532{
b6c9286a
MM
1533 return (gpc_reg_operand (op, mode)
1534 || memory_operand (op, mode)
1535 || volatile_mem_operand (op, mode));
9878760c
RK
1536}
1537
a7a813f7 1538/* Return 1 if the operand is a general register or memory operand without
3cb999d8 1539 pre_inc or pre_dec which produces invalid form of PowerPC lwa
a7a813f7
RK
1540 instruction. */
1541
1542int
1543lwa_operand (op, mode)
592696dd
SS
1544 rtx op;
1545 enum machine_mode mode;
a7a813f7
RK
1546{
1547 rtx inner = op;
1548
1549 if (reload_completed && GET_CODE (inner) == SUBREG)
1550 inner = SUBREG_REG (inner);
1551
1552 return gpc_reg_operand (inner, mode)
1553 || (memory_operand (inner, mode)
1554 && GET_CODE (XEXP (inner, 0)) != PRE_INC
6a40a9d6
DE
1555 && GET_CODE (XEXP (inner, 0)) != PRE_DEC
1556 && (GET_CODE (XEXP (inner, 0)) != PLUS
e903c96a
DE
1557 || GET_CODE (XEXP (XEXP (inner, 0), 1)) != CONST_INT
1558 || INTVAL (XEXP (XEXP (inner, 0), 1)) % 4 == 0));
a7a813f7
RK
1559}
1560
cc4d5fec
JH
1561/* Return 1 if the operand, used inside a MEM, is a SYMBOL_REF. */
1562
1563int
1564symbol_ref_operand (op, mode)
1565 rtx op;
1566 enum machine_mode mode;
1567{
1568 if (mode != VOIDmode && GET_MODE (op) != mode)
1569 return 0;
1570
1571 return (GET_CODE (op) == SYMBOL_REF);
1572}
1573
9878760c 1574/* Return 1 if the operand, used inside a MEM, is a valid first argument
cc4d5fec 1575 to CALL. This is a SYMBOL_REF, a pseudo-register, LR or CTR. */
9878760c
RK
1576
1577int
1578call_operand (op, mode)
592696dd 1579 rtx op;
9878760c
RK
1580 enum machine_mode mode;
1581{
1582 if (mode != VOIDmode && GET_MODE (op) != mode)
1583 return 0;
1584
1585 return (GET_CODE (op) == SYMBOL_REF
cc4d5fec
JH
1586 || (GET_CODE (op) == REG
1587 && (REGNO (op) == LINK_REGISTER_REGNUM
1588 || REGNO (op) == COUNT_REGISTER_REGNUM
1589 || REGNO (op) >= FIRST_PSEUDO_REGISTER)));
9878760c
RK
1590}
1591
2af3d377 1592/* Return 1 if the operand is a SYMBOL_REF for a function known to be in
a4f6c312 1593 this file and the function is not weakly defined. */
2af3d377
RK
1594
1595int
1596current_file_function_operand (op, mode)
592696dd 1597 rtx op;
296b8152 1598 enum machine_mode mode ATTRIBUTE_UNUSED;
2af3d377
RK
1599{
1600 return (GET_CODE (op) == SYMBOL_REF
1601 && (SYMBOL_REF_FLAG (op)
8f1b829e 1602 || (op == XEXP (DECL_RTL (current_function_decl), 0)
c81fc13e 1603 && ! DECL_WEAK (current_function_decl))));
2af3d377
RK
1604}
1605
9878760c
RK
1606/* Return 1 if this operand is a valid input for a move insn. */
1607
1608int
1609input_operand (op, mode)
592696dd 1610 rtx op;
9878760c
RK
1611 enum machine_mode mode;
1612{
eb4e8003 1613 /* Memory is always valid. */
9878760c
RK
1614 if (memory_operand (op, mode))
1615 return 1;
1616
34792e82 1617 /* Only a tiny bit of handling for CONSTANT_P_RTX is necessary. */
01b4cf2b 1618 if (GET_CODE (op) == CONSTANT_P_RTX)
34792e82
JL
1619 return 1;
1620
eb4e8003
RK
1621 /* For floating-point, easy constants are valid. */
1622 if (GET_MODE_CLASS (mode) == MODE_FLOAT
1623 && CONSTANT_P (op)
1624 && easy_fp_constant (op, mode))
1625 return 1;
1626
4e74d8ec
MM
1627 /* Allow any integer constant. */
1628 if (GET_MODE_CLASS (mode) == MODE_INT
e675f625 1629 && (GET_CODE (op) == CONST_INT
e675f625 1630 || GET_CODE (op) == CONST_DOUBLE))
4e74d8ec
MM
1631 return 1;
1632
eb4e8003
RK
1633 /* For floating-point or multi-word mode, the only remaining valid type
1634 is a register. */
9878760c
RK
1635 if (GET_MODE_CLASS (mode) == MODE_FLOAT
1636 || GET_MODE_SIZE (mode) > UNITS_PER_WORD)
eb4e8003 1637 return register_operand (op, mode);
9878760c 1638
88fe15a1
RK
1639 /* The only cases left are integral modes one word or smaller (we
1640 do not get called for MODE_CC values). These can be in any
1641 register. */
1642 if (register_operand (op, mode))
a8b3aeda 1643 return 1;
88fe15a1 1644
84cf9dda 1645 /* A SYMBOL_REF referring to the TOC is valid. */
7fec4abd 1646 if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (op))
84cf9dda
RK
1647 return 1;
1648
9ebbca7d
GK
1649 /* A constant pool expression (relative to the TOC) is valid */
1650 if (TOC_RELATIVE_EXPR_P (op))
b6c9286a
MM
1651 return 1;
1652
88228c4b
MM
1653 /* V.4 allows SYMBOL_REFs and CONSTs that are in the small data region
1654 to be valid. */
f607bc57 1655 if (DEFAULT_ABI == ABI_V4
88228c4b
MM
1656 && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST)
1657 && small_data_operand (op, Pmode))
1658 return 1;
1659
042259f2 1660 return 0;
9878760c 1661}
7509c759 1662
a4f6c312 1663/* Return 1 for an operand in small memory on V.4/eabi. */
7509c759
MM
1664
1665int
1666small_data_operand (op, mode)
296b8152
KG
1667 rtx op ATTRIBUTE_UNUSED;
1668 enum machine_mode mode ATTRIBUTE_UNUSED;
7509c759 1669{
38c1f2d7 1670#if TARGET_ELF
5f59ecb7 1671 rtx sym_ref;
7509c759 1672
d9407988 1673 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
a54d04b7 1674 return 0;
a54d04b7 1675
f607bc57 1676 if (DEFAULT_ABI != ABI_V4)
7509c759
MM
1677 return 0;
1678
88228c4b
MM
1679 if (GET_CODE (op) == SYMBOL_REF)
1680 sym_ref = op;
1681
1682 else if (GET_CODE (op) != CONST
1683 || GET_CODE (XEXP (op, 0)) != PLUS
1684 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
1685 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
7509c759
MM
1686 return 0;
1687
88228c4b 1688 else
dbf55e53
MM
1689 {
1690 rtx sum = XEXP (op, 0);
1691 HOST_WIDE_INT summand;
1692
1693 /* We have to be careful here, because it is the referenced address
1694 that must be 32k from _SDA_BASE_, not just the symbol. */
1695 summand = INTVAL (XEXP (sum, 1));
1696 if (summand < 0 || summand > g_switch_value)
1697 return 0;
1698
1699 sym_ref = XEXP (sum, 0);
1700 }
88228c4b
MM
1701
1702 if (*XSTR (sym_ref, 0) != '@')
7509c759
MM
1703 return 0;
1704
1705 return 1;
d9407988
MM
1706
1707#else
1708 return 0;
1709#endif
7509c759 1710}
9ebbca7d
GK
1711\f
1712static int
1713constant_pool_expr_1 (op, have_sym, have_toc)
1714 rtx op;
1715 int *have_sym;
1716 int *have_toc;
1717{
1718 switch (GET_CODE(op))
1719 {
1720 case SYMBOL_REF:
a4f6c312
SS
1721 if (CONSTANT_POOL_ADDRESS_P (op))
1722 {
1723 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op), Pmode))
1724 {
1725 *have_sym = 1;
1726 return 1;
1727 }
1728 else
1729 return 0;
1730 }
1731 else if (! strcmp (XSTR (op, 0), toc_label_name))
1732 {
1733 *have_toc = 1;
1734 return 1;
1735 }
1736 else
1737 return 0;
9ebbca7d
GK
1738 case PLUS:
1739 case MINUS:
c1f11548
DE
1740 return (constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc)
1741 && constant_pool_expr_1 (XEXP (op, 1), have_sym, have_toc));
9ebbca7d 1742 case CONST:
a4f6c312 1743 return constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc);
9ebbca7d 1744 case CONST_INT:
a4f6c312 1745 return 1;
9ebbca7d 1746 default:
a4f6c312 1747 return 0;
9ebbca7d
GK
1748 }
1749}
1750
1751int
1752constant_pool_expr_p (op)
1753 rtx op;
1754{
1755 int have_sym = 0;
1756 int have_toc = 0;
1757 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym;
1758}
1759
1760int
1761toc_relative_expr_p (op)
1762 rtx op;
1763{
1764 int have_sym = 0;
1765 int have_toc = 0;
1766 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
1767}
1768
1769/* Try machine-dependent ways of modifying an illegitimate address
1770 to be legitimate. If we find one, return the new, valid address.
1771 This is used from only one place: `memory_address' in explow.c.
1772
a4f6c312
SS
1773 OLDX is the address as it was before break_out_memory_refs was
1774 called. In some cases it is useful to look at this to decide what
1775 needs to be done.
9ebbca7d 1776
a4f6c312 1777 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
9ebbca7d 1778
a4f6c312
SS
1779 It is always safe for this function to do nothing. It exists to
1780 recognize opportunities to optimize the output.
9ebbca7d
GK
1781
1782 On RS/6000, first check for the sum of a register with a constant
1783 integer that is out of range. If so, generate code to add the
1784 constant with the low-order 16 bits masked to the register and force
1785 this result into another register (this can be done with `cau').
1786 Then generate an address of REG+(CONST&0xffff), allowing for the
1787 possibility of bit 16 being a one.
1788
1789 Then check for the sum of a register and something not constant, try to
1790 load the other things into a register and return the sum. */
1791rtx
1792rs6000_legitimize_address (x, oldx, mode)
1793 rtx x;
1794 rtx oldx ATTRIBUTE_UNUSED;
1795 enum machine_mode mode;
0ac081f6 1796{
9ebbca7d
GK
1797 if (GET_CODE (x) == PLUS
1798 && GET_CODE (XEXP (x, 0)) == REG
1799 && GET_CODE (XEXP (x, 1)) == CONST_INT
1800 && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) >= 0x10000)
1801 {
1802 HOST_WIDE_INT high_int, low_int;
1803 rtx sum;
a65c591c
DE
1804 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
1805 high_int = INTVAL (XEXP (x, 1)) - low_int;
9ebbca7d
GK
1806 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
1807 GEN_INT (high_int)), 0);
1808 return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));
1809 }
1810 else if (GET_CODE (x) == PLUS
1811 && GET_CODE (XEXP (x, 0)) == REG
1812 && GET_CODE (XEXP (x, 1)) != CONST_INT
6ac7bf2c 1813 && GET_MODE_NUNITS (mode) == 1
9ebbca7d
GK
1814 && (TARGET_HARD_FLOAT || TARGET_POWERPC64 || mode != DFmode)
1815 && (TARGET_POWERPC64 || mode != DImode)
1816 && mode != TImode)
1817 {
1818 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
1819 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
1820 }
0ac081f6
AH
1821 else if (ALTIVEC_VECTOR_MODE (mode))
1822 {
1823 rtx reg;
1824
1825 /* Make sure both operands are registers. */
1826 if (GET_CODE (x) == PLUS)
9f85ed45 1827 return gen_rtx_PLUS (Pmode, force_reg (Pmode, XEXP (x, 0)),
0ac081f6
AH
1828 force_reg (Pmode, XEXP (x, 1)));
1829
1830 reg = force_reg (Pmode, x);
1831 return reg;
1832 }
9ebbca7d
GK
1833 else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC && ! flag_pic
1834 && GET_CODE (x) != CONST_INT
1835 && GET_CODE (x) != CONST_DOUBLE
1836 && CONSTANT_P (x)
6ac7bf2c
GK
1837 && GET_MODE_NUNITS (mode) == 1
1838 && (GET_MODE_BITSIZE (mode) <= 32
c3bb62b9 1839 || (TARGET_HARD_FLOAT && mode == DFmode)))
9ebbca7d
GK
1840 {
1841 rtx reg = gen_reg_rtx (Pmode);
1842 emit_insn (gen_elf_high (reg, (x)));
1843 return gen_rtx_LO_SUM (Pmode, reg, (x));
1844 }
ee890fe2
SS
1845 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
1846 && ! flag_pic
1847 && GET_CODE (x) != CONST_INT
1848 && GET_CODE (x) != CONST_DOUBLE
1849 && CONSTANT_P (x)
1850 && (TARGET_HARD_FLOAT || mode != DFmode)
1851 && mode != DImode
1852 && mode != TImode)
1853 {
1854 rtx reg = gen_reg_rtx (Pmode);
1855 emit_insn (gen_macho_high (reg, (x)));
1856 return gen_rtx_LO_SUM (Pmode, reg, (x));
1857 }
9ebbca7d
GK
1858 else if (TARGET_TOC
1859 && CONSTANT_POOL_EXPR_P (x)
a9098fd0 1860 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
9ebbca7d
GK
1861 {
1862 return create_TOC_reference (x);
1863 }
1864 else
1865 return NULL_RTX;
1866}
258bfae2 1867
24ea750e
DJ
1868/* The convention appears to be to define this wherever it is used.
1869 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
1870 is now used here. */
1871#ifndef REG_MODE_OK_FOR_BASE_P
1872#define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
1873#endif
1874
1875/* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
1876 replace the input X, or the original X if no replacement is called for.
1877 The output parameter *WIN is 1 if the calling macro should goto WIN,
1878 0 if it should not.
1879
1880 For RS/6000, we wish to handle large displacements off a base
1881 register by splitting the addend across an addiu/addis and the mem insn.
1882 This cuts number of extra insns needed from 3 to 1.
1883
1884 On Darwin, we use this to generate code for floating point constants.
1885 A movsf_low is generated so we wind up with 2 instructions rather than 3.
1886 The Darwin code is inside #if TARGET_MACHO because only then is
1887 machopic_function_base_name() defined. */
1888rtx
1889rs6000_legitimize_reload_address (x, mode, opnum, type, ind_levels, win)
1890 rtx x;
1891 enum machine_mode mode;
1892 int opnum;
1893 int type;
1894 int ind_levels ATTRIBUTE_UNUSED;
1895 int *win;
1896{
1897 /* We must recognize output that we have already generated ourselves. */
1898 if (GET_CODE (x) == PLUS
1899 && GET_CODE (XEXP (x, 0)) == PLUS
1900 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
1901 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
1902 && GET_CODE (XEXP (x, 1)) == CONST_INT)
1903 {
1904 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
1905 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
1906 opnum, (enum reload_type)type);
1907 *win = 1;
1908 return x;
1909 }
3deb2758 1910
24ea750e
DJ
1911#if TARGET_MACHO
1912 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
1913 && GET_CODE (x) == LO_SUM
1914 && GET_CODE (XEXP (x, 0)) == PLUS
1915 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
1916 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
1917 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == CONST
1918 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
1919 && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
1920 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
1921 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF)
1922 {
1923 /* Result of previous invocation of this function on Darwin
6f317ef3 1924 floating point constant. */
24ea750e
DJ
1925 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
1926 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
1927 opnum, (enum reload_type)type);
1928 *win = 1;
1929 return x;
1930 }
1931#endif
1932 if (GET_CODE (x) == PLUS
1933 && GET_CODE (XEXP (x, 0)) == REG
1934 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
1935 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
78c875e8
AH
1936 && GET_CODE (XEXP (x, 1)) == CONST_INT
1937 && !ALTIVEC_VECTOR_MODE (mode))
24ea750e
DJ
1938 {
1939 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
1940 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1941 HOST_WIDE_INT high
1942 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
1943
1944 /* Check for 32-bit overflow. */
1945 if (high + low != val)
1946 {
1947 *win = 0;
1948 return x;
1949 }
1950
1951 /* Reload the high part into a base reg; leave the low part
1952 in the mem directly. */
1953
1954 x = gen_rtx_PLUS (GET_MODE (x),
1955 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
1956 GEN_INT (high)),
1957 GEN_INT (low));
1958
1959 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
1960 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
1961 opnum, (enum reload_type)type);
1962 *win = 1;
1963 return x;
1964 }
1965#if TARGET_MACHO
1966 if (GET_CODE (x) == SYMBOL_REF
1967 && DEFAULT_ABI == ABI_DARWIN
69ef87e2 1968 && !ALTIVEC_VECTOR_MODE (mode)
24ea750e
DJ
1969 && flag_pic)
1970 {
1971 /* Darwin load of floating point constant. */
1972 rtx offset = gen_rtx (CONST, Pmode,
1973 gen_rtx (MINUS, Pmode, x,
1974 gen_rtx (SYMBOL_REF, Pmode,
1975 machopic_function_base_name ())));
1976 x = gen_rtx (LO_SUM, GET_MODE (x),
1977 gen_rtx (PLUS, Pmode, pic_offset_table_rtx,
1978 gen_rtx (HIGH, Pmode, offset)), offset);
1979 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
1980 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
1981 opnum, (enum reload_type)type);
1982 *win = 1;
1983 return x;
1984 }
1985#endif
1986 if (TARGET_TOC
c1f11548
DE
1987 && CONSTANT_POOL_EXPR_P (x)
1988 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
24ea750e
DJ
1989 {
1990 (x) = create_TOC_reference (x);
1991 *win = 1;
1992 return x;
1993 }
1994 *win = 0;
1995 return x;
1996}
1997
258bfae2
FS
1998/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
1999 that is a valid memory address for an instruction.
2000 The MODE argument is the machine mode for the MEM expression
2001 that wants to use this address.
2002
2003 On the RS/6000, there are four valid address: a SYMBOL_REF that
2004 refers to a constant pool entry of an address (or the sum of it
2005 plus a constant), a short (16-bit signed) constant plus a register,
2006 the sum of two registers, or a register indirect, possibly with an
2007 auto-increment. For DFmode and DImode with an constant plus register,
2008 we must ensure that both words are addressable or PowerPC64 with offset
2009 word aligned.
2010
2011 For modes spanning multiple registers (DFmode in 32-bit GPRs,
2012 32-bit DImode, TImode), indexed addressing cannot be used because
2013 adjacent memory cells are accessed by adding word-sized offsets
2014 during assembly output. */
2015int
2016rs6000_legitimate_address (mode, x, reg_ok_strict)
2017 enum machine_mode mode;
2018 rtx x;
2019 int reg_ok_strict;
2020{
2021 if (LEGITIMATE_INDIRECT_ADDRESS_P (x, reg_ok_strict))
2022 return 1;
2023 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
2024 && TARGET_UPDATE
2025 && LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (x, 0), reg_ok_strict))
2026 return 1;
2027 if (LEGITIMATE_SMALL_DATA_P (mode, x))
2028 return 1;
2029 if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
2030 return 1;
2031 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
2032 if (! reg_ok_strict
2033 && GET_CODE (x) == PLUS
2034 && GET_CODE (XEXP (x, 0)) == REG
2035 && XEXP (x, 0) == virtual_stack_vars_rtx
2036 && GET_CODE (XEXP (x, 1)) == CONST_INT)
2037 return 1;
2038 if (LEGITIMATE_OFFSET_ADDRESS_P (mode, x, reg_ok_strict))
2039 return 1;
2040 if (mode != TImode
2041 && (TARGET_HARD_FLOAT || TARGET_POWERPC64 || mode != DFmode)
2042 && (TARGET_POWERPC64 || mode != DImode)
2043 && LEGITIMATE_INDEXED_ADDRESS_P (x, reg_ok_strict))
2044 return 1;
2045 if (LEGITIMATE_LO_SUM_ADDRESS_P (mode, x, reg_ok_strict))
2046 return 1;
2047 return 0;
2048}
fb4d4348 2049\f
a4f6c312
SS
2050/* Try to output insns to set TARGET equal to the constant C if it can
2051 be done in less than N insns. Do all computations in MODE.
2052 Returns the place where the output has been placed if it can be
2053 done and the insns have been emitted. If it would take more than N
2054 insns, zero is returned and no insns and emitted. */
2bfcf297
DB
2055
2056rtx
2057rs6000_emit_set_const (dest, mode, source, n)
2058 rtx dest, source;
2059 enum machine_mode mode;
2060 int n ATTRIBUTE_UNUSED;
2061{
2062 HOST_WIDE_INT c0, c1;
2063
2064 if (mode == QImode || mode == HImode || mode == SImode)
2065 {
2066 if (dest == NULL)
2067 dest = gen_reg_rtx (mode);
2068 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
2069 return dest;
2070 }
2071
2072 if (GET_CODE (source) == CONST_INT)
2073 {
2074 c0 = INTVAL (source);
2075 c1 = -(c0 < 0);
2076 }
2077 else if (GET_CODE (source) == CONST_DOUBLE)
2078 {
2079#if HOST_BITS_PER_WIDE_INT >= 64
2080 c0 = CONST_DOUBLE_LOW (source);
2081 c1 = -(c0 < 0);
2082#else
2083 c0 = CONST_DOUBLE_LOW (source);
2084 c1 = CONST_DOUBLE_HIGH (source);
2085#endif
2086 }
2087 else
a4f6c312 2088 abort ();
2bfcf297
DB
2089
2090 return rs6000_emit_set_long_const (dest, c0, c1);
2091}
2092
2093/* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
2094 fall back to a straight forward decomposition. We do this to avoid
2095 exponential run times encountered when looking for longer sequences
2096 with rs6000_emit_set_const. */
2097static rtx
2098rs6000_emit_set_long_const (dest, c1, c2)
2099 rtx dest;
2100 HOST_WIDE_INT c1, c2;
2101{
2102 if (!TARGET_POWERPC64)
2103 {
2104 rtx operand1, operand2;
2105
2106 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
2107 DImode);
2108 operand2 = operand_subword_force (dest, WORDS_BIG_ENDIAN != 0,
2109 DImode);
2110 emit_move_insn (operand1, GEN_INT (c1));
2111 emit_move_insn (operand2, GEN_INT (c2));
2112 }
2113 else
2114 {
bc06712d 2115 HOST_WIDE_INT ud1, ud2, ud3, ud4;
252b88f7 2116
bc06712d
TR
2117 ud1 = c1 & 0xffff;
2118 ud2 = (c1 & 0xffff0000) >> 16;
2bfcf297 2119#if HOST_BITS_PER_WIDE_INT >= 64
bc06712d 2120 c2 = c1 >> 32;
2bfcf297 2121#endif
bc06712d
TR
2122 ud3 = c2 & 0xffff;
2123 ud4 = (c2 & 0xffff0000) >> 16;
2bfcf297 2124
bc06712d
TR
2125 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
2126 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
2bfcf297 2127 {
bc06712d
TR
2128 if (ud1 & 0x8000)
2129 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
2130 else
2131 emit_move_insn (dest, GEN_INT (ud1));
2bfcf297 2132 }
2bfcf297 2133
bc06712d
TR
2134 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
2135 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
252b88f7 2136 {
bc06712d
TR
2137 if (ud2 & 0x8000)
2138 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
2139 - 0x80000000));
252b88f7 2140 else
bc06712d
TR
2141 emit_move_insn (dest, GEN_INT (ud2 << 16));
2142 if (ud1 != 0)
2143 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
252b88f7 2144 }
bc06712d
TR
2145 else if ((ud4 == 0xffff && (ud3 & 0x8000))
2146 || (ud4 == 0 && ! (ud3 & 0x8000)))
2147 {
2148 if (ud3 & 0x8000)
2149 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
2150 - 0x80000000));
2151 else
2152 emit_move_insn (dest, GEN_INT (ud3 << 16));
2153
2154 if (ud2 != 0)
2155 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud2)));
2156 emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (16)));
2157 if (ud1 != 0)
2158 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
2159 }
2160 else
2161 {
2162 if (ud4 & 0x8000)
2163 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
2164 - 0x80000000));
2165 else
2166 emit_move_insn (dest, GEN_INT (ud4 << 16));
2167
2168 if (ud3 != 0)
2169 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud3)));
2bfcf297 2170
bc06712d
TR
2171 emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32)));
2172 if (ud2 != 0)
2173 emit_move_insn (dest, gen_rtx_IOR (DImode, dest,
2174 GEN_INT (ud2 << 16)));
2175 if (ud1 != 0)
2176 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
2177 }
2178 }
2bfcf297
DB
2179 return dest;
2180}
2181
fb4d4348
GK
2182/* Emit a move from SOURCE to DEST in mode MODE. */
2183void
2184rs6000_emit_move (dest, source, mode)
2185 rtx dest;
2186 rtx source;
2187 enum machine_mode mode;
2188{
2189 rtx operands[2];
2190 operands[0] = dest;
2191 operands[1] = source;
2192
2193 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
2194 if (GET_CODE (operands[1]) == CONST_DOUBLE
2195 && ! FLOAT_MODE_P (mode)
2196 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
2197 {
2198 /* FIXME. This should never happen. */
2199 /* Since it seems that it does, do the safe thing and convert
2200 to a CONST_INT. */
2496c7bd 2201 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
fb4d4348
GK
2202 }
2203 if (GET_CODE (operands[1]) == CONST_DOUBLE
2204 && ! FLOAT_MODE_P (mode)
2205 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2206 && CONST_DOUBLE_LOW (operands[1]) >= 0)
2207 || (CONST_DOUBLE_HIGH (operands[1]) == -1
2208 && CONST_DOUBLE_LOW (operands[1]) < 0)))
2209 abort ();
c9e8cb32
DD
2210
2211 /* Check if GCC is setting up a block move that will end up using FP
2212 registers as temporaries. We must make sure this is acceptable. */
2213 if (GET_CODE (operands[0]) == MEM
2214 && GET_CODE (operands[1]) == MEM
2215 && mode == DImode
41543739
GK
2216 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
2217 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
2218 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
2219 ? 32 : MEM_ALIGN (operands[0])))
2220 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
2221 ? 32
2222 : MEM_ALIGN (operands[1]))))
2223 && ! MEM_VOLATILE_P (operands [0])
2224 && ! MEM_VOLATILE_P (operands [1]))
c9e8cb32 2225 {
41543739
GK
2226 emit_move_insn (adjust_address (operands[0], SImode, 0),
2227 adjust_address (operands[1], SImode, 0));
2228 emit_move_insn (adjust_address (operands[0], SImode, 4),
2229 adjust_address (operands[1], SImode, 4));
c9e8cb32
DD
2230 return;
2231 }
fb4d4348
GK
2232
2233 if (! no_new_pseudos && GET_CODE (operands[0]) != REG)
2234 operands[1] = force_reg (mode, operands[1]);
a9098fd0 2235
ffc14f31
GK
2236 if (mode == SFmode && ! TARGET_POWERPC && TARGET_HARD_FLOAT
2237 && GET_CODE (operands[0]) == MEM)
fb4d4348 2238 {
ffc14f31
GK
2239 int regnum;
2240
2241 if (reload_in_progress || reload_completed)
2242 regnum = true_regnum (operands[1]);
2243 else if (GET_CODE (operands[1]) == REG)
2244 regnum = REGNO (operands[1]);
2245 else
2246 regnum = -1;
fb4d4348
GK
2247
2248 /* If operands[1] is a register, on POWER it may have
2249 double-precision data in it, so truncate it to single
2250 precision. */
2251 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
2252 {
2253 rtx newreg;
2254 newreg = (no_new_pseudos ? operands[1] : gen_reg_rtx (mode));
2255 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
2256 operands[1] = newreg;
2257 }
2258 }
2259
a9098fd0
GK
2260 /* Handle the case where reload calls us with an invalid address;
2261 and the case of CONSTANT_P_RTX. */
69ef87e2
AH
2262 if (!VECTOR_MODE_P (mode)
2263 && (! general_operand (operands[1], mode)
2264 || ! nonimmediate_operand (operands[0], mode)
2265 || GET_CODE (operands[1]) == CONSTANT_P_RTX))
fb4d4348
GK
2266 {
2267 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2268 return;
2269 }
a9098fd0 2270
fb4d4348
GK
2271 /* FIXME: In the long term, this switch statement should go away
2272 and be replaced by a sequence of tests based on things like
2273 mode == Pmode. */
2274 switch (mode)
2275 {
2276 case HImode:
2277 case QImode:
2278 if (CONSTANT_P (operands[1])
2279 && GET_CODE (operands[1]) != CONST_INT)
a9098fd0 2280 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
2281 break;
2282
06f4e019 2283 case TFmode:
fb4d4348
GK
2284 case DFmode:
2285 case SFmode:
2286 if (CONSTANT_P (operands[1])
2287 && ! easy_fp_constant (operands[1], mode))
a9098fd0 2288 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
2289 break;
2290
0ac081f6
AH
2291 case V16QImode:
2292 case V8HImode:
2293 case V4SFmode:
2294 case V4SImode:
69ef87e2
AH
2295 if (CONSTANT_P (operands[1])
2296 && !easy_vector_constant (operands[1]))
0ac081f6
AH
2297 operands[1] = force_const_mem (mode, operands[1]);
2298 break;
2299
fb4d4348 2300 case SImode:
a9098fd0 2301 case DImode:
fb4d4348
GK
2302 /* Use default pattern for address of ELF small data */
2303 if (TARGET_ELF
a9098fd0 2304 && mode == Pmode
f607bc57 2305 && DEFAULT_ABI == ABI_V4
a9098fd0
GK
2306 && (GET_CODE (operands[1]) == SYMBOL_REF
2307 || GET_CODE (operands[1]) == CONST)
2308 && small_data_operand (operands[1], mode))
fb4d4348
GK
2309 {
2310 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2311 return;
2312 }
2313
f607bc57 2314 if (DEFAULT_ABI == ABI_V4
a9098fd0
GK
2315 && mode == Pmode && mode == SImode
2316 && flag_pic == 1 && got_operand (operands[1], mode))
fb4d4348
GK
2317 {
2318 emit_insn (gen_movsi_got (operands[0], operands[1]));
2319 return;
2320 }
2321
ee890fe2
SS
2322 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
2323 && TARGET_NO_TOC && ! flag_pic
a9098fd0 2324 && mode == Pmode
fb4d4348
GK
2325 && CONSTANT_P (operands[1])
2326 && GET_CODE (operands[1]) != HIGH
2327 && GET_CODE (operands[1]) != CONST_INT)
2328 {
a9098fd0 2329 rtx target = (no_new_pseudos ? operands[0] : gen_reg_rtx (mode));
fb4d4348
GK
2330
2331 /* If this is a function address on -mcall-aixdesc,
2332 convert it to the address of the descriptor. */
2333 if (DEFAULT_ABI == ABI_AIX
2334 && GET_CODE (operands[1]) == SYMBOL_REF
2335 && XSTR (operands[1], 0)[0] == '.')
2336 {
2337 const char *name = XSTR (operands[1], 0);
2338 rtx new_ref;
2339 while (*name == '.')
2340 name++;
2341 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
2342 CONSTANT_POOL_ADDRESS_P (new_ref)
2343 = CONSTANT_POOL_ADDRESS_P (operands[1]);
2344 SYMBOL_REF_FLAG (new_ref) = SYMBOL_REF_FLAG (operands[1]);
2345 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
2346 operands[1] = new_ref;
2347 }
7509c759 2348
ee890fe2
SS
2349 if (DEFAULT_ABI == ABI_DARWIN)
2350 {
2351 emit_insn (gen_macho_high (target, operands[1]));
2352 emit_insn (gen_macho_low (operands[0], target, operands[1]));
2353 return;
2354 }
2355
fb4d4348
GK
2356 emit_insn (gen_elf_high (target, operands[1]));
2357 emit_insn (gen_elf_low (operands[0], target, operands[1]));
2358 return;
2359 }
2360
a9098fd0
GK
2361 /* If this is a SYMBOL_REF that refers to a constant pool entry,
2362 and we have put it in the TOC, we just need to make a TOC-relative
2363 reference to it. */
2364 if (TARGET_TOC
2365 && GET_CODE (operands[1]) == SYMBOL_REF
2366 && CONSTANT_POOL_EXPR_P (operands[1])
2367 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
2368 get_pool_mode (operands[1])))
fb4d4348 2369 {
a9098fd0 2370 operands[1] = create_TOC_reference (operands[1]);
fb4d4348 2371 }
a9098fd0
GK
2372 else if (mode == Pmode
2373 && CONSTANT_P (operands[1])
38886f37
AO
2374 && ((GET_CODE (operands[1]) != CONST_INT
2375 && ! easy_fp_constant (operands[1], mode))
2376 || (GET_CODE (operands[1]) == CONST_INT
2377 && num_insns_constant (operands[1], mode) > 2)
2378 || (GET_CODE (operands[0]) == REG
2379 && FP_REGNO_P (REGNO (operands[0]))))
a9098fd0
GK
2380 && GET_CODE (operands[1]) != HIGH
2381 && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1])
2382 && ! TOC_RELATIVE_EXPR_P (operands[1]))
fb4d4348
GK
2383 {
2384 /* Emit a USE operation so that the constant isn't deleted if
2385 expensive optimizations are turned on because nobody
2386 references it. This should only be done for operands that
2387 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
2388 This should not be done for operands that contain LABEL_REFs.
2389 For now, we just handle the obvious case. */
2390 if (GET_CODE (operands[1]) != LABEL_REF)
2391 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
2392
c859cda6 2393#if TARGET_MACHO
ee890fe2
SS
2394 /* Darwin uses a special PIC legitimizer. */
2395 if (DEFAULT_ABI == ABI_DARWIN && flag_pic)
2396 {
ee890fe2
SS
2397 operands[1] =
2398 rs6000_machopic_legitimize_pic_address (operands[1], mode,
c859cda6
DJ
2399 operands[0]);
2400 if (operands[0] != operands[1])
2401 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
ee890fe2
SS
2402 return;
2403 }
c859cda6 2404#endif
ee890fe2 2405
fb4d4348
GK
2406 /* If we are to limit the number of things we put in the TOC and
2407 this is a symbol plus a constant we can add in one insn,
2408 just put the symbol in the TOC and add the constant. Don't do
2409 this if reload is in progress. */
2410 if (GET_CODE (operands[1]) == CONST
2411 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
2412 && GET_CODE (XEXP (operands[1], 0)) == PLUS
a9098fd0 2413 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
fb4d4348
GK
2414 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
2415 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
2416 && ! side_effects_p (operands[0]))
2417 {
a4f6c312
SS
2418 rtx sym =
2419 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
fb4d4348
GK
2420 rtx other = XEXP (XEXP (operands[1], 0), 1);
2421
a9098fd0
GK
2422 sym = force_reg (mode, sym);
2423 if (mode == SImode)
2424 emit_insn (gen_addsi3 (operands[0], sym, other));
2425 else
2426 emit_insn (gen_adddi3 (operands[0], sym, other));
fb4d4348
GK
2427 return;
2428 }
2429
a9098fd0 2430 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
2431
2432 if (TARGET_TOC
d34c5b80
DE
2433 && CONSTANT_POOL_EXPR_P (XEXP (operands[1], 0))
2434 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
2435 get_pool_constant (XEXP (operands[1], 0)),
2436 get_pool_mode (XEXP (operands[1], 0))))
a9098fd0 2437 {
ba4828e0
RK
2438 operands[1]
2439 = gen_rtx_MEM (mode,
2440 create_TOC_reference (XEXP (operands[1], 0)));
2441 set_mem_alias_set (operands[1], get_TOC_alias_set ());
fb4d4348 2442 RTX_UNCHANGING_P (operands[1]) = 1;
a9098fd0 2443 }
fb4d4348
GK
2444 }
2445 break;
a9098fd0 2446
fb4d4348
GK
2447 case TImode:
2448 if (GET_CODE (operands[0]) == MEM
2449 && GET_CODE (XEXP (operands[0], 0)) != REG
2450 && ! reload_in_progress)
792760b9
RK
2451 operands[0]
2452 = replace_equiv_address (operands[0],
2453 copy_addr_to_reg (XEXP (operands[0], 0)));
fb4d4348
GK
2454
2455 if (GET_CODE (operands[1]) == MEM
2456 && GET_CODE (XEXP (operands[1], 0)) != REG
2457 && ! reload_in_progress)
792760b9
RK
2458 operands[1]
2459 = replace_equiv_address (operands[1],
2460 copy_addr_to_reg (XEXP (operands[1], 0)));
fb4d4348
GK
2461 break;
2462
2463 default:
2464 abort ();
2465 }
2466
a9098fd0
GK
2467 /* Above, we may have called force_const_mem which may have returned
2468 an invalid address. If we can, fix this up; otherwise, reload will
2469 have to deal with it. */
2470 if (GET_CODE (operands[1]) == MEM
2471 && ! memory_address_p (mode, XEXP (operands[1], 0))
2472 && ! reload_in_progress)
f4ef873c 2473 operands[1] = adjust_address (operands[1], mode, 0);
a9098fd0 2474
fb4d4348 2475 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
02a4ec28 2476 return;
fb4d4348 2477}
4697a36c
MM
2478\f
2479/* Initialize a variable CUM of type CUMULATIVE_ARGS
2480 for a call to a function whose data type is FNTYPE.
2481 For a library call, FNTYPE is 0.
2482
2483 For incoming args we set the number of arguments in the prototype large
1c20ae99 2484 so we never return a PARALLEL. */
4697a36c
MM
2485
2486void
2487init_cumulative_args (cum, fntype, libname, incoming)
2488 CUMULATIVE_ARGS *cum;
2489 tree fntype;
296b8152 2490 rtx libname ATTRIBUTE_UNUSED;
4697a36c
MM
2491 int incoming;
2492{
2493 static CUMULATIVE_ARGS zero_cumulative;
2494
2495 *cum = zero_cumulative;
2496 cum->words = 0;
2497 cum->fregno = FP_ARG_MIN_REG;
0ac081f6 2498 cum->vregno = ALTIVEC_ARG_MIN_REG;
4697a36c 2499 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
7509c759 2500 cum->call_cookie = CALL_NORMAL;
4cc833b7 2501 cum->sysv_gregno = GP_ARG_MIN_REG;
4697a36c
MM
2502
2503 if (incoming)
bd227acc 2504 cum->nargs_prototype = 1000; /* don't return a PARALLEL */
4697a36c
MM
2505
2506 else if (cum->prototype)
2507 cum->nargs_prototype = (list_length (TYPE_ARG_TYPES (fntype)) - 1
2508 + (TYPE_MODE (TREE_TYPE (fntype)) == BLKmode
2509 || RETURN_IN_MEMORY (TREE_TYPE (fntype))));
2510
2511 else
2512 cum->nargs_prototype = 0;
2513
2514 cum->orig_nargs = cum->nargs_prototype;
7509c759 2515
9ebbca7d
GK
2516 /* Check for longcall's */
2517 if (fntype && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype)))
6a4cee5f
MM
2518 cum->call_cookie = CALL_LONG;
2519
4697a36c
MM
2520 if (TARGET_DEBUG_ARG)
2521 {
2522 fprintf (stderr, "\ninit_cumulative_args:");
2523 if (fntype)
2524 {
2525 tree ret_type = TREE_TYPE (fntype);
2526 fprintf (stderr, " ret code = %s,",
2527 tree_code_name[ (int)TREE_CODE (ret_type) ]);
2528 }
2529
6a4cee5f
MM
2530 if (cum->call_cookie & CALL_LONG)
2531 fprintf (stderr, " longcall,");
2532
4697a36c
MM
2533 fprintf (stderr, " proto = %d, nargs = %d\n",
2534 cum->prototype, cum->nargs_prototype);
2535 }
2536}
2537\f
c229cba9
DE
2538/* If defined, a C expression which determines whether, and in which
2539 direction, to pad out an argument with extra space. The value
2540 should be of type `enum direction': either `upward' to pad above
2541 the argument, `downward' to pad below, or `none' to inhibit
2542 padding.
2543
2544 For the AIX ABI structs are always stored left shifted in their
2545 argument slot. */
2546
9ebbca7d 2547enum direction
c229cba9
DE
2548function_arg_padding (mode, type)
2549 enum machine_mode mode;
2550 tree type;
2551{
c85f7c16 2552 if (type != 0 && AGGREGATE_TYPE_P (type))
9ebbca7d 2553 return upward;
c229cba9
DE
2554
2555 /* This is the default definition. */
2556 return (! BYTES_BIG_ENDIAN
9ebbca7d 2557 ? upward
c229cba9
DE
2558 : ((mode == BLKmode
2559 ? (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
2560 && int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT))
2561 : GET_MODE_BITSIZE (mode) < PARM_BOUNDARY)
9ebbca7d 2562 ? downward : upward));
c229cba9
DE
2563}
2564
b6c9286a
MM
2565/* If defined, a C expression that gives the alignment boundary, in bits,
2566 of an argument with the specified mode and type. If it is not defined,
2567 PARM_BOUNDARY is used for all arguments.
2568
2310f99a 2569 V.4 wants long longs to be double word aligned. */
b6c9286a
MM
2570
2571int
2572function_arg_boundary (mode, type)
2573 enum machine_mode mode;
9ebbca7d 2574 tree type ATTRIBUTE_UNUSED;
b6c9286a 2575{
f607bc57 2576 if (DEFAULT_ABI == ABI_V4 && (mode == DImode || mode == DFmode))
e1f83b4d 2577 return 64;
0ac081f6
AH
2578 else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
2579 return 128;
9ebbca7d 2580 else
b6c9286a 2581 return PARM_BOUNDARY;
b6c9286a
MM
2582}
2583\f
4697a36c
MM
2584/* Update the data in CUM to advance over an argument
2585 of mode MODE and data type TYPE.
2586 (TYPE is null for libcalls where that information may not be available.) */
2587
2588void
2589function_arg_advance (cum, mode, type, named)
2590 CUMULATIVE_ARGS *cum;
2591 enum machine_mode mode;
2592 tree type;
2593 int named;
2594{
2595 cum->nargs_prototype--;
2596
0ac081f6
AH
2597 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
2598 {
2599 if (cum->vregno <= ALTIVEC_ARG_MAX_REG && cum->nargs_prototype >= 0)
2600 cum->vregno++;
2601 else
2602 cum->words += RS6000_ARG_SIZE (mode, type);
2603 }
f607bc57 2604 else if (DEFAULT_ABI == ABI_V4)
4697a36c 2605 {
4cc833b7
RH
2606 if (TARGET_HARD_FLOAT
2607 && (mode == SFmode || mode == DFmode))
4697a36c 2608 {
4cc833b7
RH
2609 if (cum->fregno <= FP_ARG_V4_MAX_REG)
2610 cum->fregno++;
2611 else
2612 {
2613 if (mode == DFmode)
2614 cum->words += cum->words & 1;
d34c5b80 2615 cum->words += RS6000_ARG_SIZE (mode, type);
4cc833b7 2616 }
4697a36c 2617 }
4cc833b7
RH
2618 else
2619 {
2620 int n_words;
2621 int gregno = cum->sysv_gregno;
2622
2623 /* Aggregates and IEEE quad get passed by reference. */
2624 if ((type && AGGREGATE_TYPE_P (type))
2625 || mode == TFmode)
2626 n_words = 1;
2627 else
d34c5b80 2628 n_words = RS6000_ARG_SIZE (mode, type);
4cc833b7
RH
2629
2630 /* Long long is put in odd registers. */
2631 if (n_words == 2 && (gregno & 1) == 0)
2632 gregno += 1;
2633
2634 /* Long long is not split between registers and stack. */
2635 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
2636 {
2637 /* Long long is aligned on the stack. */
2638 if (n_words == 2)
2639 cum->words += cum->words & 1;
2640 cum->words += n_words;
2641 }
4697a36c 2642
4cc833b7
RH
2643 /* Note: continuing to accumulate gregno past when we've started
2644 spilling to the stack indicates the fact that we've started
2645 spilling to the stack to expand_builtin_saveregs. */
2646 cum->sysv_gregno = gregno + n_words;
2647 }
4697a36c 2648
4cc833b7
RH
2649 if (TARGET_DEBUG_ARG)
2650 {
2651 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
2652 cum->words, cum->fregno);
2653 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
2654 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
2655 fprintf (stderr, "mode = %4s, named = %d\n",
2656 GET_MODE_NAME (mode), named);
2657 }
4697a36c
MM
2658 }
2659 else
4cc833b7
RH
2660 {
2661 int align = (TARGET_32BIT && (cum->words & 1) != 0
2662 && function_arg_boundary (mode, type) == 64) ? 1 : 0;
a4f6c312 2663
d34c5b80 2664 cum->words += align + RS6000_ARG_SIZE (mode, type);
4697a36c 2665
d34c5b80
DE
2666 if (GET_MODE_CLASS (mode) == MODE_FLOAT && TARGET_HARD_FLOAT)
2667 cum->fregno++;
4cc833b7
RH
2668
2669 if (TARGET_DEBUG_ARG)
2670 {
2671 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
2672 cum->words, cum->fregno);
2673 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
2674 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
2675 fprintf (stderr, "named = %d, align = %d\n", named, align);
2676 }
2677 }
4697a36c
MM
2678}
2679\f
2680/* Determine where to put an argument to a function.
2681 Value is zero to push the argument on the stack,
2682 or a hard register in which to store the argument.
2683
2684 MODE is the argument's machine mode.
2685 TYPE is the data type of the argument (as a tree).
2686 This is null for libcalls where that information may
2687 not be available.
2688 CUM is a variable of type CUMULATIVE_ARGS which gives info about
2689 the preceding args and about the function being called.
2690 NAMED is nonzero if this argument is a named parameter
2691 (otherwise it is an extra parameter matching an ellipsis).
2692
2693 On RS/6000 the first eight words of non-FP are normally in registers
2694 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
2695 Under V.4, the first 8 FP args are in registers.
2696
2697 If this is floating-point and no prototype is specified, we use
2698 both an FP and integer register (or possibly FP reg and stack). Library
2699 functions (when TYPE is zero) always have the proper types for args,
2700 so we can pass the FP value just in one register. emit_library_function
1c20ae99 2701 doesn't support PARALLEL anyway. */
4697a36c
MM
2702
2703struct rtx_def *
2704function_arg (cum, mode, type, named)
2705 CUMULATIVE_ARGS *cum;
2706 enum machine_mode mode;
2707 tree type;
20c29ebe 2708 int named;
4697a36c 2709{
4cc833b7 2710 enum rs6000_abi abi = DEFAULT_ABI;
4697a36c 2711
a4f6c312
SS
2712 /* Return a marker to indicate whether CR1 needs to set or clear the
2713 bit that V.4 uses to say fp args were passed in registers.
2714 Assume that we don't need the marker for software floating point,
2715 or compiler generated library calls. */
4697a36c
MM
2716 if (mode == VOIDmode)
2717 {
f607bc57 2718 if (abi == ABI_V4
7509c759
MM
2719 && TARGET_HARD_FLOAT
2720 && cum->nargs_prototype < 0
4697a36c 2721 && type && (cum->prototype || TARGET_NO_PROTOTYPE))
7509c759 2722 {
6a4cee5f
MM
2723 return GEN_INT (cum->call_cookie
2724 | ((cum->fregno == FP_ARG_MIN_REG)
2725 ? CALL_V4_SET_FP_ARGS
2726 : CALL_V4_CLEAR_FP_ARGS));
7509c759 2727 }
4697a36c 2728
7509c759 2729 return GEN_INT (cum->call_cookie);
4697a36c
MM
2730 }
2731
0ac081f6
AH
2732 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
2733 {
20c29ebe 2734 if (named && cum->vregno <= ALTIVEC_ARG_MAX_REG)
0ac081f6
AH
2735 return gen_rtx_REG (mode, cum->vregno);
2736 else
2737 return NULL;
2738 }
f607bc57 2739 else if (abi == ABI_V4)
4697a36c 2740 {
4cc833b7
RH
2741 if (TARGET_HARD_FLOAT
2742 && (mode == SFmode || mode == DFmode))
2743 {
2744 if (cum->fregno <= FP_ARG_V4_MAX_REG)
2745 return gen_rtx_REG (mode, cum->fregno);
2746 else
2747 return NULL;
2748 }
2749 else
2750 {
2751 int n_words;
2752 int gregno = cum->sysv_gregno;
2753
2754 /* Aggregates and IEEE quad get passed by reference. */
2755 if ((type && AGGREGATE_TYPE_P (type))
2756 || mode == TFmode)
2757 n_words = 1;
2758 else
d34c5b80 2759 n_words = RS6000_ARG_SIZE (mode, type);
4cc833b7
RH
2760
2761 /* Long long is put in odd registers. */
2762 if (n_words == 2 && (gregno & 1) == 0)
2763 gregno += 1;
2764
2765 /* Long long is not split between registers and stack. */
2766 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
2767 return gen_rtx_REG (mode, gregno);
2768 else
2769 return NULL;
2770 }
4697a36c 2771 }
4cc833b7
RH
2772 else
2773 {
2774 int align = (TARGET_32BIT && (cum->words & 1) != 0
2775 && function_arg_boundary (mode, type) == 64) ? 1 : 0;
2776 int align_words = cum->words + align;
4697a36c 2777
4cc833b7
RH
2778 if (type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
2779 return NULL_RTX;
2780
2781 if (USE_FP_FOR_ARG_P (*cum, mode, type))
2782 {
2783 if (! type
2784 || ((cum->nargs_prototype > 0)
2785 /* IBM AIX extended its linkage convention definition always
2786 to require FP args after register save area hole on the
2787 stack. */
2788 && (DEFAULT_ABI != ABI_AIX
2789 || ! TARGET_XL_CALL
2790 || (align_words < GP_ARG_NUM_REG))))
2791 return gen_rtx_REG (mode, cum->fregno);
2792
2793 return gen_rtx_PARALLEL (mode,
2794 gen_rtvec (2,
39403d82 2795 gen_rtx_EXPR_LIST (VOIDmode,
1c20ae99
JW
2796 ((align_words >= GP_ARG_NUM_REG)
2797 ? NULL_RTX
2798 : (align_words
d34c5b80 2799 + RS6000_ARG_SIZE (mode, type)
1c20ae99
JW
2800 > GP_ARG_NUM_REG
2801 /* If this is partially on the stack, then
2802 we only include the portion actually
2803 in registers here. */
39403d82 2804 ? gen_rtx_REG (SImode,
1c20ae99 2805 GP_ARG_MIN_REG + align_words)
39403d82 2806 : gen_rtx_REG (mode,
1c20ae99
JW
2807 GP_ARG_MIN_REG + align_words))),
2808 const0_rtx),
39403d82
DE
2809 gen_rtx_EXPR_LIST (VOIDmode,
2810 gen_rtx_REG (mode, cum->fregno),
1c20ae99 2811 const0_rtx)));
4cc833b7
RH
2812 }
2813 else if (align_words < GP_ARG_NUM_REG)
2814 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
2815 else
2816 return NULL_RTX;
4697a36c 2817 }
4697a36c
MM
2818}
2819\f
2820/* For an arg passed partly in registers and partly in memory,
2821 this is the number of registers used.
2822 For args passed entirely in registers or entirely in memory, zero. */
2823
2824int
2825function_arg_partial_nregs (cum, mode, type, named)
2826 CUMULATIVE_ARGS *cum;
2827 enum machine_mode mode;
2828 tree type;
d34c5b80 2829 int named ATTRIBUTE_UNUSED;
4697a36c 2830{
f607bc57 2831 if (DEFAULT_ABI == ABI_V4)
4697a36c 2832 return 0;
4697a36c 2833
0ac081f6
AH
2834 if (USE_FP_FOR_ARG_P (*cum, mode, type)
2835 || USE_ALTIVEC_FOR_ARG_P (*cum, mode, type))
4697a36c
MM
2836 {
2837 if (cum->nargs_prototype >= 0)
2838 return 0;
2839 }
2840
2841 if (cum->words < GP_ARG_NUM_REG
d34c5b80 2842 && GP_ARG_NUM_REG < (cum->words + RS6000_ARG_SIZE (mode, type)))
4697a36c
MM
2843 {
2844 int ret = GP_ARG_NUM_REG - cum->words;
2845 if (ret && TARGET_DEBUG_ARG)
2846 fprintf (stderr, "function_arg_partial_nregs: %d\n", ret);
2847
2848 return ret;
2849 }
2850
2851 return 0;
2852}
2853\f
2854/* A C expression that indicates when an argument must be passed by
2855 reference. If nonzero for an argument, a copy of that argument is
2856 made in memory and a pointer to the argument is passed instead of
2857 the argument itself. The pointer is passed in whatever way is
2858 appropriate for passing a pointer to that type.
2859
2860 Under V.4, structures and unions are passed by reference. */
2861
2862int
2863function_arg_pass_by_reference (cum, mode, type, named)
296b8152
KG
2864 CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
2865 enum machine_mode mode ATTRIBUTE_UNUSED;
4697a36c 2866 tree type;
296b8152 2867 int named ATTRIBUTE_UNUSED;
4697a36c 2868{
f607bc57 2869 if (DEFAULT_ABI == ABI_V4
4cc833b7
RH
2870 && ((type && AGGREGATE_TYPE_P (type))
2871 || mode == TFmode))
4697a36c
MM
2872 {
2873 if (TARGET_DEBUG_ARG)
2874 fprintf (stderr, "function_arg_pass_by_reference: aggregate\n");
2875
2876 return 1;
2877 }
4697a36c
MM
2878
2879 return 0;
2880}
4697a36c
MM
2881\f
2882/* Perform any needed actions needed for a function that is receiving a
2883 variable number of arguments.
2884
2885 CUM is as above.
2886
2887 MODE and TYPE are the mode and type of the current parameter.
2888
2889 PRETEND_SIZE is a variable that should be set to the amount of stack
2890 that must be pushed by the prolog to pretend that our caller pushed
2891 it.
2892
2893 Normally, this macro will push all remaining incoming registers on the
2894 stack and set PRETEND_SIZE to the length of the registers pushed. */
2895
2896void
2897setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
2898 CUMULATIVE_ARGS *cum;
2899 enum machine_mode mode;
2900 tree type;
2901 int *pretend_size;
2902 int no_rtl;
2903
2904{
4cc833b7
RH
2905 CUMULATIVE_ARGS next_cum;
2906 int reg_size = TARGET_32BIT ? 4 : 8;
ca5adc63 2907 rtx save_area = NULL_RTX, mem;
dfafc897 2908 int first_reg_offset, set;
d34c5b80
DE
2909 tree fntype;
2910 int stdarg_p;
4697a36c 2911
d34c5b80
DE
2912 fntype = TREE_TYPE (current_function_decl);
2913 stdarg_p = (TYPE_ARG_TYPES (fntype) != 0
2914 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2915 != void_type_node));
4cc833b7 2916
d34c5b80
DE
2917 /* For varargs, we do not want to skip the dummy va_dcl argument.
2918 For stdargs, we do want to skip the last named argument. */
2919 next_cum = *cum;
2920 if (stdarg_p)
2921 function_arg_advance (&next_cum, mode, type, 1);
4cc833b7 2922
f607bc57 2923 if (DEFAULT_ABI == ABI_V4)
d34c5b80 2924 {
4cc833b7 2925 /* Indicate to allocate space on the stack for varargs save area. */
00dba523 2926 cfun->machine->sysv_varargs_p = 1;
60e2d0ca 2927 if (! no_rtl)
2c4974b7 2928 save_area = plus_constant (virtual_stack_vars_rtx,
bd227acc 2929 - RS6000_VARARGS_SIZE);
4cc833b7
RH
2930
2931 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
4697a36c 2932 }
60e2d0ca 2933 else
4697a36c 2934 {
d34c5b80 2935 first_reg_offset = next_cum.words;
4cc833b7 2936 save_area = virtual_incoming_args_rtx;
00dba523 2937 cfun->machine->sysv_varargs_p = 0;
4697a36c
MM
2938
2939 if (MUST_PASS_IN_STACK (mode, type))
d34c5b80 2940 first_reg_offset += RS6000_ARG_SIZE (TYPE_MODE (type), type);
4cc833b7 2941 }
4697a36c 2942
dfafc897 2943 set = get_varargs_alias_set ();
c81fc13e 2944 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG)
4cc833b7 2945 {
dfafc897
FS
2946 mem = gen_rtx_MEM (BLKmode,
2947 plus_constant (save_area,
2948 first_reg_offset * reg_size)),
ba4828e0 2949 set_mem_alias_set (mem, set);
8ac61af7 2950 set_mem_align (mem, BITS_PER_WORD);
dfafc897 2951
4cc833b7 2952 move_block_from_reg
dfafc897 2953 (GP_ARG_MIN_REG + first_reg_offset, mem,
4cc833b7
RH
2954 GP_ARG_NUM_REG - first_reg_offset,
2955 (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD);
2956
2957 /* ??? Does ABI_V4 need this at all? */
4697a36c
MM
2958 *pretend_size = (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD;
2959 }
2960
4697a36c 2961 /* Save FP registers if needed. */
f607bc57 2962 if (DEFAULT_ABI == ABI_V4
c81fc13e 2963 && TARGET_HARD_FLOAT && ! no_rtl
4cc833b7 2964 && next_cum.fregno <= FP_ARG_V4_MAX_REG)
4697a36c 2965 {
4cc833b7 2966 int fregno = next_cum.fregno;
9ebbca7d 2967 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
4cc833b7
RH
2968 rtx lab = gen_label_rtx ();
2969 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG) * 8);
4697a36c 2970
4cc833b7 2971 emit_jump_insn (gen_rtx_SET (VOIDmode,
4697a36c 2972 pc_rtx,
39403d82 2973 gen_rtx_IF_THEN_ELSE (VOIDmode,
4cc833b7
RH
2974 gen_rtx_NE (VOIDmode, cr1,
2975 const0_rtx),
39403d82 2976 gen_rtx_LABEL_REF (VOIDmode, lab),
4697a36c
MM
2977 pc_rtx)));
2978
4cc833b7
RH
2979 while (fregno <= FP_ARG_V4_MAX_REG)
2980 {
dfafc897 2981 mem = gen_rtx_MEM (DFmode, plus_constant (save_area, off));
ba4828e0 2982 set_mem_alias_set (mem, set);
dfafc897 2983 emit_move_insn (mem, gen_rtx_REG (DFmode, fregno));
4cc833b7
RH
2984 fregno++;
2985 off += 8;
4697a36c 2986 }
4cc833b7
RH
2987
2988 emit_label (lab);
4697a36c 2989 }
4697a36c 2990}
4697a36c 2991
dfafc897 2992/* Create the va_list data type. */
2c4974b7 2993
dfafc897
FS
2994tree
2995rs6000_build_va_list ()
2996{
bab45a51 2997 tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
4697a36c 2998
9ebbca7d
GK
2999 /* For AIX, prefer 'char *' because that's what the system
3000 header files like. */
f607bc57 3001 if (DEFAULT_ABI != ABI_V4)
9ebbca7d 3002 return build_pointer_type (char_type_node);
dfafc897 3003
f1e639b1 3004 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
bab45a51 3005 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
0f4fd75d 3006
9ebbca7d
GK
3007 f_gpr = build_decl (FIELD_DECL, get_identifier ("gpr"),
3008 unsigned_char_type_node);
3009 f_fpr = build_decl (FIELD_DECL, get_identifier ("fpr"),
3010 unsigned_char_type_node);
dfafc897
FS
3011 f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"),
3012 ptr_type_node);
3013 f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
3014 ptr_type_node);
3015
3016 DECL_FIELD_CONTEXT (f_gpr) = record;
3017 DECL_FIELD_CONTEXT (f_fpr) = record;
3018 DECL_FIELD_CONTEXT (f_ovf) = record;
3019 DECL_FIELD_CONTEXT (f_sav) = record;
3020
bab45a51
FS
3021 TREE_CHAIN (record) = type_decl;
3022 TYPE_NAME (record) = type_decl;
dfafc897
FS
3023 TYPE_FIELDS (record) = f_gpr;
3024 TREE_CHAIN (f_gpr) = f_fpr;
3025 TREE_CHAIN (f_fpr) = f_ovf;
3026 TREE_CHAIN (f_ovf) = f_sav;
3027
3028 layout_type (record);
3029
3030 /* The correct type is an array type of one element. */
3031 return build_array_type (record, build_index_type (size_zero_node));
3032}
3033
3034/* Implement va_start. */
3035
3036void
3037rs6000_va_start (stdarg_p, valist, nextarg)
3038 int stdarg_p;
3039 tree valist;
3040 rtx nextarg;
4697a36c 3041{
dfafc897
FS
3042 HOST_WIDE_INT words, n_gpr, n_fpr;
3043 tree f_gpr, f_fpr, f_ovf, f_sav;
3044 tree gpr, fpr, ovf, sav, t;
2c4974b7 3045
dfafc897 3046 /* Only SVR4 needs something special. */
f607bc57 3047 if (DEFAULT_ABI != ABI_V4)
dfafc897
FS
3048 {
3049 std_expand_builtin_va_start (stdarg_p, valist, nextarg);
3050 return;
3051 }
3052
973a648b 3053 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
dfafc897
FS
3054 f_fpr = TREE_CHAIN (f_gpr);
3055 f_ovf = TREE_CHAIN (f_fpr);
3056 f_sav = TREE_CHAIN (f_ovf);
3057
8ebecc3b 3058 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
dfafc897
FS
3059 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
3060 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
3061 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
3062 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
3063
3064 /* Count number of gp and fp argument registers used. */
4cc833b7 3065 words = current_function_args_info.words;
dfafc897
FS
3066 n_gpr = current_function_args_info.sysv_gregno - GP_ARG_MIN_REG;
3067 n_fpr = current_function_args_info.fregno - FP_ARG_MIN_REG;
3068
3069 if (TARGET_DEBUG_ARG)
78e1b90d
DE
3070 {
3071 fputs ("va_start: words = ", stderr);
3072 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, words);
3073 fputs (", n_gpr = ", stderr);
3074 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, n_gpr);
3075 fputs (", n_fpr = ", stderr);
3076 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, n_fpr);
3077 putc ('\n', stderr);
3078 }
dfafc897
FS
3079
3080 t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, build_int_2 (n_gpr, 0));
3081 TREE_SIDE_EFFECTS (t) = 1;
3082 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3083
3084 t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr, build_int_2 (n_fpr, 0));
3085 TREE_SIDE_EFFECTS (t) = 1;
3086 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3087
3088 /* Find the overflow area. */
3089 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
3090 if (words != 0)
3091 t = build (PLUS_EXPR, TREE_TYPE (ovf), t,
3092 build_int_2 (words * UNITS_PER_WORD, 0));
3093 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
3094 TREE_SIDE_EFFECTS (t) = 1;
3095 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3096
3097 /* Find the register save area. */
3098 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
3099 t = build (PLUS_EXPR, TREE_TYPE (sav), t,
3100 build_int_2 (-RS6000_VARARGS_SIZE, -1));
3101 t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
3102 TREE_SIDE_EFFECTS (t) = 1;
3103 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3104}
3105
3106/* Implement va_arg. */
3107
3108rtx
3109rs6000_va_arg (valist, type)
3110 tree valist, type;
3111{
3112 tree f_gpr, f_fpr, f_ovf, f_sav;
3113 tree gpr, fpr, ovf, sav, reg, t, u;
3114 int indirect_p, size, rsize, n_reg, sav_ofs, sav_scale;
3115 rtx lab_false, lab_over, addr_rtx, r;
3116
f607bc57 3117 if (DEFAULT_ABI != ABI_V4)
2a55fd42 3118 return std_expand_builtin_va_arg (valist, type);
dfafc897 3119
973a648b 3120 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
dfafc897
FS
3121 f_fpr = TREE_CHAIN (f_gpr);
3122 f_ovf = TREE_CHAIN (f_fpr);
3123 f_sav = TREE_CHAIN (f_ovf);
3124
8ebecc3b 3125 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
dfafc897
FS
3126 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
3127 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
3128 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
3129 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
3130
3131 size = int_size_in_bytes (type);
3132 rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
4cc833b7 3133
dfafc897 3134 if (AGGREGATE_TYPE_P (type) || TYPE_MODE (type) == TFmode)
4cc833b7 3135 {
dfafc897
FS
3136 /* Aggregates and long doubles are passed by reference. */
3137 indirect_p = 1;
3138 reg = gpr;
3139 n_reg = 1;
3140 sav_ofs = 0;
3141 sav_scale = 4;
d3294cd9
FS
3142 size = UNITS_PER_WORD;
3143 rsize = 1;
dfafc897
FS
3144 }
3145 else if (FLOAT_TYPE_P (type) && ! TARGET_SOFT_FLOAT)
3146 {
3147 /* FP args go in FP registers, if present. */
3148 indirect_p = 0;
3149 reg = fpr;
3150 n_reg = 1;
3151 sav_ofs = 8*4;
3152 sav_scale = 8;
4cc833b7 3153 }
dfafc897
FS
3154 else
3155 {
3156 /* Otherwise into GP registers. */
3157 indirect_p = 0;
3158 reg = gpr;
3159 n_reg = rsize;
3160 sav_ofs = 0;
3161 sav_scale = 4;
3162 }
3163
a4f6c312 3164 /* Pull the value out of the saved registers ... */
dfafc897
FS
3165
3166 lab_false = gen_label_rtx ();
3167 lab_over = gen_label_rtx ();
3168 addr_rtx = gen_reg_rtx (Pmode);
3169
41daaf0e
AH
3170 /* Vectors never go in registers. */
3171 if (TREE_CODE (type) != VECTOR_TYPE)
2c4974b7 3172 {
41daaf0e
AH
3173 TREE_THIS_VOLATILE (reg) = 1;
3174 emit_cmp_and_jump_insns
3175 (expand_expr (reg, NULL_RTX, QImode, EXPAND_NORMAL),
3176 GEN_INT (8 - n_reg + 1), GE, const1_rtx, QImode, 1,
3177 lab_false);
dfafc897 3178
41daaf0e
AH
3179 /* Long long is aligned in the registers. */
3180 if (n_reg > 1)
3181 {
3182 u = build (BIT_AND_EXPR, TREE_TYPE (reg), reg,
3183 build_int_2 (n_reg - 1, 0));
3184 u = build (PLUS_EXPR, TREE_TYPE (reg), reg, u);
3185 u = build (MODIFY_EXPR, TREE_TYPE (reg), reg, u);
3186 TREE_SIDE_EFFECTS (u) = 1;
3187 expand_expr (u, const0_rtx, VOIDmode, EXPAND_NORMAL);
3188 }
2c4974b7 3189
41daaf0e
AH
3190 if (sav_ofs)
3191 t = build (PLUS_EXPR, ptr_type_node, sav, build_int_2 (sav_ofs, 0));
3192 else
3193 t = sav;
2c4974b7 3194
41daaf0e
AH
3195 u = build (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg,
3196 build_int_2 (n_reg, 0));
3197 TREE_SIDE_EFFECTS (u) = 1;
2c4974b7 3198
41daaf0e
AH
3199 u = build1 (CONVERT_EXPR, integer_type_node, u);
3200 TREE_SIDE_EFFECTS (u) = 1;
dfafc897 3201
41daaf0e
AH
3202 u = build (MULT_EXPR, integer_type_node, u, build_int_2 (sav_scale, 0));
3203 TREE_SIDE_EFFECTS (u) = 1;
dfafc897 3204
41daaf0e
AH
3205 t = build (PLUS_EXPR, ptr_type_node, t, u);
3206 TREE_SIDE_EFFECTS (t) = 1;
3207
3208 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
3209 if (r != addr_rtx)
3210 emit_move_insn (addr_rtx, r);
3211
3212 emit_jump_insn (gen_jump (lab_over));
3213 emit_barrier ();
3214 }
dfafc897 3215
dfafc897
FS
3216 emit_label (lab_false);
3217
a4f6c312 3218 /* ... otherwise out of the overflow area. */
dfafc897 3219
41daaf0e
AH
3220 /* Make sure we don't find reg 7 for the next int arg.
3221
3222 All AltiVec vectors go in the overflow area. So in the AltiVec
3223 case we need to get the vectors from the overflow area, but
3224 remember where the GPRs and FPRs are. */
3225 if (n_reg > 1 && TREE_CODE (type) != VECTOR_TYPE)
dfafc897
FS
3226 {
3227 t = build (MODIFY_EXPR, TREE_TYPE (reg), reg, build_int_2 (8, 0));
3228 TREE_SIDE_EFFECTS (t) = 1;
3229 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3230 }
3231
3232 /* Care for on-stack alignment if needed. */
3233 if (rsize <= 1)
3234 t = ovf;
3235 else
3236 {
41daaf0e
AH
3237 int align;
3238
3239 /* Vectors are 16 byte aligned. */
3240 if (TREE_CODE (type) == VECTOR_TYPE)
3241 align = 15;
3242 else
3243 align = 7;
3244
3245 t = build (PLUS_EXPR, TREE_TYPE (ovf), ovf, build_int_2 (align, 0));
3246 t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align-1, -1));
dfafc897
FS
3247 }
3248 t = save_expr (t);
3249
3250 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
3251 if (r != addr_rtx)
3252 emit_move_insn (addr_rtx, r);
3253
3254 t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (size, 0));
3255 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
3256 TREE_SIDE_EFFECTS (t) = 1;
3257 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3258
3259 emit_label (lab_over);
3260
3261 if (indirect_p)
3262 {
3263 r = gen_rtx_MEM (Pmode, addr_rtx);
ba4828e0 3264 set_mem_alias_set (r, get_varargs_alias_set ());
dfafc897
FS
3265 emit_move_insn (addr_rtx, r);
3266 }
3267
3268 return addr_rtx;
4697a36c 3269}
0ac081f6
AH
3270
3271/* Builtins. */
3272
3273#define def_builtin(MASK, NAME, TYPE, CODE) \
3274do { \
3275 if ((MASK) & target_flags) \
3276 builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL); \
3277} while (0)
3278
3279struct builtin_description
3280{
3281 const unsigned int mask;
3282 const enum insn_code icode;
3283 const char *const name;
3284 const enum rs6000_builtins code;
3285};
24408032
AH
3286
3287/* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
3288
2212663f 3289static const struct builtin_description bdesc_3arg[] =
24408032
AH
3290{
3291 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
3292 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
3293 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
3294 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
3295 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
3296 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
3297 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
3298 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
3299 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
3300 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
3301 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
3302 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
3303 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
3304 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
3305 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_16qi, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
3306 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
3307 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
3308 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
3309 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
3310 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
3311 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
3312 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
3313 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
3314};
2212663f 3315
95385cbb
AH
3316/* DST operations: void foo (void *, const int, const char). */
3317
3318static const struct builtin_description bdesc_dst[] =
3319{
3320 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
3321 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
3322 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
3323 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT }
3324};
3325
2212663f 3326/* Simple binary operations: VECc = foo (VECa, VECb). */
24408032 3327
0ac081f6
AH
3328static const struct builtin_description bdesc_2arg[] =
3329{
f18c054f
DB
3330 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
3331 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
3332 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
3333 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
0ac081f6
AH
3334 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
3335 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
3336 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
3337 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
3338 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
3339 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
3340 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
f18c054f 3341 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
0ac081f6
AH
3342 { MASK_ALTIVEC, CODE_FOR_altivec_vandc, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
3343 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
3344 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
3345 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
3346 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
3347 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
3348 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
617e0e1d
DB
3349 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
3350 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
0ac081f6
AH
3351 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
3352 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequb, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
3353 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequh, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
3354 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequw, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
3355 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpeqfp, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
3356 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgefp, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
3357 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtub, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
3358 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsb, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
3359 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuh, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
3360 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsh, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
3361 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuw, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
3362 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsw, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
3363 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtfp, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
617e0e1d
DB
3364 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
3365 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
f18c054f
DB
3366 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
3367 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
3368 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
3369 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
3370 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
3371 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
3372 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
0ac081f6
AH
3373 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
3374 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
3375 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
3376 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
3377 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
3378 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
f18c054f
DB
3379 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
3380 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
3381 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
3382 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
3383 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
3384 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
3385 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
0ac081f6
AH
3386 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
3387 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
3388 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
3389 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
3390 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
3391 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
3392 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
3393 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
3394 { MASK_ALTIVEC, CODE_FOR_altivec_vnor, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
f18c054f 3395 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
0ac081f6
AH
3396 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
3397 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
3398 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
3399 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhss, "__builtin_altivec_vpkuhss", ALTIVEC_BUILTIN_VPKUHSS },
3400 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
3401 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwss, "__builtin_altivec_vpkuwss", ALTIVEC_BUILTIN_VPKUWSS },
3402 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
3403 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
3404 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
3405 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
3406 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
3407 { MASK_ALTIVEC, CODE_FOR_altivec_vrlb, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
3408 { MASK_ALTIVEC, CODE_FOR_altivec_vrlh, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
3409 { MASK_ALTIVEC, CODE_FOR_altivec_vrlw, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
3410 { MASK_ALTIVEC, CODE_FOR_altivec_vslb, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
3411 { MASK_ALTIVEC, CODE_FOR_altivec_vslh, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
3412 { MASK_ALTIVEC, CODE_FOR_altivec_vslw, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
3413 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
3414 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
2212663f
DB
3415 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
3416 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
3417 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
0ac081f6 3418 { MASK_ALTIVEC, CODE_FOR_altivec_vsrb, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
f18c054f
DB
3419 { MASK_ALTIVEC, CODE_FOR_altivec_vsrh, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
3420 { MASK_ALTIVEC, CODE_FOR_altivec_vsrw, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
0ac081f6
AH
3421 { MASK_ALTIVEC, CODE_FOR_altivec_vsrab, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
3422 { MASK_ALTIVEC, CODE_FOR_altivec_vsrah, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
3423 { MASK_ALTIVEC, CODE_FOR_altivec_vsraw, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
3424 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
3425 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
f18c054f
DB
3426 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
3427 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
3428 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
3429 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
0ac081f6
AH
3430 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
3431 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
3432 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
3433 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
3434 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
3435 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
3436 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
3437 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
3438 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
3439 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
3440 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
3441 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
f18c054f 3442 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
ae4b4a02
AH
3443};
3444
3445/* AltiVec predicates. */
3446
3447struct builtin_description_predicates
3448{
3449 const unsigned int mask;
3450 const enum insn_code icode;
3451 const char *opcode;
3452 const char *const name;
3453 const enum rs6000_builtins code;
3454};
3455
3456static const struct builtin_description_predicates bdesc_altivec_preds[] =
3457{
3458 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P },
3459 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
3460 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
3461 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
3462 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P },
3463 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P },
3464 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P },
3465 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P },
3466 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P },
3467 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P },
3468 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P },
3469 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P },
3470 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P }
0ac081f6 3471};
24408032 3472
100c4561
AH
3473/* ABS* opreations. */
3474
3475static const struct builtin_description bdesc_abs[] =
3476{
3477 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
3478 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
3479 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
3480 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
3481 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
3482 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
3483 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI }
3484};
3485
617e0e1d
DB
3486/* Simple unary operations: VECb = foo (unsigned literal) or VECb =
3487 foo (VECa). */
24408032 3488
2212663f
DB
3489static const struct builtin_description bdesc_1arg[] =
3490{
617e0e1d
DB
3491 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
3492 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
3493 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
3494 { MASK_ALTIVEC, CODE_FOR_altivec_vrfim, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
3495 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
3496 { MASK_ALTIVEC, CODE_FOR_altivec_vrfip, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
3497 { MASK_ALTIVEC, CODE_FOR_ftruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
3498 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
2212663f
DB
3499 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
3500 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
3501 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
20e26713
AH
3502 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
3503 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
3504 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
3505 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
3506 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
3507 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
2212663f
DB
3508};
3509
3510static rtx
3511altivec_expand_unop_builtin (icode, arglist, target)
3512 enum insn_code icode;
3513 tree arglist;
3514 rtx target;
3515{
3516 rtx pat;
3517 tree arg0 = TREE_VALUE (arglist);
3518 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
3519 enum machine_mode tmode = insn_data[icode].operand[0].mode;
3520 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
3521
20e26713
AH
3522 /* If we got invalid arguments bail out before generating bad rtl. */
3523 if (arg0 == error_mark_node)
95385cbb 3524 return NULL_RTX;
20e26713 3525
c62f2db5 3526 if (target == 0
2212663f
DB
3527 || GET_MODE (target) != tmode
3528 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
3529 target = gen_reg_rtx (tmode);
3530
3531 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
3532 op0 = copy_to_mode_reg (mode0, op0);
3533
3534 pat = GEN_FCN (icode) (target, op0);
3535 if (! pat)
3536 return 0;
3537 emit_insn (pat);
0ac081f6 3538
2212663f
DB
3539 return target;
3540}
ae4b4a02 3541
100c4561
AH
3542static rtx
3543altivec_expand_abs_builtin (icode, arglist, target)
3544 enum insn_code icode;
3545 tree arglist;
3546 rtx target;
3547{
3548 rtx pat, scratch1, scratch2;
3549 tree arg0 = TREE_VALUE (arglist);
3550 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
3551 enum machine_mode tmode = insn_data[icode].operand[0].mode;
3552 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
3553
3554 /* If we have invalid arguments, bail out before generating bad rtl. */
3555 if (arg0 == error_mark_node)
3556 return NULL_RTX;
3557
3558 if (target == 0
3559 || GET_MODE (target) != tmode
3560 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
3561 target = gen_reg_rtx (tmode);
3562
3563 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
3564 op0 = copy_to_mode_reg (mode0, op0);
3565
3566 scratch1 = gen_reg_rtx (mode0);
3567 scratch2 = gen_reg_rtx (mode0);
3568
3569 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
3570 if (! pat)
3571 return 0;
3572 emit_insn (pat);
3573
3574 return target;
3575}
3576
0ac081f6
AH
3577static rtx
3578altivec_expand_binop_builtin (icode, arglist, target)
3579 enum insn_code icode;
3580 tree arglist;
3581 rtx target;
3582{
3583 rtx pat;
3584 tree arg0 = TREE_VALUE (arglist);
3585 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
3586 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
3587 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
3588 enum machine_mode tmode = insn_data[icode].operand[0].mode;
3589 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
3590 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
3591
20e26713
AH
3592 /* If we got invalid arguments bail out before generating bad rtl. */
3593 if (arg0 == error_mark_node || arg1 == error_mark_node)
95385cbb 3594 return NULL_RTX;
20e26713 3595
c62f2db5 3596 if (target == 0
0ac081f6
AH
3597 || GET_MODE (target) != tmode
3598 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
3599 target = gen_reg_rtx (tmode);
3600
3601 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
3602 op0 = copy_to_mode_reg (mode0, op0);
3603 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
3604 op1 = copy_to_mode_reg (mode1, op1);
3605
3606 pat = GEN_FCN (icode) (target, op0, op1);
3607 if (! pat)
3608 return 0;
3609 emit_insn (pat);
3610
3611 return target;
3612}
6525c0e7 3613
ae4b4a02
AH
3614static rtx
3615altivec_expand_predicate_builtin (icode, opcode, arglist, target)
3616 enum insn_code icode;
3617 const char *opcode;
3618 tree arglist;
3619 rtx target;
3620{
3621 rtx pat, scratch;
3622 tree cr6_form = TREE_VALUE (arglist);
3623 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
3624 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3625 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
3626 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
3627 enum machine_mode tmode = SImode;
3628 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
3629 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
3630 int cr6_form_int;
3631
3632 if (TREE_CODE (cr6_form) != INTEGER_CST)
3633 {
3634 error ("argument 1 of __builtin_altivec_predicate must be a constant");
3635 return NULL_RTX;
3636 }
3637 else
3638 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
3639
3640 if (mode0 != mode1)
3641 abort ();
3642
3643 /* If we have invalid arguments, bail out before generating bad rtl. */
3644 if (arg0 == error_mark_node || arg1 == error_mark_node)
3645 return NULL_RTX;
3646
3647 if (target == 0
3648 || GET_MODE (target) != tmode
3649 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
3650 target = gen_reg_rtx (tmode);
3651
3652 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
3653 op0 = copy_to_mode_reg (mode0, op0);
3654 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
3655 op1 = copy_to_mode_reg (mode1, op1);
3656
3657 scratch = gen_reg_rtx (mode0);
3658
3659 pat = GEN_FCN (icode) (scratch, op0, op1,
3660 gen_rtx (SYMBOL_REF, Pmode, opcode));
3661 if (! pat)
3662 return 0;
3663 emit_insn (pat);
3664
3665 /* The vec_any* and vec_all* predicates use the same opcodes for two
3666 different operations, but the bits in CR6 will be different
3667 depending on what information we want. So we have to play tricks
3668 with CR6 to get the right bits out.
3669
3670 If you think this is disgusting, look at the specs for the
3671 AltiVec predicates. */
3672
3673 switch (cr6_form_int)
3674 {
3675 case 0:
3676 emit_insn (gen_cr6_test_for_zero (target));
3677 break;
3678 case 1:
3679 emit_insn (gen_cr6_test_for_zero_reverse (target));
3680 break;
3681 case 2:
3682 emit_insn (gen_cr6_test_for_lt (target));
3683 break;
3684 case 3:
3685 emit_insn (gen_cr6_test_for_lt_reverse (target));
3686 break;
3687 default:
3688 error ("argument 1 of __builtin_altivec_predicate is out of range");
3689 break;
3690 }
3691
3692 return target;
3693}
3694
6525c0e7
AH
3695static rtx
3696altivec_expand_stv_builtin (icode, arglist)
3697 enum insn_code icode;
3698 tree arglist;
3699{
3700 tree arg0 = TREE_VALUE (arglist);
3701 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
3702 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3703 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
3704 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
3705 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
3706 rtx pat;
3707 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
3708 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
3709 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
3710
3711 /* Invalid arguments. Bail before doing anything stoopid! */
3712 if (arg0 == error_mark_node
3713 || arg1 == error_mark_node
3714 || arg2 == error_mark_node)
3715 return NULL_RTX;
3716
3717 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
3718 op0 = copy_to_mode_reg (mode2, op0);
3719 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
3720 op1 = copy_to_mode_reg (mode0, op1);
3721 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
3722 op2 = copy_to_mode_reg (mode1, op2);
3723
3724 pat = GEN_FCN (icode) (op1, op2, op0);
3725 if (pat)
3726 emit_insn (pat);
3727 return NULL_RTX;
3728}
3729
2212663f
DB
3730static rtx
3731altivec_expand_ternop_builtin (icode, arglist, target)
3732 enum insn_code icode;
3733 tree arglist;
3734 rtx target;
3735{
3736 rtx pat;
3737 tree arg0 = TREE_VALUE (arglist);
3738 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
3739 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3740 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
3741 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
3742 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
3743 enum machine_mode tmode = insn_data[icode].operand[0].mode;
3744 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
3745 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
3746 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
0ac081f6 3747
20e26713
AH
3748 /* If we got invalid arguments bail out before generating bad rtl. */
3749 if (arg0 == error_mark_node
3750 || arg1 == error_mark_node
3751 || arg2 == error_mark_node)
95385cbb 3752 return NULL_RTX;
20e26713 3753
c62f2db5 3754 if (target == 0
2212663f
DB
3755 || GET_MODE (target) != tmode
3756 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
3757 target = gen_reg_rtx (tmode);
3758
3759 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
3760 op0 = copy_to_mode_reg (mode0, op0);
3761 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
3762 op1 = copy_to_mode_reg (mode1, op1);
3763 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
3764 op2 = copy_to_mode_reg (mode2, op2);
3765
3766 pat = GEN_FCN (icode) (target, op0, op1, op2);
3767 if (! pat)
3768 return 0;
3769 emit_insn (pat);
3770
3771 return target;
3772}
0ac081f6 3773static rtx
00b960c7 3774altivec_expand_builtin (exp, target)
0ac081f6
AH
3775 tree exp;
3776 rtx target;
0ac081f6
AH
3777{
3778 struct builtin_description *d;
ae4b4a02 3779 struct builtin_description_predicates *dp;
0ac081f6
AH
3780 size_t i;
3781 enum insn_code icode;
3782 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3783 tree arglist = TREE_OPERAND (exp, 1);
95385cbb
AH
3784 tree arg0, arg1, arg2;
3785 rtx op0, op1, op2, pat;
3786 enum machine_mode tmode, mode0, mode1, mode2;
0ac081f6
AH
3787 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
3788
3789 switch (fcode)
3790 {
f18c054f
DB
3791 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
3792 icode = CODE_FOR_altivec_lvx_16qi;
0ac081f6
AH
3793 arg0 = TREE_VALUE (arglist);
3794 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
3795 tmode = insn_data[icode].operand[0].mode;
3796 mode0 = insn_data[icode].operand[1].mode;
3797
c62f2db5 3798 if (target == 0
0ac081f6
AH
3799 || GET_MODE (target) != tmode
3800 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
3801 target = gen_reg_rtx (tmode);
3802
3803 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
3804 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
3805
3806 pat = GEN_FCN (icode) (target, op0);
3807 if (! pat)
3808 return 0;
3809 emit_insn (pat);
3810 return target;
24408032 3811
f18c054f
DB
3812 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
3813 icode = CODE_FOR_altivec_lvx_8hi;
3814 arg0 = TREE_VALUE (arglist);
3815 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
3816 tmode = insn_data[icode].operand[0].mode;
3817 mode0 = insn_data[icode].operand[1].mode;
0ac081f6 3818
c62f2db5 3819 if (target == 0
f18c054f
DB
3820 || GET_MODE (target) != tmode
3821 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
3822 target = gen_reg_rtx (tmode);
3823
3824 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
3825 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
3826
3827 pat = GEN_FCN (icode) (target, op0);
3828 if (! pat)
3829 return 0;
3830 emit_insn (pat);
3831 return target;
24408032 3832
f18c054f
DB
3833 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
3834 icode = CODE_FOR_altivec_lvx_4si;
3835 arg0 = TREE_VALUE (arglist);
3836 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
3837 tmode = insn_data[icode].operand[0].mode;
3838 mode0 = insn_data[icode].operand[1].mode;
3839
c62f2db5 3840 if (target == 0
f18c054f
DB
3841 || GET_MODE (target) != tmode
3842 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
3843 target = gen_reg_rtx (tmode);
3844
3845 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
3846 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
3847
3848 pat = GEN_FCN (icode) (target, op0);
3849 if (! pat)
3850 return 0;
3851 emit_insn (pat);
3852 return target;
24408032 3853
f18c054f
DB
3854 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
3855 icode = CODE_FOR_altivec_lvx_4sf;
3856 arg0 = TREE_VALUE (arglist);
3857 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
3858 tmode = insn_data[icode].operand[0].mode;
3859 mode0 = insn_data[icode].operand[1].mode;
3860
c62f2db5 3861 if (target == 0
f18c054f
DB
3862 || GET_MODE (target) != tmode
3863 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
3864 target = gen_reg_rtx (tmode);
3865
3866 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
3867 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
3868
3869 pat = GEN_FCN (icode) (target, op0);
3870 if (! pat)
3871 return 0;
3872 emit_insn (pat);
3873 return target;
3874
3875 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
3876 icode = CODE_FOR_altivec_stvx_16qi;
3877 arg0 = TREE_VALUE (arglist);
3878 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
3879 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
3880 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
3881 mode0 = insn_data[icode].operand[0].mode;
3882 mode1 = insn_data[icode].operand[1].mode;
3883
3884 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
3885 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
3886 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
3887 op1 = copy_to_mode_reg (mode1, op1);
3888
3889 pat = GEN_FCN (icode) (op0, op1);
95385cbb
AH
3890 if (pat)
3891 emit_insn (pat);
f18c054f 3892 return NULL_RTX;
24408032 3893
f18c054f
DB
3894 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
3895 icode = CODE_FOR_altivec_stvx_8hi;
3896 arg0 = TREE_VALUE (arglist);
3897 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
3898 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
3899 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
3900 mode0 = insn_data[icode].operand[0].mode;
3901 mode1 = insn_data[icode].operand[1].mode;
3902
3903 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
3904 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
3905 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
3906 op1 = copy_to_mode_reg (mode1, op1);
3907
3908 pat = GEN_FCN (icode) (op0, op1);
95385cbb
AH
3909 if (pat)
3910 emit_insn (pat);
f18c054f 3911 return NULL_RTX;
24408032 3912
f18c054f
DB
3913 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
3914 icode = CODE_FOR_altivec_stvx_4si;
3915 arg0 = TREE_VALUE (arglist);
3916 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
3917 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
3918 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
3919 mode0 = insn_data[icode].operand[0].mode;
3920 mode1 = insn_data[icode].operand[1].mode;
3921
3922 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
3923 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
3924 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
3925 op1 = copy_to_mode_reg (mode1, op1);
3926
3927 pat = GEN_FCN (icode) (op0, op1);
95385cbb
AH
3928 if (pat)
3929 emit_insn (pat);
f18c054f 3930 return NULL_RTX;
24408032 3931
f18c054f
DB
3932 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
3933 icode = CODE_FOR_altivec_stvx_4sf;
0ac081f6
AH
3934 arg0 = TREE_VALUE (arglist);
3935 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
3936 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
3937 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
3938 mode0 = insn_data[icode].operand[0].mode;
3939 mode1 = insn_data[icode].operand[1].mode;
3940
3941 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
3942 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
3943 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
3944 op1 = copy_to_mode_reg (mode1, op1);
3945
3946 pat = GEN_FCN (icode) (op0, op1);
95385cbb
AH
3947 if (pat)
3948 emit_insn (pat);
3949 return NULL_RTX;
3950
6525c0e7
AH
3951 case ALTIVEC_BUILTIN_STVX:
3952 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, arglist);
3953 case ALTIVEC_BUILTIN_STVEBX:
3954 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, arglist);
3955 case ALTIVEC_BUILTIN_STVEHX:
3956 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, arglist);
3957 case ALTIVEC_BUILTIN_STVEWX:
3958 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, arglist);
3959 case ALTIVEC_BUILTIN_STVXL:
3960 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, arglist);
3961
95385cbb
AH
3962 case ALTIVEC_BUILTIN_MFVSCR:
3963 icode = CODE_FOR_altivec_mfvscr;
3964 tmode = insn_data[icode].operand[0].mode;
3965
3966 if (target == 0
3967 || GET_MODE (target) != tmode
3968 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
3969 target = gen_reg_rtx (tmode);
3970
3971 pat = GEN_FCN (icode) (target);
0ac081f6
AH
3972 if (! pat)
3973 return 0;
3974 emit_insn (pat);
95385cbb
AH
3975 return target;
3976
3977 case ALTIVEC_BUILTIN_MTVSCR:
3978 icode = CODE_FOR_altivec_mtvscr;
3979 arg0 = TREE_VALUE (arglist);
3980 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
3981 mode0 = insn_data[icode].operand[0].mode;
3982
3983 /* If we got invalid arguments bail out before generating bad rtl. */
3984 if (arg0 == error_mark_node)
3985 return NULL_RTX;
3986
3987 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
3988 op0 = copy_to_mode_reg (mode0, op0);
3989
3990 pat = GEN_FCN (icode) (op0);
3991 if (pat)
3992 emit_insn (pat);
3993 return NULL_RTX;
3994
3995 case ALTIVEC_BUILTIN_DSSALL:
3996 emit_insn (gen_altivec_dssall ());
3997 return NULL_RTX;
3998
3999 case ALTIVEC_BUILTIN_DSS:
4000 icode = CODE_FOR_altivec_dss;
4001 arg0 = TREE_VALUE (arglist);
4002 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4003 mode0 = insn_data[icode].operand[0].mode;
4004
4005 /* If we got invalid arguments bail out before generating bad rtl. */
4006 if (arg0 == error_mark_node)
4007 return NULL_RTX;
4008
4009 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4010 op0 = copy_to_mode_reg (mode0, op0);
4011
4012 emit_insn (gen_altivec_dss (op0));
0ac081f6
AH
4013 return NULL_RTX;
4014 }
24408032 4015
95385cbb
AH
4016 /* Handle DST variants. */
4017 d = (struct builtin_description *) bdesc_dst;
ca7558fc 4018 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
95385cbb
AH
4019 if (d->code == fcode)
4020 {
4021 arg0 = TREE_VALUE (arglist);
4022 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4023 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4024 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4025 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4026 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4027 mode0 = insn_data[d->icode].operand[0].mode;
4028 mode1 = insn_data[d->icode].operand[1].mode;
4029 mode2 = insn_data[d->icode].operand[2].mode;
4030
4031 /* Invalid arguments, bail out before generating bad rtl. */
4032 if (arg0 == error_mark_node
4033 || arg1 == error_mark_node
4034 || arg2 == error_mark_node)
4035 return NULL_RTX;
4036
4037 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
4038 op0 = copy_to_mode_reg (mode0, op0);
4039 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
4040 op1 = copy_to_mode_reg (mode1, op1);
4041
4042 if (GET_CODE (op2) != CONST_INT || INTVAL (op2) > 3)
4043 {
4044 error ("argument 3 of `%s' must be a 2-bit literal", d->name);
4045 return NULL_RTX;
4046 }
4047
4048 pat = GEN_FCN (d->icode) (op0, op1, op2);
4049 if (pat != 0)
4050 emit_insn (pat);
4051
4052 return NULL_RTX;
4053 }
4054
100c4561
AH
4055 /* Expand abs* operations. */
4056 d = (struct builtin_description *) bdesc_abs;
ca7558fc 4057 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
100c4561
AH
4058 if (d->code == fcode)
4059 return altivec_expand_abs_builtin (d->icode, arglist, target);
4060
2212663f
DB
4061 /* Handle simple unary operations. */
4062 d = (struct builtin_description *) bdesc_1arg;
ca7558fc 4063 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
2212663f
DB
4064 if (d->code == fcode)
4065 return altivec_expand_unop_builtin (d->icode, arglist, target);
0ac081f6
AH
4066
4067 /* Handle simple binary operations. */
00b960c7 4068 d = (struct builtin_description *) bdesc_2arg;
ca7558fc 4069 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
0ac081f6
AH
4070 if (d->code == fcode)
4071 return altivec_expand_binop_builtin (d->icode, arglist, target);
4072
ae4b4a02
AH
4073 /* Expand the AltiVec predicates. */
4074 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
ca7558fc 4075 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
ae4b4a02
AH
4076 if (dp->code == fcode)
4077 return altivec_expand_predicate_builtin (dp->icode, dp->opcode, arglist, target);
4078
6525c0e7
AH
4079 /* LV* are funky. We initialized them differently. */
4080 switch (fcode)
4081 {
4082 case ALTIVEC_BUILTIN_LVSL:
4083 return altivec_expand_binop_builtin (CODE_FOR_altivec_lvsl,
4084 arglist, target);
4085 case ALTIVEC_BUILTIN_LVSR:
4086 return altivec_expand_binop_builtin (CODE_FOR_altivec_lvsr,
4087 arglist, target);
4088 case ALTIVEC_BUILTIN_LVEBX:
4089 return altivec_expand_binop_builtin (CODE_FOR_altivec_lvebx,
4090 arglist, target);
4091 case ALTIVEC_BUILTIN_LVEHX:
4092 return altivec_expand_binop_builtin (CODE_FOR_altivec_lvehx,
4093 arglist, target);
4094 case ALTIVEC_BUILTIN_LVEWX:
4095 return altivec_expand_binop_builtin (CODE_FOR_altivec_lvewx,
4096 arglist, target);
4097 case ALTIVEC_BUILTIN_LVXL:
4098 return altivec_expand_binop_builtin (CODE_FOR_altivec_lvxl,
4099 arglist, target);
4100 case ALTIVEC_BUILTIN_LVX:
4101 return altivec_expand_binop_builtin (CODE_FOR_altivec_lvx,
4102 arglist, target);
4103 default:
4104 break;
4105 /* Fall through. */
4106 }
95385cbb 4107
2212663f
DB
4108 /* Handle simple ternary operations. */
4109 d = (struct builtin_description *) bdesc_3arg;
ca7558fc 4110 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
2212663f
DB
4111 if (d->code == fcode)
4112 return altivec_expand_ternop_builtin (d->icode, arglist, target);
4113
0ac081f6
AH
4114 abort ();
4115 return NULL_RTX;
4116}
4117
4118/* Expand an expression EXP that calls a built-in function,
4119 with result going to TARGET if that's convenient
4120 (and in mode MODE if that's convenient).
4121 SUBTARGET may be used as the target for computing one of EXP's operands.
4122 IGNORE is nonzero if the value is to be ignored. */
4123
4124static rtx
4125rs6000_expand_builtin (exp, target, subtarget, mode, ignore)
4126 tree exp;
4127 rtx target;
00b960c7
AH
4128 rtx subtarget ATTRIBUTE_UNUSED;
4129 enum machine_mode mode ATTRIBUTE_UNUSED;
4130 int ignore ATTRIBUTE_UNUSED;
0ac081f6
AH
4131{
4132 if (TARGET_ALTIVEC)
00b960c7 4133 return altivec_expand_builtin (exp, target);
0ac081f6
AH
4134
4135 abort ();
4136}
4137
4138static void
6fa3f289 4139rs6000_init_builtins ()
0ac081f6
AH
4140{
4141 if (TARGET_ALTIVEC)
4142 altivec_init_builtins ();
4143}
4144
4145static void
4146altivec_init_builtins (void)
4147{
ae4b4a02
AH
4148 struct builtin_description *d;
4149 struct builtin_description_predicates *dp;
0ac081f6
AH
4150 size_t i;
4151
4152 tree endlink = void_list_node;
4153
4154 tree pint_type_node = build_pointer_type (integer_type_node);
95385cbb 4155 tree pvoid_type_node = build_pointer_type (void_type_node);
f18c054f
DB
4156 tree pshort_type_node = build_pointer_type (short_integer_type_node);
4157 tree pchar_type_node = build_pointer_type (char_type_node);
4158 tree pfloat_type_node = build_pointer_type (float_type_node);
20e26713 4159
2212663f
DB
4160 tree v4sf_ftype_v4sf_v4sf_v16qi
4161 = build_function_type (V4SF_type_node,
4162 tree_cons (NULL_TREE, V4SF_type_node,
4163 tree_cons (NULL_TREE, V4SF_type_node,
4164 tree_cons (NULL_TREE,
4165 V16QI_type_node,
4166 endlink))));
4167 tree v4si_ftype_v4si_v4si_v16qi
4168 = build_function_type (V4SI_type_node,
4169 tree_cons (NULL_TREE, V4SI_type_node,
4170 tree_cons (NULL_TREE, V4SI_type_node,
4171 tree_cons (NULL_TREE,
4172 V16QI_type_node,
4173 endlink))));
4174 tree v8hi_ftype_v8hi_v8hi_v16qi
4175 = build_function_type (V8HI_type_node,
4176 tree_cons (NULL_TREE, V8HI_type_node,
4177 tree_cons (NULL_TREE, V8HI_type_node,
4178 tree_cons (NULL_TREE,
4179 V16QI_type_node,
4180 endlink))));
4181 tree v16qi_ftype_v16qi_v16qi_v16qi
4182 = build_function_type (V16QI_type_node,
4183 tree_cons (NULL_TREE, V16QI_type_node,
4184 tree_cons (NULL_TREE, V16QI_type_node,
4185 tree_cons (NULL_TREE,
4186 V16QI_type_node,
4187 endlink))));
4188
24408032 4189 /* V4SI foo (char). */
2212663f
DB
4190 tree v4si_ftype_char
4191 = build_function_type (V4SI_type_node,
4192 tree_cons (NULL_TREE, char_type_node, endlink));
4193
24408032 4194 /* V8HI foo (char). */
2212663f
DB
4195 tree v8hi_ftype_char
4196 = build_function_type (V8HI_type_node,
4197 tree_cons (NULL_TREE, char_type_node, endlink));
4198
24408032 4199 /* V16QI foo (char). */
2212663f
DB
4200 tree v16qi_ftype_char
4201 = build_function_type (V16QI_type_node,
4202 tree_cons (NULL_TREE, char_type_node, endlink));
24408032 4203 /* V4SF foo (V4SF). */
617e0e1d
DB
4204 tree v4sf_ftype_v4sf
4205 = build_function_type (V4SF_type_node,
4206 tree_cons (NULL_TREE, V4SF_type_node, endlink));
0ac081f6
AH
4207
4208 /* V4SI foo (int *). */
4209 tree v4si_ftype_pint
4210 = build_function_type (V4SI_type_node,
4211 tree_cons (NULL_TREE, pint_type_node, endlink));
f18c054f
DB
4212 /* V8HI foo (short *). */
4213 tree v8hi_ftype_pshort
4214 = build_function_type (V8HI_type_node,
4215 tree_cons (NULL_TREE, pshort_type_node, endlink));
4216 /* V16QI foo (char *). */
4217 tree v16qi_ftype_pchar
4218 = build_function_type (V16QI_type_node,
4219 tree_cons (NULL_TREE, pchar_type_node, endlink));
4220 /* V4SF foo (float *). */
4221 tree v4sf_ftype_pfloat
4222 = build_function_type (V4SF_type_node,
4223 tree_cons (NULL_TREE, pfloat_type_node, endlink));
0ac081f6 4224
20e26713
AH
4225 /* V8HI foo (V16QI). */
4226 tree v8hi_ftype_v16qi
4227 = build_function_type (V8HI_type_node,
4228 tree_cons (NULL_TREE, V16QI_type_node, endlink));
4229
95385cbb
AH
4230 /* void foo (void *, int, char/literal). */
4231 tree void_ftype_pvoid_int_char
4232 = build_function_type (void_type_node,
4233 tree_cons (NULL_TREE, pvoid_type_node,
4234 tree_cons (NULL_TREE, integer_type_node,
4235 tree_cons (NULL_TREE,
4236 char_type_node,
4237 endlink))));
4238
0ac081f6
AH
4239 /* void foo (int *, V4SI). */
4240 tree void_ftype_pint_v4si
4241 = build_function_type (void_type_node,
4242 tree_cons (NULL_TREE, pint_type_node,
4243 tree_cons (NULL_TREE, V4SI_type_node,
4244 endlink)));
f18c054f
DB
4245 /* void foo (short *, V8HI). */
4246 tree void_ftype_pshort_v8hi
4247 = build_function_type (void_type_node,
4248 tree_cons (NULL_TREE, pshort_type_node,
4249 tree_cons (NULL_TREE, V8HI_type_node,
4250 endlink)));
4251 /* void foo (char *, V16QI). */
4252 tree void_ftype_pchar_v16qi
4253 = build_function_type (void_type_node,
4254 tree_cons (NULL_TREE, pchar_type_node,
4255 tree_cons (NULL_TREE, V16QI_type_node,
4256 endlink)));
4257 /* void foo (float *, V4SF). */
4258 tree void_ftype_pfloat_v4sf
4259 = build_function_type (void_type_node,
4260 tree_cons (NULL_TREE, pfloat_type_node,
4261 tree_cons (NULL_TREE, V4SF_type_node,
4262 endlink)));
0ac081f6 4263
95385cbb
AH
4264 /* void foo (V4SI). */
4265 tree void_ftype_v4si
4266 = build_function_type (void_type_node,
4267 tree_cons (NULL_TREE, V4SI_type_node,
4268 endlink));
4269
6525c0e7
AH
4270 /* void foo (vint, int, void *). */
4271 tree void_ftype_v4si_int_pvoid
4272 = build_function_type (void_type_node,
4273 tree_cons (NULL_TREE, V4SI_type_node,
4274 tree_cons (NULL_TREE, integer_type_node,
4275 tree_cons (NULL_TREE,
4276 pvoid_type_node,
4277 endlink))));
4278
4279 /* void foo (vchar, int, void *). */
4280 tree void_ftype_v16qi_int_pvoid
4281 = build_function_type (void_type_node,
4282 tree_cons (NULL_TREE, V16QI_type_node,
4283 tree_cons (NULL_TREE, integer_type_node,
4284 tree_cons (NULL_TREE,
4285 pvoid_type_node,
4286 endlink))));
4287
4288 /* void foo (vshort, int, void *). */
4289 tree void_ftype_v8hi_int_pvoid
4290 = build_function_type (void_type_node,
4291 tree_cons (NULL_TREE, V8HI_type_node,
4292 tree_cons (NULL_TREE, integer_type_node,
4293 tree_cons (NULL_TREE,
4294 pvoid_type_node,
4295 endlink))));
4296
95385cbb
AH
4297 /* void foo (char). */
4298 tree void_ftype_qi
4299 = build_function_type (void_type_node,
4300 tree_cons (NULL_TREE, char_type_node,
4301 endlink));
4302
4303 /* void foo (void). */
4304 tree void_ftype_void
3deb2758 4305 = build_function_type (void_type_node, void_list_node);
95385cbb
AH
4306
4307 /* vshort foo (void). */
4308 tree v8hi_ftype_void
3deb2758 4309 = build_function_type (V8HI_type_node, void_list_node);
95385cbb 4310
0ac081f6
AH
4311 tree v4si_ftype_v4si_v4si
4312 = build_function_type (V4SI_type_node,
4313 tree_cons (NULL_TREE, V4SI_type_node,
4314 tree_cons (NULL_TREE, V4SI_type_node,
4315 endlink)));
24408032
AH
4316
4317 /* These are for the unsigned 5 bit literals. */
4318
617e0e1d
DB
4319 tree v4sf_ftype_v4si_char
4320 = build_function_type (V4SF_type_node,
4321 tree_cons (NULL_TREE, V4SI_type_node,
4322 tree_cons (NULL_TREE, char_type_node,
4323 endlink)));
4324 tree v4si_ftype_v4sf_char
4325 = build_function_type (V4SI_type_node,
4326 tree_cons (NULL_TREE, V4SF_type_node,
4327 tree_cons (NULL_TREE, char_type_node,
4328 endlink)));
2212663f
DB
4329 tree v4si_ftype_v4si_char
4330 = build_function_type (V4SI_type_node,
4331 tree_cons (NULL_TREE, V4SI_type_node,
4332 tree_cons (NULL_TREE, char_type_node,
4333 endlink)));
4334 tree v8hi_ftype_v8hi_char
4335 = build_function_type (V8HI_type_node,
4336 tree_cons (NULL_TREE, V8HI_type_node,
4337 tree_cons (NULL_TREE, char_type_node,
4338 endlink)));
4339 tree v16qi_ftype_v16qi_char
4340 = build_function_type (V16QI_type_node,
4341 tree_cons (NULL_TREE, V16QI_type_node,
4342 tree_cons (NULL_TREE, char_type_node,
4343 endlink)));
0ac081f6 4344
24408032
AH
4345 /* These are for the unsigned 4 bit literals. */
4346
4347 tree v16qi_ftype_v16qi_v16qi_char
4348 = build_function_type (V16QI_type_node,
4349 tree_cons (NULL_TREE, V16QI_type_node,
4350 tree_cons (NULL_TREE, V16QI_type_node,
4351 tree_cons (NULL_TREE,
4352 char_type_node,
4353 endlink))));
4354
4355 tree v8hi_ftype_v8hi_v8hi_char
4356 = build_function_type (V8HI_type_node,
4357 tree_cons (NULL_TREE, V8HI_type_node,
4358 tree_cons (NULL_TREE, V8HI_type_node,
4359 tree_cons (NULL_TREE,
4360 char_type_node,
4361 endlink))));
4362
4363 tree v4si_ftype_v4si_v4si_char
4364 = build_function_type (V4SI_type_node,
4365 tree_cons (NULL_TREE, V4SI_type_node,
4366 tree_cons (NULL_TREE, V4SI_type_node,
4367 tree_cons (NULL_TREE,
4368 char_type_node,
4369 endlink))));
4370
4371 tree v4sf_ftype_v4sf_v4sf_char
4372 = build_function_type (V4SF_type_node,
4373 tree_cons (NULL_TREE, V4SF_type_node,
4374 tree_cons (NULL_TREE, V4SF_type_node,
4375 tree_cons (NULL_TREE,
4376 char_type_node,
4377 endlink))));
4378
4379 /* End of 4 bit literals. */
4380
0ac081f6
AH
4381 tree v4sf_ftype_v4sf_v4sf
4382 = build_function_type (V4SF_type_node,
4383 tree_cons (NULL_TREE, V4SF_type_node,
4384 tree_cons (NULL_TREE, V4SF_type_node,
4385 endlink)));
617e0e1d
DB
4386 tree v4sf_ftype_v4sf_v4sf_v4si
4387 = build_function_type (V4SF_type_node,
4388 tree_cons (NULL_TREE, V4SF_type_node,
4389 tree_cons (NULL_TREE, V4SF_type_node,
4390 tree_cons (NULL_TREE,
4391 V4SI_type_node,
4392 endlink))));
2212663f
DB
4393 tree v4sf_ftype_v4sf_v4sf_v4sf
4394 = build_function_type (V4SF_type_node,
4395 tree_cons (NULL_TREE, V4SF_type_node,
4396 tree_cons (NULL_TREE, V4SF_type_node,
4397 tree_cons (NULL_TREE,
4398 V4SF_type_node,
4399 endlink))));
617e0e1d
DB
4400 tree v4si_ftype_v4si_v4si_v4si
4401 = build_function_type (V4SI_type_node,
4402 tree_cons (NULL_TREE, V4SI_type_node,
4403 tree_cons (NULL_TREE, V4SI_type_node,
4404 tree_cons (NULL_TREE,
4405 V4SI_type_node,
4406 endlink))));
2212663f 4407
0ac081f6
AH
4408 tree v8hi_ftype_v8hi_v8hi
4409 = build_function_type (V8HI_type_node,
4410 tree_cons (NULL_TREE, V8HI_type_node,
4411 tree_cons (NULL_TREE, V8HI_type_node,
4412 endlink)));
2212663f
DB
4413 tree v8hi_ftype_v8hi_v8hi_v8hi
4414 = build_function_type (V8HI_type_node,
4415 tree_cons (NULL_TREE, V8HI_type_node,
4416 tree_cons (NULL_TREE, V8HI_type_node,
4417 tree_cons (NULL_TREE,
4418 V8HI_type_node,
4419 endlink))));
4420 tree v4si_ftype_v8hi_v8hi_v4si
4421 = build_function_type (V4SI_type_node,
4422 tree_cons (NULL_TREE, V8HI_type_node,
4423 tree_cons (NULL_TREE, V8HI_type_node,
4424 tree_cons (NULL_TREE,
4425 V4SI_type_node,
4426 endlink))));
4427 tree v4si_ftype_v16qi_v16qi_v4si
4428 = build_function_type (V4SI_type_node,
4429 tree_cons (NULL_TREE, V16QI_type_node,
4430 tree_cons (NULL_TREE, V16QI_type_node,
4431 tree_cons (NULL_TREE,
4432 V4SI_type_node,
4433 endlink))));
4434
0ac081f6
AH
4435 tree v16qi_ftype_v16qi_v16qi
4436 = build_function_type (V16QI_type_node,
4437 tree_cons (NULL_TREE, V16QI_type_node,
4438 tree_cons (NULL_TREE, V16QI_type_node,
4439 endlink)));
2212663f 4440
0ac081f6
AH
4441 tree v4si_ftype_v4sf_v4sf
4442 = build_function_type (V4SI_type_node,
4443 tree_cons (NULL_TREE, V4SF_type_node,
4444 tree_cons (NULL_TREE, V4SF_type_node,
4445 endlink)));
4446
100c4561
AH
4447 tree v4si_ftype_v4si
4448 = build_function_type (V4SI_type_node,
4449 tree_cons (NULL_TREE, V4SI_type_node, endlink));
4450
4451 tree v8hi_ftype_v8hi
4452 = build_function_type (V8HI_type_node,
4453 tree_cons (NULL_TREE, V8HI_type_node, endlink));
4454
4455 tree v16qi_ftype_v16qi
4456 = build_function_type (V16QI_type_node,
4457 tree_cons (NULL_TREE, V16QI_type_node, endlink));
4458
0ac081f6
AH
4459 tree v8hi_ftype_v16qi_v16qi
4460 = build_function_type (V8HI_type_node,
4461 tree_cons (NULL_TREE, V16QI_type_node,
4462 tree_cons (NULL_TREE, V16QI_type_node,
4463 endlink)));
4464
4465 tree v4si_ftype_v8hi_v8hi
4466 = build_function_type (V4SI_type_node,
4467 tree_cons (NULL_TREE, V8HI_type_node,
4468 tree_cons (NULL_TREE, V8HI_type_node,
4469 endlink)));
4470
4471 tree v8hi_ftype_v4si_v4si
4472 = build_function_type (V8HI_type_node,
4473 tree_cons (NULL_TREE, V4SI_type_node,
4474 tree_cons (NULL_TREE, V4SI_type_node,
4475 endlink)));
4476
4477 tree v16qi_ftype_v8hi_v8hi
4478 = build_function_type (V16QI_type_node,
4479 tree_cons (NULL_TREE, V8HI_type_node,
4480 tree_cons (NULL_TREE, V8HI_type_node,
4481 endlink)));
4482
4483 tree v4si_ftype_v16qi_v4si
4484 = build_function_type (V4SI_type_node,
4485 tree_cons (NULL_TREE, V16QI_type_node,
4486 tree_cons (NULL_TREE, V4SI_type_node,
4487 endlink)));
4488
fa066a23
AH
4489 tree v4si_ftype_v16qi_v16qi
4490 = build_function_type (V4SI_type_node,
4491 tree_cons (NULL_TREE, V16QI_type_node,
4492 tree_cons (NULL_TREE, V16QI_type_node,
4493 endlink)));
4494
0ac081f6
AH
4495 tree v4si_ftype_v8hi_v4si
4496 = build_function_type (V4SI_type_node,
4497 tree_cons (NULL_TREE, V8HI_type_node,
4498 tree_cons (NULL_TREE, V4SI_type_node,
4499 endlink)));
4500
20e26713
AH
4501 tree v4si_ftype_v8hi
4502 = build_function_type (V4SI_type_node,
4503 tree_cons (NULL_TREE, V8HI_type_node, endlink));
4504
0ac081f6
AH
4505 tree int_ftype_v4si_v4si
4506 = build_function_type (integer_type_node,
4507 tree_cons (NULL_TREE, V4SI_type_node,
4508 tree_cons (NULL_TREE, V4SI_type_node,
4509 endlink)));
4510
4511 tree int_ftype_v4sf_v4sf
4512 = build_function_type (integer_type_node,
4513 tree_cons (NULL_TREE, V4SF_type_node,
4514 tree_cons (NULL_TREE, V4SF_type_node,
4515 endlink)));
4516
4517 tree int_ftype_v16qi_v16qi
4518 = build_function_type (integer_type_node,
4519 tree_cons (NULL_TREE, V16QI_type_node,
4520 tree_cons (NULL_TREE, V16QI_type_node,
4521 endlink)));
4522
ae4b4a02
AH
4523 tree int_ftype_int_v4si_v4si
4524 = build_function_type
4525 (integer_type_node,
4526 tree_cons (NULL_TREE, integer_type_node,
4527 tree_cons (NULL_TREE, V4SI_type_node,
4528 tree_cons (NULL_TREE, V4SI_type_node,
4529 endlink))));
4530
4531 tree int_ftype_int_v4sf_v4sf
4532 = build_function_type
4533 (integer_type_node,
4534 tree_cons (NULL_TREE, integer_type_node,
4535 tree_cons (NULL_TREE, V4SF_type_node,
4536 tree_cons (NULL_TREE, V4SF_type_node,
4537 endlink))));
4538
4539 tree int_ftype_int_v8hi_v8hi
4540 = build_function_type
4541 (integer_type_node,
4542 tree_cons (NULL_TREE, integer_type_node,
4543 tree_cons (NULL_TREE, V8HI_type_node,
4544 tree_cons (NULL_TREE, V8HI_type_node,
4545 endlink))));
4546
4547 tree int_ftype_int_v16qi_v16qi
4548 = build_function_type
4549 (integer_type_node,
4550 tree_cons (NULL_TREE, integer_type_node,
4551 tree_cons (NULL_TREE, V16QI_type_node,
4552 tree_cons (NULL_TREE, V16QI_type_node,
4553 endlink))));
4554
95385cbb
AH
4555 tree v16qi_ftype_int_pvoid
4556 = build_function_type (V16QI_type_node,
4557 tree_cons (NULL_TREE, integer_type_node,
4558 tree_cons (NULL_TREE, pvoid_type_node,
4559 endlink)));
4560
6525c0e7
AH
4561 tree v4si_ftype_int_pvoid
4562 = build_function_type (V4SI_type_node,
4563 tree_cons (NULL_TREE, integer_type_node,
4564 tree_cons (NULL_TREE, pvoid_type_node,
4565 endlink)));
4566
4567 tree v8hi_ftype_int_pvoid
4568 = build_function_type (V8HI_type_node,
4569 tree_cons (NULL_TREE, integer_type_node,
4570 tree_cons (NULL_TREE, pvoid_type_node,
4571 endlink)));
4572
0ac081f6
AH
4573 tree int_ftype_v8hi_v8hi
4574 = build_function_type (integer_type_node,
4575 tree_cons (NULL_TREE, V8HI_type_node,
4576 tree_cons (NULL_TREE, V8HI_type_node,
4577 endlink)));
4578
f18c054f
DB
4579 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pfloat, ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
4580 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf, ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
4581 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pint, ALTIVEC_BUILTIN_LD_INTERNAL_4si);
4582 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si, ALTIVEC_BUILTIN_ST_INTERNAL_4si);
4583 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pshort, ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
4584 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi, ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
4585 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pchar, ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
4586 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi, ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
95385cbb
AH
4587 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
4588 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
4589 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
4590 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_qi, ALTIVEC_BUILTIN_DSS);
4591 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVSL);
4592 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVSR);
6525c0e7
AH
4593 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVEBX);
4594 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVEHX);
4595 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_int_pvoid, ALTIVEC_BUILTIN_LVEWX);
4596 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_int_pvoid, ALTIVEC_BUILTIN_LVXL);
4597 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_int_pvoid, ALTIVEC_BUILTIN_LVX);
4598 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVX);
4599 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_int_pvoid, ALTIVEC_BUILTIN_STVEBX);
4600 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_int_pvoid, ALTIVEC_BUILTIN_STVEHX);
4601 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVEWX);
4602 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVXL);
100c4561 4603
6f317ef3 4604 /* Add the simple ternary operators. */
2212663f 4605 d = (struct builtin_description *) bdesc_3arg;
ca7558fc 4606 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
2212663f
DB
4607 {
4608
4609 enum machine_mode mode0, mode1, mode2, mode3;
4610 tree type;
4611
4612 if (d->name == 0)
4613 continue;
4614
4615 mode0 = insn_data[d->icode].operand[0].mode;
4616 mode1 = insn_data[d->icode].operand[1].mode;
4617 mode2 = insn_data[d->icode].operand[2].mode;
4618 mode3 = insn_data[d->icode].operand[3].mode;
4619
4620 /* When all four are of the same mode. */
4621 if (mode0 == mode1 && mode1 == mode2 && mode2 == mode3)
4622 {
4623 switch (mode0)
4624 {
617e0e1d
DB
4625 case V4SImode:
4626 type = v4si_ftype_v4si_v4si_v4si;
4627 break;
2212663f
DB
4628 case V4SFmode:
4629 type = v4sf_ftype_v4sf_v4sf_v4sf;
4630 break;
4631 case V8HImode:
4632 type = v8hi_ftype_v8hi_v8hi_v8hi;
4633 break;
4634 case V16QImode:
4635 type = v16qi_ftype_v16qi_v16qi_v16qi;
4636 break;
4637 default:
4638 abort();
4639 }
4640 }
4641 else if (mode0 == mode1 && mode1 == mode2 && mode3 == V16QImode)
4642 {
4643 switch (mode0)
4644 {
4645 case V4SImode:
4646 type = v4si_ftype_v4si_v4si_v16qi;
4647 break;
4648 case V4SFmode:
4649 type = v4sf_ftype_v4sf_v4sf_v16qi;
4650 break;
4651 case V8HImode:
4652 type = v8hi_ftype_v8hi_v8hi_v16qi;
4653 break;
4654 case V16QImode:
4655 type = v16qi_ftype_v16qi_v16qi_v16qi;
4656 break;
4657 default:
4658 abort();
4659 }
4660 }
4661 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode
4662 && mode3 == V4SImode)
24408032 4663 type = v4si_ftype_v16qi_v16qi_v4si;
2212663f
DB
4664 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode
4665 && mode3 == V4SImode)
24408032 4666 type = v4si_ftype_v8hi_v8hi_v4si;
617e0e1d
DB
4667 else if (mode0 == V4SFmode && mode1 == V4SFmode && mode2 == V4SFmode
4668 && mode3 == V4SImode)
24408032
AH
4669 type = v4sf_ftype_v4sf_v4sf_v4si;
4670
4671 /* vchar, vchar, vchar, 4 bit literal. */
4672 else if (mode0 == V16QImode && mode1 == mode0 && mode2 == mode0
4673 && mode3 == QImode)
4674 type = v16qi_ftype_v16qi_v16qi_char;
4675
4676 /* vshort, vshort, vshort, 4 bit literal. */
4677 else if (mode0 == V8HImode && mode1 == mode0 && mode2 == mode0
4678 && mode3 == QImode)
4679 type = v8hi_ftype_v8hi_v8hi_char;
4680
4681 /* vint, vint, vint, 4 bit literal. */
4682 else if (mode0 == V4SImode && mode1 == mode0 && mode2 == mode0
4683 && mode3 == QImode)
4684 type = v4si_ftype_v4si_v4si_char;
4685
4686 /* vfloat, vfloat, vfloat, 4 bit literal. */
4687 else if (mode0 == V4SFmode && mode1 == mode0 && mode2 == mode0
4688 && mode3 == QImode)
4689 type = v4sf_ftype_v4sf_v4sf_char;
4690
2212663f
DB
4691 else
4692 abort ();
4693
4694 def_builtin (d->mask, d->name, type, d->code);
4695 }
4696
95385cbb
AH
4697 /* Add the DST variants. */
4698 d = (struct builtin_description *) bdesc_dst;
ca7558fc 4699 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
95385cbb
AH
4700 def_builtin (d->mask, d->name, void_ftype_pvoid_int_char, d->code);
4701
ae4b4a02
AH
4702 /* Initialize the predicates. */
4703 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
ca7558fc 4704 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
ae4b4a02
AH
4705 {
4706 enum machine_mode mode1;
4707 tree type;
4708
4709 mode1 = insn_data[dp->icode].operand[1].mode;
4710
4711 switch (mode1)
4712 {
4713 case V4SImode:
4714 type = int_ftype_int_v4si_v4si;
4715 break;
4716 case V8HImode:
4717 type = int_ftype_int_v8hi_v8hi;
4718 break;
4719 case V16QImode:
4720 type = int_ftype_int_v16qi_v16qi;
4721 break;
4722 case V4SFmode:
4723 type = int_ftype_int_v4sf_v4sf;
4724 break;
4725 default:
4726 abort ();
4727 }
4728
4729 def_builtin (dp->mask, dp->name, type, dp->code);
4730 }
4731
0ac081f6 4732 /* Add the simple binary operators. */
00b960c7 4733 d = (struct builtin_description *) bdesc_2arg;
ca7558fc 4734 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
0ac081f6
AH
4735 {
4736 enum machine_mode mode0, mode1, mode2;
4737 tree type;
4738
4739 if (d->name == 0)
4740 continue;
4741
4742 mode0 = insn_data[d->icode].operand[0].mode;
4743 mode1 = insn_data[d->icode].operand[1].mode;
4744 mode2 = insn_data[d->icode].operand[2].mode;
4745
4746 /* When all three operands are of the same mode. */
4747 if (mode0 == mode1 && mode1 == mode2)
4748 {
4749 switch (mode0)
4750 {
4751 case V4SFmode:
4752 type = v4sf_ftype_v4sf_v4sf;
4753 break;
4754 case V4SImode:
4755 type = v4si_ftype_v4si_v4si;
4756 break;
4757 case V16QImode:
4758 type = v16qi_ftype_v16qi_v16qi;
4759 break;
4760 case V8HImode:
4761 type = v8hi_ftype_v8hi_v8hi;
4762 break;
4763 default:
4764 abort ();
4765 }
4766 }
4767
4768 /* A few other combos we really don't want to do manually. */
4769
4770 /* vint, vfloat, vfloat. */
4771 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
4772 type = v4si_ftype_v4sf_v4sf;
4773
4774 /* vshort, vchar, vchar. */
4775 else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
4776 type = v8hi_ftype_v16qi_v16qi;
4777
4778 /* vint, vshort, vshort. */
4779 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
4780 type = v4si_ftype_v8hi_v8hi;
4781
4782 /* vshort, vint, vint. */
4783 else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
4784 type = v8hi_ftype_v4si_v4si;
4785
4786 /* vchar, vshort, vshort. */
4787 else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
4788 type = v16qi_ftype_v8hi_v8hi;
4789
4790 /* vint, vchar, vint. */
4791 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
4792 type = v4si_ftype_v16qi_v4si;
4793
fa066a23
AH
4794 /* vint, vchar, vchar. */
4795 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode)
4796 type = v4si_ftype_v16qi_v16qi;
4797
0ac081f6
AH
4798 /* vint, vshort, vint. */
4799 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
4800 type = v4si_ftype_v8hi_v4si;
2212663f
DB
4801
4802 /* vint, vint, 5 bit literal. */
4803 else if (mode0 == V4SImode && mode1 == V4SImode && mode2 == QImode)
4804 type = v4si_ftype_v4si_char;
4805
4806 /* vshort, vshort, 5 bit literal. */
4807 else if (mode0 == V8HImode && mode1 == V8HImode && mode2 == QImode)
4808 type = v8hi_ftype_v8hi_char;
4809
4810 /* vchar, vchar, 5 bit literal. */
4811 else if (mode0 == V16QImode && mode1 == V16QImode && mode2 == QImode)
4812 type = v16qi_ftype_v16qi_char;
0ac081f6 4813
617e0e1d
DB
4814 /* vfloat, vint, 5 bit literal. */
4815 else if (mode0 == V4SFmode && mode1 == V4SImode && mode2 == QImode)
4816 type = v4sf_ftype_v4si_char;
4817
4818 /* vint, vfloat, 5 bit literal. */
4819 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == QImode)
4820 type = v4si_ftype_v4sf_char;
4821
0ac081f6
AH
4822 /* int, x, x. */
4823 else if (mode0 == SImode)
4824 {
4825 switch (mode1)
4826 {
4827 case V4SImode:
4828 type = int_ftype_v4si_v4si;
4829 break;
4830 case V4SFmode:
4831 type = int_ftype_v4sf_v4sf;
4832 break;
4833 case V16QImode:
4834 type = int_ftype_v16qi_v16qi;
4835 break;
4836 case V8HImode:
4837 type = int_ftype_v8hi_v8hi;
4838 break;
4839 default:
4840 abort ();
4841 }
4842 }
4843
4844 else
4845 abort ();
4846
2212663f
DB
4847 def_builtin (d->mask, d->name, type, d->code);
4848 }
24408032 4849
100c4561
AH
4850 /* Initialize the abs* operators. */
4851 d = (struct builtin_description *) bdesc_abs;
ca7558fc 4852 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
100c4561
AH
4853 {
4854 enum machine_mode mode0;
4855 tree type;
4856
4857 mode0 = insn_data[d->icode].operand[0].mode;
4858
4859 switch (mode0)
4860 {
4861 case V4SImode:
4862 type = v4si_ftype_v4si;
4863 break;
4864 case V8HImode:
4865 type = v8hi_ftype_v8hi;
4866 break;
4867 case V16QImode:
4868 type = v16qi_ftype_v16qi;
4869 break;
4870 case V4SFmode:
4871 type = v4sf_ftype_v4sf;
4872 break;
4873 default:
4874 abort ();
4875 }
4876
4877 def_builtin (d->mask, d->name, type, d->code);
4878 }
4879
2212663f
DB
4880 /* Add the simple unary operators. */
4881 d = (struct builtin_description *) bdesc_1arg;
ca7558fc 4882 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
2212663f
DB
4883 {
4884 enum machine_mode mode0, mode1;
4885 tree type;
4886
4887 if (d->name == 0)
4888 continue;
4889
4890 mode0 = insn_data[d->icode].operand[0].mode;
4891 mode1 = insn_data[d->icode].operand[1].mode;
4892
4893 if (mode0 == V4SImode && mode1 == QImode)
4894 type = v4si_ftype_char;
4895 else if (mode0 == V8HImode && mode1 == QImode)
4896 type = v8hi_ftype_char;
4897 else if (mode0 == V16QImode && mode1 == QImode)
4898 type = v16qi_ftype_char;
617e0e1d
DB
4899 else if (mode0 == V4SFmode && mode1 == V4SFmode)
4900 type = v4sf_ftype_v4sf;
20e26713
AH
4901 else if (mode0 == V8HImode && mode1 == V16QImode)
4902 type = v8hi_ftype_v16qi;
4903 else if (mode0 == V4SImode && mode1 == V8HImode)
4904 type = v4si_ftype_v8hi;
2212663f
DB
4905 else
4906 abort ();
4907
0ac081f6
AH
4908 def_builtin (d->mask, d->name, type, d->code);
4909 }
4910}
4911
5b5040b9
RK
4912\f
4913/* Generate a memory reference for expand_block_move, copying volatile,
4914 and other bits from an original memory reference. */
4915
4916static rtx
4917expand_block_move_mem (mode, addr, orig_mem)
4918 enum machine_mode mode;
4919 rtx addr;
4920 rtx orig_mem;
4921{
39403d82 4922 rtx mem = gen_rtx_MEM (mode, addr);
b6c9286a 4923
c6df88cb 4924 MEM_COPY_ATTRIBUTES (mem, orig_mem);
5b5040b9
RK
4925 return mem;
4926}
4927
7e69e155
MM
4928/* Expand a block move operation, and return 1 if successful. Return 0
4929 if we should let the compiler generate normal code.
4930
4931 operands[0] is the destination
4932 operands[1] is the source
4933 operands[2] is the length
4934 operands[3] is the alignment */
4935
3933e0e1
MM
4936#define MAX_MOVE_REG 4
4937
7e69e155
MM
4938int
4939expand_block_move (operands)
4940 rtx operands[];
4941{
b6c9286a
MM
4942 rtx orig_dest = operands[0];
4943 rtx orig_src = operands[1];
7e69e155 4944 rtx bytes_rtx = operands[2];
7e69e155 4945 rtx align_rtx = operands[3];
3933e0e1 4946 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
5ee95df6 4947 int align;
3933e0e1
MM
4948 int bytes;
4949 int offset;
4950 int num_reg;
4951 int i;
7e69e155
MM
4952 rtx src_reg;
4953 rtx dest_reg;
3933e0e1
MM
4954 rtx src_addr;
4955 rtx dest_addr;
7e69e155 4956 rtx tmp_reg;
3933e0e1 4957 rtx stores[MAX_MOVE_REG];
7e69e155
MM
4958 int move_bytes;
4959
3933e0e1 4960 /* If this is not a fixed size move, just call memcpy */
cc0d9ba8 4961 if (! constp)
3933e0e1
MM
4962 return 0;
4963
5ee95df6
FS
4964 /* If this is not a fixed size alignment, abort */
4965 if (GET_CODE (align_rtx) != CONST_INT)
4966 abort ();
4967 align = INTVAL (align_rtx);
4968
7e69e155 4969 /* Anything to move? */
3933e0e1
MM
4970 bytes = INTVAL (bytes_rtx);
4971 if (bytes <= 0)
7e69e155
MM
4972 return 1;
4973
ea9982a8 4974 /* store_one_arg depends on expand_block_move to handle at least the size of
6f317ef3 4975 reg_parm_stack_space. */
ea9982a8 4976 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
7e69e155
MM
4977 return 0;
4978
4979 /* Move the address into scratch registers. */
b6c9286a
MM
4980 dest_reg = copy_addr_to_reg (XEXP (orig_dest, 0));
4981 src_reg = copy_addr_to_reg (XEXP (orig_src, 0));
7e69e155 4982
3933e0e1 4983 if (TARGET_STRING) /* string instructions are available */
7e69e155 4984 {
3933e0e1 4985 for ( ; bytes > 0; bytes -= move_bytes)
7e69e155 4986 {
3933e0e1 4987 if (bytes > 24 /* move up to 32 bytes at a time */
cc0d9ba8
DE
4988 && ! fixed_regs[5]
4989 && ! fixed_regs[6]
4990 && ! fixed_regs[7]
4991 && ! fixed_regs[8]
4992 && ! fixed_regs[9]
4993 && ! fixed_regs[10]
4994 && ! fixed_regs[11]
4995 && ! fixed_regs[12])
3933e0e1
MM
4996 {
4997 move_bytes = (bytes > 32) ? 32 : bytes;
cc0d9ba8
DE
4998 emit_insn (gen_movstrsi_8reg (expand_block_move_mem (BLKmode,
4999 dest_reg,
5000 orig_dest),
5001 expand_block_move_mem (BLKmode,
5002 src_reg,
5003 orig_src),
5004 GEN_INT ((move_bytes == 32)
5005 ? 0 : move_bytes),
4c64a852 5006 align_rtx));
3933e0e1
MM
5007 }
5008 else if (bytes > 16 /* move up to 24 bytes at a time */
f9562f27
DE
5009 && ! fixed_regs[5]
5010 && ! fixed_regs[6]
cc0d9ba8
DE
5011 && ! fixed_regs[7]
5012 && ! fixed_regs[8]
5013 && ! fixed_regs[9]
f9562f27 5014 && ! fixed_regs[10])
3933e0e1
MM
5015 {
5016 move_bytes = (bytes > 24) ? 24 : bytes;
cc0d9ba8
DE
5017 emit_insn (gen_movstrsi_6reg (expand_block_move_mem (BLKmode,
5018 dest_reg,
5019 orig_dest),
5020 expand_block_move_mem (BLKmode,
5021 src_reg,
5022 orig_src),
3933e0e1 5023 GEN_INT (move_bytes),
4c64a852 5024 align_rtx));
3933e0e1
MM
5025 }
5026 else if (bytes > 8 /* move up to 16 bytes at a time */
f9562f27
DE
5027 && ! fixed_regs[5]
5028 && ! fixed_regs[6]
5029 && ! fixed_regs[7]
5030 && ! fixed_regs[8])
3933e0e1
MM
5031 {
5032 move_bytes = (bytes > 16) ? 16 : bytes;
cc0d9ba8
DE
5033 emit_insn (gen_movstrsi_4reg (expand_block_move_mem (BLKmode,
5034 dest_reg,
5035 orig_dest),
5036 expand_block_move_mem (BLKmode,
5037 src_reg,
5038 orig_src),
3933e0e1 5039 GEN_INT (move_bytes),
4c64a852 5040 align_rtx));
3933e0e1 5041 }
acad7ed3 5042 else if (bytes >= 8 && TARGET_POWERPC64
a4f6c312 5043 /* 64-bit loads and stores require word-aligned
82e41834 5044 displacements. */
a4f6c312 5045 && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
acad7ed3
DE
5046 {
5047 move_bytes = 8;
5048 tmp_reg = gen_reg_rtx (DImode);
5049 emit_move_insn (tmp_reg,
5050 expand_block_move_mem (DImode,
2eba1afa 5051 src_reg, orig_src));
acad7ed3 5052 emit_move_insn (expand_block_move_mem (DImode,
2eba1afa 5053 dest_reg, orig_dest),
acad7ed3
DE
5054 tmp_reg);
5055 }
09a625f7 5056 else if (bytes > 4 && !TARGET_POWERPC64)
3933e0e1
MM
5057 { /* move up to 8 bytes at a time */
5058 move_bytes = (bytes > 8) ? 8 : bytes;
cc0d9ba8
DE
5059 emit_insn (gen_movstrsi_2reg (expand_block_move_mem (BLKmode,
5060 dest_reg,
5061 orig_dest),
5062 expand_block_move_mem (BLKmode,
5063 src_reg,
5064 orig_src),
3933e0e1 5065 GEN_INT (move_bytes),
4c64a852 5066 align_rtx));
3933e0e1 5067 }
cc0d9ba8 5068 else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
3933e0e1
MM
5069 { /* move 4 bytes */
5070 move_bytes = 4;
5071 tmp_reg = gen_reg_rtx (SImode);
cc0d9ba8
DE
5072 emit_move_insn (tmp_reg,
5073 expand_block_move_mem (SImode,
5074 src_reg, orig_src));
5075 emit_move_insn (expand_block_move_mem (SImode,
5076 dest_reg, orig_dest),
5077 tmp_reg);
3933e0e1 5078 }
cc0d9ba8 5079 else if (bytes == 2 && (align >= 2 || ! STRICT_ALIGNMENT))
3933e0e1
MM
5080 { /* move 2 bytes */
5081 move_bytes = 2;
5082 tmp_reg = gen_reg_rtx (HImode);
cc0d9ba8
DE
5083 emit_move_insn (tmp_reg,
5084 expand_block_move_mem (HImode,
5085 src_reg, orig_src));
5086 emit_move_insn (expand_block_move_mem (HImode,
5087 dest_reg, orig_dest),
5088 tmp_reg);
3933e0e1
MM
5089 }
5090 else if (bytes == 1) /* move 1 byte */
5091 {
5092 move_bytes = 1;
5093 tmp_reg = gen_reg_rtx (QImode);
cc0d9ba8
DE
5094 emit_move_insn (tmp_reg,
5095 expand_block_move_mem (QImode,
5096 src_reg, orig_src));
5097 emit_move_insn (expand_block_move_mem (QImode,
5098 dest_reg, orig_dest),
5099 tmp_reg);
3933e0e1
MM
5100 }
5101 else
5102 { /* move up to 4 bytes at a time */
5103 move_bytes = (bytes > 4) ? 4 : bytes;
cc0d9ba8
DE
5104 emit_insn (gen_movstrsi_1reg (expand_block_move_mem (BLKmode,
5105 dest_reg,
5106 orig_dest),
5107 expand_block_move_mem (BLKmode,
5108 src_reg,
5109 orig_src),
3933e0e1 5110 GEN_INT (move_bytes),
4c64a852 5111 align_rtx));
3933e0e1 5112 }
4c64a852 5113
015892ee
RK
5114 if (bytes > move_bytes)
5115 {
cc0d9ba8
DE
5116 if (! TARGET_POWERPC64)
5117 {
5118 emit_insn (gen_addsi3 (src_reg, src_reg,
5119 GEN_INT (move_bytes)));
5120 emit_insn (gen_addsi3 (dest_reg, dest_reg,
5121 GEN_INT (move_bytes)));
5122 }
5123 else
5124 {
5125 emit_insn (gen_adddi3 (src_reg, src_reg,
5126 GEN_INT (move_bytes)));
5127 emit_insn (gen_adddi3 (dest_reg, dest_reg,
5128 GEN_INT (move_bytes)));
5129 }
015892ee 5130 }
4c64a852 5131 }
3933e0e1
MM
5132 }
5133
5134 else /* string instructions not available */
5135 {
5136 num_reg = offset = 0;
5137 for ( ; bytes > 0; (bytes -= move_bytes), (offset += move_bytes))
7e69e155 5138 {
3933e0e1
MM
5139 /* Calculate the correct offset for src/dest */
5140 if (offset == 0)
7e69e155 5141 {
3933e0e1
MM
5142 src_addr = src_reg;
5143 dest_addr = dest_reg;
5144 }
5145 else
5146 {
c5c76735
JL
5147 src_addr = plus_constant (src_reg, offset);
5148 dest_addr = plus_constant (dest_reg, offset);
3933e0e1
MM
5149 }
5150
cc0d9ba8
DE
5151 /* Generate the appropriate load and store, saving the stores
5152 for later. */
5153 if (bytes >= 8 && TARGET_POWERPC64
a4f6c312
SS
5154 /* 64-bit loads and stores require word-aligned
5155 displacements. */
cc0d9ba8 5156 && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
b6c9286a
MM
5157 {
5158 move_bytes = 8;
5159 tmp_reg = gen_reg_rtx (DImode);
cc0d9ba8
DE
5160 emit_insn (gen_movdi (tmp_reg,
5161 expand_block_move_mem (DImode,
5162 src_addr,
5163 orig_src)));
5164 stores[num_reg++] = gen_movdi (expand_block_move_mem (DImode,
5165 dest_addr,
5166 orig_dest),
5167 tmp_reg);
b6c9286a 5168 }
cc0d9ba8 5169 else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
3933e0e1
MM
5170 {
5171 move_bytes = 4;
5172 tmp_reg = gen_reg_rtx (SImode);
cc0d9ba8
DE
5173 emit_insn (gen_movsi (tmp_reg,
5174 expand_block_move_mem (SImode,
5175 src_addr,
5176 orig_src)));
5177 stores[num_reg++] = gen_movsi (expand_block_move_mem (SImode,
5178 dest_addr,
5179 orig_dest),
5180 tmp_reg);
3933e0e1 5181 }
cc0d9ba8 5182 else if (bytes >= 2 && (align >= 2 || ! STRICT_ALIGNMENT))
3933e0e1
MM
5183 {
5184 move_bytes = 2;
5185 tmp_reg = gen_reg_rtx (HImode);
c81fc13e 5186 emit_insn (gen_movhi (tmp_reg,
cc0d9ba8
DE
5187 expand_block_move_mem (HImode,
5188 src_addr,
5189 orig_src)));
5190 stores[num_reg++] = gen_movhi (expand_block_move_mem (HImode,
5191 dest_addr,
5192 orig_dest),
5193 tmp_reg);
3933e0e1
MM
5194 }
5195 else
5196 {
5197 move_bytes = 1;
5198 tmp_reg = gen_reg_rtx (QImode);
c81fc13e 5199 emit_insn (gen_movqi (tmp_reg,
cc0d9ba8
DE
5200 expand_block_move_mem (QImode,
5201 src_addr,
5202 orig_src)));
5203 stores[num_reg++] = gen_movqi (expand_block_move_mem (QImode,
5204 dest_addr,
5205 orig_dest),
a4f6c312 5206 tmp_reg);
3933e0e1
MM
5207 }
5208
5209 if (num_reg >= MAX_MOVE_REG)
5210 {
5211 for (i = 0; i < num_reg; i++)
5212 emit_insn (stores[i]);
5213 num_reg = 0;
7e69e155
MM
5214 }
5215 }
3933e0e1 5216
b6c9286a
MM
5217 for (i = 0; i < num_reg; i++)
5218 emit_insn (stores[i]);
7e69e155
MM
5219 }
5220
5221 return 1;
5222}
5223
9878760c
RK
5224\f
5225/* Return 1 if OP is a load multiple operation. It is known to be a
5226 PARALLEL and the first section will be tested. */
5227
5228int
5229load_multiple_operation (op, mode)
5230 rtx op;
296b8152 5231 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
5232{
5233 int count = XVECLEN (op, 0);
e2c953b6 5234 unsigned int dest_regno;
9878760c
RK
5235 rtx src_addr;
5236 int i;
5237
5238 /* Perform a quick check so we don't blow up below. */
5239 if (count <= 1
5240 || GET_CODE (XVECEXP (op, 0, 0)) != SET
5241 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
5242 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
5243 return 0;
5244
5245 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
5246 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
5247
5248 for (i = 1; i < count; i++)
5249 {
5250 rtx elt = XVECEXP (op, 0, i);
5251
5252 if (GET_CODE (elt) != SET
5253 || GET_CODE (SET_DEST (elt)) != REG
5254 || GET_MODE (SET_DEST (elt)) != SImode
5255 || REGNO (SET_DEST (elt)) != dest_regno + i
5256 || GET_CODE (SET_SRC (elt)) != MEM
5257 || GET_MODE (SET_SRC (elt)) != SImode
5258 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
5259 || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
5260 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
5261 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4)
5262 return 0;
5263 }
5264
5265 return 1;
5266}
5267
5268/* Similar, but tests for store multiple. Here, the second vector element
5269 is a CLOBBER. It will be tested later. */
5270
5271int
5272store_multiple_operation (op, mode)
5273 rtx op;
296b8152 5274 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
5275{
5276 int count = XVECLEN (op, 0) - 1;
e2c953b6 5277 unsigned int src_regno;
9878760c
RK
5278 rtx dest_addr;
5279 int i;
5280
5281 /* Perform a quick check so we don't blow up below. */
5282 if (count <= 1
5283 || GET_CODE (XVECEXP (op, 0, 0)) != SET
5284 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
5285 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
5286 return 0;
5287
5288 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
5289 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
5290
5291 for (i = 1; i < count; i++)
5292 {
5293 rtx elt = XVECEXP (op, 0, i + 1);
5294
5295 if (GET_CODE (elt) != SET
5296 || GET_CODE (SET_SRC (elt)) != REG
5297 || GET_MODE (SET_SRC (elt)) != SImode
5298 || REGNO (SET_SRC (elt)) != src_regno + i
5299 || GET_CODE (SET_DEST (elt)) != MEM
5300 || GET_MODE (SET_DEST (elt)) != SImode
5301 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
5302 || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
5303 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
5304 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4)
5305 return 0;
5306 }
5307
5308 return 1;
5309}
9ebbca7d 5310
00b960c7
AH
5311/* Return 1 for a parallel vrsave operation. */
5312
5313int
5314vrsave_operation (op, mode)
5315 rtx op;
5316 enum machine_mode mode ATTRIBUTE_UNUSED;
5317{
5318 int count = XVECLEN (op, 0);
5319 unsigned int dest_regno, src_regno;
5320 int i;
5321
5322 if (count <= 1
5323 || GET_CODE (XVECEXP (op, 0, 0)) != SET
5324 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
a004eb82 5325 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC_VOLATILE)
00b960c7
AH
5326 return 0;
5327
5328 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
5329 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
5330
5331 if (dest_regno != VRSAVE_REGNO
5332 && src_regno != VRSAVE_REGNO)
5333 return 0;
5334
5335 for (i = 1; i < count; i++)
5336 {
5337 rtx elt = XVECEXP (op, 0, i);
5338
9aa86737
AH
5339 if (GET_CODE (elt) != CLOBBER
5340 && GET_CODE (elt) != SET)
00b960c7
AH
5341 return 0;
5342 }
5343
5344 return 1;
5345}
5346
a4f6c312 5347/* Return 1 for an PARALLEL suitable for mtcrf. */
9ebbca7d
GK
5348
5349int
5350mtcrf_operation (op, mode)
5351 rtx op;
5352 enum machine_mode mode ATTRIBUTE_UNUSED;
5353{
5354 int count = XVECLEN (op, 0);
5355 int i;
9ebbca7d
GK
5356 rtx src_reg;
5357
5358 /* Perform a quick check so we don't blow up below. */
e35b9579
GK
5359 if (count < 1
5360 || GET_CODE (XVECEXP (op, 0, 0)) != SET
5361 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC
5362 || XVECLEN (SET_SRC (XVECEXP (op, 0, 0)), 0) != 2)
9ebbca7d 5363 return 0;
e35b9579 5364 src_reg = XVECEXP (SET_SRC (XVECEXP (op, 0, 0)), 0, 0);
9ebbca7d
GK
5365
5366 if (GET_CODE (src_reg) != REG
5367 || GET_MODE (src_reg) != SImode
5368 || ! INT_REGNO_P (REGNO (src_reg)))
5369 return 0;
5370
e35b9579 5371 for (i = 0; i < count; i++)
9ebbca7d
GK
5372 {
5373 rtx exp = XVECEXP (op, 0, i);
5374 rtx unspec;
5375 int maskval;
5376
5377 if (GET_CODE (exp) != SET
5378 || GET_CODE (SET_DEST (exp)) != REG
5379 || GET_MODE (SET_DEST (exp)) != CCmode
5380 || ! CR_REGNO_P (REGNO (SET_DEST (exp))))
5381 return 0;
5382 unspec = SET_SRC (exp);
5383 maskval = 1 << (MAX_CR_REGNO - REGNO (SET_DEST (exp)));
9ebbca7d
GK
5384
5385 if (GET_CODE (unspec) != UNSPEC
5386 || XINT (unspec, 1) != 20
5387 || XVECLEN (unspec, 0) != 2
5388 || XVECEXP (unspec, 0, 0) != src_reg
5389 || GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT
5390 || INTVAL (XVECEXP (unspec, 0, 1)) != maskval)
5391 return 0;
5392 }
e35b9579 5393 return 1;
9ebbca7d
GK
5394}
5395
a4f6c312 5396/* Return 1 for an PARALLEL suitable for lmw. */
9ebbca7d
GK
5397
5398int
5399lmw_operation (op, mode)
5400 rtx op;
5401 enum machine_mode mode ATTRIBUTE_UNUSED;
5402{
5403 int count = XVECLEN (op, 0);
e2c953b6 5404 unsigned int dest_regno;
9ebbca7d 5405 rtx src_addr;
e2c953b6 5406 unsigned int base_regno;
9ebbca7d
GK
5407 HOST_WIDE_INT offset;
5408 int i;
5409
5410 /* Perform a quick check so we don't blow up below. */
5411 if (count <= 1
5412 || GET_CODE (XVECEXP (op, 0, 0)) != SET
5413 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
5414 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
5415 return 0;
5416
5417 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
5418 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
5419
5420 if (dest_regno > 31
e2c953b6 5421 || count != 32 - (int) dest_regno)
9ebbca7d
GK
5422 return 0;
5423
258bfae2 5424 if (LEGITIMATE_INDIRECT_ADDRESS_P (src_addr, 0))
9ebbca7d
GK
5425 {
5426 offset = 0;
5427 base_regno = REGNO (src_addr);
5428 if (base_regno == 0)
5429 return 0;
5430 }
258bfae2 5431 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, src_addr, 0))
9ebbca7d
GK
5432 {
5433 offset = INTVAL (XEXP (src_addr, 1));
5434 base_regno = REGNO (XEXP (src_addr, 0));
5435 }
5436 else
5437 return 0;
5438
5439 for (i = 0; i < count; i++)
5440 {
5441 rtx elt = XVECEXP (op, 0, i);
5442 rtx newaddr;
5443 rtx addr_reg;
5444 HOST_WIDE_INT newoffset;
5445
5446 if (GET_CODE (elt) != SET
5447 || GET_CODE (SET_DEST (elt)) != REG
5448 || GET_MODE (SET_DEST (elt)) != SImode
5449 || REGNO (SET_DEST (elt)) != dest_regno + i
5450 || GET_CODE (SET_SRC (elt)) != MEM
5451 || GET_MODE (SET_SRC (elt)) != SImode)
5452 return 0;
5453 newaddr = XEXP (SET_SRC (elt), 0);
258bfae2 5454 if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
9ebbca7d
GK
5455 {
5456 newoffset = 0;
5457 addr_reg = newaddr;
5458 }
258bfae2 5459 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
9ebbca7d
GK
5460 {
5461 addr_reg = XEXP (newaddr, 0);
5462 newoffset = INTVAL (XEXP (newaddr, 1));
5463 }
5464 else
5465 return 0;
5466 if (REGNO (addr_reg) != base_regno
5467 || newoffset != offset + 4 * i)
5468 return 0;
5469 }
5470
5471 return 1;
5472}
5473
a4f6c312 5474/* Return 1 for an PARALLEL suitable for stmw. */
9ebbca7d
GK
5475
5476int
5477stmw_operation (op, mode)
5478 rtx op;
5479 enum machine_mode mode ATTRIBUTE_UNUSED;
5480{
5481 int count = XVECLEN (op, 0);
e2c953b6 5482 unsigned int src_regno;
9ebbca7d 5483 rtx dest_addr;
e2c953b6 5484 unsigned int base_regno;
9ebbca7d
GK
5485 HOST_WIDE_INT offset;
5486 int i;
5487
5488 /* Perform a quick check so we don't blow up below. */
5489 if (count <= 1
5490 || GET_CODE (XVECEXP (op, 0, 0)) != SET
5491 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
5492 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
5493 return 0;
5494
5495 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
5496 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
5497
5498 if (src_regno > 31
e2c953b6 5499 || count != 32 - (int) src_regno)
9ebbca7d
GK
5500 return 0;
5501
258bfae2 5502 if (LEGITIMATE_INDIRECT_ADDRESS_P (dest_addr, 0))
9ebbca7d
GK
5503 {
5504 offset = 0;
5505 base_regno = REGNO (dest_addr);
5506 if (base_regno == 0)
5507 return 0;
5508 }
258bfae2 5509 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, dest_addr, 0))
9ebbca7d
GK
5510 {
5511 offset = INTVAL (XEXP (dest_addr, 1));
5512 base_regno = REGNO (XEXP (dest_addr, 0));
5513 }
5514 else
5515 return 0;
5516
5517 for (i = 0; i < count; i++)
5518 {
5519 rtx elt = XVECEXP (op, 0, i);
5520 rtx newaddr;
5521 rtx addr_reg;
5522 HOST_WIDE_INT newoffset;
5523
5524 if (GET_CODE (elt) != SET
5525 || GET_CODE (SET_SRC (elt)) != REG
5526 || GET_MODE (SET_SRC (elt)) != SImode
5527 || REGNO (SET_SRC (elt)) != src_regno + i
5528 || GET_CODE (SET_DEST (elt)) != MEM
5529 || GET_MODE (SET_DEST (elt)) != SImode)
5530 return 0;
5531 newaddr = XEXP (SET_DEST (elt), 0);
258bfae2 5532 if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
9ebbca7d
GK
5533 {
5534 newoffset = 0;
5535 addr_reg = newaddr;
5536 }
258bfae2 5537 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
9ebbca7d
GK
5538 {
5539 addr_reg = XEXP (newaddr, 0);
5540 newoffset = INTVAL (XEXP (newaddr, 1));
5541 }
5542 else
5543 return 0;
5544 if (REGNO (addr_reg) != base_regno
5545 || newoffset != offset + 4 * i)
5546 return 0;
5547 }
5548
5549 return 1;
5550}
9878760c 5551\f
a4f6c312
SS
5552/* A validation routine: say whether CODE, a condition code, and MODE
5553 match. The other alternatives either don't make sense or should
5554 never be generated. */
39a10a29 5555
39a10a29
GK
5556static void
5557validate_condition_mode (code, mode)
5558 enum rtx_code code;
5559 enum machine_mode mode;
5560{
5561 if (GET_RTX_CLASS (code) != '<'
5562 || GET_MODE_CLASS (mode) != MODE_CC)
5563 abort ();
5564
5565 /* These don't make sense. */
5566 if ((code == GT || code == LT || code == GE || code == LE)
5567 && mode == CCUNSmode)
5568 abort ();
5569
5570 if ((code == GTU || code == LTU || code == GEU || code == LEU)
5571 && mode != CCUNSmode)
5572 abort ();
5573
5574 if (mode != CCFPmode
5575 && (code == ORDERED || code == UNORDERED
5576 || code == UNEQ || code == LTGT
5577 || code == UNGT || code == UNLT
5578 || code == UNGE || code == UNLE))
a4f6c312 5579 abort ();
39a10a29 5580
de6c5979
BL
5581 /* These should never be generated except for
5582 flag_unsafe_math_optimizations. */
39a10a29 5583 if (mode == CCFPmode
de6c5979 5584 && ! flag_unsafe_math_optimizations
39a10a29
GK
5585 && (code == LE || code == GE
5586 || code == UNEQ || code == LTGT
5587 || code == UNGT || code == UNLT))
5588 abort ();
5589
5590 /* These are invalid; the information is not there. */
5591 if (mode == CCEQmode
5592 && code != EQ && code != NE)
5593 abort ();
5594}
5595
9878760c
RK
5596/* Return 1 if OP is a comparison operation that is valid for a branch insn.
5597 We only check the opcode against the mode of the CC value here. */
5598
5599int
5600branch_comparison_operator (op, mode)
592696dd 5601 rtx op;
296b8152 5602 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
5603{
5604 enum rtx_code code = GET_CODE (op);
5605 enum machine_mode cc_mode;
5606
5607 if (GET_RTX_CLASS (code) != '<')
5608 return 0;
5609
5610 cc_mode = GET_MODE (XEXP (op, 0));
5611 if (GET_MODE_CLASS (cc_mode) != MODE_CC)
5612 return 0;
5613
39a10a29 5614 validate_condition_mode (code, cc_mode);
9878760c 5615
39a10a29
GK
5616 return 1;
5617}
5618
5619/* Return 1 if OP is a comparison operation that is valid for a branch
5620 insn and which is true if the corresponding bit in the CC register
5621 is set. */
5622
5623int
5624branch_positive_comparison_operator (op, mode)
592696dd 5625 rtx op;
39a10a29
GK
5626 enum machine_mode mode;
5627{
5628 enum rtx_code code;
5629
5630 if (! branch_comparison_operator (op, mode))
9878760c
RK
5631 return 0;
5632
39a10a29
GK
5633 code = GET_CODE (op);
5634 return (code == EQ || code == LT || code == GT
5635 || code == LTU || code == GTU
5636 || code == UNORDERED);
9878760c
RK
5637}
5638
5639/* Return 1 if OP is a comparison operation that is valid for an scc insn.
5640 We check the opcode against the mode of the CC value and disallow EQ or
5641 NE comparisons for integers. */
5642
5643int
5644scc_comparison_operator (op, mode)
592696dd 5645 rtx op;
9878760c
RK
5646 enum machine_mode mode;
5647{
5648 enum rtx_code code = GET_CODE (op);
5649 enum machine_mode cc_mode;
5650
5651 if (GET_MODE (op) != mode && mode != VOIDmode)
5652 return 0;
5653
5654 if (GET_RTX_CLASS (code) != '<')
5655 return 0;
5656
5657 cc_mode = GET_MODE (XEXP (op, 0));
5658 if (GET_MODE_CLASS (cc_mode) != MODE_CC)
5659 return 0;
5660
39a10a29 5661 validate_condition_mode (code, cc_mode);
9878760c 5662
39a10a29 5663 if (code == NE && cc_mode != CCFPmode)
c5defebb
RK
5664 return 0;
5665
9878760c
RK
5666 return 1;
5667}
e0cd0770
JC
5668
5669int
5670trap_comparison_operator (op, mode)
5671 rtx op;
5672 enum machine_mode mode;
5673{
5674 if (mode != VOIDmode && mode != GET_MODE (op))
5675 return 0;
39a10a29 5676 return GET_RTX_CLASS (GET_CODE (op)) == '<';
e0cd0770 5677}
dfbdccdb
GK
5678
5679int
5680boolean_operator (op, mode)
5681 rtx op;
5682 enum machine_mode mode ATTRIBUTE_UNUSED;
5683{
5684 enum rtx_code code = GET_CODE (op);
5685 return (code == AND || code == IOR || code == XOR);
5686}
1d328b19
GK
5687
5688int
5689boolean_or_operator (op, mode)
5690 rtx op;
5691 enum machine_mode mode ATTRIBUTE_UNUSED;
5692{
5693 enum rtx_code code = GET_CODE (op);
5694 return (code == IOR || code == XOR);
5695}
50a0b056
GK
5696
5697int
5698min_max_operator (op, mode)
5699 rtx op;
5700 enum machine_mode mode ATTRIBUTE_UNUSED;
5701{
5702 enum rtx_code code = GET_CODE (op);
5703 return (code == SMIN || code == SMAX || code == UMIN || code == UMAX);
5704}
9878760c
RK
5705\f
5706/* Return 1 if ANDOP is a mask that has no bits on that are not in the
5707 mask required to convert the result of a rotate insn into a shift
b1765bde 5708 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
9878760c
RK
5709
5710int
5711includes_lshift_p (shiftop, andop)
592696dd
SS
5712 rtx shiftop;
5713 rtx andop;
9878760c 5714{
e2c953b6
DE
5715 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
5716
5717 shift_mask <<= INTVAL (shiftop);
9878760c 5718
b1765bde 5719 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
9878760c
RK
5720}
5721
5722/* Similar, but for right shift. */
5723
5724int
5725includes_rshift_p (shiftop, andop)
592696dd
SS
5726 rtx shiftop;
5727 rtx andop;
9878760c 5728{
a7653a2c 5729 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
9878760c
RK
5730
5731 shift_mask >>= INTVAL (shiftop);
5732
b1765bde 5733 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
e2c953b6
DE
5734}
5735
c5059423
AM
5736/* Return 1 if ANDOP is a mask suitable for use with an rldic insn
5737 to perform a left shift. It must have exactly SHIFTOP least
5738 signifigant 0's, then one or more 1's, then zero or more 0's. */
e2c953b6
DE
5739
5740int
c5059423 5741includes_rldic_lshift_p (shiftop, andop)
592696dd
SS
5742 rtx shiftop;
5743 rtx andop;
e2c953b6 5744{
c5059423
AM
5745 if (GET_CODE (andop) == CONST_INT)
5746 {
02071907 5747 HOST_WIDE_INT c, lsb, shift_mask;
e2c953b6 5748
c5059423 5749 c = INTVAL (andop);
02071907 5750 if (c == 0 || c == ~0)
c5059423 5751 return 0;
e2c953b6 5752
02071907 5753 shift_mask = ~0;
c5059423
AM
5754 shift_mask <<= INTVAL (shiftop);
5755
5756 /* Find the least signifigant one bit. */
5757 lsb = c & -c;
5758
5759 /* It must coincide with the LSB of the shift mask. */
5760 if (-lsb != shift_mask)
5761 return 0;
e2c953b6 5762
c5059423
AM
5763 /* Invert to look for the next transition (if any). */
5764 c = ~c;
5765
5766 /* Remove the low group of ones (originally low group of zeros). */
5767 c &= -lsb;
5768
5769 /* Again find the lsb, and check we have all 1's above. */
5770 lsb = c & -c;
5771 return c == -lsb;
5772 }
5773 else if (GET_CODE (andop) == CONST_DOUBLE
5774 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
5775 {
02071907
AM
5776 HOST_WIDE_INT low, high, lsb;
5777 HOST_WIDE_INT shift_mask_low, shift_mask_high;
c5059423
AM
5778
5779 low = CONST_DOUBLE_LOW (andop);
5780 if (HOST_BITS_PER_WIDE_INT < 64)
5781 high = CONST_DOUBLE_HIGH (andop);
5782
5783 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
02071907 5784 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
c5059423
AM
5785 return 0;
5786
5787 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
5788 {
02071907 5789 shift_mask_high = ~0;
c5059423
AM
5790 if (INTVAL (shiftop) > 32)
5791 shift_mask_high <<= INTVAL (shiftop) - 32;
5792
5793 lsb = high & -high;
5794
5795 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
5796 return 0;
5797
5798 high = ~high;
5799 high &= -lsb;
5800
5801 lsb = high & -high;
5802 return high == -lsb;
5803 }
5804
02071907 5805 shift_mask_low = ~0;
c5059423
AM
5806 shift_mask_low <<= INTVAL (shiftop);
5807
5808 lsb = low & -low;
5809
5810 if (-lsb != shift_mask_low)
5811 return 0;
5812
5813 if (HOST_BITS_PER_WIDE_INT < 64)
5814 high = ~high;
5815 low = ~low;
5816 low &= -lsb;
5817
5818 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
5819 {
5820 lsb = high & -high;
5821 return high == -lsb;
5822 }
5823
5824 lsb = low & -low;
5825 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
5826 }
5827 else
5828 return 0;
5829}
e2c953b6 5830
c5059423
AM
5831/* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
5832 to perform a left shift. It must have SHIFTOP or more least
5833 signifigant 0's, with the remainder of the word 1's. */
e2c953b6 5834
c5059423
AM
5835int
5836includes_rldicr_lshift_p (shiftop, andop)
592696dd
SS
5837 rtx shiftop;
5838 rtx andop;
c5059423 5839{
e2c953b6 5840 if (GET_CODE (andop) == CONST_INT)
c5059423 5841 {
02071907 5842 HOST_WIDE_INT c, lsb, shift_mask;
c5059423 5843
02071907 5844 shift_mask = ~0;
c5059423
AM
5845 shift_mask <<= INTVAL (shiftop);
5846 c = INTVAL (andop);
5847
5848 /* Find the least signifigant one bit. */
5849 lsb = c & -c;
5850
5851 /* It must be covered by the shift mask.
a4f6c312 5852 This test also rejects c == 0. */
c5059423
AM
5853 if ((lsb & shift_mask) == 0)
5854 return 0;
5855
5856 /* Check we have all 1's above the transition, and reject all 1's. */
5857 return c == -lsb && lsb != 1;
5858 }
5859 else if (GET_CODE (andop) == CONST_DOUBLE
5860 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
5861 {
02071907 5862 HOST_WIDE_INT low, lsb, shift_mask_low;
c5059423
AM
5863
5864 low = CONST_DOUBLE_LOW (andop);
5865
5866 if (HOST_BITS_PER_WIDE_INT < 64)
5867 {
02071907 5868 HOST_WIDE_INT high, shift_mask_high;
c5059423
AM
5869
5870 high = CONST_DOUBLE_HIGH (andop);
5871
5872 if (low == 0)
5873 {
02071907 5874 shift_mask_high = ~0;
c5059423
AM
5875 if (INTVAL (shiftop) > 32)
5876 shift_mask_high <<= INTVAL (shiftop) - 32;
5877
5878 lsb = high & -high;
5879
5880 if ((lsb & shift_mask_high) == 0)
5881 return 0;
5882
5883 return high == -lsb;
5884 }
5885 if (high != ~0)
5886 return 0;
5887 }
5888
02071907 5889 shift_mask_low = ~0;
c5059423
AM
5890 shift_mask_low <<= INTVAL (shiftop);
5891
5892 lsb = low & -low;
5893
5894 if ((lsb & shift_mask_low) == 0)
5895 return 0;
5896
5897 return low == -lsb && lsb != 1;
5898 }
e2c953b6 5899 else
c5059423 5900 return 0;
9878760c 5901}
35068b43
RK
5902
5903/* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
5904 for lfq and stfq insns.
5905
5906 Note reg1 and reg2 *must* be hard registers. To be sure we will
5907 abort if we are passed pseudo registers. */
5908
5909int
5910registers_ok_for_quad_peep (reg1, reg2)
5911 rtx reg1, reg2;
5912{
5913 /* We might have been passed a SUBREG. */
5914 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
5915 return 0;
5916
5917 return (REGNO (reg1) == REGNO (reg2) - 1);
5918}
5919
a4f6c312
SS
5920/* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
5921 addr1 and addr2 must be in consecutive memory locations
5922 (addr2 == addr1 + 8). */
35068b43
RK
5923
5924int
5925addrs_ok_for_quad_peep (addr1, addr2)
592696dd
SS
5926 rtx addr1;
5927 rtx addr2;
35068b43 5928{
e2c953b6 5929 unsigned int reg1;
35068b43
RK
5930 int offset1;
5931
5932 /* Extract an offset (if used) from the first addr. */
5933 if (GET_CODE (addr1) == PLUS)
5934 {
5935 /* If not a REG, return zero. */
5936 if (GET_CODE (XEXP (addr1, 0)) != REG)
5937 return 0;
5938 else
5939 {
5940 reg1 = REGNO (XEXP (addr1, 0));
5941 /* The offset must be constant! */
5942 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
5943 return 0;
5944 offset1 = INTVAL (XEXP (addr1, 1));
5945 }
5946 }
5947 else if (GET_CODE (addr1) != REG)
5948 return 0;
5949 else
5950 {
5951 reg1 = REGNO (addr1);
5952 /* This was a simple (mem (reg)) expression. Offset is 0. */
5953 offset1 = 0;
5954 }
5955
acad7ed3 5956 /* Make sure the second address is a (mem (plus (reg) (const_int))). */
35068b43
RK
5957 if (GET_CODE (addr2) != PLUS)
5958 return 0;
5959
5960 if (GET_CODE (XEXP (addr2, 0)) != REG
5961 || GET_CODE (XEXP (addr2, 1)) != CONST_INT)
5962 return 0;
5963
5964 if (reg1 != REGNO (XEXP (addr2, 0)))
5965 return 0;
5966
5967 /* The offset for the second addr must be 8 more than the first addr. */
5968 if (INTVAL (XEXP (addr2, 1)) != offset1 + 8)
5969 return 0;
5970
5971 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
5972 instructions. */
5973 return 1;
5974}
9878760c
RK
5975\f
5976/* Return the register class of a scratch register needed to copy IN into
5977 or out of a register in CLASS in MODE. If it can be done directly,
5978 NO_REGS is returned. */
5979
5980enum reg_class
5981secondary_reload_class (class, mode, in)
5982 enum reg_class class;
296b8152 5983 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
5984 rtx in;
5985{
5accd822 5986 int regno;
9878760c 5987
46fad5b7
DJ
5988 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN && flag_pic))
5989 {
5990 /* We cannot copy a symbolic operand directly into anything
5991 other than BASE_REGS for TARGET_ELF. So indicate that a
5992 register from BASE_REGS is needed as an intermediate
5993 register.
5994
5995 On Darwin, pic addresses require a load from memory, which
5996 needs a base register. */
5997 if (class != BASE_REGS
5998 && (GET_CODE (in) == SYMBOL_REF
5999 || GET_CODE (in) == HIGH
6000 || GET_CODE (in) == LABEL_REF
6001 || GET_CODE (in) == CONST))
6002 return BASE_REGS;
6003 }
e7b7998a 6004
5accd822
DE
6005 if (GET_CODE (in) == REG)
6006 {
6007 regno = REGNO (in);
6008 if (regno >= FIRST_PSEUDO_REGISTER)
6009 {
6010 regno = true_regnum (in);
6011 if (regno >= FIRST_PSEUDO_REGISTER)
6012 regno = -1;
6013 }
6014 }
6015 else if (GET_CODE (in) == SUBREG)
6016 {
6017 regno = true_regnum (in);
6018 if (regno >= FIRST_PSEUDO_REGISTER)
6019 regno = -1;
6020 }
6021 else
6022 regno = -1;
6023
9878760c
RK
6024 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
6025 into anything. */
6026 if (class == GENERAL_REGS || class == BASE_REGS
6027 || (regno >= 0 && INT_REGNO_P (regno)))
6028 return NO_REGS;
6029
6030 /* Constants, memory, and FP registers can go into FP registers. */
6031 if ((regno == -1 || FP_REGNO_P (regno))
6032 && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
6033 return NO_REGS;
6034
0ac081f6
AH
6035 /* Memory, and AltiVec registers can go into AltiVec registers. */
6036 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
6037 && class == ALTIVEC_REGS)
6038 return NO_REGS;
6039
9878760c
RK
6040 /* We can copy among the CR registers. */
6041 if ((class == CR_REGS || class == CR0_REGS)
6042 && regno >= 0 && CR_REGNO_P (regno))
6043 return NO_REGS;
6044
6045 /* Otherwise, we need GENERAL_REGS. */
6046 return GENERAL_REGS;
6047}
6048\f
6049/* Given a comparison operation, return the bit number in CCR to test. We
6050 know this is a valid comparison.
6051
6052 SCC_P is 1 if this is for an scc. That means that %D will have been
6053 used instead of %C, so the bits will be in different places.
6054
b4ac57ab 6055 Return -1 if OP isn't a valid comparison for some reason. */
9878760c
RK
6056
6057int
6058ccr_bit (op, scc_p)
592696dd 6059 rtx op;
9878760c
RK
6060 int scc_p;
6061{
6062 enum rtx_code code = GET_CODE (op);
6063 enum machine_mode cc_mode;
6064 int cc_regnum;
6065 int base_bit;
9ebbca7d 6066 rtx reg;
9878760c
RK
6067
6068 if (GET_RTX_CLASS (code) != '<')
6069 return -1;
6070
9ebbca7d
GK
6071 reg = XEXP (op, 0);
6072
6073 if (GET_CODE (reg) != REG
6074 || ! CR_REGNO_P (REGNO (reg)))
6075 abort ();
6076
6077 cc_mode = GET_MODE (reg);
6078 cc_regnum = REGNO (reg);
6079 base_bit = 4 * (cc_regnum - CR0_REGNO);
9878760c 6080
39a10a29 6081 validate_condition_mode (code, cc_mode);
c5defebb 6082
9878760c
RK
6083 switch (code)
6084 {
6085 case NE:
6086 return scc_p ? base_bit + 3 : base_bit + 2;
6087 case EQ:
6088 return base_bit + 2;
1c882ea4 6089 case GT: case GTU: case UNLE:
9878760c 6090 return base_bit + 1;
1c882ea4 6091 case LT: case LTU: case UNGE:
9878760c 6092 return base_bit;
1c882ea4
GK
6093 case ORDERED: case UNORDERED:
6094 return base_bit + 3;
9878760c
RK
6095
6096 case GE: case GEU:
39a10a29 6097 /* If scc, we will have done a cror to put the bit in the
9878760c
RK
6098 unordered position. So test that bit. For integer, this is ! LT
6099 unless this is an scc insn. */
39a10a29 6100 return scc_p ? base_bit + 3 : base_bit;
9878760c
RK
6101
6102 case LE: case LEU:
39a10a29 6103 return scc_p ? base_bit + 3 : base_bit + 1;
1c882ea4 6104
9878760c
RK
6105 default:
6106 abort ();
6107 }
6108}
1ff7789b 6109\f
8d30c4ee 6110/* Return the GOT register. */
1ff7789b
MM
6111
6112struct rtx_def *
6113rs6000_got_register (value)
5f59ecb7 6114 rtx value ATTRIBUTE_UNUSED;
1ff7789b 6115{
a4f6c312
SS
6116 /* The second flow pass currently (June 1999) can't update
6117 regs_ever_live without disturbing other parts of the compiler, so
6118 update it here to make the prolog/epilogue code happy. */
1db02437
FS
6119 if (no_new_pseudos && ! regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM])
6120 regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
1ff7789b 6121
8d30c4ee 6122 current_function_uses_pic_offset_table = 1;
3cb999d8 6123
1ff7789b
MM
6124 return pic_offset_table_rtx;
6125}
a7df97e6 6126\f
71f123ca 6127/* Functions to init, mark and free struct machine_function.
a7df97e6
MM
6128 These will be called, via pointer variables,
6129 from push_function_context and pop_function_context. */
6130
00dba523
NC
6131static void
6132rs6000_init_machine_status (p)
a7df97e6
MM
6133 struct function *p;
6134{
71f123ca
FS
6135 p->machine = (machine_function *) xcalloc (1, sizeof (machine_function));
6136}
a7df97e6 6137
00dba523
NC
6138static void
6139rs6000_free_machine_status (p)
a7df97e6
MM
6140 struct function *p;
6141{
00dba523
NC
6142 if (p->machine == NULL)
6143 return;
a7df97e6 6144
00dba523
NC
6145 free (p->machine);
6146 p->machine = NULL;
a7df97e6
MM
6147}
6148
9878760c
RK
6149\f
6150/* Print an operand. Recognize special options, documented below. */
6151
38c1f2d7 6152#if TARGET_ELF
d9407988 6153#define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
8fbd2dc7 6154#define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
ba5e43aa
MM
6155#else
6156#define SMALL_DATA_RELOC "sda21"
8fbd2dc7 6157#define SMALL_DATA_REG 0
ba5e43aa
MM
6158#endif
6159
9878760c
RK
6160void
6161print_operand (file, x, code)
6162 FILE *file;
6163 rtx x;
9ebbca7d 6164 int code;
9878760c
RK
6165{
6166 int i;
a260abc9 6167 HOST_WIDE_INT val;
9878760c
RK
6168
6169 /* These macros test for integers and extract the low-order bits. */
6170#define INT_P(X) \
6171((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
6172 && GET_MODE (X) == VOIDmode)
6173
6174#define INT_LOWPART(X) \
6175 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
6176
6177 switch (code)
6178 {
a8b3aeda 6179 case '.':
a85d226b
RK
6180 /* Write out an instruction after the call which may be replaced
6181 with glue code by the loader. This depends on the AIX version. */
6182 asm_fprintf (file, RS6000_CALL_GLUE);
a8b3aeda
RK
6183 return;
6184
81eace42
GK
6185 /* %a is output_address. */
6186
9854d9ed
RK
6187 case 'A':
6188 /* If X is a constant integer whose low-order 5 bits are zero,
6189 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
76229ac8 6190 in the AIX assembler where "sri" with a zero shift count
20e26713 6191 writes a trash instruction. */
9854d9ed 6192 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
76229ac8 6193 putc ('l', file);
9854d9ed 6194 else
76229ac8 6195 putc ('r', file);
9854d9ed
RK
6196 return;
6197
6198 case 'b':
e2c953b6
DE
6199 /* If constant, low-order 16 bits of constant, unsigned.
6200 Otherwise, write normally. */
6201 if (INT_P (x))
6202 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
6203 else
6204 print_operand (file, x, 0);
cad12a8d
RK
6205 return;
6206
a260abc9
DE
6207 case 'B':
6208 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
6209 for 64-bit mask direction. */
296b8152 6210 putc (((INT_LOWPART(x) & 1) == 0 ? 'r' : 'l'), file);
a238cd8b 6211 return;
a260abc9 6212
81eace42
GK
6213 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
6214 output_operand. */
6215
9854d9ed 6216 case 'D':
39a10a29
GK
6217 /* There used to be a comment for 'C' reading "This is an
6218 optional cror needed for certain floating-point
6219 comparisons. Otherwise write nothing." */
6220
9854d9ed
RK
6221 /* Similar, except that this is for an scc, so we must be able to
6222 encode the test in a single bit that is one. We do the above
6223 for any LE, GE, GEU, or LEU and invert the bit for NE. */
6224 if (GET_CODE (x) == LE || GET_CODE (x) == GE
6225 || GET_CODE (x) == LEU || GET_CODE (x) == GEU)
6226 {
9ebbca7d 6227 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
9854d9ed
RK
6228
6229 fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3,
6230 base_bit + 2,
6231 base_bit + (GET_CODE (x) == GE || GET_CODE (x) == GEU));
6232 }
6233
6234 else if (GET_CODE (x) == NE)
6235 {
9ebbca7d 6236 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
9854d9ed
RK
6237
6238 fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 3,
6239 base_bit + 2, base_bit + 2);
6240 }
6241 return;
6242
6243 case 'E':
39a10a29 6244 /* X is a CR register. Print the number of the EQ bit of the CR */
9854d9ed
RK
6245 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
6246 output_operand_lossage ("invalid %%E value");
78fbdbf7 6247 else
39a10a29 6248 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
a85d226b 6249 return;
9854d9ed
RK
6250
6251 case 'f':
6252 /* X is a CR register. Print the shift count needed to move it
6253 to the high-order four bits. */
6254 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
6255 output_operand_lossage ("invalid %%f value");
6256 else
9ebbca7d 6257 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
9854d9ed
RK
6258 return;
6259
6260 case 'F':
6261 /* Similar, but print the count for the rotate in the opposite
6262 direction. */
6263 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
6264 output_operand_lossage ("invalid %%F value");
6265 else
9ebbca7d 6266 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
9854d9ed
RK
6267 return;
6268
6269 case 'G':
6270 /* X is a constant integer. If it is negative, print "m",
6271 otherwise print "z". This is to make a aze or ame insn. */
6272 if (GET_CODE (x) != CONST_INT)
6273 output_operand_lossage ("invalid %%G value");
6274 else if (INTVAL (x) >= 0)
76229ac8 6275 putc ('z', file);
9854d9ed 6276 else
76229ac8 6277 putc ('m', file);
9854d9ed 6278 return;
e2c953b6 6279
9878760c 6280 case 'h':
a4f6c312
SS
6281 /* If constant, output low-order five bits. Otherwise, write
6282 normally. */
9878760c 6283 if (INT_P (x))
5f59ecb7 6284 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
9878760c
RK
6285 else
6286 print_operand (file, x, 0);
6287 return;
6288
64305719 6289 case 'H':
a4f6c312
SS
6290 /* If constant, output low-order six bits. Otherwise, write
6291 normally. */
64305719 6292 if (INT_P (x))
5f59ecb7 6293 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
64305719
DE
6294 else
6295 print_operand (file, x, 0);
6296 return;
6297
9854d9ed
RK
6298 case 'I':
6299 /* Print `i' if this is a constant, else nothing. */
9878760c 6300 if (INT_P (x))
76229ac8 6301 putc ('i', file);
9878760c
RK
6302 return;
6303
9854d9ed
RK
6304 case 'j':
6305 /* Write the bit number in CCR for jump. */
6306 i = ccr_bit (x, 0);
6307 if (i == -1)
6308 output_operand_lossage ("invalid %%j code");
9878760c 6309 else
9854d9ed 6310 fprintf (file, "%d", i);
9878760c
RK
6311 return;
6312
9854d9ed
RK
6313 case 'J':
6314 /* Similar, but add one for shift count in rlinm for scc and pass
6315 scc flag to `ccr_bit'. */
6316 i = ccr_bit (x, 1);
6317 if (i == -1)
6318 output_operand_lossage ("invalid %%J code");
6319 else
a0466a68
RK
6320 /* If we want bit 31, write a shift count of zero, not 32. */
6321 fprintf (file, "%d", i == 31 ? 0 : i + 1);
9878760c
RK
6322 return;
6323
9854d9ed
RK
6324 case 'k':
6325 /* X must be a constant. Write the 1's complement of the
6326 constant. */
9878760c 6327 if (! INT_P (x))
9854d9ed 6328 output_operand_lossage ("invalid %%k value");
e2c953b6
DE
6329 else
6330 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
9878760c
RK
6331 return;
6332
81eace42 6333 case 'K':
9ebbca7d
GK
6334 /* X must be a symbolic constant on ELF. Write an
6335 expression suitable for an 'addi' that adds in the low 16
6336 bits of the MEM. */
6337 if (GET_CODE (x) != CONST)
6338 {
6339 print_operand_address (file, x);
6340 fputs ("@l", file);
6341 }
6342 else
6343 {
6344 if (GET_CODE (XEXP (x, 0)) != PLUS
6345 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
6346 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
6347 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
53cd5d6c 6348 output_operand_lossage ("invalid %%K value");
9ebbca7d
GK
6349 print_operand_address (file, XEXP (XEXP (x, 0), 0));
6350 fputs ("@l", file);
6351 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
6352 }
81eace42
GK
6353 return;
6354
6355 /* %l is output_asm_label. */
9ebbca7d 6356
9854d9ed
RK
6357 case 'L':
6358 /* Write second word of DImode or DFmode reference. Works on register
6359 or non-indexed memory only. */
6360 if (GET_CODE (x) == REG)
5ebfb2ba 6361 fprintf (file, "%s", reg_names[REGNO (x) + 1]);
9854d9ed
RK
6362 else if (GET_CODE (x) == MEM)
6363 {
6364 /* Handle possible auto-increment. Since it is pre-increment and
1427100a 6365 we have already done it, we can just use an offset of word. */
9854d9ed
RK
6366 if (GET_CODE (XEXP (x, 0)) == PRE_INC
6367 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
ed8908e7
RK
6368 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
6369 UNITS_PER_WORD));
9854d9ed 6370 else
d7624dc0
RK
6371 output_address (XEXP (adjust_address_nv (x, SImode,
6372 UNITS_PER_WORD),
6373 0));
ed8908e7 6374
ba5e43aa 6375 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
6376 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
6377 reg_names[SMALL_DATA_REG]);
9854d9ed 6378 }
9878760c 6379 return;
9854d9ed 6380
9878760c
RK
6381 case 'm':
6382 /* MB value for a mask operand. */
b1765bde 6383 if (! mask_operand (x, SImode))
9878760c
RK
6384 output_operand_lossage ("invalid %%m value");
6385
6386 val = INT_LOWPART (x);
6387
6388 /* If the high bit is set and the low bit is not, the value is zero.
6389 If the high bit is zero, the value is the first 1 bit we find from
6390 the left. */
0858c623 6391 if ((val & 0x80000000) && ((val & 1) == 0))
9878760c 6392 {
19d2d16f 6393 putc ('0', file);
9878760c
RK
6394 return;
6395 }
0858c623 6396 else if ((val & 0x80000000) == 0)
9878760c
RK
6397 {
6398 for (i = 1; i < 32; i++)
0858c623 6399 if ((val <<= 1) & 0x80000000)
9878760c
RK
6400 break;
6401 fprintf (file, "%d", i);
6402 return;
6403 }
6404
6405 /* Otherwise, look for the first 0 bit from the right. The result is its
6406 number plus 1. We know the low-order bit is one. */
6407 for (i = 0; i < 32; i++)
6408 if (((val >>= 1) & 1) == 0)
6409 break;
6410
a260abc9 6411 /* If we ended in ...01, i would be 0. The correct value is 31, so
9878760c
RK
6412 we want 31 - i. */
6413 fprintf (file, "%d", 31 - i);
6414 return;
6415
6416 case 'M':
6417 /* ME value for a mask operand. */
b1765bde 6418 if (! mask_operand (x, SImode))
a260abc9 6419 output_operand_lossage ("invalid %%M value");
9878760c
RK
6420
6421 val = INT_LOWPART (x);
6422
6423 /* If the low bit is set and the high bit is not, the value is 31.
6424 If the low bit is zero, the value is the first 1 bit we find from
6425 the right. */
0858c623 6426 if ((val & 1) && ((val & 0x80000000) == 0))
9878760c 6427 {
76229ac8 6428 fputs ("31", file);
9878760c
RK
6429 return;
6430 }
6431 else if ((val & 1) == 0)
6432 {
6433 for (i = 0; i < 32; i++)
6434 if ((val >>= 1) & 1)
6435 break;
6436
a260abc9 6437 /* If we had ....10, i would be 0. The result should be
9878760c
RK
6438 30, so we need 30 - i. */
6439 fprintf (file, "%d", 30 - i);
6440 return;
6441 }
6442
6443 /* Otherwise, look for the first 0 bit from the left. The result is its
6444 number minus 1. We know the high-order bit is one. */
6445 for (i = 0; i < 32; i++)
0858c623 6446 if (((val <<= 1) & 0x80000000) == 0)
9878760c
RK
6447 break;
6448
6449 fprintf (file, "%d", i);
6450 return;
6451
81eace42
GK
6452 /* %n outputs the negative of its operand. */
6453
9878760c
RK
6454 case 'N':
6455 /* Write the number of elements in the vector times 4. */
6456 if (GET_CODE (x) != PARALLEL)
6457 output_operand_lossage ("invalid %%N value");
e2c953b6
DE
6458 else
6459 fprintf (file, "%d", XVECLEN (x, 0) * 4);
9878760c
RK
6460 return;
6461
6462 case 'O':
6463 /* Similar, but subtract 1 first. */
6464 if (GET_CODE (x) != PARALLEL)
1427100a 6465 output_operand_lossage ("invalid %%O value");
e2c953b6
DE
6466 else
6467 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
9878760c
RK
6468 return;
6469
9854d9ed
RK
6470 case 'p':
6471 /* X is a CONST_INT that is a power of two. Output the logarithm. */
6472 if (! INT_P (x)
2bfcf297 6473 || INT_LOWPART (x) < 0
9854d9ed
RK
6474 || (i = exact_log2 (INT_LOWPART (x))) < 0)
6475 output_operand_lossage ("invalid %%p value");
e2c953b6
DE
6476 else
6477 fprintf (file, "%d", i);
9854d9ed
RK
6478 return;
6479
9878760c
RK
6480 case 'P':
6481 /* The operand must be an indirect memory reference. The result
a4f6c312 6482 is the register number. */
9878760c
RK
6483 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
6484 || REGNO (XEXP (x, 0)) >= 32)
6485 output_operand_lossage ("invalid %%P value");
e2c953b6
DE
6486 else
6487 fprintf (file, "%d", REGNO (XEXP (x, 0)));
9878760c
RK
6488 return;
6489
dfbdccdb
GK
6490 case 'q':
6491 /* This outputs the logical code corresponding to a boolean
6492 expression. The expression may have one or both operands
39a10a29
GK
6493 negated (if one, only the first one). For condition register
6494 logical operations, it will also treat the negated
6495 CR codes as NOTs, but not handle NOTs of them. */
dfbdccdb 6496 {
63bc1d05 6497 const char *const *t = 0;
dfbdccdb
GK
6498 const char *s;
6499 enum rtx_code code = GET_CODE (x);
6500 static const char * const tbl[3][3] = {
6501 { "and", "andc", "nor" },
6502 { "or", "orc", "nand" },
6503 { "xor", "eqv", "xor" } };
6504
6505 if (code == AND)
6506 t = tbl[0];
6507 else if (code == IOR)
6508 t = tbl[1];
6509 else if (code == XOR)
6510 t = tbl[2];
6511 else
6512 output_operand_lossage ("invalid %%q value");
6513
6514 if (GET_CODE (XEXP (x, 0)) != NOT)
6515 s = t[0];
6516 else
6517 {
6518 if (GET_CODE (XEXP (x, 1)) == NOT)
6519 s = t[2];
6520 else
6521 s = t[1];
6522 }
6523
6524 fputs (s, file);
6525 }
6526 return;
6527
9854d9ed
RK
6528 case 'R':
6529 /* X is a CR register. Print the mask for `mtcrf'. */
6530 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
6531 output_operand_lossage ("invalid %%R value");
6532 else
9ebbca7d 6533 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
9878760c 6534 return;
9854d9ed
RK
6535
6536 case 's':
6537 /* Low 5 bits of 32 - value */
6538 if (! INT_P (x))
6539 output_operand_lossage ("invalid %%s value");
e2c953b6
DE
6540 else
6541 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
9878760c 6542 return;
9854d9ed 6543
a260abc9
DE
6544 case 'S':
6545 /* PowerPC64 mask position. All 0's and all 1's are excluded.
6546 CONST_INT 32-bit mask is considered sign-extended so any
6547 transition must occur within the CONST_INT, not on the boundary. */
b1765bde 6548 if (! mask64_operand (x, DImode))
a260abc9
DE
6549 output_operand_lossage ("invalid %%S value");
6550
6551 val = INT_LOWPART (x);
6552
6553 if (val & 1) /* Clear Left */
6554 {
a238cd8b
DE
6555 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
6556 if (!((val >>= 1) & 1))
6557 break;
a260abc9 6558
a238cd8b
DE
6559#if HOST_BITS_PER_WIDE_INT == 32
6560 if (GET_CODE (x) == CONST_DOUBLE && i == 32)
6561 {
6562 val = CONST_DOUBLE_HIGH (x);
6563
6564 if (val == 0)
6565 --i;
6566 else
6567 for (i = 32; i < 64; i++)
6568 if (!((val >>= 1) & 1))
6569 break;
6570 }
a260abc9 6571#endif
a238cd8b
DE
6572 /* i = index of last set bit from right
6573 mask begins at 63 - i from left */
6574 if (i > 63)
6575 output_operand_lossage ("%%S computed all 1's mask");
cccf3bdc 6576
a260abc9
DE
6577 fprintf (file, "%d", 63 - i);
6578 return;
6579 }
6580 else /* Clear Right */
6581 {
a238cd8b
DE
6582 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
6583 if ((val >>= 1) & 1)
6584 break;
a260abc9 6585
a238cd8b 6586#if HOST_BITS_PER_WIDE_INT == 32
a260abc9
DE
6587 if (GET_CODE (x) == CONST_DOUBLE && i == 32)
6588 {
a238cd8b 6589 val = CONST_DOUBLE_HIGH (x);
a260abc9 6590
a238cd8b 6591 if (val == (HOST_WIDE_INT) -1)
a260abc9 6592 --i;
a260abc9 6593 else
a238cd8b
DE
6594 for (i = 32; i < 64; i++)
6595 if ((val >>= 1) & 1)
a260abc9
DE
6596 break;
6597 }
6598#endif
a238cd8b
DE
6599 /* i = index of last clear bit from right
6600 mask ends at 62 - i from left */
6601 if (i > 62)
6602 output_operand_lossage ("%%S computed all 0's mask");
cccf3bdc 6603
a238cd8b 6604 fprintf (file, "%d", 62 - i);
a260abc9
DE
6605 return;
6606 }
6607
cccf3bdc
DE
6608 case 'T':
6609 /* Print the symbolic name of a branch target register. */
6610 if (GET_CODE (x) != REG || (REGNO (x) != LINK_REGISTER_REGNUM
6611 && REGNO (x) != COUNT_REGISTER_REGNUM))
6612 output_operand_lossage ("invalid %%T value");
e2c953b6 6613 else if (REGNO (x) == LINK_REGISTER_REGNUM)
cccf3bdc
DE
6614 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
6615 else
6616 fputs ("ctr", file);
6617 return;
6618
9854d9ed 6619 case 'u':
802a0058 6620 /* High-order 16 bits of constant for use in unsigned operand. */
9854d9ed
RK
6621 if (! INT_P (x))
6622 output_operand_lossage ("invalid %%u value");
e2c953b6
DE
6623 else
6624 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
6625 (INT_LOWPART (x) >> 16) & 0xffff);
9878760c
RK
6626 return;
6627
802a0058
MM
6628 case 'v':
6629 /* High-order 16 bits of constant for use in signed operand. */
6630 if (! INT_P (x))
6631 output_operand_lossage ("invalid %%v value");
e2c953b6 6632 else
134c32f6
DE
6633 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
6634 (INT_LOWPART (x) >> 16) & 0xffff);
6635 return;
802a0058 6636
9854d9ed
RK
6637 case 'U':
6638 /* Print `u' if this has an auto-increment or auto-decrement. */
6639 if (GET_CODE (x) == MEM
6640 && (GET_CODE (XEXP (x, 0)) == PRE_INC
6641 || GET_CODE (XEXP (x, 0)) == PRE_DEC))
76229ac8 6642 putc ('u', file);
9854d9ed 6643 return;
9878760c 6644
e0cd0770
JC
6645 case 'V':
6646 /* Print the trap code for this operand. */
6647 switch (GET_CODE (x))
6648 {
6649 case EQ:
6650 fputs ("eq", file); /* 4 */
6651 break;
6652 case NE:
6653 fputs ("ne", file); /* 24 */
6654 break;
6655 case LT:
6656 fputs ("lt", file); /* 16 */
6657 break;
6658 case LE:
6659 fputs ("le", file); /* 20 */
6660 break;
6661 case GT:
6662 fputs ("gt", file); /* 8 */
6663 break;
6664 case GE:
6665 fputs ("ge", file); /* 12 */
6666 break;
6667 case LTU:
6668 fputs ("llt", file); /* 2 */
6669 break;
6670 case LEU:
6671 fputs ("lle", file); /* 6 */
6672 break;
6673 case GTU:
6674 fputs ("lgt", file); /* 1 */
6675 break;
6676 case GEU:
6677 fputs ("lge", file); /* 5 */
6678 break;
6679 default:
6680 abort ();
6681 }
6682 break;
6683
9854d9ed
RK
6684 case 'w':
6685 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
6686 normally. */
6687 if (INT_P (x))
5f59ecb7
DE
6688 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
6689 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
9854d9ed
RK
6690 else
6691 print_operand (file, x, 0);
9878760c
RK
6692 return;
6693
9854d9ed 6694 case 'W':
e2c953b6 6695 /* MB value for a PowerPC64 rldic operand. */
e2c953b6
DE
6696 val = (GET_CODE (x) == CONST_INT
6697 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
6698
6699 if (val < 0)
6700 i = -1;
9854d9ed 6701 else
e2c953b6
DE
6702 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
6703 if ((val <<= 1) < 0)
6704 break;
6705
6706#if HOST_BITS_PER_WIDE_INT == 32
6707 if (GET_CODE (x) == CONST_INT && i >= 0)
6708 i += 32; /* zero-extend high-part was all 0's */
6709 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
6710 {
6711 val = CONST_DOUBLE_LOW (x);
6712
6713 if (val == 0)
a4f6c312 6714 abort ();
e2c953b6
DE
6715 else if (val < 0)
6716 --i;
6717 else
6718 for ( ; i < 64; i++)
6719 if ((val <<= 1) < 0)
6720 break;
6721 }
6722#endif
6723
6724 fprintf (file, "%d", i + 1);
9854d9ed 6725 return;
9878760c 6726
9854d9ed
RK
6727 case 'X':
6728 if (GET_CODE (x) == MEM
258bfae2 6729 && LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0), 0))
76229ac8 6730 putc ('x', file);
9854d9ed 6731 return;
9878760c 6732
9854d9ed
RK
6733 case 'Y':
6734 /* Like 'L', for third word of TImode */
6735 if (GET_CODE (x) == REG)
5ebfb2ba 6736 fprintf (file, "%s", reg_names[REGNO (x) + 2]);
9854d9ed 6737 else if (GET_CODE (x) == MEM)
9878760c 6738 {
9854d9ed
RK
6739 if (GET_CODE (XEXP (x, 0)) == PRE_INC
6740 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
a54d04b7 6741 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
9854d9ed 6742 else
d7624dc0 6743 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
ba5e43aa 6744 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
6745 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
6746 reg_names[SMALL_DATA_REG]);
9878760c
RK
6747 }
6748 return;
9854d9ed 6749
9878760c 6750 case 'z':
b4ac57ab
RS
6751 /* X is a SYMBOL_REF. Write out the name preceded by a
6752 period and without any trailing data in brackets. Used for function
4d30c363
MM
6753 names. If we are configured for System V (or the embedded ABI) on
6754 the PowerPC, do not emit the period, since those systems do not use
6755 TOCs and the like. */
9878760c
RK
6756 if (GET_CODE (x) != SYMBOL_REF)
6757 abort ();
6758
b6c9286a
MM
6759 if (XSTR (x, 0)[0] != '.')
6760 {
6761 switch (DEFAULT_ABI)
6762 {
6763 default:
6764 abort ();
6765
6766 case ABI_AIX:
6767 putc ('.', file);
6768 break;
6769
6770 case ABI_V4:
6771 case ABI_AIX_NODESC:
ee890fe2 6772 case ABI_DARWIN:
b6c9286a 6773 break;
b6c9286a
MM
6774 }
6775 }
54ee9799
DE
6776#if TARGET_AIX
6777 RS6000_OUTPUT_BASENAME (file, XSTR (x, 0));
6778#else
9ebbca7d 6779 assemble_name (file, XSTR (x, 0));
54ee9799 6780#endif
9878760c
RK
6781 return;
6782
9854d9ed
RK
6783 case 'Z':
6784 /* Like 'L', for last word of TImode. */
6785 if (GET_CODE (x) == REG)
5ebfb2ba 6786 fprintf (file, "%s", reg_names[REGNO (x) + 3]);
9854d9ed
RK
6787 else if (GET_CODE (x) == MEM)
6788 {
6789 if (GET_CODE (XEXP (x, 0)) == PRE_INC
6790 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
a54d04b7 6791 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
9854d9ed 6792 else
d7624dc0 6793 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
ba5e43aa 6794 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
6795 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
6796 reg_names[SMALL_DATA_REG]);
9854d9ed 6797 }
5c23c401 6798 return;
0ac081f6
AH
6799
6800 /* Print AltiVec memory operand. */
6801 case 'y':
6802 {
6803 rtx tmp;
6804
6805 if (GET_CODE (x) != MEM)
6806 abort ();
6807
6808 tmp = XEXP (x, 0);
6809
6810 if (GET_CODE (tmp) == REG)
c62f2db5 6811 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
0ac081f6
AH
6812 else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
6813 {
6814 if (REGNO (XEXP (tmp, 0)) == 0)
6815 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
6816 reg_names[ REGNO (XEXP (tmp, 0)) ]);
6817 else
6818 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
6819 reg_names[ REGNO (XEXP (tmp, 1)) ]);
6820 }
6821 else
6822 abort ();
6823 break;
6824 }
9854d9ed 6825
9878760c
RK
6826 case 0:
6827 if (GET_CODE (x) == REG)
6828 fprintf (file, "%s", reg_names[REGNO (x)]);
6829 else if (GET_CODE (x) == MEM)
6830 {
6831 /* We need to handle PRE_INC and PRE_DEC here, since we need to
6832 know the width from the mode. */
6833 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
79ba6d34
MM
6834 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
6835 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
9878760c 6836 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
79ba6d34
MM
6837 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
6838 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
9878760c 6839 else
a54d04b7 6840 output_address (XEXP (x, 0));
9878760c
RK
6841 }
6842 else
a54d04b7 6843 output_addr_const (file, x);
a85d226b 6844 return;
9878760c
RK
6845
6846 default:
6847 output_operand_lossage ("invalid %%xn code");
6848 }
6849}
6850\f
6851/* Print the address of an operand. */
6852
6853void
6854print_operand_address (file, x)
6855 FILE *file;
592696dd 6856 rtx x;
9878760c
RK
6857{
6858 if (GET_CODE (x) == REG)
4697a36c 6859 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
9ebbca7d
GK
6860 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
6861 || GET_CODE (x) == LABEL_REF)
9878760c
RK
6862 {
6863 output_addr_const (file, x);
ba5e43aa 6864 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
6865 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
6866 reg_names[SMALL_DATA_REG]);
9ebbca7d 6867 else if (TARGET_TOC)
a4f6c312 6868 abort ();
9878760c
RK
6869 }
6870 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
6871 {
6872 if (REGNO (XEXP (x, 0)) == 0)
4697a36c
MM
6873 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
6874 reg_names[ REGNO (XEXP (x, 0)) ]);
9878760c 6875 else
4697a36c
MM
6876 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
6877 reg_names[ REGNO (XEXP (x, 1)) ]);
9878760c
RK
6878 }
6879 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
5f59ecb7
DE
6880 {
6881 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (XEXP (x, 1)));
6882 fprintf (file, "(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
6883 }
3cb999d8
DE
6884#if TARGET_ELF
6885 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
6886 && CONSTANT_P (XEXP (x, 1)))
4697a36c
MM
6887 {
6888 output_addr_const (file, XEXP (x, 1));
6889 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
6890 }
c859cda6
DJ
6891#endif
6892#if TARGET_MACHO
6893 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
6894 && CONSTANT_P (XEXP (x, 1)))
6895 {
6896 fprintf (file, "lo16(");
6897 output_addr_const (file, XEXP (x, 1));
6898 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
6899 }
3cb999d8 6900#endif
9ebbca7d
GK
6901 else if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
6902 {
2bfcf297 6903 if (TARGET_AIX && (!TARGET_ELF || !TARGET_MINIMAL_TOC))
9ebbca7d 6904 {
2bfcf297
DB
6905 rtx contains_minus = XEXP (x, 1);
6906 rtx minus, symref;
6907 const char *name;
9ebbca7d
GK
6908
6909 /* Find the (minus (sym) (toc)) buried in X, and temporarily
a4f6c312 6910 turn it into (sym) for output_addr_const. */
9ebbca7d
GK
6911 while (GET_CODE (XEXP (contains_minus, 0)) != MINUS)
6912 contains_minus = XEXP (contains_minus, 0);
6913
2bfcf297
DB
6914 minus = XEXP (contains_minus, 0);
6915 symref = XEXP (minus, 0);
6916 XEXP (contains_minus, 0) = symref;
6917 if (TARGET_ELF)
6918 {
6919 char *newname;
6920
6921 name = XSTR (symref, 0);
6922 newname = alloca (strlen (name) + sizeof ("@toc"));
6923 strcpy (newname, name);
6924 strcat (newname, "@toc");
6925 XSTR (symref, 0) = newname;
6926 }
6927 output_addr_const (file, XEXP (x, 1));
6928 if (TARGET_ELF)
6929 XSTR (symref, 0) = name;
9ebbca7d
GK
6930 XEXP (contains_minus, 0) = minus;
6931 }
6932 else
6933 output_addr_const (file, XEXP (x, 1));
6934
6935 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
6936 }
9878760c
RK
6937 else
6938 abort ();
6939}
6940\f
301d03af
RS
6941/* Target hook for assembling integer objects. The powerpc version has
6942 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
6943 is defined. It also needs to handle DI-mode objects on 64-bit
6944 targets. */
6945
6946static bool
6947rs6000_assemble_integer (x, size, aligned_p)
6948 rtx x;
6949 unsigned int size;
6950 int aligned_p;
6951{
6952#ifdef RELOCATABLE_NEEDS_FIXUP
6953 /* Special handling for SI values. */
6954 if (size == 4 && aligned_p)
6955 {
6956 extern int in_toc_section PARAMS ((void));
6957 static int recurse = 0;
6958
6959 /* For -mrelocatable, we mark all addresses that need to be fixed up
6960 in the .fixup section. */
6961 if (TARGET_RELOCATABLE
6962 && !in_toc_section ()
6963 && !in_text_section ()
6964 && !recurse
6965 && GET_CODE (x) != CONST_INT
6966 && GET_CODE (x) != CONST_DOUBLE
6967 && CONSTANT_P (x))
6968 {
6969 char buf[256];
6970
6971 recurse = 1;
6972 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
6973 fixuplabelno++;
6974 ASM_OUTPUT_LABEL (asm_out_file, buf);
6975 fprintf (asm_out_file, "\t.long\t(");
6976 output_addr_const (asm_out_file, x);
6977 fprintf (asm_out_file, ")@fixup\n");
6978 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
6979 ASM_OUTPUT_ALIGN (asm_out_file, 2);
6980 fprintf (asm_out_file, "\t.long\t");
6981 assemble_name (asm_out_file, buf);
6982 fprintf (asm_out_file, "\n\t.previous\n");
6983 recurse = 0;
6984 return true;
6985 }
6986 /* Remove initial .'s to turn a -mcall-aixdesc function
6987 address into the address of the descriptor, not the function
6988 itself. */
6989 else if (GET_CODE (x) == SYMBOL_REF
6990 && XSTR (x, 0)[0] == '.'
6991 && DEFAULT_ABI == ABI_AIX)
6992 {
6993 const char *name = XSTR (x, 0);
6994 while (*name == '.')
6995 name++;
6996
6997 fprintf (asm_out_file, "\t.long\t%s\n", name);
6998 return true;
6999 }
7000 }
7001#endif /* RELOCATABLE_NEEDS_FIXUP */
7002 return default_assemble_integer (x, size, aligned_p);
7003}
7004\f
39a10a29
GK
7005enum rtx_code
7006rs6000_reverse_condition (mode, code)
7007 enum machine_mode mode;
7008 enum rtx_code code;
7009{
7010 /* Reversal of FP compares takes care -- an ordered compare
7011 becomes an unordered compare and vice versa. */
7012 if (mode == CCFPmode)
bab6226b 7013 return reverse_condition_maybe_unordered (code);
39a10a29 7014 else
bab6226b 7015 return reverse_condition (code);
39a10a29
GK
7016}
7017
39a10a29
GK
7018/* Generate a compare for CODE. Return a brand-new rtx that
7019 represents the result of the compare. */
a4f6c312 7020
39a10a29
GK
7021static rtx
7022rs6000_generate_compare (code)
7023 enum rtx_code code;
7024{
7025 enum machine_mode comp_mode;
7026 rtx compare_result;
7027
7028 if (rs6000_compare_fp_p)
7029 comp_mode = CCFPmode;
7030 else if (code == GTU || code == LTU
7031 || code == GEU || code == LEU)
7032 comp_mode = CCUNSmode;
7033 else
7034 comp_mode = CCmode;
7035
7036 /* First, the compare. */
7037 compare_result = gen_reg_rtx (comp_mode);
7038 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
7039 gen_rtx_COMPARE (comp_mode,
7040 rs6000_compare_op0,
7041 rs6000_compare_op1)));
7042
ca5adc63 7043 /* Some kinds of FP comparisons need an OR operation;
de6c5979 7044 except for flag_unsafe_math_optimizations we don't bother. */
39a10a29 7045 if (rs6000_compare_fp_p
de6c5979 7046 && ! flag_unsafe_math_optimizations
39a10a29
GK
7047 && (code == LE || code == GE
7048 || code == UNEQ || code == LTGT
7049 || code == UNGT || code == UNLT))
7050 {
7051 enum rtx_code or1, or2;
7052 rtx or1_rtx, or2_rtx, compare2_rtx;
7053 rtx or_result = gen_reg_rtx (CCEQmode);
7054
7055 switch (code)
7056 {
7057 case LE: or1 = LT; or2 = EQ; break;
7058 case GE: or1 = GT; or2 = EQ; break;
7059 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
7060 case LTGT: or1 = LT; or2 = GT; break;
7061 case UNGT: or1 = UNORDERED; or2 = GT; break;
7062 case UNLT: or1 = UNORDERED; or2 = LT; break;
7063 default: abort ();
7064 }
7065 validate_condition_mode (or1, comp_mode);
7066 validate_condition_mode (or2, comp_mode);
7067 or1_rtx = gen_rtx (or1, SImode, compare_result, const0_rtx);
7068 or2_rtx = gen_rtx (or2, SImode, compare_result, const0_rtx);
7069 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
7070 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
7071 const_true_rtx);
7072 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
7073
7074 compare_result = or_result;
7075 code = EQ;
7076 }
7077
7078 validate_condition_mode (code, GET_MODE (compare_result));
7079
7080 return gen_rtx (code, VOIDmode, compare_result, const0_rtx);
7081}
7082
7083
7084/* Emit the RTL for an sCOND pattern. */
7085
7086void
7087rs6000_emit_sCOND (code, result)
7088 enum rtx_code code;
7089 rtx result;
7090{
7091 rtx condition_rtx;
7092 enum machine_mode op_mode;
7093
7094 condition_rtx = rs6000_generate_compare (code);
7095
7096 op_mode = GET_MODE (rs6000_compare_op0);
7097 if (op_mode == VOIDmode)
7098 op_mode = GET_MODE (rs6000_compare_op1);
7099
7100 if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p))
7101 {
7102 PUT_MODE (condition_rtx, DImode);
7103 convert_move (result, condition_rtx, 0);
7104 }
7105 else
7106 {
7107 PUT_MODE (condition_rtx, SImode);
7108 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
7109 }
7110}
7111
39a10a29
GK
7112/* Emit a branch of kind CODE to location LOC. */
7113
7114void
7115rs6000_emit_cbranch (code, loc)
7116 enum rtx_code code;
7117 rtx loc;
7118{
7119 rtx condition_rtx, loc_ref;
7120
7121 condition_rtx = rs6000_generate_compare (code);
7122 loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
7123 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
7124 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
7125 loc_ref, pc_rtx)));
7126}
7127
12a4e8c5
GK
7128/* Return the string to output a conditional branch to LABEL, which is
7129 the operand number of the label, or -1 if the branch is really a
7130 conditional return.
7131
7132 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
7133 condition code register and its mode specifies what kind of
7134 comparison we made.
7135
7136 REVERSED is non-zero if we should reverse the sense of the comparison.
7137
7138 INSN is the insn. */
7139
7140char *
7141output_cbranch (op, label, reversed, insn)
7142 rtx op;
7143 const char * label;
7144 int reversed;
7145 rtx insn;
7146{
7147 static char string[64];
7148 enum rtx_code code = GET_CODE (op);
7149 rtx cc_reg = XEXP (op, 0);
7150 enum machine_mode mode = GET_MODE (cc_reg);
7151 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
39a10a29 7152 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
12a4e8c5
GK
7153 int really_reversed = reversed ^ need_longbranch;
7154 char *s = string;
7155 const char *ccode;
7156 const char *pred;
7157 rtx note;
7158
39a10a29
GK
7159 validate_condition_mode (code, mode);
7160
7161 /* Work out which way this really branches. We could use
7162 reverse_condition_maybe_unordered here always but this
7163 makes the resulting assembler clearer. */
12a4e8c5 7164 if (really_reversed)
39a10a29 7165 code = rs6000_reverse_condition (mode, code);
12a4e8c5 7166
39a10a29 7167 switch (code)
12a4e8c5
GK
7168 {
7169 /* Not all of these are actually distinct opcodes, but
7170 we distinguish them for clarity of the resulting assembler. */
50a0b056
GK
7171 case NE: case LTGT:
7172 ccode = "ne"; break;
7173 case EQ: case UNEQ:
7174 ccode = "eq"; break;
7175 case GE: case GEU:
7176 ccode = "ge"; break;
7177 case GT: case GTU: case UNGT:
7178 ccode = "gt"; break;
7179 case LE: case LEU:
7180 ccode = "le"; break;
7181 case LT: case LTU: case UNLT:
7182 ccode = "lt"; break;
12a4e8c5
GK
7183 case UNORDERED: ccode = "un"; break;
7184 case ORDERED: ccode = "nu"; break;
7185 case UNGE: ccode = "nl"; break;
7186 case UNLE: ccode = "ng"; break;
7187 default:
a4f6c312 7188 abort ();
12a4e8c5
GK
7189 }
7190
94a54f47
GK
7191 /* Maybe we have a guess as to how likely the branch is.
7192 The old mnemonics don't have a way to specify this information. */
12a4e8c5
GK
7193 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
7194 if (note != NULL_RTX)
7195 {
7196 /* PROB is the difference from 50%. */
7197 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
7198
7199 /* For branches that are very close to 50%, assume not-taken. */
7200 if (abs (prob) > REG_BR_PROB_BASE / 20
7201 && ((prob > 0) ^ need_longbranch))
7202 pred = "+";
7203 else
7204 pred = "-";
7205 }
7206 else
7207 pred = "";
7208
7209 if (label == NULL)
94a54f47 7210 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
12a4e8c5 7211 else
94a54f47 7212 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
12a4e8c5 7213
37c67319
GK
7214 /* We need to escape any '%' characters in the reg_names string.
7215 Assume they'd only be the first character... */
7216 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
7217 *s++ = '%';
94a54f47 7218 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
12a4e8c5
GK
7219
7220 if (label != NULL)
7221 {
7222 /* If the branch distance was too far, we may have to use an
7223 unconditional branch to go the distance. */
7224 if (need_longbranch)
44518ddd 7225 s += sprintf (s, ",$+8\n\tb %s", label);
12a4e8c5
GK
7226 else
7227 s += sprintf (s, ",%s", label);
7228 }
7229
7230 return string;
7231}
50a0b056
GK
7232
7233/* Emit a conditional move: move TRUE_COND to DEST if OP of the
7234 operands of the last comparison is nonzero/true, FALSE_COND if it
7235 is zero/false. Return 0 if the hardware has no such operation. */
a4f6c312 7236
50a0b056
GK
7237int
7238rs6000_emit_cmove (dest, op, true_cond, false_cond)
7239 rtx dest;
7240 rtx op;
7241 rtx true_cond;
7242 rtx false_cond;
7243{
7244 enum rtx_code code = GET_CODE (op);
7245 rtx op0 = rs6000_compare_op0;
7246 rtx op1 = rs6000_compare_op1;
7247 REAL_VALUE_TYPE c1;
7248 enum machine_mode mode = GET_MODE (op0);
7249 rtx temp;
7250
7251 /* First, work out if the hardware can do this at all, or
7252 if it's too slow... */
7253 /* If the comparison is an integer one, since we only have fsel
7254 it'll be cheaper to use a branch. */
7255 if (! rs6000_compare_fp_p)
7256 return 0;
7257
7258 /* Eliminate half of the comparisons by switching operands, this
7259 makes the remaining code simpler. */
7260 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
7261 || code == LTGT || code == LT)
7262 {
7263 code = reverse_condition_maybe_unordered (code);
7264 temp = true_cond;
7265 true_cond = false_cond;
7266 false_cond = temp;
7267 }
7268
7269 /* UNEQ and LTGT take four instructions for a comparison with zero,
7270 it'll probably be faster to use a branch here too. */
7271 if (code == UNEQ)
7272 return 0;
7273
7274 if (GET_CODE (op1) == CONST_DOUBLE)
7275 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
7276
7277 /* We're going to try to implement comparions by performing
7278 a subtract, then comparing against zero. Unfortunately,
7279 Inf - Inf is NaN which is not zero, and so if we don't
7280 know that the the operand is finite and the comparison
7281 would treat EQ different to UNORDERED, we can't do it. */
7282 if (! flag_unsafe_math_optimizations
7283 && code != GT && code != UNGE
7284 && (GET_CODE (op1) != CONST_DOUBLE || target_isinf (c1))
7285 /* Constructs of the form (a OP b ? a : b) are safe. */
7286 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
7287 || (! rtx_equal_p (op0, true_cond)
7288 && ! rtx_equal_p (op1, true_cond))))
7289 return 0;
7290 /* At this point we know we can use fsel. */
7291
7292 /* Reduce the comparison to a comparison against zero. */
7293 temp = gen_reg_rtx (mode);
7294 emit_insn (gen_rtx_SET (VOIDmode, temp,
7295 gen_rtx_MINUS (mode, op0, op1)));
7296 op0 = temp;
7297 op1 = CONST0_RTX (mode);
7298
7299 /* If we don't care about NaNs we can reduce some of the comparisons
7300 down to faster ones. */
7301 if (flag_unsafe_math_optimizations)
7302 switch (code)
7303 {
7304 case GT:
7305 code = LE;
7306 temp = true_cond;
7307 true_cond = false_cond;
7308 false_cond = temp;
7309 break;
7310 case UNGE:
7311 code = GE;
7312 break;
7313 case UNEQ:
7314 code = EQ;
7315 break;
7316 default:
7317 break;
7318 }
7319
7320 /* Now, reduce everything down to a GE. */
7321 switch (code)
7322 {
7323 case GE:
7324 break;
7325
7326 case LE:
7327 temp = gen_reg_rtx (mode);
7328 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (mode, op0)));
7329 op0 = temp;
7330 break;
7331
7332 case ORDERED:
7333 temp = gen_reg_rtx (mode);
7334 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (mode, op0)));
7335 op0 = temp;
7336 break;
7337
7338 case EQ:
7339 temp = gen_reg_rtx (mode);
7340 emit_insn (gen_rtx_SET (VOIDmode, temp,
7341 gen_rtx_NEG (mode,
7342 gen_rtx_ABS (mode, op0))));
7343 op0 = temp;
7344 break;
7345
7346 case UNGE:
7347 temp = gen_reg_rtx (mode);
7348 emit_insn (gen_rtx_SET (VOIDmode, temp,
7349 gen_rtx_IF_THEN_ELSE (mode,
7350 gen_rtx_GE (VOIDmode,
7351 op0, op1),
7352 true_cond, false_cond)));
7353 false_cond = temp;
7354 true_cond = false_cond;
7355
7356 temp = gen_reg_rtx (mode);
7357 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (mode, op0)));
7358 op0 = temp;
7359 break;
7360
7361 case GT:
7362 temp = gen_reg_rtx (mode);
7363 emit_insn (gen_rtx_SET (VOIDmode, temp,
7364 gen_rtx_IF_THEN_ELSE (mode,
7365 gen_rtx_GE (VOIDmode,
7366 op0, op1),
7367 true_cond, false_cond)));
7368 true_cond = temp;
7369 false_cond = true_cond;
7370
7371 temp = gen_reg_rtx (mode);
7372 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (mode, op0)));
7373 op0 = temp;
7374 break;
7375
7376 default:
7377 abort ();
7378 }
7379
7380 emit_insn (gen_rtx_SET (VOIDmode, dest,
9f1a9740 7381 gen_rtx_IF_THEN_ELSE (GET_MODE (dest),
50a0b056
GK
7382 gen_rtx_GE (VOIDmode,
7383 op0, op1),
7384 true_cond, false_cond)));
7385 return 1;
7386}
7387
7388void
7389rs6000_emit_minmax (dest, code, op0, op1)
7390 rtx dest;
7391 enum rtx_code code;
7392 rtx op0;
7393 rtx op1;
7394{
7395 enum machine_mode mode = GET_MODE (op0);
7396 rtx target;
7397 if (code == SMAX || code == UMAX)
7398 target = emit_conditional_move (dest, GE, op0, op1, mode,
7399 op0, op1, mode, 0);
7400 else
7401 target = emit_conditional_move (dest, GE, op0, op1, mode,
7402 op1, op0, mode, 0);
7403 if (target == NULL_RTX)
7404 abort ();
7405 if (target != dest)
7406 emit_move_insn (dest, target);
7407}
12a4e8c5 7408\f
a4f6c312
SS
7409/* This page contains routines that are used to determine what the
7410 function prologue and epilogue code will do and write them out. */
9878760c 7411
a4f6c312
SS
7412/* Return the first fixed-point register that is required to be
7413 saved. 32 if none. */
9878760c
RK
7414
7415int
7416first_reg_to_save ()
7417{
7418 int first_reg;
7419
7420 /* Find lowest numbered live register. */
7421 for (first_reg = 13; first_reg <= 31; first_reg++)
a38d360d
GK
7422 if (regs_ever_live[first_reg]
7423 && (! call_used_regs[first_reg]
1db02437 7424 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
f607bc57
ZW
7425 && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
7426 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)))))
9878760c
RK
7427 break;
7428
70f4f91c 7429 if (current_function_profile)
b5253831
DE
7430 {
7431 /* AIX must save/restore every register that contains a parameter
7432 before/after the .__mcount call plus an additional register
7433 for the static chain, if needed; use registers from 30 down to 22
7434 to do this. */
ee890fe2 7435 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
b5253831
DE
7436 {
7437 int last_parm_reg, profile_first_reg;
7438
7439 /* Figure out last used parameter register. The proper thing
7440 to do is to walk incoming args of the function. A function
7441 might have live parameter registers even if it has no
7442 incoming args. */
7443 for (last_parm_reg = 10;
7444 last_parm_reg > 2 && ! regs_ever_live [last_parm_reg];
7445 last_parm_reg--)
7446 ;
7447
7448 /* Calculate first reg for saving parameter registers
7449 and static chain.
7450 Skip reg 31 which may contain the frame pointer. */
7451 profile_first_reg = (33 - last_parm_reg
7452 - (current_function_needs_context ? 1 : 0));
ee890fe2
SS
7453#if TARGET_MACHO
7454 /* Need to skip another reg to account for R31 being PICBASE
7455 (when flag_pic is set) or R30 being used as the frame
7456 pointer (when flag_pic is not set). */
7457 --profile_first_reg;
7458#endif
b5253831
DE
7459 /* Do not save frame pointer if no parameters needs to be saved. */
7460 if (profile_first_reg == 31)
7461 profile_first_reg = 32;
7462
7463 if (first_reg > profile_first_reg)
7464 first_reg = profile_first_reg;
7465 }
e165f3f0 7466
b5253831
DE
7467 /* SVR4 may need one register to preserve the static chain. */
7468 else if (current_function_needs_context)
7469 {
7470 /* Skip reg 31 which may contain the frame pointer. */
7471 if (first_reg > 30)
7472 first_reg = 30;
7473 }
7474 }
e165f3f0 7475
ee890fe2
SS
7476#if TARGET_MACHO
7477 if (flag_pic && current_function_uses_pic_offset_table &&
1db02437
FS
7478 (first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM))
7479 return RS6000_PIC_OFFSET_TABLE_REGNUM;
ee890fe2
SS
7480#endif
7481
9878760c
RK
7482 return first_reg;
7483}
7484
7485/* Similar, for FP regs. */
7486
7487int
7488first_fp_reg_to_save ()
7489{
7490 int first_reg;
7491
7492 /* Find lowest numbered live register. */
7493 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
7494 if (regs_ever_live[first_reg])
7495 break;
7496
7497 return first_reg;
7498}
00b960c7
AH
7499
7500/* Similar, for AltiVec regs. */
7501
7502static int
7503first_altivec_reg_to_save ()
7504{
7505 int i;
7506
7507 /* Stack frame remains as is unless we are in AltiVec ABI. */
7508 if (! TARGET_ALTIVEC_ABI)
7509 return LAST_ALTIVEC_REGNO + 1;
7510
7511 /* Find lowest numbered live register. */
7512 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
7513 if (regs_ever_live[i])
7514 break;
7515
7516 return i;
7517}
7518
7519/* Return a 32-bit mask of the AltiVec registers we need to set in
7520 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
7521 the 32-bit word is 0. */
7522
7523static unsigned int
7524compute_vrsave_mask ()
7525{
7526 unsigned int i, mask = 0;
7527
7528 /* First, find out if we use _any_ altivec registers. */
7529 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
7530 if (regs_ever_live[i])
7531 mask |= ALTIVEC_REG_BIT (i);
7532
7533 if (mask == 0)
7534 return mask;
7535
7536 /* Next, add all registers that are call-clobbered. We do this
7537 because post-reload register optimizers such as regrename_optimize
7538 may choose to use them. They never change the register class
7539 chosen by reload, so cannot create new uses of altivec registers
7540 if there were none before, so the early exit above is safe. */
7541 /* ??? Alternately, we could define HARD_REGNO_RENAME_OK to disallow
7542 altivec registers not saved in the mask, which might well make the
7543 adjustments below more effective in eliding the save/restore of
7544 VRSAVE in small functions. */
7545 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
7546 if (call_used_regs[i])
7547 mask |= ALTIVEC_REG_BIT (i);
7548
7549 /* Next, remove the argument registers from the set. These must
7550 be in the VRSAVE mask set by the caller, so we don't need to add
7551 them in again. More importantly, the mask we compute here is
7552 used to generate CLOBBERs in the set_vrsave insn, and we do not
7553 wish the argument registers to die. */
7554 for (i = cfun->args_info.vregno; i >= ALTIVEC_ARG_MIN_REG; --i)
7555 mask &= ~ALTIVEC_REG_BIT (i);
7556
7557 /* Similarly, remove the return value from the set. */
7558 {
7559 bool yes = false;
7560 diddle_return_value (is_altivec_return_reg, &yes);
7561 if (yes)
7562 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
7563 }
7564
7565 return mask;
7566}
7567
7568static void
7569is_altivec_return_reg (reg, xyes)
7570 rtx reg;
7571 void *xyes;
7572{
7573 bool *yes = (bool *) xyes;
7574 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
7575 *yes = true;
7576}
7577
4697a36c
MM
7578\f
7579/* Calculate the stack information for the current function. This is
7580 complicated by having two separate calling sequences, the AIX calling
7581 sequence and the V.4 calling sequence.
7582
592696dd 7583 AIX (and Darwin/Mac OS X) stack frames look like:
a260abc9 7584 32-bit 64-bit
4697a36c 7585 SP----> +---------------------------------------+
a260abc9 7586 | back chain to caller | 0 0
4697a36c 7587 +---------------------------------------+
a260abc9 7588 | saved CR | 4 8 (8-11)
4697a36c 7589 +---------------------------------------+
a260abc9 7590 | saved LR | 8 16
4697a36c 7591 +---------------------------------------+
a260abc9 7592 | reserved for compilers | 12 24
4697a36c 7593 +---------------------------------------+
a260abc9 7594 | reserved for binders | 16 32
4697a36c 7595 +---------------------------------------+
a260abc9 7596 | saved TOC pointer | 20 40
4697a36c 7597 +---------------------------------------+
a260abc9 7598 | Parameter save area (P) | 24 48
4697a36c 7599 +---------------------------------------+
a260abc9 7600 | Alloca space (A) | 24+P etc.
802a0058 7601 +---------------------------------------+
a7df97e6 7602 | Local variable space (L) | 24+P+A
4697a36c 7603 +---------------------------------------+
a7df97e6 7604 | Float/int conversion temporary (X) | 24+P+A+L
4697a36c 7605 +---------------------------------------+
00b960c7
AH
7606 | Save area for AltiVec registers (W) | 24+P+A+L+X
7607 +---------------------------------------+
7608 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
7609 +---------------------------------------+
7610 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
4697a36c 7611 +---------------------------------------+
00b960c7
AH
7612 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
7613 +---------------------------------------+
7614 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
4697a36c
MM
7615 +---------------------------------------+
7616 old SP->| back chain to caller's caller |
7617 +---------------------------------------+
7618
5376a30c
KR
7619 The required alignment for AIX configurations is two words (i.e., 8
7620 or 16 bytes).
7621
7622
4697a36c
MM
7623 V.4 stack frames look like:
7624
7625 SP----> +---------------------------------------+
7626 | back chain to caller | 0
7627 +---------------------------------------+
5eb387b8 7628 | caller's saved LR | 4
4697a36c
MM
7629 +---------------------------------------+
7630 | Parameter save area (P) | 8
7631 +---------------------------------------+
a7df97e6
MM
7632 | Alloca space (A) | 8+P
7633 +---------------------------------------+
7634 | Varargs save area (V) | 8+P+A
7635 +---------------------------------------+
7636 | Local variable space (L) | 8+P+A+V
7637 +---------------------------------------+
7638 | Float/int conversion temporary (X) | 8+P+A+V+L
4697a36c 7639 +---------------------------------------+
00b960c7
AH
7640 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
7641 +---------------------------------------+
7642 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
7643 +---------------------------------------+
7644 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
7645 +---------------------------------------+
7646 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
a7df97e6 7647 +---------------------------------------+
00b960c7 7648 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
a7df97e6 7649 +---------------------------------------+
00b960c7 7650 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
4697a36c
MM
7651 +---------------------------------------+
7652 old SP->| back chain to caller's caller |
7653 +---------------------------------------+
b6c9286a 7654
5376a30c
KR
7655 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
7656 given. (But note below and in sysv4.h that we require only 8 and
7657 may round up the size of our stack frame anyways. The historical
7658 reason is early versions of powerpc-linux which didn't properly
7659 align the stack at program startup. A happy side-effect is that
7660 -mno-eabi libraries can be used with -meabi programs.)
7661
5376a30c
KR
7662 The EABI configuration defaults to the V.4 layout, unless
7663 -mcall-aix is used, in which case the AIX layout is used. However,
7664 the stack alignment requirements may differ. If -mno-eabi is not
7665 given, the required stack alignment is 8 bytes; if -mno-eabi is
7666 given, the required alignment is 16 bytes. (But see V.4 comment
7667 above.) */
4697a36c 7668
61b2fbe7
MM
7669#ifndef ABI_STACK_BOUNDARY
7670#define ABI_STACK_BOUNDARY STACK_BOUNDARY
7671#endif
7672
4697a36c
MM
7673rs6000_stack_t *
7674rs6000_stack_info ()
7675{
7676 static rs6000_stack_t info, zero_info;
7677 rs6000_stack_t *info_ptr = &info;
9ebbca7d 7678 int reg_size = TARGET_POWERPC64 ? 8 : 4;
24d304eb 7679 enum rs6000_abi abi;
83720594 7680 int ehrd_size;
b6c9286a 7681 int total_raw_size;
4697a36c 7682
a4f6c312 7683 /* Zero all fields portably. */
4697a36c
MM
7684 info = zero_info;
7685
a4f6c312 7686 /* Select which calling sequence. */
b6c9286a 7687 info_ptr->abi = abi = DEFAULT_ABI;
9878760c 7688
a4f6c312 7689 /* Calculate which registers need to be saved & save area size. */
4697a36c 7690 info_ptr->first_gp_reg_save = first_reg_to_save ();
1db02437 7691 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
906fb125 7692 even if it currently looks like we won't. */
2bfcf297 7693 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
f607bc57
ZW
7694 || (flag_pic == 1 && abi == ABI_V4)
7695 || (flag_pic && abi == ABI_DARWIN))
1db02437
FS
7696 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
7697 info_ptr->gp_size = reg_size * (32 - RS6000_PIC_OFFSET_TABLE_REGNUM);
906fb125
GK
7698 else
7699 info_ptr->gp_size = reg_size * (32 - info_ptr->first_gp_reg_save);
4697a36c
MM
7700
7701 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
7702 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
7703
00b960c7
AH
7704 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
7705 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
7706 - info_ptr->first_altivec_reg_save);
7707
592696dd 7708 /* Does this function call anything? */
71f123ca
FS
7709 info_ptr->calls_p = (! current_function_is_leaf
7710 || cfun->machine->ra_needs_full_frame);
b6c9286a 7711
a4f6c312 7712 /* Determine if we need to save the link register. */
71f123ca 7713 if (rs6000_ra_ever_killed ()
70f4f91c 7714 || (DEFAULT_ABI == ABI_AIX && current_function_profile)
4697a36c
MM
7715#ifdef TARGET_RELOCATABLE
7716 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
7717#endif
7718 || (info_ptr->first_fp_reg_save != 64
7719 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
00b960c7 7720 || info_ptr->first_altivec_reg_save <= LAST_ALTIVEC_REGNO
24d304eb 7721 || (abi == ABI_V4 && current_function_calls_alloca)
a4f6c312
SS
7722 || (DEFAULT_ABI == ABI_DARWIN
7723 && flag_pic
7724 && current_function_uses_pic_offset_table)
4697a36c
MM
7725 || info_ptr->calls_p)
7726 {
7727 info_ptr->lr_save_p = 1;
9ebbca7d 7728 regs_ever_live[LINK_REGISTER_REGNUM] = 1;
4697a36c
MM
7729 }
7730
9ebbca7d
GK
7731 /* Determine if we need to save the condition code registers. */
7732 if (regs_ever_live[CR2_REGNO]
7733 || regs_ever_live[CR3_REGNO]
7734 || regs_ever_live[CR4_REGNO])
4697a36c
MM
7735 {
7736 info_ptr->cr_save_p = 1;
f607bc57 7737 if (abi == ABI_V4)
4697a36c
MM
7738 info_ptr->cr_size = reg_size;
7739 }
7740
83720594
RH
7741 /* If the current function calls __builtin_eh_return, then we need
7742 to allocate stack space for registers that will hold data for
7743 the exception handler. */
7744 if (current_function_calls_eh_return)
7745 {
7746 unsigned int i;
7747 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
7748 continue;
7749 ehrd_size = i * UNITS_PER_WORD;
7750 }
7751 else
7752 ehrd_size = 0;
7753
592696dd 7754 /* Determine various sizes. */
4697a36c
MM
7755 info_ptr->reg_size = reg_size;
7756 info_ptr->fixed_size = RS6000_SAVE_AREA;
7757 info_ptr->varargs_size = RS6000_VARARGS_AREA;
189e03e3 7758 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
a4f6c312
SS
7759 info_ptr->parm_size = RS6000_ALIGN (current_function_outgoing_args_size,
7760 8);
00b960c7
AH
7761
7762 if (TARGET_ALTIVEC_ABI)
7763 {
7764 info_ptr->vrsave_mask = compute_vrsave_mask ();
7765 info_ptr->vrsave_size = info_ptr->vrsave_mask ? 4 : 0;
7766 }
7767 else
7768 {
7769 info_ptr->vrsave_mask = 0;
7770 info_ptr->vrsave_size = 0;
7771 }
b6c9286a 7772
592696dd 7773 /* Calculate the offsets. */
24d304eb 7774 switch (abi)
4697a36c 7775 {
b6c9286a 7776 case ABI_NONE:
24d304eb 7777 default:
b6c9286a
MM
7778 abort ();
7779
7780 case ABI_AIX:
7781 case ABI_AIX_NODESC:
ee890fe2 7782 case ABI_DARWIN:
b6c9286a
MM
7783 info_ptr->fp_save_offset = - info_ptr->fp_size;
7784 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
00b960c7
AH
7785
7786 if (TARGET_ALTIVEC_ABI)
7787 {
7788 info_ptr->vrsave_save_offset
7789 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
7790
7791 /* Align stack so vector save area is on a quadword boundary. */
7792 if (info_ptr->altivec_size != 0)
7793 info_ptr->altivec_padding_size
7794 = 16 - (-info_ptr->vrsave_save_offset % 16);
7795 else
7796 info_ptr->altivec_padding_size = 0;
7797
7798 info_ptr->altivec_save_offset
7799 = info_ptr->vrsave_save_offset
7800 - info_ptr->altivec_padding_size
7801 - info_ptr->altivec_size;
7802
7803 /* Adjust for AltiVec case. */
7804 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
7805 }
7806 else
7807 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
a260abc9
DE
7808 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
7809 info_ptr->lr_save_offset = 2*reg_size;
24d304eb
RK
7810 break;
7811
7812 case ABI_V4:
b6c9286a
MM
7813 info_ptr->fp_save_offset = - info_ptr->fp_size;
7814 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
a7df97e6 7815 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
00b960c7
AH
7816
7817 if (TARGET_ALTIVEC_ABI)
7818 {
7819 info_ptr->vrsave_save_offset
7820 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
7821
7822 /* Align stack so vector save area is on a quadword boundary. */
7823 if (info_ptr->altivec_size != 0)
7824 info_ptr->altivec_padding_size
7825 = 16 - (-info_ptr->vrsave_save_offset % 16);
7826 else
7827 info_ptr->altivec_padding_size = 0;
7828
7829 info_ptr->altivec_save_offset
7830 = info_ptr->vrsave_save_offset
7831 - info_ptr->altivec_padding_size
7832 - info_ptr->altivec_size;
7833
7834 /* Adjust for AltiVec case. */
7835 info_ptr->toc_save_offset
7836 = info_ptr->altivec_save_offset - info_ptr->toc_size;
7837 }
7838 else
7839 info_ptr->toc_save_offset = info_ptr->cr_save_offset - info_ptr->toc_size;
83720594 7840 info_ptr->ehrd_offset = info_ptr->toc_save_offset - ehrd_size;
b6c9286a
MM
7841 info_ptr->lr_save_offset = reg_size;
7842 break;
4697a36c
MM
7843 }
7844
00b960c7
AH
7845 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
7846 + info_ptr->gp_size
7847 + info_ptr->altivec_size
7848 + info_ptr->altivec_padding_size
7849 + info_ptr->vrsave_size
7850 + ehrd_size
7851 + info_ptr->cr_size
7852 + info_ptr->lr_size
7853 + info_ptr->vrsave_size
7854 + info_ptr->toc_size,
7855 (TARGET_ALTIVEC_ABI || ABI_DARWIN)
7856 ? 16 : 8);
7857
ff381587
MM
7858 total_raw_size = (info_ptr->vars_size
7859 + info_ptr->parm_size
ff381587
MM
7860 + info_ptr->save_size
7861 + info_ptr->varargs_size
7862 + info_ptr->fixed_size);
7863
a4f6c312
SS
7864 info_ptr->total_size =
7865 RS6000_ALIGN (total_raw_size, ABI_STACK_BOUNDARY / BITS_PER_UNIT);
ff381587
MM
7866
7867 /* Determine if we need to allocate any stack frame:
7868
a4f6c312
SS
7869 For AIX we need to push the stack if a frame pointer is needed
7870 (because the stack might be dynamically adjusted), if we are
7871 debugging, if we make calls, or if the sum of fp_save, gp_save,
7872 and local variables are more than the space needed to save all
7873 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
7874 + 18*8 = 288 (GPR13 reserved).
ff381587 7875
a4f6c312
SS
7876 For V.4 we don't have the stack cushion that AIX uses, but assume
7877 that the debugger can handle stackless frames. */
ff381587
MM
7878
7879 if (info_ptr->calls_p)
7880 info_ptr->push_p = 1;
7881
f607bc57 7882 else if (abi == ABI_V4)
e72247f4 7883 info_ptr->push_p = total_raw_size > info_ptr->fixed_size;
ff381587
MM
7884
7885 else
7886 info_ptr->push_p = (frame_pointer_needed
ee890fe2 7887 || (abi != ABI_DARWIN && write_symbols != NO_DEBUG)
ff381587 7888 || ((total_raw_size - info_ptr->fixed_size)
bfc79d3b 7889 > (TARGET_32BIT ? 220 : 288)));
ff381587 7890
a4f6c312 7891 /* Zero offsets if we're not saving those registers. */
8dda1a21 7892 if (info_ptr->fp_size == 0)
4697a36c
MM
7893 info_ptr->fp_save_offset = 0;
7894
8dda1a21 7895 if (info_ptr->gp_size == 0)
4697a36c
MM
7896 info_ptr->gp_save_offset = 0;
7897
00b960c7
AH
7898 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
7899 info_ptr->altivec_save_offset = 0;
7900
7901 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
7902 info_ptr->vrsave_save_offset = 0;
7903
c81fc13e 7904 if (! info_ptr->lr_save_p)
4697a36c
MM
7905 info_ptr->lr_save_offset = 0;
7906
c81fc13e 7907 if (! info_ptr->cr_save_p)
4697a36c
MM
7908 info_ptr->cr_save_offset = 0;
7909
c81fc13e 7910 if (! info_ptr->toc_save_p)
b6c9286a
MM
7911 info_ptr->toc_save_offset = 0;
7912
4697a36c
MM
7913 return info_ptr;
7914}
7915
7916void
7917debug_stack_info (info)
7918 rs6000_stack_t *info;
9878760c 7919{
d330fd93 7920 const char *abi_string;
24d304eb 7921
c81fc13e 7922 if (! info)
4697a36c
MM
7923 info = rs6000_stack_info ();
7924
7925 fprintf (stderr, "\nStack information for function %s:\n",
7926 ((current_function_decl && DECL_NAME (current_function_decl))
7927 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
7928 : "<unknown>"));
7929
24d304eb
RK
7930 switch (info->abi)
7931 {
b6c9286a
MM
7932 default: abi_string = "Unknown"; break;
7933 case ABI_NONE: abi_string = "NONE"; break;
f607bc57 7934 case ABI_AIX:
b6c9286a 7935 case ABI_AIX_NODESC: abi_string = "AIX"; break;
ee890fe2 7936 case ABI_DARWIN: abi_string = "Darwin"; break;
b6c9286a 7937 case ABI_V4: abi_string = "V.4"; break;
24d304eb
RK
7938 }
7939
7940 fprintf (stderr, "\tABI = %5s\n", abi_string);
7941
00b960c7
AH
7942 if (TARGET_ALTIVEC_ABI)
7943 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
7944
4697a36c
MM
7945 if (info->first_gp_reg_save != 32)
7946 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
7947
7948 if (info->first_fp_reg_save != 64)
7949 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
9878760c 7950
00b960c7
AH
7951 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
7952 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
7953 info->first_altivec_reg_save);
7954
4697a36c
MM
7955 if (info->lr_save_p)
7956 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
9878760c 7957
4697a36c
MM
7958 if (info->cr_save_p)
7959 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
7960
b6c9286a
MM
7961 if (info->toc_save_p)
7962 fprintf (stderr, "\ttoc_save_p = %5d\n", info->toc_save_p);
7963
00b960c7
AH
7964 if (info->vrsave_mask)
7965 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
7966
4697a36c
MM
7967 if (info->push_p)
7968 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
7969
7970 if (info->calls_p)
7971 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
7972
4697a36c
MM
7973 if (info->gp_save_offset)
7974 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
7975
7976 if (info->fp_save_offset)
7977 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
7978
00b960c7
AH
7979 if (info->altivec_save_offset)
7980 fprintf (stderr, "\taltivec_save_offset = %5d\n",
7981 info->altivec_save_offset);
7982
7983 if (info->vrsave_save_offset)
7984 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
7985 info->vrsave_save_offset);
7986
4697a36c
MM
7987 if (info->lr_save_offset)
7988 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
7989
7990 if (info->cr_save_offset)
7991 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
7992
b6c9286a
MM
7993 if (info->toc_save_offset)
7994 fprintf (stderr, "\ttoc_save_offset = %5d\n", info->toc_save_offset);
7995
4697a36c
MM
7996 if (info->varargs_save_offset)
7997 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
7998
7999 if (info->total_size)
8000 fprintf (stderr, "\ttotal_size = %5d\n", info->total_size);
8001
8002 if (info->varargs_size)
8003 fprintf (stderr, "\tvarargs_size = %5d\n", info->varargs_size);
8004
8005 if (info->vars_size)
8006 fprintf (stderr, "\tvars_size = %5d\n", info->vars_size);
8007
8008 if (info->parm_size)
8009 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
8010
8011 if (info->fixed_size)
8012 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
8013
8014 if (info->gp_size)
8015 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
8016
8017 if (info->fp_size)
8018 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
8019
00b960c7
AH
8020 if (info->altivec_size)
8021 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
8022
8023 if (info->vrsave_size)
8024 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
8025
8026 if (info->altivec_padding_size)
8027 fprintf (stderr, "\taltivec_padding_size= %5d\n",
8028 info->altivec_padding_size);
8029
a4f6c312 8030 if (info->lr_size)
ed947a96 8031 fprintf (stderr, "\tlr_size = %5d\n", info->lr_size);
b6c9286a 8032
4697a36c
MM
8033 if (info->cr_size)
8034 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
8035
a4f6c312 8036 if (info->toc_size)
b6c9286a
MM
8037 fprintf (stderr, "\ttoc_size = %5d\n", info->toc_size);
8038
4697a36c
MM
8039 if (info->save_size)
8040 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
8041
8042 if (info->reg_size != 4)
8043 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
8044
8045 fprintf (stderr, "\n");
9878760c 8046}
71f123ca
FS
8047
8048rtx
8049rs6000_return_addr (count, frame)
8050 int count;
8051 rtx frame;
8052{
a4f6c312
SS
8053 /* Currently we don't optimize very well between prolog and body
8054 code and for PIC code the code can be actually quite bad, so
8055 don't try to be too clever here. */
f585a356 8056 if (count != 0 || flag_pic != 0)
71f123ca
FS
8057 {
8058 cfun->machine->ra_needs_full_frame = 1;
8ac61af7
RK
8059
8060 return
8061 gen_rtx_MEM
8062 (Pmode,
8063 memory_address
8064 (Pmode,
8065 plus_constant (copy_to_reg
8066 (gen_rtx_MEM (Pmode,
8067 memory_address (Pmode, frame))),
8068 RETURN_ADDRESS_OFFSET)));
71f123ca
FS
8069 }
8070
9e2f7ec7 8071 return get_hard_reg_initial_val (Pmode, LINK_REGISTER_REGNUM);
71f123ca
FS
8072}
8073
8074static int
8075rs6000_ra_ever_killed ()
8076{
8077 rtx top;
8078
8079#ifdef ASM_OUTPUT_MI_THUNK
8080 if (current_function_is_thunk)
8081 return 0;
8082#endif
9e2f7ec7
DD
8083 if (!has_hard_reg_initial_val (Pmode, LINK_REGISTER_REGNUM)
8084 || cfun->machine->ra_needs_full_frame)
71f123ca
FS
8085 return regs_ever_live[LINK_REGISTER_REGNUM];
8086
8087 push_topmost_sequence ();
8088 top = get_insns ();
8089 pop_topmost_sequence ();
8090
8091 return reg_set_between_p (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
8092 top, NULL_RTX);
8093}
4697a36c 8094\f
8cd8f856
GK
8095/* Add a REG_MAYBE_DEAD note to the insn. */
8096static void
8097rs6000_maybe_dead (insn)
8098 rtx insn;
8099{
8100 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,
8101 const0_rtx,
8102 REG_NOTES (insn));
8103}
8104
9ebbca7d 8105/* Emit instructions needed to load the TOC register.
c7ca610e 8106 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
9ebbca7d 8107 a constant pool; or for SVR4 -fpic. */
c7ca610e
RK
8108
8109void
9ebbca7d
GK
8110rs6000_emit_load_toc_table (fromprolog)
8111 int fromprolog;
c7ca610e 8112{
9ebbca7d 8113 rtx dest;
1db02437 8114 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
c7ca610e 8115
2bfcf297 8116 if (TARGET_ELF && DEFAULT_ABI != ABI_AIX)
c7ca610e 8117 {
f607bc57 8118 if (DEFAULT_ABI == ABI_V4 && flag_pic == 1)
38c1f2d7 8119 {
9ebbca7d
GK
8120 rtx temp = (fromprolog
8121 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
8122 : gen_reg_rtx (Pmode));
2bfcf297 8123 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_pic_si (temp)));
8cd8f856 8124 rs6000_maybe_dead (emit_move_insn (dest, temp));
38c1f2d7 8125 }
9ebbca7d
GK
8126 else if (flag_pic == 2)
8127 {
8128 char buf[30];
8129 rtx tempLR = (fromprolog
8130 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
8131 : gen_reg_rtx (Pmode));
8132 rtx temp0 = (fromprolog
8133 ? gen_rtx_REG (Pmode, 0)
8134 : gen_reg_rtx (Pmode));
8135 rtx symF;
8136
8137 /* possibly create the toc section */
8138 if (! toc_initialized)
8139 {
8140 toc_section ();
8141 function_section (current_function_decl);
8142 }
8143
8144 if (fromprolog)
8145 {
8146 rtx symL;
8147
8148 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
a8a05998 8149 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
38c1f2d7 8150
9ebbca7d 8151 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
a8a05998 8152 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
38c1f2d7 8153
8cd8f856
GK
8154 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1 (tempLR,
8155 symF)));
8156 rs6000_maybe_dead (emit_move_insn (dest, tempLR));
8157 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest,
8158 symL,
8159 symF)));
9ebbca7d
GK
8160 }
8161 else
8162 {
8163 rtx tocsym;
8164 static int reload_toc_labelno = 0;
8165
b999aaeb 8166 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
38c1f2d7 8167
9ebbca7d 8168 ASM_GENERATE_INTERNAL_LABEL (buf, "LCG", reload_toc_labelno++);
a8a05998 8169 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9ebbca7d 8170
8cd8f856
GK
8171 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1b (tempLR,
8172 symF,
8173 tocsym)));
8174 rs6000_maybe_dead (emit_move_insn (dest, tempLR));
8175 rs6000_maybe_dead (emit_move_insn (temp0,
8176 gen_rtx_MEM (Pmode, dest)));
9ebbca7d 8177 }
8cd8f856 8178 rs6000_maybe_dead (emit_insn (gen_addsi3 (dest, temp0, dest)));
9ebbca7d
GK
8179 }
8180 else if (flag_pic == 0 && TARGET_MINIMAL_TOC)
8181 {
8182 /* This is for AIX code running in non-PIC ELF. */
8183 char buf[30];
8184 rtx realsym;
38c1f2d7 8185 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
a8a05998 8186 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9ebbca7d 8187
8cd8f856
GK
8188 rs6000_maybe_dead (emit_insn (gen_elf_high (dest, realsym)));
8189 rs6000_maybe_dead (emit_insn (gen_elf_low (dest, dest, realsym)));
9ebbca7d
GK
8190 }
8191 else
a4f6c312 8192 abort ();
9ebbca7d
GK
8193 }
8194 else
8195 {
8196 if (TARGET_32BIT)
8cd8f856 8197 rs6000_maybe_dead (emit_insn (gen_load_toc_aix_si (dest)));
9ebbca7d 8198 else
8cd8f856 8199 rs6000_maybe_dead (emit_insn (gen_load_toc_aix_di (dest)));
9ebbca7d
GK
8200 }
8201}
8202
8203int
8204get_TOC_alias_set ()
8205{
8206 static int set = -1;
8207 if (set == -1)
8208 set = new_alias_set ();
8209 return set;
8210}
8211
8212/* This retuns nonzero if the current function uses the TOC. This is
8213 determined by the presence of (unspec ... 7), which is generated by
8214 the various load_toc_* patterns. */
a4f6c312 8215
9ebbca7d
GK
8216int
8217uses_TOC ()
8218{
8219 rtx insn;
38c1f2d7 8220
9ebbca7d 8221 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2c3c49de 8222 if (INSN_P (insn))
9ebbca7d
GK
8223 {
8224 rtx pat = PATTERN (insn);
8225 int i;
8226
8cd8f856 8227 if (GET_CODE (pat) == PARALLEL)
9ebbca7d
GK
8228 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
8229 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == UNSPEC
8230 && XINT (XVECEXP (PATTERN (insn), 0, i), 1) == 7)
8231 return 1;
38c1f2d7 8232 }
9ebbca7d
GK
8233 return 0;
8234}
38c1f2d7 8235
9ebbca7d 8236rtx
a4f6c312 8237create_TOC_reference (symbol)
9ebbca7d
GK
8238 rtx symbol;
8239{
a8a05998
ZW
8240 return gen_rtx_PLUS (Pmode,
8241 gen_rtx_REG (Pmode, TOC_REGISTER),
8242 gen_rtx_CONST (Pmode,
8243 gen_rtx_MINUS (Pmode, symbol,
b999aaeb 8244 gen_rtx_SYMBOL_REF (Pmode, toc_label_name))));
9ebbca7d 8245}
38c1f2d7 8246
9ebbca7d
GK
8247#if TARGET_AIX
8248/* __throw will restore its own return address to be the same as the
8249 return address of the function that the throw is being made to.
8250 This is unfortunate, because we want to check the original
8251 return address to see if we need to restore the TOC.
8252 So we have to squirrel it away here.
8253 This is used only in compiling __throw and __rethrow.
c7ca610e 8254
9ebbca7d
GK
8255 Most of this code should be removed by CSE. */
8256static rtx insn_after_throw;
c7ca610e 8257
a4f6c312 8258/* This does the saving... */
9ebbca7d
GK
8259void
8260rs6000_aix_emit_builtin_unwind_init ()
8261{
8262 rtx mem;
8263 rtx stack_top = gen_reg_rtx (Pmode);
8264 rtx opcode_addr = gen_reg_rtx (Pmode);
8265
8266 insn_after_throw = gen_reg_rtx (SImode);
8267
8268 mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
8269 emit_move_insn (stack_top, mem);
8270
8271 mem = gen_rtx_MEM (Pmode,
8272 gen_rtx_PLUS (Pmode, stack_top,
8273 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
8274 emit_move_insn (opcode_addr, mem);
8275 emit_move_insn (insn_after_throw, gen_rtx_MEM (SImode, opcode_addr));
c7ca610e
RK
8276}
8277
a4f6c312
SS
8278/* Emit insns to _restore_ the TOC register, at runtime (specifically
8279 in _eh.o). Only used on AIX.
9ebbca7d
GK
8280
8281 The idea is that on AIX, function calls look like this:
8282 bl somefunction-trampoline
8283 lwz r2,20(sp)
8284
a4f6c312 8285 and later,
9ebbca7d
GK
8286 somefunction-trampoline:
8287 stw r2,20(sp)
8288 ... load function address in the count register ...
8289 bctr
8290 or like this, if the linker determines that this is not a cross-module call
8291 and so the TOC need not be restored:
8292 bl somefunction
8293 nop
8294 or like this, if the compiler could determine that this is not a
8295 cross-module call:
8296 bl somefunction
8297 now, the tricky bit here is that register 2 is saved and restored
8298 by the _linker_, so we can't readily generate debugging information
8299 for it. So we need to go back up the call chain looking at the
8300 insns at return addresses to see which calls saved the TOC register
8301 and so see where it gets restored from.
8302
8303 Oh, and all this gets done in RTL inside the eh_epilogue pattern,
8304 just before the actual epilogue.
8305
8306 On the bright side, this incurs no space or time overhead unless an
8307 exception is thrown, except for the extra code in libgcc.a.
8308
8309 The parameter STACKSIZE is a register containing (at runtime)
8310 the amount to be popped off the stack in addition to the stack frame
8311 of this routine (which will be __throw or __rethrow, and so is
8312 guaranteed to have a stack frame). */
a4f6c312 8313
9ebbca7d
GK
8314void
8315rs6000_emit_eh_toc_restore (stacksize)
8316 rtx stacksize;
8317{
8318 rtx top_of_stack;
8319 rtx bottom_of_stack = gen_reg_rtx (Pmode);
8320 rtx tocompare = gen_reg_rtx (SImode);
8321 rtx opcode = gen_reg_rtx (SImode);
8322 rtx opcode_addr = gen_reg_rtx (Pmode);
8323 rtx mem;
8324 rtx loop_start = gen_label_rtx ();
8325 rtx no_toc_restore_needed = gen_label_rtx ();
8326 rtx loop_exit = gen_label_rtx ();
8327
8328 mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
ba4828e0 8329 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
8330 emit_move_insn (bottom_of_stack, mem);
8331
8332 top_of_stack = expand_binop (Pmode, add_optab,
8333 bottom_of_stack, stacksize,
8334 NULL_RTX, 1, OPTAB_WIDEN);
8335
2496c7bd
LB
8336 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
8337 : 0xE8410028, SImode));
9ebbca7d
GK
8338
8339 if (insn_after_throw == NULL_RTX)
a4f6c312 8340 abort ();
9ebbca7d
GK
8341 emit_move_insn (opcode, insn_after_throw);
8342
6496a589 8343 emit_note (NULL, NOTE_INSN_LOOP_BEG);
9ebbca7d
GK
8344 emit_label (loop_start);
8345
8346 do_compare_rtx_and_jump (opcode, tocompare, NE, 1,
06f4e019 8347 SImode, NULL_RTX, NULL_RTX,
9ebbca7d
GK
8348 no_toc_restore_needed);
8349
8350 mem = gen_rtx_MEM (Pmode,
8351 gen_rtx_PLUS (Pmode, bottom_of_stack,
8352 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
8353 emit_move_insn (gen_rtx_REG (Pmode, 2), mem);
8354
8355 emit_label (no_toc_restore_needed);
8356 do_compare_rtx_and_jump (top_of_stack, bottom_of_stack, EQ, 1,
06f4e019 8357 Pmode, NULL_RTX, NULL_RTX,
9ebbca7d
GK
8358 loop_exit);
8359
8360 mem = gen_rtx_MEM (Pmode, bottom_of_stack);
ba4828e0 8361 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
8362 emit_move_insn (bottom_of_stack, mem);
8363
8364 mem = gen_rtx_MEM (Pmode,
8365 gen_rtx_PLUS (Pmode, bottom_of_stack,
8366 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
8367 emit_move_insn (opcode_addr, mem);
8368 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
8369
6496a589 8370 emit_note (NULL, NOTE_INSN_LOOP_CONT);
9ebbca7d 8371 emit_jump (loop_start);
6496a589 8372 emit_note (NULL, NOTE_INSN_LOOP_END);
9ebbca7d
GK
8373 emit_label (loop_exit);
8374}
8375#endif /* TARGET_AIX */
38c1f2d7 8376\f
ba4828e0
RK
8377/* This ties together stack memory (MEM with an alias set of
8378 rs6000_sr_alias_set) and the change to the stack pointer. */
8379
9ebbca7d
GK
8380static void
8381rs6000_emit_stack_tie ()
8382{
ba4828e0
RK
8383 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
8384
8385 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
8386 emit_insn (gen_stack_tie (mem));
8387}
38c1f2d7 8388
9ebbca7d
GK
8389/* Emit the correct code for allocating stack space, as insns.
8390 If COPY_R12, make sure a copy of the old frame is left in r12.
8391 The generated code may use hard register 0 as a temporary. */
8392
8393static void
8394rs6000_emit_allocate_stack (size, copy_r12)
8395 HOST_WIDE_INT size;
38c1f2d7
MM
8396 int copy_r12;
8397{
9ebbca7d
GK
8398 rtx insn;
8399 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
8400 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
8401 rtx todec = GEN_INT (-size);
a157febd
GK
8402
8403 if (current_function_limit_stack)
8404 {
8405 if (REG_P (stack_limit_rtx)
8406 && REGNO (stack_limit_rtx) > 1
8407 && REGNO (stack_limit_rtx) <= 31)
8408 {
9ebbca7d
GK
8409 emit_insn (Pmode == SImode
8410 ? gen_addsi3 (tmp_reg,
8411 stack_limit_rtx,
8412 GEN_INT (size))
8413 : gen_adddi3 (tmp_reg,
8414 stack_limit_rtx,
8415 GEN_INT (size)));
8416
8417 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
8418 const0_rtx));
a157febd
GK
8419 }
8420 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
9ebbca7d 8421 && TARGET_32BIT
f607bc57 8422 && DEFAULT_ABI == ABI_V4)
a157febd 8423 {
9ebbca7d
GK
8424 rtx toload = gen_rtx_CONST (VOIDmode,
8425 gen_rtx_PLUS (Pmode,
8426 stack_limit_rtx,
8427 GEN_INT (size)));
8428
8429 emit_insn (gen_elf_high (tmp_reg, toload));
8430 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
8431 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
8432 const0_rtx));
a157febd
GK
8433 }
8434 else
8435 warning ("stack limit expression is not supported");
8436 }
8437
9ebbca7d
GK
8438 if (copy_r12 || ! TARGET_UPDATE)
8439 emit_move_insn (gen_rtx_REG (Pmode, 12), stack_reg);
8440
38c1f2d7
MM
8441 if (TARGET_UPDATE)
8442 {
9ebbca7d 8443 if (size > 32767)
38c1f2d7 8444 {
9ebbca7d
GK
8445 /* Need a note here so that try_split doesn't get confused. */
8446 if (get_last_insn() == NULL_RTX)
8447 emit_note (0, NOTE_INSN_DELETED);
8448 insn = emit_move_insn (tmp_reg, todec);
8449 try_split (PATTERN (insn), insn, 0);
8450 todec = tmp_reg;
38c1f2d7 8451 }
9ebbca7d
GK
8452
8453 if (Pmode == SImode)
8454 insn = emit_insn (gen_movsi_update (stack_reg, stack_reg,
8455 todec, stack_reg));
8456 else
8457 insn = emit_insn (gen_movdi_update (stack_reg, stack_reg,
8458 todec, stack_reg));
38c1f2d7
MM
8459 }
8460 else
8461 {
9ebbca7d
GK
8462 if (Pmode == SImode)
8463 insn = emit_insn (gen_addsi3 (stack_reg, stack_reg, todec));
38c1f2d7 8464 else
9ebbca7d
GK
8465 insn = emit_insn (gen_adddi3 (stack_reg, stack_reg, todec));
8466 emit_move_insn (gen_rtx_MEM (Pmode, stack_reg),
8467 gen_rtx_REG (Pmode, 12));
8468 }
8469
8470 RTX_FRAME_RELATED_P (insn) = 1;
8471 REG_NOTES (insn) =
8472 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
8473 gen_rtx_SET (VOIDmode, stack_reg,
8474 gen_rtx_PLUS (Pmode, stack_reg,
8475 GEN_INT (-size))),
8476 REG_NOTES (insn));
8477}
8478
9aa86737
AH
8479/* Add a RTX_FRAME_RELATED note so that dwarf2out_frame_debug_expr
8480 knows that:
8481
8482 (mem (plus (blah) (regXX)))
8483
8484 is really:
8485
8486 (mem (plus (blah) (const VALUE_OF_REGXX))). */
8487
8488static void
8489altivec_frame_fixup (insn, reg, val)
8490 rtx insn, reg;
8491 HOST_WIDE_INT val;
8492{
8493 rtx real;
8494
8495 real = copy_rtx (PATTERN (insn));
8496
8497 real = replace_rtx (real, reg, GEN_INT (val));
8498
8499 RTX_FRAME_RELATED_P (insn) = 1;
8500 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
8501 real,
8502 REG_NOTES (insn));
8503}
8504
a4f6c312
SS
8505/* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
8506 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
8507 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
8508 deduce these equivalences by itself so it wasn't necessary to hold
8509 its hand so much. */
9ebbca7d
GK
8510
8511static void
8512rs6000_frame_related (insn, reg, val, reg2, rreg)
8513 rtx insn;
8514 rtx reg;
8515 HOST_WIDE_INT val;
8516 rtx reg2;
8517 rtx rreg;
8518{
8519 rtx real, temp;
8520
8521 real = copy_rtx (PATTERN (insn));
8522
8523 real = replace_rtx (real, reg,
8524 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
8525 STACK_POINTER_REGNUM),
8526 GEN_INT (val)));
8527
8528 /* We expect that 'real' is either a SET or a PARALLEL containing
8529 SETs (and possibly other stuff). In a PARALLEL, all the SETs
8530 are important so they all have to be marked RTX_FRAME_RELATED_P. */
8531
8532 if (GET_CODE (real) == SET)
8533 {
8534 rtx set = real;
8535
8536 temp = simplify_rtx (SET_SRC (set));
8537 if (temp)
8538 SET_SRC (set) = temp;
8539 temp = simplify_rtx (SET_DEST (set));
8540 if (temp)
8541 SET_DEST (set) = temp;
8542 if (GET_CODE (SET_DEST (set)) == MEM)
38c1f2d7 8543 {
9ebbca7d
GK
8544 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
8545 if (temp)
8546 XEXP (SET_DEST (set), 0) = temp;
38c1f2d7 8547 }
38c1f2d7 8548 }
9ebbca7d
GK
8549 else if (GET_CODE (real) == PARALLEL)
8550 {
8551 int i;
8552 for (i = 0; i < XVECLEN (real, 0); i++)
8553 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
8554 {
8555 rtx set = XVECEXP (real, 0, i);
8556
8557 temp = simplify_rtx (SET_SRC (set));
8558 if (temp)
8559 SET_SRC (set) = temp;
8560 temp = simplify_rtx (SET_DEST (set));
8561 if (temp)
8562 SET_DEST (set) = temp;
8563 if (GET_CODE (SET_DEST (set)) == MEM)
8564 {
8565 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
8566 if (temp)
8567 XEXP (SET_DEST (set), 0) = temp;
8568 }
8569 RTX_FRAME_RELATED_P (set) = 1;
8570 }
8571 }
8572 else
a4f6c312 8573 abort ();
9ebbca7d
GK
8574
8575 if (reg2 != NULL_RTX)
8576 real = replace_rtx (real, reg2, rreg);
8577
8578 RTX_FRAME_RELATED_P (insn) = 1;
8579 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
8580 real,
8581 REG_NOTES (insn));
38c1f2d7
MM
8582}
8583
00b960c7
AH
8584/* Returns an insn that has a vrsave set operation with the
8585 appropriate CLOBBERs. */
8586
8587static rtx
9aa86737 8588generate_set_vrsave (reg, info, epiloguep)
00b960c7
AH
8589 rtx reg;
8590 rs6000_stack_t *info;
9aa86737 8591 int epiloguep;
00b960c7
AH
8592{
8593 int nclobs, i;
8594 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
a004eb82 8595 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
00b960c7 8596
a004eb82
AH
8597 clobs[0]
8598 = gen_rtx_SET (VOIDmode,
8599 vrsave,
8600 gen_rtx_UNSPEC_VOLATILE (SImode,
8601 gen_rtvec (2, reg, vrsave),
8602 30));
00b960c7
AH
8603
8604 nclobs = 1;
8605
9aa86737
AH
8606 /* We need to clobber the registers in the mask so the scheduler
8607 does not move sets to VRSAVE before sets of AltiVec registers.
8608
8609 However, if the function receives nonlocal gotos, reload will set
8610 all call saved registers live. We will end up with:
8611
8612 (set (reg 999) (mem))
8613 (parallel [ (set (reg vrsave) (unspec blah))
8614 (clobber (reg 999))])
8615
8616 The clobber will cause the store into reg 999 to be dead, and
8617 flow will attempt to delete an epilogue insn. In this case, we
8618 need an unspec use/set of the register. */
00b960c7
AH
8619
8620 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
8621 if (info->vrsave_mask != 0 && ALTIVEC_REG_BIT (i) != 0)
9aa86737
AH
8622 {
8623 if (!epiloguep || call_used_regs [i])
8624 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
8625 gen_rtx_REG (V4SImode, i));
8626 else
8627 {
8628 rtx reg = gen_rtx_REG (V4SImode, i);
9aa86737
AH
8629
8630 clobs[nclobs++]
a004eb82
AH
8631 = gen_rtx_SET (VOIDmode,
8632 reg,
8633 gen_rtx_UNSPEC (V4SImode,
8634 gen_rtvec (1, reg), 27));
9aa86737
AH
8635 }
8636 }
00b960c7
AH
8637
8638 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
8639
8640 for (i = 0; i < nclobs; ++i)
8641 XVECEXP (insn, 0, i) = clobs[i];
8642
8643 return insn;
8644}
8645
9ebbca7d
GK
8646/* Emit function prologue as insns. */
8647
9878760c 8648void
83720594 8649rs6000_emit_prologue ()
9878760c 8650{
4697a36c 8651 rs6000_stack_t *info = rs6000_stack_info ();
9ebbca7d
GK
8652 enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
8653 int reg_size = TARGET_POWERPC64 ? 8 : 4;
8654 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
8655 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
8656 rtx frame_reg_rtx = sp_reg_rtx;
8657 rtx cr_save_rtx = NULL;
8658 rtx insn;
8659 int saving_FPRs_inline;
8660 int using_store_multiple;
8661 HOST_WIDE_INT sp_offset = 0;
8662
8663 using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
8664 && info->first_gp_reg_save < 31);
8665 saving_FPRs_inline = (info->first_fp_reg_save == 64
8666 || FP_SAVE_INLINE (info->first_fp_reg_save));
8667
8668 /* For V.4, update stack before we do any saving and set back pointer. */
f607bc57 8669 if (info->push_p && DEFAULT_ABI == ABI_V4)
9ebbca7d
GK
8670 {
8671 if (info->total_size < 32767)
8672 sp_offset = info->total_size;
8673 else
8674 frame_reg_rtx = frame_ptr_rtx;
8675 rs6000_emit_allocate_stack (info->total_size,
8676 (frame_reg_rtx != sp_reg_rtx
8677 && (info->cr_save_p
8678 || info->lr_save_p
8679 || info->first_fp_reg_save < 64
8680 || info->first_gp_reg_save < 32
8681 )));
8682 if (frame_reg_rtx != sp_reg_rtx)
8683 rs6000_emit_stack_tie ();
8684 }
8685
9aa86737
AH
8686 /* Save AltiVec registers if needed. */
8687 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
8688 {
8689 int i;
8690
8691 /* There should be a non inline version of this, for when we
8692 are saving lots of vector registers. */
8693 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
8694 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
8695 {
8696 rtx areg, savereg, mem;
8697 int offset;
8698
8699 offset = info->altivec_save_offset + sp_offset
8700 + 16 * (i - info->first_altivec_reg_save);
8701
8702 savereg = gen_rtx_REG (V4SImode, i);
8703
8704 areg = gen_rtx_REG (Pmode, 0);
8705 emit_move_insn (areg, GEN_INT (offset));
8706
8707 /* AltiVec addressing mode is [reg+reg]. */
8708 mem = gen_rtx_MEM (V4SImode,
8709 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
8710
8711 set_mem_alias_set (mem, rs6000_sr_alias_set);
8712
8713 insn = emit_move_insn (mem, savereg);
8714
8715 altivec_frame_fixup (insn, areg, offset);
8716 }
8717 }
8718
8719 /* VRSAVE is a bit vector representing which AltiVec registers
8720 are used. The OS uses this to determine which vector
8721 registers to save on a context switch. We need to save
8722 VRSAVE on the stack frame, add whatever AltiVec registers we
8723 used in this function, and do the corresponding magic in the
8724 epilogue. */
8725
8726 if (TARGET_ALTIVEC && info->vrsave_mask != 0)
8727 {
a004eb82 8728 rtx reg, mem, vrsave;
9aa86737
AH
8729 int offset;
8730
8731 /* Get VRSAVE onto a GPR. */
8732 reg = gen_rtx_REG (SImode, 12);
a004eb82 8733 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
b188f760
AH
8734 if (TARGET_MACHO)
8735 emit_insn (gen_get_vrsave_internal (reg));
8736 else
8737 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
9aa86737
AH
8738
8739 /* Save VRSAVE. */
8740 offset = info->vrsave_save_offset + sp_offset;
8741 mem
8742 = gen_rtx_MEM (SImode,
8743 gen_rtx_PLUS (Pmode, frame_reg_rtx, GEN_INT (offset)));
8744 set_mem_alias_set (mem, rs6000_sr_alias_set);
8745 insn = emit_move_insn (mem, reg);
8746
8747 /* Include the registers in the mask. */
8748 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
8749
8750 insn = emit_insn (generate_set_vrsave (reg, info, 0));
8751 }
8752
9ebbca7d
GK
8753 /* If we use the link register, get it into r0. */
8754 if (info->lr_save_p)
71f123ca 8755 emit_move_insn (gen_rtx_REG (Pmode, 0),
9ebbca7d
GK
8756 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
8757
8758 /* If we need to save CR, put it into r12. */
8759 if (info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
8760 {
8761 cr_save_rtx = gen_rtx_REG (SImode, 12);
8762 emit_insn (gen_movesi_from_cr (cr_save_rtx));
8763 }
8764
a4f6c312
SS
8765 /* Do any required saving of fpr's. If only one or two to save, do
8766 it ourselves. Otherwise, call function. */
9ebbca7d
GK
8767 if (saving_FPRs_inline)
8768 {
8769 int i;
8770 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
8771 if ((regs_ever_live[info->first_fp_reg_save+i]
8772 && ! call_used_regs[info->first_fp_reg_save+i]))
8773 {
8774 rtx addr, reg, mem;
8775 reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
8776 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
8777 GEN_INT (info->fp_save_offset
8778 + sp_offset
a4f6c312 8779 + 8 * i));
9ebbca7d 8780 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 8781 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
8782
8783 insn = emit_move_insn (mem, reg);
8784 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
8785 NULL_RTX, NULL_RTX);
8786 }
8787 }
8788 else if (info->first_fp_reg_save != 64)
8789 {
8790 int i;
8791 char rname[30];
520a57c8 8792 const char *alloc_rname;
9ebbca7d
GK
8793 rtvec p;
8794 p = rtvec_alloc (2 + 64 - info->first_fp_reg_save);
8795
8796 RTVEC_ELT (p, 0) = gen_rtx_CLOBBER (VOIDmode,
8797 gen_rtx_REG (Pmode,
8798 LINK_REGISTER_REGNUM));
8799 sprintf (rname, "%s%d%s", SAVE_FP_PREFIX,
8800 info->first_fp_reg_save - 32, SAVE_FP_SUFFIX);
a8a05998 8801 alloc_rname = ggc_strdup (rname);
9ebbca7d
GK
8802 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
8803 gen_rtx_SYMBOL_REF (Pmode,
8804 alloc_rname));
8805 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
8806 {
8807 rtx addr, reg, mem;
8808 reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
8809 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
8810 GEN_INT (info->fp_save_offset
8811 + sp_offset + 8*i));
8812 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 8813 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
8814
8815 RTVEC_ELT (p, i + 2) = gen_rtx_SET (VOIDmode, mem, reg);
8816 }
8817 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
8818 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
8819 NULL_RTX, NULL_RTX);
8820 }
b6c9286a 8821
9ebbca7d
GK
8822 /* Save GPRs. This is done as a PARALLEL if we are using
8823 the store-multiple instructions. */
8824 if (using_store_multiple)
b6c9286a 8825 {
9ebbca7d
GK
8826 rtvec p, dwarfp;
8827 int i;
8828 p = rtvec_alloc (32 - info->first_gp_reg_save);
8829 dwarfp = rtvec_alloc (32 - info->first_gp_reg_save);
8830 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
8831 {
8832 rtx addr, reg, mem;
8833 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
8834 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
8835 GEN_INT (info->gp_save_offset
8836 + sp_offset
8837 + reg_size * i));
8838 mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0 8839 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
8840
8841 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
8842 }
8843 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
8844 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
8845 NULL_RTX, NULL_RTX);
b6c9286a
MM
8846 }
8847 else
8848 {
9ebbca7d
GK
8849 int i;
8850 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
8851 if ((regs_ever_live[info->first_gp_reg_save+i]
8852 && ! call_used_regs[info->first_gp_reg_save+i])
1db02437 8853 || (i+info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
f607bc57
ZW
8854 && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
8855 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
9ebbca7d
GK
8856 {
8857 rtx addr, reg, mem;
8858 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
8859 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
8860 GEN_INT (info->gp_save_offset
8861 + sp_offset
8862 + reg_size * i));
8863 mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0 8864 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
8865
8866 insn = emit_move_insn (mem, reg);
8867 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
8868 NULL_RTX, NULL_RTX);
8869 }
8870 }
8871
83720594
RH
8872 /* ??? There's no need to emit actual instructions here, but it's the
8873 easiest way to get the frame unwind information emitted. */
8874 if (current_function_calls_eh_return)
8875 {
78e1b90d
DE
8876 unsigned int i, regno;
8877
83720594
RH
8878 for (i = 0; ; ++i)
8879 {
8880 rtx addr, reg, mem;
8881
8882 regno = EH_RETURN_DATA_REGNO (i);
8883 if (regno == INVALID_REGNUM)
8884 break;
8885
8886 reg = gen_rtx_REG (reg_mode, regno);
8887 addr = plus_constant (frame_reg_rtx,
78e1b90d
DE
8888 info->ehrd_offset + sp_offset
8889 + reg_size * (int) i);
83720594 8890 mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0 8891 set_mem_alias_set (mem, rs6000_sr_alias_set);
83720594
RH
8892
8893 insn = emit_move_insn (mem, reg);
8894 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
8895 NULL_RTX, NULL_RTX);
8896 }
8897 }
8898
9ebbca7d
GK
8899 /* Save lr if we used it. */
8900 if (info->lr_save_p)
8901 {
8902 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
8903 GEN_INT (info->lr_save_offset + sp_offset));
8904 rtx reg = gen_rtx_REG (Pmode, 0);
8905 rtx mem = gen_rtx_MEM (Pmode, addr);
8906 /* This should not be of rs6000_sr_alias_set, because of
8907 __builtin_return_address. */
8908
8909 insn = emit_move_insn (mem, reg);
8910 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
8911 reg, gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
8912 }
8913
8914 /* Save CR if we use any that must be preserved. */
8915 if (info->cr_save_p)
8916 {
8917 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
8918 GEN_INT (info->cr_save_offset + sp_offset));
8919 rtx mem = gen_rtx_MEM (SImode, addr);
ba4828e0
RK
8920
8921 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
8922
8923 /* If r12 was used to hold the original sp, copy cr into r0 now
8924 that it's free. */
8925 if (REGNO (frame_reg_rtx) == 12)
8926 {
8927 cr_save_rtx = gen_rtx_REG (SImode, 0);
8928 emit_insn (gen_movesi_from_cr (cr_save_rtx));
8929 }
8930 insn = emit_move_insn (mem, cr_save_rtx);
8931
8932 /* Now, there's no way that dwarf2out_frame_debug_expr is going
8933 to understand '(unspec:SI [(reg:CC 68) ...] 19)'. But that's
8934 OK. All we have to do is specify that _one_ condition code
8935 register is saved in this stack slot. The thrower's epilogue
a1dc9455
FS
8936 will then restore all the call-saved registers.
8937 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
9ebbca7d 8938 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
a1dc9455 8939 cr_save_rtx, gen_rtx_REG (SImode, CR2_REGNO));
9ebbca7d
GK
8940 }
8941
8942 /* Update stack and set back pointer unless this is V.4,
8943 for which it was done previously. */
f607bc57 8944 if (info->push_p && DEFAULT_ABI != ABI_V4)
9ebbca7d
GK
8945 rs6000_emit_allocate_stack (info->total_size, FALSE);
8946
8947 /* Set frame pointer, if needed. */
8948 if (frame_pointer_needed)
8949 {
8950 insn = emit_move_insn (gen_rtx_REG (reg_mode, FRAME_POINTER_REGNUM),
8951 sp_reg_rtx);
8952 RTX_FRAME_RELATED_P (insn) = 1;
b6c9286a 8953 }
9878760c 8954
1db02437 8955 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
9ebbca7d 8956 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
f607bc57 8957 || (DEFAULT_ABI == ABI_V4 && flag_pic == 1
1db02437 8958 && regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM]))
9ebbca7d
GK
8959 {
8960 /* If emit_load_toc_table will use the link register, we need to save
8961 it. We use R11 for this purpose because emit_load_toc_table
8962 can use register 0. This allows us to use a plain 'blr' to return
8963 from the procedure more often. */
d5fa86ba
GK
8964 int save_LR_around_toc_setup = (TARGET_ELF && flag_pic != 0
8965 && ! info->lr_save_p
8966 && EXIT_BLOCK_PTR->pred != NULL);
9ebbca7d
GK
8967 if (save_LR_around_toc_setup)
8968 emit_move_insn (gen_rtx_REG (Pmode, 11),
8969 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
8970
8971 rs6000_emit_load_toc_table (TRUE);
8972
8973 if (save_LR_around_toc_setup)
8974 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
8975 gen_rtx_REG (Pmode, 11));
8976 }
ee890fe2
SS
8977
8978 if (DEFAULT_ABI == ABI_DARWIN
8979 && flag_pic && current_function_uses_pic_offset_table)
8980 {
8981 rtx dest = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
8982
8983 rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (dest)));
8984
8985 rs6000_maybe_dead (
1db02437 8986 emit_move_insn (gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM),
ee890fe2
SS
8987 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)));
8988 }
9ebbca7d
GK
8989}
8990
9ebbca7d 8991/* Write function prologue. */
a4f6c312 8992
08c148a8
NB
8993static void
8994rs6000_output_function_prologue (file, size)
9ebbca7d 8995 FILE *file;
08c148a8 8996 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
9ebbca7d
GK
8997{
8998 rs6000_stack_t *info = rs6000_stack_info ();
8999
4697a36c
MM
9000 if (TARGET_DEBUG_STACK)
9001 debug_stack_info (info);
9878760c 9002
a4f6c312
SS
9003 /* Write .extern for any function we will call to save and restore
9004 fp values. */
9005 if (info->first_fp_reg_save < 64
9006 && !FP_SAVE_INLINE (info->first_fp_reg_save))
4d30c363 9007 fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
4697a36c 9008 SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX,
a4f6c312
SS
9009 RESTORE_FP_PREFIX, info->first_fp_reg_save - 32,
9010 RESTORE_FP_SUFFIX);
9878760c 9011
c764f757
RK
9012 /* Write .extern for AIX common mode routines, if needed. */
9013 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
9014 {
f6709c70
JW
9015 fputs ("\t.extern __mulh\n", file);
9016 fputs ("\t.extern __mull\n", file);
9017 fputs ("\t.extern __divss\n", file);
9018 fputs ("\t.extern __divus\n", file);
9019 fputs ("\t.extern __quoss\n", file);
9020 fputs ("\t.extern __quous\n", file);
c764f757
RK
9021 common_mode_defined = 1;
9022 }
9878760c 9023
9ebbca7d 9024 if (! HAVE_prologue)
979721f8 9025 {
9ebbca7d
GK
9026 start_sequence ();
9027
a4f6c312
SS
9028 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
9029 the "toplevel" insn chain. */
9ebbca7d
GK
9030 emit_note (0, NOTE_INSN_DELETED);
9031 rs6000_emit_prologue ();
9032 emit_note (0, NOTE_INSN_DELETED);
9033
9034 if (TARGET_DEBUG_STACK)
a4f6c312
SS
9035 debug_rtx_list (get_insns (), 100);
9036 final (get_insns (), file, FALSE, FALSE);
9ebbca7d 9037 end_sequence ();
979721f8
MM
9038 }
9039
9ebbca7d
GK
9040 rs6000_pic_labelno++;
9041}
9042
9043/* Emit function epilogue as insns.
9878760c 9044
9ebbca7d
GK
9045 At present, dwarf2out_frame_debug_expr doesn't understand
9046 register restores, so we don't bother setting RTX_FRAME_RELATED_P
9047 anywhere in the epilogue. Most of the insns below would in any case
9048 need special notes to explain where r11 is in relation to the stack. */
9878760c 9049
9ebbca7d 9050void
83720594 9051rs6000_emit_epilogue (sibcall)
9ebbca7d
GK
9052 int sibcall;
9053{
9054 rs6000_stack_t *info;
9055 int restoring_FPRs_inline;
9056 int using_load_multiple;
9057 int using_mfcr_multiple;
9058 int use_backchain_to_restore_sp;
9059 int sp_offset = 0;
9060 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
9061 rtx frame_reg_rtx = sp_reg_rtx;
9062 enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
9063 int reg_size = TARGET_POWERPC64 ? 8 : 4;
9064 int i;
9065
9066 info = rs6000_stack_info ();
9067 using_load_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
9068 && info->first_gp_reg_save < 31);
9069 restoring_FPRs_inline = (sibcall
83720594 9070 || current_function_calls_eh_return
9ebbca7d
GK
9071 || info->first_fp_reg_save == 64
9072 || FP_SAVE_INLINE (info->first_fp_reg_save));
9073 use_backchain_to_restore_sp = (frame_pointer_needed
9074 || current_function_calls_alloca
9075 || info->total_size > 32767);
9076 using_mfcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
9077 || rs6000_cpu == PROCESSOR_PPC603
9078 || rs6000_cpu == PROCESSOR_PPC750
9079 || optimize_size);
9080
9081 /* If we have a frame pointer, a call to alloca, or a large stack
9082 frame, restore the old stack pointer using the backchain. Otherwise,
9083 we know what size to update it with. */
9084 if (use_backchain_to_restore_sp)
bacbde18 9085 {
9ebbca7d
GK
9086 /* Under V.4, don't reset the stack pointer until after we're done
9087 loading the saved registers. */
f607bc57 9088 if (DEFAULT_ABI == ABI_V4)
9ebbca7d 9089 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
4697a36c 9090
9ebbca7d
GK
9091 emit_move_insn (frame_reg_rtx,
9092 gen_rtx_MEM (Pmode, sp_reg_rtx));
9093
bacbde18 9094 }
9ebbca7d 9095 else if (info->push_p)
85638c0d 9096 {
f607bc57 9097 if (DEFAULT_ABI == ABI_V4)
9ebbca7d
GK
9098 sp_offset = info->total_size;
9099 else
9100 {
9101 emit_insn (TARGET_32BIT
9102 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
9103 GEN_INT (info->total_size))
9104 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
9105 GEN_INT (info->total_size)));
9106 }
85638c0d 9107 }
9ebbca7d 9108
9aa86737
AH
9109 /* Restore AltiVec registers if needed. */
9110 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
9111 {
9112 int i;
9113
9114 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
9115 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
9116 {
9117 rtx addr, areg, mem;
9118
9119 areg = gen_rtx_REG (Pmode, 0);
9120 emit_move_insn
9121 (areg, GEN_INT (info->altivec_save_offset
9122 + sp_offset
9123 + 16 * (i - info->first_altivec_reg_save)));
9124
9125 /* AltiVec addressing mode is [reg+reg]. */
9126 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
9127 mem = gen_rtx_MEM (V4SImode, addr);
9128 set_mem_alias_set (mem, rs6000_sr_alias_set);
9129
9130 emit_move_insn (gen_rtx_REG (V4SImode, i), mem);
9131 }
9132 }
9133
9134 /* Restore VRSAVE if needed. */
9135 if (TARGET_ALTIVEC_ABI && info->vrsave_mask != 0)
9136 {
9137 rtx addr, mem, reg;
9138
9139 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
9140 GEN_INT (info->vrsave_save_offset + sp_offset));
9141 mem = gen_rtx_MEM (SImode, addr);
9142 set_mem_alias_set (mem, rs6000_sr_alias_set);
9143 reg = gen_rtx_REG (SImode, 12);
9144 emit_move_insn (reg, mem);
9145
9146 emit_insn (generate_set_vrsave (reg, info, 1));
9147 }
9148
9ebbca7d
GK
9149 /* Get the old lr if we saved it. */
9150 if (info->lr_save_p)
b6c9286a 9151 {
9ebbca7d
GK
9152 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
9153 GEN_INT (info->lr_save_offset + sp_offset));
9154 rtx mem = gen_rtx_MEM (Pmode, addr);
ba4828e0
RK
9155
9156 set_mem_alias_set (mem, rs6000_sr_alias_set);
b6c9286a 9157
9ebbca7d 9158 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
b6c9286a 9159 }
9ebbca7d
GK
9160
9161 /* Get the old cr if we saved it. */
9162 if (info->cr_save_p)
9163 {
9164 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
9165 GEN_INT (info->cr_save_offset + sp_offset));
9166 rtx mem = gen_rtx_MEM (SImode, addr);
ba4828e0
RK
9167
9168 set_mem_alias_set (mem, rs6000_sr_alias_set);
b6c9286a 9169
9ebbca7d
GK
9170 emit_move_insn (gen_rtx_REG (SImode, 12), mem);
9171 }
9172
9173 /* Set LR here to try to overlap restores below. */
4697a36c 9174 if (info->lr_save_p)
9ebbca7d
GK
9175 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
9176 gen_rtx_REG (Pmode, 0));
9177
83720594
RH
9178 /* Load exception handler data registers, if needed. */
9179 if (current_function_calls_eh_return)
9180 {
78e1b90d
DE
9181 unsigned int i, regno;
9182
83720594
RH
9183 for (i = 0; ; ++i)
9184 {
9185 rtx addr, mem;
9186
9187 regno = EH_RETURN_DATA_REGNO (i);
9188 if (regno == INVALID_REGNUM)
9189 break;
9190
9191 addr = plus_constant (frame_reg_rtx,
78e1b90d
DE
9192 info->ehrd_offset + sp_offset
9193 + reg_size * (int) i);
83720594 9194 mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0 9195 set_mem_alias_set (mem, rs6000_sr_alias_set);
83720594
RH
9196
9197 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
9198 }
9199 }
9ebbca7d
GK
9200
9201 /* Restore GPRs. This is done as a PARALLEL if we are using
9202 the load-multiple instructions. */
9203 if (using_load_multiple)
979721f8 9204 {
9ebbca7d
GK
9205 rtvec p;
9206 p = rtvec_alloc (32 - info->first_gp_reg_save);
9207 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
979721f8 9208 {
9ebbca7d
GK
9209 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
9210 GEN_INT (info->gp_save_offset
9211 + sp_offset
9212 + reg_size * i));
9213 rtx mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0
RK
9214
9215 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
9216
9217 RTVEC_ELT (p, i) =
9218 gen_rtx_SET (VOIDmode,
9219 gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
9220 mem);
979721f8 9221 }
9ebbca7d 9222 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
979721f8 9223 }
9ebbca7d
GK
9224 else
9225 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
9226 if ((regs_ever_live[info->first_gp_reg_save+i]
9227 && ! call_used_regs[info->first_gp_reg_save+i])
1db02437 9228 || (i+info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
f607bc57
ZW
9229 && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
9230 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
9ebbca7d
GK
9231 {
9232 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
9233 GEN_INT (info->gp_save_offset
9234 + sp_offset
9235 + reg_size * i));
9236 rtx mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0
RK
9237
9238 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
9239
9240 emit_move_insn (gen_rtx_REG (reg_mode,
9241 info->first_gp_reg_save + i),
9242 mem);
9243 }
9878760c 9244
9ebbca7d
GK
9245 /* Restore fpr's if we need to do it without calling a function. */
9246 if (restoring_FPRs_inline)
9247 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
9248 if ((regs_ever_live[info->first_fp_reg_save+i]
9249 && ! call_used_regs[info->first_fp_reg_save+i]))
9250 {
9251 rtx addr, mem;
9252 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
9253 GEN_INT (info->fp_save_offset
9254 + sp_offset
a4f6c312 9255 + 8 * i));
9ebbca7d 9256 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 9257 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
9258
9259 emit_move_insn (gen_rtx_REG (DFmode,
9260 info->first_fp_reg_save + i),
9261 mem);
9262 }
8d30c4ee 9263
9ebbca7d
GK
9264 /* If we saved cr, restore it here. Just those that were used. */
9265 if (info->cr_save_p)
979721f8 9266 {
9ebbca7d 9267 rtx r12_rtx = gen_rtx_REG (SImode, 12);
e35b9579 9268 int count = 0;
9ebbca7d
GK
9269
9270 if (using_mfcr_multiple)
979721f8 9271 {
9ebbca7d
GK
9272 for (i = 0; i < 8; i++)
9273 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
e35b9579 9274 count++;
9ebbca7d 9275 if (count == 0)
e35b9579
GK
9276 abort ();
9277 }
9278
9279 if (using_mfcr_multiple && count > 1)
9280 {
9281 rtvec p;
9282 int ndx;
9ebbca7d 9283
e35b9579 9284 p = rtvec_alloc (count);
9ebbca7d 9285
e35b9579 9286 ndx = 0;
9ebbca7d
GK
9287 for (i = 0; i < 8; i++)
9288 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
9289 {
9290 rtvec r = rtvec_alloc (2);
9291 RTVEC_ELT (r, 0) = r12_rtx;
9292 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
e35b9579 9293 RTVEC_ELT (p, ndx) =
9ebbca7d
GK
9294 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
9295 gen_rtx_UNSPEC (CCmode, r, 20));
e35b9579 9296 ndx++;
9ebbca7d
GK
9297 }
9298 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
e35b9579
GK
9299 if (ndx != count)
9300 abort ();
979721f8
MM
9301 }
9302 else
9ebbca7d
GK
9303 for (i = 0; i < 8; i++)
9304 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
979721f8 9305 {
9ebbca7d
GK
9306 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
9307 CR0_REGNO+i),
9308 r12_rtx));
979721f8 9309 }
979721f8
MM
9310 }
9311
9ebbca7d
GK
9312 /* If this is V.4, unwind the stack pointer after all of the loads
9313 have been done. We need to emit a block here so that sched
9314 doesn't decide to move the sp change before the register restores
9315 (which may not have any obvious dependency on the stack). This
9316 doesn't hurt performance, because there is no scheduling that can
9317 be done after this point. */
f607bc57 9318 if (DEFAULT_ABI == ABI_V4)
b6c9286a 9319 {
9ebbca7d
GK
9320 if (frame_reg_rtx != sp_reg_rtx)
9321 rs6000_emit_stack_tie ();
b6c9286a 9322
9ebbca7d 9323 if (use_backchain_to_restore_sp)
b6c9286a 9324 {
9ebbca7d 9325 emit_move_insn (sp_reg_rtx, frame_reg_rtx);
b6c9286a 9326 }
9ebbca7d 9327 else if (sp_offset != 0)
13f1623b 9328 {
9ebbca7d
GK
9329 emit_insn (Pmode == SImode
9330 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
9331 GEN_INT (sp_offset))
9332 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
9333 GEN_INT (sp_offset)));
13f1623b 9334 }
9ebbca7d 9335 }
b6c9286a 9336
83720594
RH
9337 if (current_function_calls_eh_return)
9338 {
9339 rtx sa = EH_RETURN_STACKADJ_RTX;
9340 emit_insn (Pmode == SImode
9341 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, sa)
9342 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx, sa));
9343 }
9344
9ebbca7d
GK
9345 if (!sibcall)
9346 {
9347 rtvec p;
9348 if (! restoring_FPRs_inline)
9349 p = rtvec_alloc (3 + 64 - info->first_fp_reg_save);
9350 else
9351 p = rtvec_alloc (2);
b6c9286a 9352
e35b9579
GK
9353 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
9354 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
9ebbca7d
GK
9355 gen_rtx_REG (Pmode,
9356 LINK_REGISTER_REGNUM));
9ebbca7d
GK
9357
9358 /* If we have to restore more than two FP registers, branch to the
9359 restore function. It will return to our caller. */
9360 if (! restoring_FPRs_inline)
9361 {
9362 int i;
9363 char rname[30];
520a57c8 9364 const char *alloc_rname;
979721f8 9365
9ebbca7d
GK
9366 sprintf (rname, "%s%d%s", RESTORE_FP_PREFIX,
9367 info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
a8a05998 9368 alloc_rname = ggc_strdup (rname);
9ebbca7d
GK
9369 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode,
9370 gen_rtx_SYMBOL_REF (Pmode,
9371 alloc_rname));
b6c9286a 9372
9ebbca7d
GK
9373 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
9374 {
9375 rtx addr, mem;
9376 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
9377 GEN_INT (info->fp_save_offset + 8*i));
9378 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 9379 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
9380
9381 RTVEC_ELT (p, i+3) =
9382 gen_rtx_SET (VOIDmode,
9383 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
9384 mem);
b6c9286a
MM
9385 }
9386 }
9ebbca7d
GK
9387
9388 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
3daf36a4 9389 }
9878760c
RK
9390}
9391
9392/* Write function epilogue. */
9393
08c148a8
NB
9394static void
9395rs6000_output_function_epilogue (file, size)
9878760c 9396 FILE *file;
08c148a8 9397 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
9878760c 9398{
4697a36c 9399 rs6000_stack_t *info = rs6000_stack_info ();
6041bf2f 9400 int optional_tbtab = (optimize_size || TARGET_ELF) ? 0 : 1;
9878760c 9401
9ebbca7d 9402 if (! HAVE_epilogue)
9878760c 9403 {
9ebbca7d
GK
9404 rtx insn = get_last_insn ();
9405 /* If the last insn was a BARRIER, we don't have to write anything except
9406 the trace table. */
9407 if (GET_CODE (insn) == NOTE)
9408 insn = prev_nonnote_insn (insn);
9409 if (insn == 0 || GET_CODE (insn) != BARRIER)
4697a36c 9410 {
9ebbca7d
GK
9411 /* This is slightly ugly, but at least we don't have two
9412 copies of the epilogue-emitting code. */
9413 start_sequence ();
9414
9415 /* A NOTE_INSN_DELETED is supposed to be at the start
9416 and end of the "toplevel" insn chain. */
9417 emit_note (0, NOTE_INSN_DELETED);
9418 rs6000_emit_epilogue (FALSE);
9419 emit_note (0, NOTE_INSN_DELETED);
9420
9421 if (TARGET_DEBUG_STACK)
a4f6c312
SS
9422 debug_rtx_list (get_insns (), 100);
9423 final (get_insns (), file, FALSE, FALSE);
9ebbca7d 9424 end_sequence ();
4697a36c 9425 }
9878760c 9426 }
b4ac57ab 9427
9b30bae2 9428 /* Output a traceback table here. See /usr/include/sys/debug.h for info
314fc5a9
ILT
9429 on its format.
9430
9431 We don't output a traceback table if -finhibit-size-directive was
9432 used. The documentation for -finhibit-size-directive reads
9433 ``don't output a @code{.size} assembler directive, or anything
9434 else that would cause trouble if the function is split in the
9435 middle, and the two halves are placed at locations far apart in
9436 memory.'' The traceback table has this property, since it
9437 includes the offset from the start of the function to the
4d30c363
MM
9438 traceback table itself.
9439
9440 System V.4 Powerpc's (and the embedded ABI derived from it) use a
b6c9286a
MM
9441 different traceback table. */
9442 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive)
9b30bae2 9443 {
3cce094d 9444 const char *fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
3ac88239 9445 const char *language_string = lang_hooks.name;
6041bf2f 9446 int fixed_parms = 0, float_parms = 0, parm_info = 0;
314fc5a9
ILT
9447 int i;
9448
b6c9286a
MM
9449 while (*fname == '.') /* V.4 encodes . in the name */
9450 fname++;
9451
314fc5a9
ILT
9452 /* Need label immediately before tbtab, so we can compute its offset
9453 from the function start. */
9454 if (*fname == '*')
9455 ++fname;
9456 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
9457 ASM_OUTPUT_LABEL (file, fname);
9458
9459 /* The .tbtab pseudo-op can only be used for the first eight
9460 expressions, since it can't handle the possibly variable
9461 length fields that follow. However, if you omit the optional
9462 fields, the assembler outputs zeros for all optional fields
9463 anyways, giving each variable length field is minimum length
9464 (as defined in sys/debug.h). Thus we can not use the .tbtab
9465 pseudo-op at all. */
9466
9467 /* An all-zero word flags the start of the tbtab, for debuggers
9468 that have to find it by searching forward from the entry
9469 point or from the current pc. */
19d2d16f 9470 fputs ("\t.long 0\n", file);
314fc5a9
ILT
9471
9472 /* Tbtab format type. Use format type 0. */
19d2d16f 9473 fputs ("\t.byte 0,", file);
314fc5a9
ILT
9474
9475 /* Language type. Unfortunately, there doesn't seem to be any
9476 official way to get this info, so we use language_string. C
9477 is 0. C++ is 9. No number defined for Obj-C, so use the
9517ead8 9478 value for C for now. There is no official value for Java,
6f573ff9 9479 although IBM appears to be using 13. There is no official value
f710504c 9480 for Chill, so we've chosen 44 pseudo-randomly. */
314fc5a9 9481 if (! strcmp (language_string, "GNU C")
e2c953b6 9482 || ! strcmp (language_string, "GNU Objective-C"))
314fc5a9
ILT
9483 i = 0;
9484 else if (! strcmp (language_string, "GNU F77"))
9485 i = 1;
9486 else if (! strcmp (language_string, "GNU Ada"))
9487 i = 3;
8b83775b 9488 else if (! strcmp (language_string, "GNU Pascal"))
314fc5a9
ILT
9489 i = 2;
9490 else if (! strcmp (language_string, "GNU C++"))
9491 i = 9;
9517ead8
AG
9492 else if (! strcmp (language_string, "GNU Java"))
9493 i = 13;
6f573ff9
JL
9494 else if (! strcmp (language_string, "GNU CHILL"))
9495 i = 44;
314fc5a9
ILT
9496 else
9497 abort ();
9498 fprintf (file, "%d,", i);
9499
9500 /* 8 single bit fields: global linkage (not set for C extern linkage,
9501 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
9502 from start of procedure stored in tbtab, internal function, function
9503 has controlled storage, function has no toc, function uses fp,
9504 function logs/aborts fp operations. */
9505 /* Assume that fp operations are used if any fp reg must be saved. */
6041bf2f
DE
9506 fprintf (file, "%d,",
9507 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
314fc5a9
ILT
9508
9509 /* 6 bitfields: function is interrupt handler, name present in
9510 proc table, function calls alloca, on condition directives
9511 (controls stack walks, 3 bits), saves condition reg, saves
9512 link reg. */
9513 /* The `function calls alloca' bit seems to be set whenever reg 31 is
9514 set up as a frame pointer, even when there is no alloca call. */
9515 fprintf (file, "%d,",
6041bf2f
DE
9516 ((optional_tbtab << 6)
9517 | ((optional_tbtab & frame_pointer_needed) << 5)
9518 | (info->cr_save_p << 1)
9519 | (info->lr_save_p)));
314fc5a9 9520
6041bf2f 9521 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
314fc5a9
ILT
9522 (6 bits). */
9523 fprintf (file, "%d,",
4697a36c 9524 (info->push_p << 7) | (64 - info->first_fp_reg_save));
314fc5a9
ILT
9525
9526 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
9527 fprintf (file, "%d,", (32 - first_reg_to_save ()));
9528
6041bf2f
DE
9529 if (optional_tbtab)
9530 {
9531 /* Compute the parameter info from the function decl argument
9532 list. */
9533 tree decl;
9534 int next_parm_info_bit = 31;
314fc5a9 9535
6041bf2f
DE
9536 for (decl = DECL_ARGUMENTS (current_function_decl);
9537 decl; decl = TREE_CHAIN (decl))
9538 {
9539 rtx parameter = DECL_INCOMING_RTL (decl);
9540 enum machine_mode mode = GET_MODE (parameter);
314fc5a9 9541
6041bf2f
DE
9542 if (GET_CODE (parameter) == REG)
9543 {
9544 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
9545 {
9546 int bits;
9547
9548 float_parms++;
9549
9550 if (mode == SFmode)
9551 bits = 0x2;
9552 else if (mode == DFmode)
9553 bits = 0x3;
9554 else
9555 abort ();
9556
9557 /* If only one bit will fit, don't or in this entry. */
9558 if (next_parm_info_bit > 0)
9559 parm_info |= (bits << (next_parm_info_bit - 1));
9560 next_parm_info_bit -= 2;
9561 }
9562 else
9563 {
9564 fixed_parms += ((GET_MODE_SIZE (mode)
9565 + (UNITS_PER_WORD - 1))
9566 / UNITS_PER_WORD);
9567 next_parm_info_bit -= 1;
9568 }
9569 }
9570 }
9571 }
314fc5a9
ILT
9572
9573 /* Number of fixed point parameters. */
9574 /* This is actually the number of words of fixed point parameters; thus
9575 an 8 byte struct counts as 2; and thus the maximum value is 8. */
9576 fprintf (file, "%d,", fixed_parms);
9577
9578 /* 2 bitfields: number of floating point parameters (7 bits), parameters
9579 all on stack. */
9580 /* This is actually the number of fp registers that hold parameters;
9581 and thus the maximum value is 13. */
9582 /* Set parameters on stack bit if parameters are not in their original
9583 registers, regardless of whether they are on the stack? Xlc
9584 seems to set the bit when not optimizing. */
9585 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
9586
6041bf2f
DE
9587 if (! optional_tbtab)
9588 return;
9589
314fc5a9
ILT
9590 /* Optional fields follow. Some are variable length. */
9591
9592 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
9593 11 double float. */
9594 /* There is an entry for each parameter in a register, in the order that
9595 they occur in the parameter list. Any intervening arguments on the
9596 stack are ignored. If the list overflows a long (max possible length
9597 34 bits) then completely leave off all elements that don't fit. */
9598 /* Only emit this long if there was at least one parameter. */
9599 if (fixed_parms || float_parms)
9600 fprintf (file, "\t.long %d\n", parm_info);
9601
9602 /* Offset from start of code to tb table. */
19d2d16f 9603 fputs ("\t.long ", file);
314fc5a9 9604 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
54ee9799
DE
9605#if TARGET_AIX
9606 RS6000_OUTPUT_BASENAME (file, fname);
9607#else
9ebbca7d 9608 assemble_name (file, fname);
54ee9799 9609#endif
19d2d16f 9610 fputs ("-.", file);
54ee9799
DE
9611#if TARGET_AIX
9612 RS6000_OUTPUT_BASENAME (file, fname);
9613#else
9ebbca7d 9614 assemble_name (file, fname);
54ee9799 9615#endif
19d2d16f 9616 putc ('\n', file);
314fc5a9
ILT
9617
9618 /* Interrupt handler mask. */
9619 /* Omit this long, since we never set the interrupt handler bit
9620 above. */
9621
9622 /* Number of CTL (controlled storage) anchors. */
9623 /* Omit this long, since the has_ctl bit is never set above. */
9624
9625 /* Displacement into stack of each CTL anchor. */
9626 /* Omit this list of longs, because there are no CTL anchors. */
9627
9628 /* Length of function name. */
296b8152 9629 fprintf (file, "\t.short %d\n", (int) strlen (fname));
314fc5a9
ILT
9630
9631 /* Function name. */
9632 assemble_string (fname, strlen (fname));
9633
9634 /* Register for alloca automatic storage; this is always reg 31.
9635 Only emit this if the alloca bit was set above. */
9636 if (frame_pointer_needed)
19d2d16f 9637 fputs ("\t.byte 31\n", file);
b1765bde
DE
9638
9639 fputs ("\t.align 2\n", file);
9b30bae2 9640 }
6041bf2f 9641 return;
9878760c 9642}
17167fd8 9643\f
a4f6c312
SS
9644/* A C compound statement that outputs the assembler code for a thunk
9645 function, used to implement C++ virtual function calls with
9646 multiple inheritance. The thunk acts as a wrapper around a virtual
9647 function, adjusting the implicit object parameter before handing
9648 control off to the real function.
9649
9650 First, emit code to add the integer DELTA to the location that
9651 contains the incoming first argument. Assume that this argument
9652 contains a pointer, and is the one used to pass the `this' pointer
9653 in C++. This is the incoming argument *before* the function
9654 prologue, e.g. `%o0' on a sparc. The addition must preserve the
9655 values of all other incoming arguments.
17167fd8
MM
9656
9657 After the addition, emit code to jump to FUNCTION, which is a
a4f6c312
SS
9658 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
9659 not touch the return address. Hence returning from FUNCTION will
9660 return to whoever called the current `thunk'.
17167fd8 9661
a4f6c312
SS
9662 The effect must be as if FUNCTION had been called directly with the
9663 adjusted first argument. This macro is responsible for emitting
9664 all of the code for a thunk function; output_function_prologue()
9665 and output_function_epilogue() are not invoked.
17167fd8 9666
a4f6c312
SS
9667 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
9668 been extracted from it.) It might possibly be useful on some
9669 targets, but probably not.
17167fd8 9670
a4f6c312
SS
9671 If you do not define this macro, the target-independent code in the
9672 C++ frontend will generate a less efficient heavyweight thunk that
9673 calls FUNCTION instead of jumping to it. The generic approach does
9674 not support varargs. */
17167fd8
MM
9675
9676void
9677output_mi_thunk (file, thunk_fndecl, delta, function)
9678 FILE *file;
d330fd93 9679 tree thunk_fndecl ATTRIBUTE_UNUSED;
17167fd8
MM
9680 int delta;
9681 tree function;
9682{
a4f6c312
SS
9683 const char *this_reg =
9684 reg_names[ aggregate_value_p (TREE_TYPE (TREE_TYPE (function))) ? 4 : 3 ];
d330fd93 9685 const char *prefix;
3cce094d 9686 const char *fname;
d330fd93 9687 const char *r0 = reg_names[0];
d330fd93
KG
9688 const char *toc = reg_names[2];
9689 const char *schain = reg_names[11];
9690 const char *r12 = reg_names[12];
17167fd8
MM
9691 char buf[512];
9692 static int labelno = 0;
9693
a4f6c312 9694 /* Small constants that can be done by one add instruction. */
17167fd8
MM
9695 if (delta >= -32768 && delta <= 32767)
9696 {
22b4a3b0 9697 if (! TARGET_NEW_MNEMONICS)
17167fd8
MM
9698 fprintf (file, "\tcal %s,%d(%s)\n", this_reg, delta, this_reg);
9699 else
9700 fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, delta);
9701 }
9702
a4f6c312 9703 /* Large constants that can be done by one addis instruction. */
17167fd8
MM
9704 else if ((delta & 0xffff) == 0 && num_insns_constant_wide (delta) == 1)
9705 asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
9706 delta >> 16);
9707
9708 /* 32-bit constants that can be done by an add and addis instruction. */
9709 else if (TARGET_32BIT || num_insns_constant_wide (delta) == 1)
9710 {
a4f6c312
SS
9711 /* Break into two pieces, propagating the sign bit from the low
9712 word to the upper word. */
17167fd8
MM
9713 int delta_high = delta >> 16;
9714 int delta_low = delta & 0xffff;
9715 if ((delta_low & 0x8000) != 0)
9716 {
9717 delta_high++;
9718 delta_low = (delta_low ^ 0x8000) - 0x8000; /* sign extend */
9719 }
9720
9721 asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
9722 delta_high);
9723
22b4a3b0 9724 if (! TARGET_NEW_MNEMONICS)
17167fd8
MM
9725 fprintf (file, "\tcal %s,%d(%s)\n", this_reg, delta_low, this_reg);
9726 else
9727 fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, delta_low);
9728 }
9729
9730 /* 64-bit constants, fixme */
9731 else
9732 abort ();
9733
9734 /* Get the prefix in front of the names. */
9735 switch (DEFAULT_ABI)
9736 {
9737 default:
9738 abort ();
9739
9740 case ABI_AIX:
9741 prefix = ".";
9742 break;
9743
9744 case ABI_V4:
9745 case ABI_AIX_NODESC:
17167fd8
MM
9746 prefix = "";
9747 break;
17167fd8
MM
9748 }
9749
9750 /* If the function is compiled in this module, jump to it directly.
9751 Otherwise, load up its address and jump to it. */
9752
9753 fname = XSTR (XEXP (DECL_RTL (function), 0), 0);
42820a49 9754
9ebbca7d 9755 if (current_file_function_operand (XEXP (DECL_RTL (function), 0), VOIDmode)
22b4a3b0
FS
9756 && ! lookup_attribute ("longcall",
9757 TYPE_ATTRIBUTES (TREE_TYPE (function))))
17167fd8
MM
9758 {
9759 fprintf (file, "\tb %s", prefix);
9760 assemble_name (file, fname);
22b4a3b0 9761 if (DEFAULT_ABI == ABI_V4 && flag_pic) fputs ("@local", file);
949ea356 9762 putc ('\n', file);
17167fd8
MM
9763 }
9764
9765 else
9766 {
9767 switch (DEFAULT_ABI)
9768 {
9769 default:
17167fd8
MM
9770 abort ();
9771
9772 case ABI_AIX:
9773 /* Set up a TOC entry for the function. */
9774 ASM_GENERATE_INTERNAL_LABEL (buf, "Lthunk", labelno);
9775 toc_section ();
9776 ASM_OUTPUT_INTERNAL_LABEL (file, "Lthunk", labelno);
9777 labelno++;
9778
fa9b5c6b
DE
9779 if (TARGET_MINIMAL_TOC)
9780 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
9781 else
9782 {
9783 fputs ("\t.tc ", file);
9784 assemble_name (file, fname);
9785 fputs ("[TC],", file);
9786 }
9787 assemble_name (file, fname);
17167fd8
MM
9788 putc ('\n', file);
9789 text_section ();
468e8dba
DE
9790 if (TARGET_MINIMAL_TOC)
9791 asm_fprintf (file, (TARGET_32BIT)
9792 ? "\t{l|lwz} %s,%s(%s)\n" : "\tld %s,%s(%s)\n", r12,
9793 TARGET_ELF ? ".LCTOC0@toc" : ".LCTOC..1", toc);
d2574c50 9794 asm_fprintf (file, (TARGET_32BIT) ? "\t{l|lwz} %s," : "\tld %s,", r12);
17167fd8 9795 assemble_name (file, buf);
468e8dba
DE
9796 if (TARGET_ELF && TARGET_MINIMAL_TOC)
9797 fputs ("-(.LCTOC1)", file);
9798 asm_fprintf (file, "(%s)\n", TARGET_MINIMAL_TOC ? r12 : toc);
17167fd8
MM
9799 asm_fprintf (file,
9800 (TARGET_32BIT) ? "\t{l|lwz} %s,0(%s)\n" : "\tld %s,0(%s)\n",
9801 r0, r12);
9802
9803 asm_fprintf (file,
9804 (TARGET_32BIT) ? "\t{l|lwz} %s,4(%s)\n" : "\tld %s,8(%s)\n",
9805 toc, r12);
9806
9807 asm_fprintf (file, "\tmtctr %s\n", r0);
9808 asm_fprintf (file,
9809 (TARGET_32BIT) ? "\t{l|lwz} %s,8(%s)\n" : "\tld %s,16(%s)\n",
9810 schain, r12);
9811
9812 asm_fprintf (file, "\tbctr\n");
9813 break;
9814
9ebbca7d 9815 case ABI_AIX_NODESC:
17167fd8 9816 case ABI_V4:
22b4a3b0
FS
9817 fprintf (file, "\tb %s", prefix);
9818 assemble_name (file, fname);
9819 if (flag_pic) fputs ("@plt", file);
949ea356 9820 putc ('\n', file);
22b4a3b0 9821 break;
ee890fe2
SS
9822
9823#if TARGET_MACHO
9824 case ABI_DARWIN:
9825 fprintf (file, "\tb %s", prefix);
9826 if (flag_pic && !machopic_name_defined_p (fname))
9827 assemble_name (file, machopic_stub_name (fname));
9828 else
9829 assemble_name (file, fname);
9830 putc ('\n', file);
9831 break;
9832#endif
9ebbca7d
GK
9833 }
9834 }
9835}
42820a49 9836
9ebbca7d
GK
9837\f
9838/* A quick summary of the various types of 'constant-pool tables'
9839 under PowerPC:
9840
9841 Target Flags Name One table per
9842 AIX (none) AIX TOC object file
9843 AIX -mfull-toc AIX TOC object file
9844 AIX -mminimal-toc AIX minimal TOC translation unit
9845 SVR4/EABI (none) SVR4 SDATA object file
9846 SVR4/EABI -fpic SVR4 pic object file
9847 SVR4/EABI -fPIC SVR4 PIC translation unit
9848 SVR4/EABI -mrelocatable EABI TOC function
9849 SVR4/EABI -maix AIX TOC object file
9850 SVR4/EABI -maix -mminimal-toc
9851 AIX minimal TOC translation unit
9852
9853 Name Reg. Set by entries contains:
9854 made by addrs? fp? sum?
9855
9856 AIX TOC 2 crt0 as Y option option
9857 AIX minimal TOC 30 prolog gcc Y Y option
9858 SVR4 SDATA 13 crt0 gcc N Y N
9859 SVR4 pic 30 prolog ld Y not yet N
9860 SVR4 PIC 30 prolog gcc Y option option
9861 EABI TOC 30 prolog gcc Y option option
9862
9863*/
9864
9865/* Hash table stuff for keeping track of TOC entries. */
9866
9867struct toc_hash_struct
9868{
9869 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
9870 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
9871 rtx key;
a9098fd0 9872 enum machine_mode key_mode;
9ebbca7d
GK
9873 int labelno;
9874};
17167fd8 9875
9ebbca7d
GK
9876static htab_t toc_hash_table;
9877
9878/* Hash functions for the hash table. */
9879
9880static unsigned
9881rs6000_hash_constant (k)
9882 rtx k;
9883{
a9098fd0 9884 unsigned result = (GET_CODE (k) << 3) ^ GET_MODE (k);
9ebbca7d
GK
9885 const char *format = GET_RTX_FORMAT (GET_CODE (k));
9886 int flen = strlen (format);
9887 int fidx;
9888
9889 if (GET_CODE (k) == LABEL_REF)
832ea3b3 9890 return result * 1231 + X0INT (XEXP (k, 0), 3);
9ebbca7d
GK
9891
9892 if (GET_CODE (k) == CONST_DOUBLE)
592bf28c 9893 fidx = 1;
9ebbca7d
GK
9894 else if (GET_CODE (k) == CODE_LABEL)
9895 fidx = 3;
9896 else
9897 fidx = 0;
9898
9899 for (; fidx < flen; fidx++)
9900 switch (format[fidx])
9901 {
9902 case 's':
9903 {
9904 unsigned i, len;
9905 const char *str = XSTR (k, fidx);
9906 len = strlen (str);
9907 result = result * 613 + len;
9908 for (i = 0; i < len; i++)
9909 result = result * 613 + (unsigned) str[i];
17167fd8
MM
9910 break;
9911 }
9ebbca7d
GK
9912 case 'u':
9913 case 'e':
9914 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
9915 break;
9916 case 'i':
9917 case 'n':
9918 result = result * 613 + (unsigned) XINT (k, fidx);
9919 break;
9920 case 'w':
9921 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
9922 result = result * 613 + (unsigned) XWINT (k, fidx);
9923 else
9924 {
9925 size_t i;
9926 for (i = 0; i < sizeof(HOST_WIDE_INT)/sizeof(unsigned); i++)
9927 result = result * 613 + (unsigned) (XWINT (k, fidx)
9928 >> CHAR_BIT * i);
9929 }
9930 break;
9931 default:
a4f6c312 9932 abort ();
9ebbca7d
GK
9933 }
9934 return result;
9935}
9936
9937static unsigned
9938toc_hash_function (hash_entry)
9939 const void * hash_entry;
9940{
a9098fd0
GK
9941 const struct toc_hash_struct *thc =
9942 (const struct toc_hash_struct *) hash_entry;
9943 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
9ebbca7d
GK
9944}
9945
9946/* Compare H1 and H2 for equivalence. */
9947
9948static int
9949toc_hash_eq (h1, h2)
9950 const void * h1;
9951 const void * h2;
9952{
9953 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
9954 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
9955
a9098fd0
GK
9956 if (((const struct toc_hash_struct *) h1)->key_mode
9957 != ((const struct toc_hash_struct *) h2)->key_mode)
9958 return 0;
9959
9ebbca7d
GK
9960 /* Gotcha: One of these const_doubles will be in memory.
9961 The other may be on the constant-pool chain.
a4f6c312 9962 So rtx_equal_p will think they are different... */
9ebbca7d
GK
9963 if (r1 == r2)
9964 return 1;
9965 if (GET_CODE (r1) != GET_CODE (r2)
9966 || GET_MODE (r1) != GET_MODE (r2))
9967 return 0;
9968 if (GET_CODE (r1) == CONST_DOUBLE)
9969 {
9970 int format_len = strlen (GET_RTX_FORMAT (CONST_DOUBLE));
9971 int i;
592bf28c 9972 for (i = 1; i < format_len; i++)
9ebbca7d
GK
9973 if (XWINT (r1, i) != XWINT (r2, i))
9974 return 0;
9975
9976 return 1;
17167fd8 9977 }
9ebbca7d 9978 else if (GET_CODE (r1) == LABEL_REF)
e4a0656f
GK
9979 return (CODE_LABEL_NUMBER (XEXP (r1, 0))
9980 == CODE_LABEL_NUMBER (XEXP (r2, 0)));
9ebbca7d
GK
9981 else
9982 return rtx_equal_p (r1, r2);
9983}
9984
9985/* Mark the hash table-entry HASH_ENTRY. */
9986
9987static int
9988toc_hash_mark_entry (hash_slot, unused)
2eba1afa 9989 void ** hash_slot;
9ebbca7d
GK
9990 void * unused ATTRIBUTE_UNUSED;
9991{
9992 const struct toc_hash_struct * hash_entry =
9993 *(const struct toc_hash_struct **) hash_slot;
9994 rtx r = hash_entry->key;
9995 ggc_set_mark (hash_entry);
a4f6c312 9996 /* For CODE_LABELS, we don't want to drag in the whole insn chain... */
9ebbca7d
GK
9997 if (GET_CODE (r) == LABEL_REF)
9998 {
9999 ggc_set_mark (r);
10000 ggc_set_mark (XEXP (r, 0));
10001 }
10002 else
10003 ggc_mark_rtx (r);
10004 return 1;
10005}
10006
10007/* Mark all the elements of the TOC hash-table *HT. */
10008
10009static void
10010toc_hash_mark_table (vht)
10011 void *vht;
10012{
10013 htab_t *ht = vht;
10014
10015 htab_traverse (*ht, toc_hash_mark_entry, (void *)0);
17167fd8
MM
10016}
10017
28e510bd
MM
10018/* These are the names given by the C++ front-end to vtables, and
10019 vtable-like objects. Ideally, this logic should not be here;
10020 instead, there should be some programmatic way of inquiring as
10021 to whether or not an object is a vtable. */
10022
10023#define VTABLE_NAME_P(NAME) \
10024 (strncmp ("_vt.", name, strlen("_vt.")) == 0 \
10025 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
10026 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
10027 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
10028
10029void
10030rs6000_output_symbol_ref (file, x)
10031 FILE *file;
10032 rtx x;
10033{
10034 /* Currently C++ toc references to vtables can be emitted before it
10035 is decided whether the vtable is public or private. If this is
10036 the case, then the linker will eventually complain that there is
10037 a reference to an unknown section. Thus, for vtables only,
10038 we emit the TOC reference to reference the symbol and not the
10039 section. */
10040 const char *name = XSTR (x, 0);
54ee9799
DE
10041
10042 if (VTABLE_NAME_P (name))
10043 {
10044 RS6000_OUTPUT_BASENAME (file, name);
10045 }
10046 else
10047 assemble_name (file, name);
28e510bd
MM
10048}
10049
a4f6c312
SS
10050/* Output a TOC entry. We derive the entry name from what is being
10051 written. */
9878760c
RK
10052
10053void
a9098fd0 10054output_toc (file, x, labelno, mode)
9878760c
RK
10055 FILE *file;
10056 rtx x;
10057 int labelno;
a9098fd0 10058 enum machine_mode mode;
9878760c
RK
10059{
10060 char buf[256];
3cce094d 10061 const char *name = buf;
ec940faa 10062 const char *real_name;
9878760c
RK
10063 rtx base = x;
10064 int offset = 0;
10065
4697a36c
MM
10066 if (TARGET_NO_TOC)
10067 abort ();
10068
9ebbca7d
GK
10069 /* When the linker won't eliminate them, don't output duplicate
10070 TOC entries (this happens on AIX if there is any kind of TOC,
1f8f4a0b
MM
10071 and on SVR4 under -fPIC or -mrelocatable). */
10072 if (TARGET_TOC)
9ebbca7d
GK
10073 {
10074 struct toc_hash_struct *h;
10075 void * * found;
10076
10077 h = ggc_alloc (sizeof (*h));
10078 h->key = x;
a9098fd0 10079 h->key_mode = mode;
9ebbca7d
GK
10080 h->labelno = labelno;
10081
10082 found = htab_find_slot (toc_hash_table, h, 1);
10083 if (*found == NULL)
10084 *found = h;
10085 else /* This is indeed a duplicate.
10086 Set this label equal to that label. */
10087 {
10088 fputs ("\t.set ", file);
10089 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
10090 fprintf (file, "%d,", labelno);
10091 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
10092 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
10093 found)->labelno));
10094 return;
10095 }
10096 }
10097
10098 /* If we're going to put a double constant in the TOC, make sure it's
10099 aligned properly when strict alignment is on. */
ff1720ed
RK
10100 if (GET_CODE (x) == CONST_DOUBLE
10101 && STRICT_ALIGNMENT
a9098fd0 10102 && GET_MODE_BITSIZE (mode) >= 64
ff1720ed
RK
10103 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
10104 ASM_OUTPUT_ALIGN (file, 3);
10105 }
10106
9ebbca7d 10107 ASM_OUTPUT_INTERNAL_LABEL (file, "LC", labelno);
9878760c 10108
37c37a57
RK
10109 /* Handle FP constants specially. Note that if we have a minimal
10110 TOC, things we put here aren't actually in the TOC, so we can allow
10111 FP constants. */
a9098fd0 10112 if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
9878760c 10113 {
042259f2
DE
10114 REAL_VALUE_TYPE rv;
10115 long k[2];
0adc764e 10116
042259f2
DE
10117 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
10118 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
31bfaa0b 10119
13ded975
DE
10120 if (TARGET_64BIT)
10121 {
10122 if (TARGET_MINIMAL_TOC)
2bfcf297 10123 fputs (DOUBLE_INT_ASM_OP, file);
13ded975 10124 else
2bfcf297
DB
10125 fprintf (file, "\t.tc FD_%lx_%lx[TC],", k[0], k[1]);
10126 fprintf (file, "0x%lx%08lx\n", k[0], k[1]);
13ded975
DE
10127 return;
10128 }
1875cc88 10129 else
13ded975
DE
10130 {
10131 if (TARGET_MINIMAL_TOC)
2bfcf297 10132 fputs ("\t.long ", file);
13ded975 10133 else
2bfcf297
DB
10134 fprintf (file, "\t.tc FD_%lx_%lx[TC],", k[0], k[1]);
10135 fprintf (file, "0x%lx,0x%lx\n", k[0], k[1]);
13ded975
DE
10136 return;
10137 }
9878760c 10138 }
a9098fd0 10139 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
9878760c 10140 {
042259f2
DE
10141 REAL_VALUE_TYPE rv;
10142 long l;
9878760c 10143
042259f2
DE
10144 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
10145 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
10146
31bfaa0b
DE
10147 if (TARGET_64BIT)
10148 {
10149 if (TARGET_MINIMAL_TOC)
2bfcf297 10150 fputs (DOUBLE_INT_ASM_OP, file);
31bfaa0b 10151 else
2bfcf297
DB
10152 fprintf (file, "\t.tc FS_%lx[TC],", l);
10153 fprintf (file, "0x%lx00000000\n", l);
31bfaa0b
DE
10154 return;
10155 }
042259f2 10156 else
31bfaa0b
DE
10157 {
10158 if (TARGET_MINIMAL_TOC)
2bfcf297 10159 fputs ("\t.long ", file);
31bfaa0b 10160 else
2bfcf297
DB
10161 fprintf (file, "\t.tc FS_%lx[TC],", l);
10162 fprintf (file, "0x%lx\n", l);
31bfaa0b
DE
10163 return;
10164 }
042259f2 10165 }
f176e826 10166 else if (GET_MODE (x) == VOIDmode
a9098fd0 10167 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
042259f2 10168 {
e2c953b6 10169 unsigned HOST_WIDE_INT low;
042259f2
DE
10170 HOST_WIDE_INT high;
10171
10172 if (GET_CODE (x) == CONST_DOUBLE)
10173 {
10174 low = CONST_DOUBLE_LOW (x);
10175 high = CONST_DOUBLE_HIGH (x);
10176 }
10177 else
10178#if HOST_BITS_PER_WIDE_INT == 32
10179 {
10180 low = INTVAL (x);
0858c623 10181 high = (low & 0x80000000) ? ~0 : 0;
042259f2
DE
10182 }
10183#else
10184 {
0858c623 10185 low = INTVAL (x) & 0xffffffff;
042259f2
DE
10186 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
10187 }
10188#endif
9878760c 10189
a9098fd0
GK
10190 /* TOC entries are always Pmode-sized, but since this
10191 is a bigendian machine then if we're putting smaller
10192 integer constants in the TOC we have to pad them.
10193 (This is still a win over putting the constants in
10194 a separate constant pool, because then we'd have
02a4ec28
FS
10195 to have both a TOC entry _and_ the actual constant.)
10196
10197 For a 32-bit target, CONST_INT values are loaded and shifted
10198 entirely within `low' and can be stored in one TOC entry. */
10199
10200 if (TARGET_64BIT && POINTER_SIZE < GET_MODE_BITSIZE (mode))
a9098fd0 10201 abort ();/* It would be easy to make this work, but it doesn't now. */
02a4ec28
FS
10202
10203 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
a9098fd0
GK
10204 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
10205 POINTER_SIZE, &low, &high, 0);
10206
13ded975
DE
10207 if (TARGET_64BIT)
10208 {
10209 if (TARGET_MINIMAL_TOC)
2bfcf297 10210 fputs (DOUBLE_INT_ASM_OP, file);
13ded975 10211 else
e72247f4 10212 fprintf (file, "\t.tc ID_%lx_%lx[TC],", (long) high, (long) low);
2bfcf297 10213 fprintf (file, "0x%lx%08lx\n", (long) high, (long) low);
13ded975
DE
10214 return;
10215 }
1875cc88 10216 else
13ded975 10217 {
02a4ec28
FS
10218 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
10219 {
10220 if (TARGET_MINIMAL_TOC)
2bfcf297 10221 fputs ("\t.long ", file);
02a4ec28 10222 else
2bfcf297 10223 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
e72247f4 10224 (long) high, (long) low);
2bfcf297 10225 fprintf (file, "0x%lx,0x%lx\n", (long) high, (long) low);
02a4ec28 10226 }
13ded975 10227 else
02a4ec28
FS
10228 {
10229 if (TARGET_MINIMAL_TOC)
2bfcf297 10230 fputs ("\t.long ", file);
02a4ec28 10231 else
2bfcf297
DB
10232 fprintf (file, "\t.tc IS_%lx[TC],", (long) low);
10233 fprintf (file, "0x%lx\n", (long) low);
02a4ec28 10234 }
13ded975
DE
10235 return;
10236 }
9878760c
RK
10237 }
10238
10239 if (GET_CODE (x) == CONST)
10240 {
2bfcf297
DB
10241 if (GET_CODE (XEXP (x, 0)) != PLUS)
10242 abort ();
10243
9878760c
RK
10244 base = XEXP (XEXP (x, 0), 0);
10245 offset = INTVAL (XEXP (XEXP (x, 0), 1));
10246 }
10247
10248 if (GET_CODE (base) == SYMBOL_REF)
10249 name = XSTR (base, 0);
10250 else if (GET_CODE (base) == LABEL_REF)
10251 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (base, 0)));
10252 else if (GET_CODE (base) == CODE_LABEL)
10253 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
10254 else
10255 abort ();
10256
2e4eb9b0 10257 STRIP_NAME_ENCODING (real_name, name);
1875cc88 10258 if (TARGET_MINIMAL_TOC)
2bfcf297 10259 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
1875cc88
JW
10260 else
10261 {
b6c9286a 10262 fprintf (file, "\t.tc %s", real_name);
9878760c 10263
1875cc88
JW
10264 if (offset < 0)
10265 fprintf (file, ".N%d", - offset);
10266 else if (offset)
10267 fprintf (file, ".P%d", offset);
9878760c 10268
19d2d16f 10269 fputs ("[TC],", file);
1875cc88 10270 }
581bc4de
MM
10271
10272 /* Currently C++ toc references to vtables can be emitted before it
10273 is decided whether the vtable is public or private. If this is
10274 the case, then the linker will eventually complain that there is
10275 a TOC reference to an unknown section. Thus, for vtables only,
10276 we emit the TOC reference to reference the symbol and not the
10277 section. */
28e510bd 10278 if (VTABLE_NAME_P (name))
581bc4de 10279 {
54ee9799 10280 RS6000_OUTPUT_BASENAME (file, name);
581bc4de
MM
10281 if (offset < 0)
10282 fprintf (file, "%d", offset);
10283 else if (offset > 0)
10284 fprintf (file, "+%d", offset);
10285 }
10286 else
10287 output_addr_const (file, x);
19d2d16f 10288 putc ('\n', file);
9878760c
RK
10289}
10290\f
10291/* Output an assembler pseudo-op to write an ASCII string of N characters
10292 starting at P to FILE.
10293
10294 On the RS/6000, we have to do this using the .byte operation and
10295 write out special characters outside the quoted string.
10296 Also, the assembler is broken; very long strings are truncated,
a4f6c312 10297 so we must artificially break them up early. */
9878760c
RK
10298
10299void
10300output_ascii (file, p, n)
10301 FILE *file;
d330fd93 10302 const char *p;
9878760c
RK
10303 int n;
10304{
10305 char c;
10306 int i, count_string;
d330fd93
KG
10307 const char *for_string = "\t.byte \"";
10308 const char *for_decimal = "\t.byte ";
10309 const char *to_close = NULL;
9878760c
RK
10310
10311 count_string = 0;
10312 for (i = 0; i < n; i++)
10313 {
10314 c = *p++;
10315 if (c >= ' ' && c < 0177)
10316 {
10317 if (for_string)
10318 fputs (for_string, file);
10319 putc (c, file);
10320
10321 /* Write two quotes to get one. */
10322 if (c == '"')
10323 {
10324 putc (c, file);
10325 ++count_string;
10326 }
10327
10328 for_string = NULL;
10329 for_decimal = "\"\n\t.byte ";
10330 to_close = "\"\n";
10331 ++count_string;
10332
10333 if (count_string >= 512)
10334 {
10335 fputs (to_close, file);
10336
10337 for_string = "\t.byte \"";
10338 for_decimal = "\t.byte ";
10339 to_close = NULL;
10340 count_string = 0;
10341 }
10342 }
10343 else
10344 {
10345 if (for_decimal)
10346 fputs (for_decimal, file);
10347 fprintf (file, "%d", c);
10348
10349 for_string = "\n\t.byte \"";
10350 for_decimal = ", ";
10351 to_close = "\n";
10352 count_string = 0;
10353 }
10354 }
10355
10356 /* Now close the string if we have written one. Then end the line. */
10357 if (to_close)
9ebbca7d 10358 fputs (to_close, file);
9878760c
RK
10359}
10360\f
10361/* Generate a unique section name for FILENAME for a section type
10362 represented by SECTION_DESC. Output goes into BUF.
10363
10364 SECTION_DESC can be any string, as long as it is different for each
10365 possible section type.
10366
10367 We name the section in the same manner as xlc. The name begins with an
10368 underscore followed by the filename (after stripping any leading directory
11e5fe42
RK
10369 names) with the last period replaced by the string SECTION_DESC. If
10370 FILENAME does not contain a period, SECTION_DESC is appended to the end of
10371 the name. */
9878760c
RK
10372
10373void
10374rs6000_gen_section_name (buf, filename, section_desc)
10375 char **buf;
9ebbca7d
GK
10376 const char *filename;
10377 const char *section_desc;
9878760c 10378{
9ebbca7d 10379 const char *q, *after_last_slash, *last_period = 0;
9878760c
RK
10380 char *p;
10381 int len;
9878760c
RK
10382
10383 after_last_slash = filename;
10384 for (q = filename; *q; q++)
11e5fe42
RK
10385 {
10386 if (*q == '/')
10387 after_last_slash = q + 1;
10388 else if (*q == '.')
10389 last_period = q;
10390 }
9878760c 10391
11e5fe42 10392 len = strlen (after_last_slash) + strlen (section_desc) + 2;
9878760c
RK
10393 *buf = (char *) permalloc (len);
10394
10395 p = *buf;
10396 *p++ = '_';
10397
10398 for (q = after_last_slash; *q; q++)
10399 {
11e5fe42 10400 if (q == last_period)
9878760c
RK
10401 {
10402 strcpy (p, section_desc);
10403 p += strlen (section_desc);
9878760c
RK
10404 }
10405
e9a780ec 10406 else if (ISALNUM (*q))
9878760c
RK
10407 *p++ = *q;
10408 }
10409
11e5fe42 10410 if (last_period == 0)
9878760c
RK
10411 strcpy (p, section_desc);
10412 else
10413 *p = '\0';
10414}
e165f3f0 10415\f
a4f6c312 10416/* Emit profile function. */
411707f4 10417
411707f4
CC
10418void
10419output_profile_hook (labelno)
10420 int labelno;
10421{
8480e480
CC
10422 if (DEFAULT_ABI == ABI_AIX)
10423 {
10424 char buf[30];
40501e5f 10425 const char *label_name;
8480e480 10426 rtx fun;
411707f4 10427
8480e480 10428 labelno += 1;
411707f4 10429
8480e480
CC
10430 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
10431 STRIP_NAME_ENCODING (label_name, ggc_strdup (buf));
10432 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
411707f4 10433
8480e480
CC
10434 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1,
10435 fun, Pmode);
10436 }
ee890fe2
SS
10437 else if (DEFAULT_ABI == ABI_DARWIN)
10438 {
d5fa86ba 10439 const char *mcount_name = RS6000_MCOUNT;
ee890fe2
SS
10440 int caller_addr_regno = LINK_REGISTER_REGNUM;
10441
10442 /* Be conservative and always set this, at least for now. */
10443 current_function_uses_pic_offset_table = 1;
10444
10445#if TARGET_MACHO
10446 /* For PIC code, set up a stub and collect the caller's address
10447 from r0, which is where the prologue puts it. */
10448 if (flag_pic)
10449 {
10450 mcount_name = machopic_stub_name (mcount_name);
10451 if (current_function_uses_pic_offset_table)
10452 caller_addr_regno = 0;
10453 }
10454#endif
10455 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
10456 0, VOIDmode, 1,
10457 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
10458 }
411707f4
CC
10459}
10460
a4f6c312 10461/* Write function profiler code. */
e165f3f0
RK
10462
10463void
10464output_function_profiler (file, labelno)
10465 FILE *file;
10466 int labelno;
10467{
3daf36a4 10468 char buf[100];
e165f3f0 10469
3daf36a4 10470 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
38c1f2d7 10471 switch (DEFAULT_ABI)
3daf36a4 10472 {
38c1f2d7
MM
10473 default:
10474 abort ();
10475
10476 case ABI_V4:
38c1f2d7
MM
10477 case ABI_AIX_NODESC:
10478 fprintf (file, "\tmflr %s\n", reg_names[0]);
10479 if (flag_pic == 1)
10480 {
dfdfa60f
DE
10481 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
10482 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
10483 reg_names[0], reg_names[1]);
17167fd8 10484 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
dfdfa60f 10485 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
38c1f2d7 10486 assemble_name (file, buf);
17167fd8 10487 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
38c1f2d7 10488 }
9ebbca7d 10489 else if (flag_pic > 1)
38c1f2d7 10490 {
dfdfa60f
DE
10491 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
10492 reg_names[0], reg_names[1]);
9ebbca7d
GK
10493 /* Now, we need to get the address of the label. */
10494 fputs ("\tbl 1f\n\t.long ", file);
034e84c4 10495 assemble_name (file, buf);
9ebbca7d
GK
10496 fputs ("-.\n1:", file);
10497 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
10498 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
10499 reg_names[0], reg_names[11]);
10500 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
10501 reg_names[0], reg_names[0], reg_names[11]);
38c1f2d7 10502 }
38c1f2d7
MM
10503 else
10504 {
17167fd8 10505 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
38c1f2d7 10506 assemble_name (file, buf);
dfdfa60f 10507 fputs ("@ha\n", file);
b5253831
DE
10508 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
10509 reg_names[0], reg_names[1]);
a260abc9 10510 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
38c1f2d7 10511 assemble_name (file, buf);
17167fd8 10512 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
38c1f2d7
MM
10513 }
10514
b5253831
DE
10515 if (current_function_needs_context)
10516 asm_fprintf (file, "\tmr %s,%s\n",
10517 reg_names[30], reg_names[STATIC_CHAIN_REGNUM]);
38c1f2d7 10518 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
b5253831
DE
10519 if (current_function_needs_context)
10520 asm_fprintf (file, "\tmr %s,%s\n",
10521 reg_names[STATIC_CHAIN_REGNUM], reg_names[30]);
38c1f2d7
MM
10522 break;
10523
10524 case ABI_AIX:
ee890fe2 10525 case ABI_DARWIN:
a4f6c312 10526 /* Don't do anything, done in output_profile_hook (). */
38c1f2d7 10527 break;
411707f4 10528
38c1f2d7 10529 }
e165f3f0 10530}
a251ffd0
TG
10531
10532/* Adjust the cost of a scheduling dependency. Return the new cost of
10533 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
10534
c237e94a 10535static int
a06faf84 10536rs6000_adjust_cost (insn, link, dep_insn, cost)
a251ffd0
TG
10537 rtx insn;
10538 rtx link;
296b8152 10539 rtx dep_insn ATTRIBUTE_UNUSED;
a251ffd0
TG
10540 int cost;
10541{
10542 if (! recog_memoized (insn))
10543 return 0;
10544
10545 if (REG_NOTE_KIND (link) != 0)
10546 return 0;
10547
10548 if (REG_NOTE_KIND (link) == 0)
10549 {
ed947a96
DJ
10550 /* Data dependency; DEP_INSN writes a register that INSN reads
10551 some cycles later. */
10552 switch (get_attr_type (insn))
10553 {
10554 case TYPE_JMPREG:
10555 /* Tell the first scheduling pass about the latency between
10556 a mtctr and bctr (and mtlr and br/blr). The first
10557 scheduling pass will not know about this latency since
10558 the mtctr instruction, which has the latency associated
10559 to it, will be generated by reload. */
10560 return TARGET_POWER ? 5 : 4;
10561 case TYPE_BRANCH:
10562 /* Leave some extra cycles between a compare and its
10563 dependent branch, to inhibit expensive mispredicts. */
10564 if ((rs6000_cpu_attr == CPU_PPC750
10565 || rs6000_cpu_attr == CPU_PPC7400
10566 || rs6000_cpu_attr == CPU_PPC7450)
10567 && recog_memoized (dep_insn)
10568 && (INSN_CODE (dep_insn) >= 0)
10569 && (get_attr_type (dep_insn) == TYPE_COMPARE
10570 || get_attr_type (dep_insn) == TYPE_DELAYED_COMPARE
10571 || get_attr_type (dep_insn) == TYPE_FPCOMPARE
10572 || get_attr_type (dep_insn) == TYPE_CR_LOGICAL))
10573 return cost + 2;
10574 default:
10575 break;
10576 }
a251ffd0
TG
10577 /* Fall out to return default cost. */
10578 }
10579
10580 return cost;
10581}
b6c9286a 10582
a4f6c312
SS
10583/* A C statement (sans semicolon) to update the integer scheduling
10584 priority INSN_PRIORITY (INSN). Reduce the priority to execute the
10585 INSN earlier, increase the priority to execute INSN later. Do not
10586 define this macro if you do not need to adjust the scheduling
10587 priorities of insns. */
bef84347 10588
c237e94a 10589static int
bef84347 10590rs6000_adjust_priority (insn, priority)
d330fd93 10591 rtx insn ATTRIBUTE_UNUSED;
bef84347
VM
10592 int priority;
10593{
a4f6c312
SS
10594 /* On machines (like the 750) which have asymmetric integer units,
10595 where one integer unit can do multiply and divides and the other
10596 can't, reduce the priority of multiply/divide so it is scheduled
10597 before other integer operations. */
bef84347
VM
10598
10599#if 0
2c3c49de 10600 if (! INSN_P (insn))
bef84347
VM
10601 return priority;
10602
10603 if (GET_CODE (PATTERN (insn)) == USE)
10604 return priority;
10605
10606 switch (rs6000_cpu_attr) {
10607 case CPU_PPC750:
10608 switch (get_attr_type (insn))
10609 {
10610 default:
10611 break;
10612
10613 case TYPE_IMUL:
10614 case TYPE_IDIV:
3cb999d8
DE
10615 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
10616 priority, priority);
bef84347
VM
10617 if (priority >= 0 && priority < 0x01000000)
10618 priority >>= 3;
10619 break;
10620 }
10621 }
10622#endif
10623
10624 return priority;
10625}
10626
a4f6c312
SS
10627/* Return how many instructions the machine can issue per cycle. */
10628
c237e94a
ZW
10629static int
10630rs6000_issue_rate ()
b6c9286a
MM
10631{
10632 switch (rs6000_cpu_attr) {
3cb999d8
DE
10633 case CPU_RIOS1: /* ? */
10634 case CPU_RS64A:
10635 case CPU_PPC601: /* ? */
ed947a96 10636 case CPU_PPC7450:
3cb999d8 10637 return 3;
b6c9286a 10638 case CPU_PPC603:
bef84347 10639 case CPU_PPC750:
ed947a96 10640 case CPU_PPC7400:
bef84347 10641 return 2;
3cb999d8 10642 case CPU_RIOS2:
b6c9286a 10643 case CPU_PPC604:
19684119 10644 case CPU_PPC604E:
b6c9286a 10645 case CPU_PPC620:
3cb999d8 10646 case CPU_PPC630:
b6c9286a
MM
10647 return 4;
10648 default:
10649 return 1;
10650 }
10651}
10652
b6c9286a 10653\f
b6c9286a
MM
10654/* Length in units of the trampoline for entering a nested function. */
10655
10656int
10657rs6000_trampoline_size ()
10658{
10659 int ret = 0;
10660
10661 switch (DEFAULT_ABI)
10662 {
10663 default:
10664 abort ();
10665
10666 case ABI_AIX:
8f802bfb 10667 ret = (TARGET_32BIT) ? 12 : 24;
b6c9286a
MM
10668 break;
10669
4dabc42d 10670 case ABI_DARWIN:
b6c9286a
MM
10671 case ABI_V4:
10672 case ABI_AIX_NODESC:
03a7e1a5 10673 ret = (TARGET_32BIT) ? 40 : 48;
b6c9286a 10674 break;
b6c9286a
MM
10675 }
10676
10677 return ret;
10678}
10679
10680/* Emit RTL insns to initialize the variable parts of a trampoline.
10681 FNADDR is an RTX for the address of the function's pure code.
10682 CXT is an RTX for the static chain value for the function. */
10683
10684void
10685rs6000_initialize_trampoline (addr, fnaddr, cxt)
10686 rtx addr;
10687 rtx fnaddr;
10688 rtx cxt;
10689{
ac2a93a1 10690 enum machine_mode pmode = Pmode;
8bd04c56
MM
10691 int regsize = (TARGET_32BIT) ? 4 : 8;
10692 rtx ctx_reg = force_reg (pmode, cxt);
b6c9286a
MM
10693
10694 switch (DEFAULT_ABI)
10695 {
10696 default:
10697 abort ();
10698
8bd04c56 10699/* Macros to shorten the code expansions below. */
39403d82 10700#define MEM_DEREF(addr) gen_rtx_MEM (pmode, memory_address (pmode, addr))
c5c76735
JL
10701#define MEM_PLUS(addr,offset) \
10702 gen_rtx_MEM (pmode, memory_address (pmode, plus_constant (addr, offset)))
7c59dc5d 10703
b6c9286a
MM
10704 /* Under AIX, just build the 3 word function descriptor */
10705 case ABI_AIX:
8bd04c56
MM
10706 {
10707 rtx fn_reg = gen_reg_rtx (pmode);
10708 rtx toc_reg = gen_reg_rtx (pmode);
10709 emit_move_insn (fn_reg, MEM_DEREF (fnaddr));
1cb18e3c 10710 emit_move_insn (toc_reg, MEM_PLUS (fnaddr, regsize));
8bd04c56
MM
10711 emit_move_insn (MEM_DEREF (addr), fn_reg);
10712 emit_move_insn (MEM_PLUS (addr, regsize), toc_reg);
10713 emit_move_insn (MEM_PLUS (addr, 2*regsize), ctx_reg);
10714 }
b6c9286a
MM
10715 break;
10716
4dabc42d
TC
10717 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
10718 case ABI_DARWIN:
b6c9286a
MM
10719 case ABI_V4:
10720 case ABI_AIX_NODESC:
39403d82 10721 emit_library_call (gen_rtx_SYMBOL_REF (SImode, "__trampoline_setup"),
eaf1bcf1
MM
10722 FALSE, VOIDmode, 4,
10723 addr, pmode,
10724 GEN_INT (rs6000_trampoline_size ()), SImode,
10725 fnaddr, pmode,
10726 ctx_reg, pmode);
b6c9286a 10727 break;
b6c9286a
MM
10728 }
10729
10730 return;
10731}
7509c759
MM
10732
10733\f
91d231cb 10734/* Table of valid machine attributes. */
a4f6c312 10735
91d231cb 10736const struct attribute_spec rs6000_attribute_table[] =
7509c759 10737{
91d231cb
JM
10738 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
10739 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
10740 { NULL, 0, 0, false, false, false, NULL }
10741};
7509c759 10742
a4f6c312
SS
10743/* Handle a "longcall" attribute; arguments as in struct
10744 attribute_spec.handler. */
10745
91d231cb
JM
10746static tree
10747rs6000_handle_longcall_attribute (node, name, args, flags, no_add_attrs)
10748 tree *node;
10749 tree name;
10750 tree args ATTRIBUTE_UNUSED;
10751 int flags ATTRIBUTE_UNUSED;
10752 bool *no_add_attrs;
10753{
10754 if (TREE_CODE (*node) != FUNCTION_TYPE
10755 && TREE_CODE (*node) != FIELD_DECL
10756 && TREE_CODE (*node) != TYPE_DECL)
10757 {
10758 warning ("`%s' attribute only applies to functions",
10759 IDENTIFIER_POINTER (name));
10760 *no_add_attrs = true;
10761 }
6a4cee5f 10762
91d231cb 10763 return NULL_TREE;
7509c759
MM
10764}
10765
3cb999d8
DE
10766/* Return a reference suitable for calling a function with the
10767 longcall attribute. */
a4f6c312 10768
6a4cee5f
MM
10769struct rtx_def *
10770rs6000_longcall_ref (call_ref)
10771 rtx call_ref;
10772{
d330fd93 10773 const char *call_name;
6a4cee5f
MM
10774 tree node;
10775
10776 if (GET_CODE (call_ref) != SYMBOL_REF)
10777 return call_ref;
10778
10779 /* System V adds '.' to the internal name, so skip them. */
10780 call_name = XSTR (call_ref, 0);
10781 if (*call_name == '.')
10782 {
10783 while (*call_name == '.')
10784 call_name++;
10785
10786 node = get_identifier (call_name);
39403d82 10787 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
6a4cee5f
MM
10788 }
10789
10790 return force_reg (Pmode, call_ref);
10791}
10792
7509c759
MM
10793\f
10794/* A C statement or statements to switch to the appropriate section
10795 for output of RTX in mode MODE. You can assume that RTX is some
10796 kind of constant in RTL. The argument MODE is redundant except in
10797 the case of a `const_int' rtx. Select the section by calling
10798 `text_section' or one of the alternatives for other sections.
10799
10800 Do not define this macro if you put all constants in the read-only
10801 data section. */
10802
b91da81f 10803#ifdef USING_ELFOS_H
7509c759
MM
10804
10805void
10806rs6000_select_rtx_section (mode, x)
a9098fd0 10807 enum machine_mode mode;
7509c759
MM
10808 rtx x;
10809{
a9098fd0 10810 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
7509c759 10811 toc_section ();
5b19b10c
RH
10812 else if (flag_pic
10813 && (GET_CODE (x) == SYMBOL_REF
10814 || GET_CODE (x) == LABEL_REF
10815 || GET_CODE (x) == CONST))
10816 data_section ();
7509c759
MM
10817 else
10818 const_section ();
10819}
10820
10821/* A C statement or statements to switch to the appropriate
10822 section for output of DECL. DECL is either a `VAR_DECL' node
10823 or a constant of some sort. RELOC indicates whether forming
10824 the initial value of DECL requires link-time relocations. */
10825
10826void
10827rs6000_select_section (decl, reloc)
10828 tree decl;
10829 int reloc;
10830{
10831 int size = int_size_in_bytes (TREE_TYPE (decl));
63019373
GK
10832 int needs_sdata;
10833 int readonly;
10834 static void (* const sec_funcs[4]) PARAMS ((void)) = {
10835 &const_section,
10836 &sdata2_section,
10837 &data_section,
10838 &sdata_section
10839 };
10840
10841 needs_sdata = (size > 0
10842 && size <= g_switch_value
10843 && rs6000_sdata != SDATA_NONE
10844 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)));
7509c759
MM
10845
10846 if (TREE_CODE (decl) == STRING_CST)
63019373 10847 readonly = ! flag_writable_strings;
a9098fd0 10848 else if (TREE_CODE (decl) == VAR_DECL)
63019373
GK
10849 readonly = (! (flag_pic && reloc)
10850 && TREE_READONLY (decl)
10851 && ! TREE_SIDE_EFFECTS (decl)
10852 && DECL_INITIAL (decl)
10853 && DECL_INITIAL (decl) != error_mark_node
10854 && TREE_CONSTANT (DECL_INITIAL (decl)));
ac4f7ad9
GK
10855 else if (TREE_CODE (decl) == CONSTRUCTOR)
10856 readonly = (! (flag_pic && reloc)
ac4f7ad9 10857 && ! TREE_SIDE_EFFECTS (decl)
f3afc192 10858 && TREE_CONSTANT (decl));
7509c759 10859 else
63019373
GK
10860 readonly = 1;
10861 if (needs_sdata && rs6000_sdata != SDATA_EABI)
10862 readonly = 0;
10863
10864 (*sec_funcs[(readonly ? 0 : 2) + (needs_sdata ? 1 : 0)])();
10865}
10866
10867/* A C statement to build up a unique section name, expressed as a
10868 STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
10869 RELOC indicates whether the initial value of EXP requires
10870 link-time relocations. If you do not define this macro, GCC will use
10871 the symbol name prefixed by `.' as the section name. Note - this
f5143c46 10872 macro can now be called for uninitialized data items as well as
63019373
GK
10873 initialised data and functions. */
10874
10875void
10876rs6000_unique_section (decl, reloc)
10877 tree decl;
10878 int reloc;
10879{
63019373
GK
10880 int len;
10881 int sec;
10882 const char *name;
10883 char *string;
10884 const char *prefix;
10885
10886 static const char *const prefixes[7][2] =
10887 {
63019373
GK
10888 { ".rodata.", ".gnu.linkonce.r." },
10889 { ".sdata2.", ".gnu.linkonce.s2." },
10890 { ".data.", ".gnu.linkonce.d." },
10891 { ".sdata.", ".gnu.linkonce.s." },
10892 { ".bss.", ".gnu.linkonce.b." },
5b8c2356
AM
10893 { ".sbss.", ".gnu.linkonce.sb." },
10894 { ".text.", ".gnu.linkonce.t." }
63019373 10895 };
63019373 10896
5b8c2356
AM
10897 if (TREE_CODE (decl) == FUNCTION_DECL)
10898 sec = 6;
63019373 10899 else
5b8c2356
AM
10900 {
10901 int readonly;
10902 int needs_sdata;
10903 int size;
10904
10905 readonly = 1;
10906 if (TREE_CODE (decl) == STRING_CST)
10907 readonly = ! flag_writable_strings;
10908 else if (TREE_CODE (decl) == VAR_DECL)
10909 readonly = (! (flag_pic && reloc)
10910 && TREE_READONLY (decl)
10911 && ! TREE_SIDE_EFFECTS (decl)
10912 && TREE_CONSTANT (DECL_INITIAL (decl)));
10913
10914 size = int_size_in_bytes (TREE_TYPE (decl));
10915 needs_sdata = (size > 0
10916 && size <= g_switch_value
10917 && rs6000_sdata != SDATA_NONE
10918 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)));
10919
10920 if (DECL_INITIAL (decl) == 0
10921 || DECL_INITIAL (decl) == error_mark_node)
10922 sec = 4;
10923 else if (! readonly)
10924 sec = 2;
10925 else
10926 sec = 0;
63019373 10927
5b8c2356
AM
10928 if (needs_sdata)
10929 {
10930 /* .sdata2 is only for EABI. */
10931 if (sec == 0 && rs6000_sdata != SDATA_EABI)
10932 sec = 2;
10933 sec += 1;
10934 }
10935 }
63019373 10936
e6978109 10937 STRIP_NAME_ENCODING (name, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
63019373
GK
10938 prefix = prefixes[sec][DECL_ONE_ONLY (decl)];
10939 len = strlen (name) + strlen (prefix);
10940 string = alloca (len + 1);
10941
10942 sprintf (string, "%s%s", prefix, name);
10943
10944 DECL_SECTION_NAME (decl) = build_string (len, string);
7509c759 10945}
d9407988
MM
10946
10947\f
d9407988
MM
10948/* If we are referencing a function that is static or is known to be
10949 in this file, make the SYMBOL_REF special. We can use this to indicate
10950 that we can branch to this function without emitting a no-op after the
9ebbca7d 10951 call. For real AIX calling sequences, we also replace the
d9407988
MM
10952 function name with the real name (1 or 2 leading .'s), rather than
10953 the function descriptor name. This saves a lot of overriding code
a260abc9 10954 to read the prefixes. */
d9407988
MM
10955
10956void
b2003250 10957rs6000_encode_section_info (decl, first)
d9407988 10958 tree decl;
b2003250 10959 int first;
d9407988 10960{
b2003250
RH
10961 if (!first)
10962 return;
10963
d9407988
MM
10964 if (TREE_CODE (decl) == FUNCTION_DECL)
10965 {
10966 rtx sym_ref = XEXP (DECL_RTL (decl), 0);
8f1b829e 10967 if ((TREE_ASM_WRITTEN (decl) || ! TREE_PUBLIC (decl))
c81fc13e 10968 && ! DECL_WEAK (decl))
d9407988
MM
10969 SYMBOL_REF_FLAG (sym_ref) = 1;
10970
9ebbca7d 10971 if (DEFAULT_ABI == ABI_AIX)
d9407988 10972 {
ff669a6c
RH
10973 size_t len1 = (DEFAULT_ABI == ABI_AIX) ? 1 : 2;
10974 size_t len2 = strlen (XSTR (sym_ref, 0));
520a57c8 10975 char *str = alloca (len1 + len2 + 1);
ff669a6c
RH
10976 str[0] = '.';
10977 str[1] = '.';
10978 memcpy (str + len1, XSTR (sym_ref, 0), len2 + 1);
10979
520a57c8 10980 XSTR (sym_ref, 0) = ggc_alloc_string (str, len1 + len2);
d9407988
MM
10981 }
10982 }
10983 else if (rs6000_sdata != SDATA_NONE
f607bc57 10984 && DEFAULT_ABI == ABI_V4
d9407988
MM
10985 && TREE_CODE (decl) == VAR_DECL)
10986 {
10987 int size = int_size_in_bytes (TREE_TYPE (decl));
10988 tree section_name = DECL_SECTION_NAME (decl);
d330fd93 10989 const char *name = (char *)0;
d9407988
MM
10990 int len = 0;
10991
10992 if (section_name)
10993 {
10994 if (TREE_CODE (section_name) == STRING_CST)
10995 {
10996 name = TREE_STRING_POINTER (section_name);
10997 len = TREE_STRING_LENGTH (section_name);
10998 }
10999 else
11000 abort ();
11001 }
11002
11003 if ((size > 0 && size <= g_switch_value)
11004 || (name
5f59ecb7 11005 && ((len == sizeof (".sdata") - 1
3cb999d8 11006 && strcmp (name, ".sdata") == 0)
5f59ecb7 11007 || (len == sizeof (".sdata2") - 1
3cb999d8 11008 && strcmp (name, ".sdata2") == 0)
5f59ecb7 11009 || (len == sizeof (".sbss") - 1
3cb999d8 11010 && strcmp (name, ".sbss") == 0)
5f59ecb7 11011 || (len == sizeof (".sbss2") - 1
3cb999d8 11012 && strcmp (name, ".sbss2") == 0)
5f59ecb7 11013 || (len == sizeof (".PPC.EMB.sdata0") - 1
3cb999d8 11014 && strcmp (name, ".PPC.EMB.sdata0") == 0)
5f59ecb7 11015 || (len == sizeof (".PPC.EMB.sbss0") - 1
3cb999d8 11016 && strcmp (name, ".PPC.EMB.sbss0") == 0))))
d9407988
MM
11017 {
11018 rtx sym_ref = XEXP (DECL_RTL (decl), 0);
ff669a6c 11019 size_t len = strlen (XSTR (sym_ref, 0));
88c1e412 11020 char *str = alloca (len + 2);
ff669a6c 11021
ff669a6c
RH
11022 str[0] = '@';
11023 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
88c1e412 11024 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
d9407988
MM
11025 }
11026 }
11027}
11028
b91da81f 11029#endif /* USING_ELFOS_H */
000034eb 11030
a6c2a102 11031\f
000034eb 11032/* Return a REG that occurs in ADDR with coefficient 1.
02441cd6
JL
11033 ADDR can be effectively incremented by incrementing REG.
11034
11035 r0 is special and we must not select it as an address
11036 register by this routine since our caller will try to
11037 increment the returned register via an "la" instruction. */
000034eb
DE
11038
11039struct rtx_def *
11040find_addr_reg (addr)
11041 rtx addr;
11042{
11043 while (GET_CODE (addr) == PLUS)
11044 {
02441cd6
JL
11045 if (GET_CODE (XEXP (addr, 0)) == REG
11046 && REGNO (XEXP (addr, 0)) != 0)
000034eb 11047 addr = XEXP (addr, 0);
02441cd6
JL
11048 else if (GET_CODE (XEXP (addr, 1)) == REG
11049 && REGNO (XEXP (addr, 1)) != 0)
000034eb
DE
11050 addr = XEXP (addr, 1);
11051 else if (CONSTANT_P (XEXP (addr, 0)))
11052 addr = XEXP (addr, 1);
11053 else if (CONSTANT_P (XEXP (addr, 1)))
11054 addr = XEXP (addr, 0);
11055 else
11056 abort ();
11057 }
02441cd6 11058 if (GET_CODE (addr) == REG && REGNO (addr) != 0)
000034eb
DE
11059 return addr;
11060 abort ();
11061}
11062
a6c2a102
DE
11063void
11064rs6000_fatal_bad_address (op)
11065 rtx op;
11066{
11067 fatal_insn ("bad address", op);
11068}
c8023011
MM
11069
11070/* Called to register all of our global variables with the garbage
11071 collector. */
11072
11073static void
11074rs6000_add_gc_roots ()
11075{
11076 ggc_add_rtx_root (&rs6000_compare_op0, 1);
11077 ggc_add_rtx_root (&rs6000_compare_op1, 1);
9ebbca7d
GK
11078
11079 toc_hash_table = htab_create (1021, toc_hash_function, toc_hash_eq, NULL);
11080 ggc_add_root (&toc_hash_table, 1, sizeof (toc_hash_table),
11081 toc_hash_mark_table);
ee890fe2
SS
11082
11083#if TARGET_MACHO
11084 machopic_add_gc_roots ();
11085#endif
11086}
11087
11088#if TARGET_MACHO
11089
11090#if 0
11091/* Returns 1 if OP is either a symbol reference or a sum of a symbol
11092 reference and a constant. */
11093
11094int
11095symbolic_operand (op)
592696dd 11096 rtx op;
ee890fe2
SS
11097{
11098 switch (GET_CODE (op))
11099 {
11100 case SYMBOL_REF:
11101 case LABEL_REF:
11102 return 1;
11103 case CONST:
11104 op = XEXP (op, 0);
11105 return (GET_CODE (op) == SYMBOL_REF ||
11106 (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
11107 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
11108 && GET_CODE (XEXP (op, 1)) == CONST_INT);
11109 default:
11110 return 0;
11111 }
c8023011 11112}
ee890fe2
SS
11113#endif
11114
11115#ifdef RS6000_LONG_BRANCH
11116
11117static tree stub_list = 0;
11118
11119/* ADD_COMPILER_STUB adds the compiler generated stub for handling
11120 procedure calls to the linked list. */
11121
11122void
11123add_compiler_stub (label_name, function_name, line_number)
11124 tree label_name;
11125 tree function_name;
11126 int line_number;
11127{
11128 tree stub = build_tree_list (function_name, label_name);
11129 TREE_TYPE (stub) = build_int_2 (line_number, 0);
11130 TREE_CHAIN (stub) = stub_list;
11131 stub_list = stub;
11132}
11133
11134#define STUB_LABEL_NAME(STUB) TREE_VALUE (STUB)
11135#define STUB_FUNCTION_NAME(STUB) TREE_PURPOSE (STUB)
11136#define STUB_LINE_NUMBER(STUB) TREE_INT_CST_LOW (TREE_TYPE (STUB))
11137
a4f6c312
SS
11138/* OUTPUT_COMPILER_STUB outputs the compiler generated stub for
11139 handling procedure calls from the linked list and initializes the
11140 linked list. */
ee890fe2 11141
a4f6c312
SS
11142void
11143output_compiler_stub ()
ee890fe2
SS
11144{
11145 char tmp_buf[256];
11146 char label_buf[256];
11147 char *label;
11148 tree tmp_stub, stub;
11149
11150 if (!flag_pic)
11151 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
11152 {
11153 fprintf (asm_out_file,
11154 "%s:\n", IDENTIFIER_POINTER(STUB_LABEL_NAME(stub)));
11155
11156#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
11157 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
11158 fprintf (asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER(stub));
11159#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
11160
11161 if (IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))[0] == '*')
11162 strcpy (label_buf,
11163 IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))+1);
11164 else
11165 {
11166 label_buf[0] = '_';
11167 strcpy (label_buf+1,
11168 IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub)));
11169 }
11170
11171 strcpy (tmp_buf, "lis r12,hi16(");
11172 strcat (tmp_buf, label_buf);
11173 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
11174 strcat (tmp_buf, label_buf);
11175 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
11176 output_asm_insn (tmp_buf, 0);
11177
11178#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
11179 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
11180 fprintf(asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER (stub));
11181#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
11182 }
11183
11184 stub_list = 0;
11185}
11186
11187/* NO_PREVIOUS_DEF checks in the link list whether the function name is
11188 already there or not. */
11189
a4f6c312
SS
11190int
11191no_previous_def (function_name)
ee890fe2
SS
11192 tree function_name;
11193{
11194 tree stub;
11195 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
11196 if (function_name == STUB_FUNCTION_NAME (stub))
11197 return 0;
11198 return 1;
11199}
11200
11201/* GET_PREV_LABEL gets the label name from the previous definition of
11202 the function. */
11203
a4f6c312
SS
11204tree
11205get_prev_label (function_name)
ee890fe2
SS
11206 tree function_name;
11207{
11208 tree stub;
11209 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
11210 if (function_name == STUB_FUNCTION_NAME (stub))
11211 return STUB_LABEL_NAME (stub);
11212 return 0;
11213}
11214
11215/* INSN is either a function call or a millicode call. It may have an
11216 unconditional jump in its delay slot.
11217
11218 CALL_DEST is the routine we are calling. */
11219
11220char *
11221output_call (insn, call_dest, operand_number)
11222 rtx insn;
11223 rtx call_dest;
11224 int operand_number;
11225{
11226 static char buf[256];
11227 if (GET_CODE (call_dest) == SYMBOL_REF && TARGET_LONG_BRANCH && !flag_pic)
11228 {
11229 tree labelname;
11230 tree funname = get_identifier (XSTR (call_dest, 0));
11231
11232 if (no_previous_def (funname))
11233 {
11234 int line_number;
11235 rtx label_rtx = gen_label_rtx ();
11236 char *label_buf, temp_buf[256];
11237 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
11238 CODE_LABEL_NUMBER (label_rtx));
11239 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
11240 labelname = get_identifier (label_buf);
11241 for (; insn && GET_CODE (insn) != NOTE; insn = PREV_INSN (insn));
11242 if (insn)
11243 line_number = NOTE_LINE_NUMBER (insn);
11244 add_compiler_stub (labelname, funname, line_number);
11245 }
11246 else
11247 labelname = get_prev_label (funname);
11248
11249 sprintf (buf, "jbsr %%z%d,%.246s",
11250 operand_number, IDENTIFIER_POINTER (labelname));
11251 return buf;
11252 }
11253 else
11254 {
11255 sprintf (buf, "bl %%z%d", operand_number);
11256 return buf;
11257 }
11258}
11259
11260#endif /* RS6000_LONG_BRANCH */
11261
11262#define GEN_LOCAL_LABEL_FOR_SYMBOL(BUF,SYMBOL,LENGTH,N) \
11263 do { \
83182544 11264 const char *const symbol_ = (SYMBOL); \
ee890fe2
SS
11265 char *buffer_ = (BUF); \
11266 if (symbol_[0] == '"') \
11267 { \
11268 sprintf(buffer_, "\"L%d$%s", (N), symbol_+1); \
11269 } \
11270 else if (name_needs_quotes(symbol_)) \
11271 { \
11272 sprintf(buffer_, "\"L%d$%s\"", (N), symbol_); \
11273 } \
11274 else \
11275 { \
11276 sprintf(buffer_, "L%d$%s", (N), symbol_); \
11277 } \
11278 } while (0)
11279
11280
11281/* Generate PIC and indirect symbol stubs. */
11282
11283void
11284machopic_output_stub (file, symb, stub)
11285 FILE *file;
11286 const char *symb, *stub;
11287{
11288 unsigned int length;
a4f6c312
SS
11289 char *symbol_name, *lazy_ptr_name;
11290 char *local_label_0;
ee890fe2
SS
11291 static int label = 0;
11292
df56a27f
SS
11293 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
11294 STRIP_NAME_ENCODING (symb, symb);
11295
ee890fe2
SS
11296 label += 1;
11297
ee890fe2
SS
11298 length = strlen (symb);
11299 symbol_name = alloca (length + 32);
11300 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
11301
11302 lazy_ptr_name = alloca (length + 32);
11303 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
11304
11305 local_label_0 = alloca (length + 32);
11306 GEN_LOCAL_LABEL_FOR_SYMBOL (local_label_0, symb, length, 0);
11307
ee890fe2
SS
11308 if (flag_pic == 2)
11309 machopic_picsymbol_stub_section ();
11310 else
11311 machopic_symbol_stub_section ();
11312
11313 fprintf (file, "%s:\n", stub);
11314 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
11315
11316 if (flag_pic == 2)
11317 {
11318 fprintf (file, "\tmflr r0\n");
11319 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
11320 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
11321 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
11322 lazy_ptr_name, local_label_0);
11323 fprintf (file, "\tmtlr r0\n");
11324 fprintf (file, "\tlwz r12,lo16(%s-%s)(r11)\n",
11325 lazy_ptr_name, local_label_0);
11326 fprintf (file, "\tmtctr r12\n");
11327 fprintf (file, "\taddi r11,r11,lo16(%s-%s)\n",
11328 lazy_ptr_name, local_label_0);
11329 fprintf (file, "\tbctr\n");
11330 }
11331 else
11332 fprintf (file, "non-pure not supported\n");
11333
11334 machopic_lazy_symbol_ptr_section ();
11335 fprintf (file, "%s:\n", lazy_ptr_name);
11336 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
11337 fprintf (file, "\t.long dyld_stub_binding_helper\n");
11338}
11339
11340/* Legitimize PIC addresses. If the address is already
11341 position-independent, we return ORIG. Newly generated
11342 position-independent addresses go into a reg. This is REG if non
11343 zero, otherwise we allocate register(s) as necessary. */
11344
c859cda6 11345#define SMALL_INT(X) ((unsigned) (INTVAL(X) + 0x8000) < 0x10000)
ee890fe2
SS
11346
11347rtx
11348rs6000_machopic_legitimize_pic_address (orig, mode, reg)
11349 rtx orig;
11350 enum machine_mode mode;
11351 rtx reg;
11352{
11353 rtx base, offset;
11354
11355 if (reg == NULL && ! reload_in_progress && ! reload_completed)
11356 reg = gen_reg_rtx (Pmode);
11357
11358 if (GET_CODE (orig) == CONST)
11359 {
11360 if (GET_CODE (XEXP (orig, 0)) == PLUS
11361 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
11362 return orig;
11363
11364 if (GET_CODE (XEXP (orig, 0)) == PLUS)
11365 {
a4f6c312
SS
11366 base =
11367 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
11368 Pmode, reg);
11369 offset =
11370 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
11371 Pmode, reg);
ee890fe2
SS
11372 }
11373 else
11374 abort ();
11375
11376 if (GET_CODE (offset) == CONST_INT)
11377 {
11378 if (SMALL_INT (offset))
ed8908e7 11379 return plus_constant (base, INTVAL (offset));
ee890fe2
SS
11380 else if (! reload_in_progress && ! reload_completed)
11381 offset = force_reg (Pmode, offset);
11382 else
c859cda6
DJ
11383 {
11384 rtx mem = force_const_mem (Pmode, orig);
11385 return machopic_legitimize_pic_address (mem, Pmode, reg);
11386 }
ee890fe2
SS
11387 }
11388 return gen_rtx (PLUS, Pmode, base, offset);
11389 }
11390
11391 /* Fall back on generic machopic code. */
11392 return machopic_legitimize_pic_address (orig, mode, reg);
11393}
11394
11395/* This is just a placeholder to make linking work without having to
11396 add this to the generic Darwin EXTRA_SECTIONS. If -mcall-aix is
11397 ever needed for Darwin (not too likely!) this would have to get a
11398 real definition. */
11399
11400void
11401toc_section ()
11402{
11403}
11404
11405#endif /* TARGET_MACHO */
7c262518
RH
11406
11407#if TARGET_ELF
11408static unsigned int
11409rs6000_elf_section_type_flags (decl, name, reloc)
11410 tree decl;
11411 const char *name;
11412 int reloc;
11413{
11414 unsigned int flags = default_section_type_flags (decl, name, reloc);
11415
270fc29b
RH
11416 if (TARGET_RELOCATABLE)
11417 flags |= SECTION_WRITE;
7c262518 11418
d0101753 11419 return flags;
7c262518 11420}
d9f6800d
RH
11421
11422/* Record an element in the table of global constructors. SYMBOL is
11423 a SYMBOL_REF of the function to be called; PRIORITY is a number
11424 between 0 and MAX_INIT_PRIORITY.
11425
11426 This differs from default_named_section_asm_out_constructor in
11427 that we have special handling for -mrelocatable. */
11428
11429static void
11430rs6000_elf_asm_out_constructor (symbol, priority)
11431 rtx symbol;
11432 int priority;
11433{
11434 const char *section = ".ctors";
11435 char buf[16];
11436
11437 if (priority != DEFAULT_INIT_PRIORITY)
11438 {
11439 sprintf (buf, ".ctors.%.5u",
11440 /* Invert the numbering so the linker puts us in the proper
11441 order; constructors are run from right to left, and the
11442 linker sorts in increasing order. */
11443 MAX_INIT_PRIORITY - priority);
11444 section = buf;
11445 }
11446
715bdd29
RH
11447 named_section_flags (section, SECTION_WRITE);
11448 assemble_align (POINTER_SIZE);
d9f6800d
RH
11449
11450 if (TARGET_RELOCATABLE)
11451 {
11452 fputs ("\t.long (", asm_out_file);
11453 output_addr_const (asm_out_file, symbol);
11454 fputs (")@fixup\n", asm_out_file);
11455 }
11456 else
c8af3574 11457 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
d9f6800d
RH
11458}
11459
11460static void
11461rs6000_elf_asm_out_destructor (symbol, priority)
11462 rtx symbol;
11463 int priority;
11464{
11465 const char *section = ".dtors";
11466 char buf[16];
11467
11468 if (priority != DEFAULT_INIT_PRIORITY)
11469 {
11470 sprintf (buf, ".dtors.%.5u",
11471 /* Invert the numbering so the linker puts us in the proper
11472 order; constructors are run from right to left, and the
11473 linker sorts in increasing order. */
11474 MAX_INIT_PRIORITY - priority);
11475 section = buf;
11476 }
11477
715bdd29
RH
11478 named_section_flags (section, SECTION_WRITE);
11479 assemble_align (POINTER_SIZE);
d9f6800d
RH
11480
11481 if (TARGET_RELOCATABLE)
11482 {
11483 fputs ("\t.long (", asm_out_file);
11484 output_addr_const (asm_out_file, symbol);
11485 fputs (")@fixup\n", asm_out_file);
11486 }
11487 else
c8af3574 11488 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
d9f6800d 11489}
7c262518
RH
11490#endif
11491
11492#ifdef OBJECT_FORMAT_COFF
11493static void
715bdd29 11494xcoff_asm_named_section (name, flags)
7c262518
RH
11495 const char *name;
11496 unsigned int flags ATTRIBUTE_UNUSED;
7c262518
RH
11497{
11498 fprintf (asm_out_file, "\t.csect %s\n", name);
11499}
11500#endif