]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/rs6000/rs6000.c
Merge basic-improvements-branch to trunk
[thirdparty/gcc.git] / gcc / config / rs6000 / rs6000.c
CommitLineData
d1bd513e 1/* Subroutines used for code generation on IBM RS/6000.
bbd21807 2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
87ebe3d2 3 2000, 2001, 2002 Free Software Foundation, Inc.
f8404b35 4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
d1bd513e 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
9b754436 20the Free Software Foundation, 59 Temple Place - Suite 330,
21Boston, MA 02111-1307, USA. */
d1bd513e 22
ad87de1e 23#include "config.h"
a665c153 24#include "system.h"
805e22b2 25#include "coretypes.h"
26#include "tm.h"
d1bd513e 27#include "rtl.h"
28#include "regs.h"
29#include "hard-reg-set.h"
30#include "real.h"
31#include "insn-config.h"
32#include "conditions.h"
d1bd513e 33#include "insn-attr.h"
34#include "flags.h"
35#include "recog.h"
d1bd513e 36#include "obstack.h"
c5767608 37#include "tree.h"
7da94773 38#include "expr.h"
3c356178 39#include "optabs.h"
1dd58798 40#include "except.h"
33e46abb 41#include "function.h"
600e851b 42#include "output.h"
aee5207b 43#include "basic-block.h"
16544f20 44#include "integrate.h"
600e851b 45#include "toplev.h"
b36db59b 46#include "ggc.h"
bbd21807 47#include "hashtab.h"
48#include "tm_p.h"
a767736d 49#include "target.h"
50#include "target-def.h"
d19bd1f0 51#include "langhooks.h"
e3374f82 52#include "reload.h"
c5767608 53
7a2fc9d6 54#ifndef TARGET_NO_PROTOTYPE
55#define TARGET_NO_PROTOTYPE 0
56#endif
57
d1bd513e 58#define min(A,B) ((A) < (B) ? (A) : (B))
59#define max(A,B) ((A) > (B) ? (A) : (B))
60
2569277d 61/* Target cpu type */
62
63enum processor_type rs6000_cpu;
2c3f5685 64struct rs6000_cpu_select rs6000_select[3] =
65{
9aba4661 66 /* switch name, tune arch */
67 { (const char *)0, "--with-cpu=", 1, 1 },
68 { (const char *)0, "-mcpu=", 1, 1 },
69 { (const char *)0, "-mtune=", 1, 0 },
2c3f5685 70};
2569277d 71
5b53fefa 72/* Size of long double */
73const char *rs6000_long_double_size_string;
74int rs6000_long_double_type_size;
75
76/* Whether -mabi=altivec has appeared */
77int rs6000_altivec_abi;
78
10363e0e 79/* Whether VRSAVE instructions should be generated. */
80int rs6000_altivec_vrsave;
81
82/* String from -mvrsave= option. */
83const char *rs6000_altivec_vrsave_string;
84
f19493d5 85/* Nonzero if we want SPE ABI extensions. */
86int rs6000_spe_abi;
87
88/* Whether isel instructions should be generated. */
89int rs6000_isel;
90
91/* Nonzero if we have FPRs. */
92int rs6000_fprs = 1;
93
94/* String from -misel=. */
95const char *rs6000_isel_string;
96
e911aedf 97/* Set to nonzero once AIX common-mode calls have been defined. */
f789c138 98static int common_mode_defined;
a91f63e4 99
62afdbc8 100/* Private copy of original value of flag_pic for ABI_AIX. */
101static int rs6000_flag_pic;
102
d1bd513e 103/* Save information from a "cmpxx" operation until the branch or scc is
104 emitted. */
d1bd513e 105rtx rs6000_compare_op0, rs6000_compare_op1;
106int rs6000_compare_fp_p;
f9390446 107
f9390446 108/* Label number of label created for -mrelocatable, to call to so we can
109 get the address of the GOT section */
110int rs6000_pic_labelno;
a91f63e4 111
327811ee 112#ifdef USING_ELFOS_H
a91f63e4 113/* Which abi to adhere to */
9aba4661 114const char *rs6000_abi_name = RS6000_ABI_NAME;
d72e2a6e 115
116/* Semantics of the small data area */
117enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
118
119/* Which small data model to use */
9aba4661 120const char *rs6000_sdata_name = (char *)0;
bbd21807 121
122/* Counter for labels which are to be placed in .fixup. */
123int fixuplabelno = 0;
f9390446 124#endif
a3bbc303 125
6b02f2a5 126/* ABI enumeration available for subtarget to use. */
127enum rs6000_abi rs6000_current_abi;
128
500c7157 129/* ABI string from -mabi= option. */
130const char *rs6000_abi_string;
131
bda6fa4d 132/* Debug flags */
9aba4661 133const char *rs6000_debug_name;
bda6fa4d 134int rs6000_debug_stack; /* debug stack applications */
135int rs6000_debug_arg; /* debug argument handling */
136
58a8d617 137const char *rs6000_traceback_name;
138static enum {
139 traceback_default = 0,
140 traceback_none,
141 traceback_part,
142 traceback_full
143} rs6000_traceback;
144
bda6fa4d 145/* Flag to say the TOC is initialized */
146int toc_initialized;
bbd21807 147char toc_label_name[10];
bda6fa4d 148
bbd21807 149/* Alias set for saves and restores from the rs6000 stack. */
150static int rs6000_sr_alias_set;
b36db59b 151
edd2f2ae 152/* Call distance, overridden by -mlongcall and #pragma longcall(1).
153 The only place that looks at this is rs6000_set_default_type_attributes;
154 everywhere else should rely on the presence or absence of a longcall
155 attribute on the function declaration. */
156int rs6000_default_long_calls;
157const char *rs6000_longcall_switch;
158
f19493d5 159struct builtin_description
160{
161 /* mask is not const because we're going to alter it below. This
162 nonsense will go away when we rewrite the -march infrastructure
163 to give us more target flag bits. */
164 unsigned int mask;
165 const enum insn_code icode;
166 const char *const name;
167 const enum rs6000_builtins code;
168};
169
805e22b2 170static bool rs6000_function_ok_for_sibcall PARAMS ((tree, tree));
bbd21807 171static void rs6000_add_gc_roots PARAMS ((void));
172static int num_insns_constant_wide PARAMS ((HOST_WIDE_INT));
ac313e39 173static void validate_condition_mode
174 PARAMS ((enum rtx_code, enum machine_mode));
175static rtx rs6000_generate_compare PARAMS ((enum rtx_code));
cd97e64a 176static void rs6000_maybe_dead PARAMS ((rtx));
bbd21807 177static void rs6000_emit_stack_tie PARAMS ((void));
178static void rs6000_frame_related PARAMS ((rtx, rtx, HOST_WIDE_INT, rtx, rtx));
012f60b0 179static void emit_frame_save PARAMS ((rtx, rtx, enum machine_mode,
180 unsigned int, int, int));
f19493d5 181static rtx gen_frame_mem_offset PARAMS ((enum machine_mode, rtx, int));
bbd21807 182static void rs6000_emit_allocate_stack PARAMS ((HOST_WIDE_INT, int));
183static unsigned rs6000_hash_constant PARAMS ((rtx));
184static unsigned toc_hash_function PARAMS ((const void *));
185static int toc_hash_eq PARAMS ((const void *, const void *));
a019e19d 186static int toc_hash_mark_entry PARAMS ((void **, void *));
bbd21807 187static void toc_hash_mark_table PARAMS ((void *));
188static int constant_pool_expr_1 PARAMS ((rtx, int *, int *));
1f3233d1 189static struct machine_function * rs6000_init_machine_status PARAMS ((void));
58356836 190static bool rs6000_assemble_integer PARAMS ((rtx, unsigned int, int));
d3e1259a 191#ifdef HAVE_GAS_HIDDEN
8cf34b34 192static void rs6000_assemble_visibility PARAMS ((tree, int));
d3e1259a 193#endif
8f474918 194static int rs6000_ra_ever_killed PARAMS ((void));
e3c541f0 195static tree rs6000_handle_longcall_attribute PARAMS ((tree *, tree, tree, int, bool *));
196const struct attribute_spec rs6000_attribute_table[];
edd2f2ae 197static void rs6000_set_default_type_attributes PARAMS ((tree));
17d9b0c3 198static void rs6000_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
199static void rs6000_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
eb344f43 200static void rs6000_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
201 HOST_WIDE_INT, tree));
8eaf2dd1 202static rtx rs6000_emit_set_long_const PARAMS ((rtx,
203 HOST_WIDE_INT, HOST_WIDE_INT));
2cb4ac60 204#if TARGET_ELF
205static unsigned int rs6000_elf_section_type_flags PARAMS ((tree, const char *,
206 int));
b77e8561 207static void rs6000_elf_asm_out_constructor PARAMS ((rtx, int));
208static void rs6000_elf_asm_out_destructor PARAMS ((rtx, int));
52470889 209static void rs6000_elf_select_section PARAMS ((tree, int,
210 unsigned HOST_WIDE_INT));
211static void rs6000_elf_unique_section PARAMS ((tree, int));
bbfbe351 212static void rs6000_elf_select_rtx_section PARAMS ((enum machine_mode, rtx,
213 unsigned HOST_WIDE_INT));
62afdbc8 214static void rs6000_elf_encode_section_info PARAMS ((tree, int))
215 ATTRIBUTE_UNUSED;
7b4a38a6 216static const char *rs6000_elf_strip_name_encoding PARAMS ((const char *));
62afdbc8 217static bool rs6000_elf_in_small_data_p PARAMS ((tree));
2cb4ac60 218#endif
17fb2af4 219#if TARGET_XCOFF
f9648009 220static void rs6000_xcoff_asm_globalize_label PARAMS ((FILE *, const char *));
221static void rs6000_xcoff_asm_named_section PARAMS ((const char *, unsigned int));
52470889 222static void rs6000_xcoff_select_section PARAMS ((tree, int,
223 unsigned HOST_WIDE_INT));
224static void rs6000_xcoff_unique_section PARAMS ((tree, int));
bbfbe351 225static void rs6000_xcoff_select_rtx_section PARAMS ((enum machine_mode, rtx,
226 unsigned HOST_WIDE_INT));
7b4a38a6 227static const char * rs6000_xcoff_strip_name_encoding PARAMS ((const char *));
d3e1259a 228static unsigned int rs6000_xcoff_section_type_flags PARAMS ((tree, const char *, int));
2cb4ac60 229#endif
7811991d 230static void rs6000_xcoff_encode_section_info PARAMS ((tree, int))
231 ATTRIBUTE_UNUSED;
4e06ed1d 232static bool rs6000_binds_local_p PARAMS ((tree));
747af5e7 233static int rs6000_adjust_cost PARAMS ((rtx, rtx, rtx, int));
234static int rs6000_adjust_priority PARAMS ((rtx, int));
235static int rs6000_issue_rate PARAMS ((void));
236
5b53fefa 237static void rs6000_init_builtins PARAMS ((void));
6d829a46 238static rtx rs6000_expand_unop_builtin PARAMS ((enum insn_code, tree, rtx));
239static rtx rs6000_expand_binop_builtin PARAMS ((enum insn_code, tree, rtx));
240static rtx rs6000_expand_ternop_builtin PARAMS ((enum insn_code, tree, rtx));
500c7157 241static rtx rs6000_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
6d829a46 242static void altivec_init_builtins PARAMS ((void));
f19493d5 243static void rs6000_common_init_builtins PARAMS ((void));
244
245static void enable_mask_for_builtins PARAMS ((struct builtin_description *,
246 int, enum rs6000_builtins,
247 enum rs6000_builtins));
248static void spe_init_builtins PARAMS ((void));
249static rtx spe_expand_builtin PARAMS ((tree, rtx, bool *));
250static rtx spe_expand_predicate_builtin PARAMS ((enum insn_code, tree, rtx));
251static rtx spe_expand_evsel_builtin PARAMS ((enum insn_code, tree, rtx));
252static int rs6000_emit_int_cmove PARAMS ((rtx, rtx, rtx, rtx));
253
6d829a46 254static rtx altivec_expand_builtin PARAMS ((tree, rtx, bool *));
ae1526b2 255static rtx altivec_expand_ld_builtin PARAMS ((tree, rtx, bool *));
256static rtx altivec_expand_st_builtin PARAMS ((tree, rtx, bool *));
257static rtx altivec_expand_dst_builtin PARAMS ((tree, rtx, bool *));
3971c992 258static rtx altivec_expand_abs_builtin PARAMS ((enum insn_code, tree, rtx));
15e5a1c8 259static rtx altivec_expand_predicate_builtin PARAMS ((enum insn_code, const char *, tree, rtx));
9f710c67 260static rtx altivec_expand_stv_builtin PARAMS ((enum insn_code, tree));
500c7157 261static void rs6000_parse_abi_options PARAMS ((void));
10363e0e 262static void rs6000_parse_vrsave_option PARAMS ((void));
f19493d5 263static void rs6000_parse_isel_option PARAMS ((void));
bb78803e 264static int first_altivec_reg_to_save PARAMS ((void));
265static unsigned int compute_vrsave_mask PARAMS ((void));
266static void is_altivec_return_reg PARAMS ((rtx, void *));
43b7e951 267static rtx generate_set_vrsave PARAMS ((rtx, rs6000_stack_t *, int));
268static void altivec_frame_fixup PARAMS ((rtx, rtx, HOST_WIDE_INT));
886cfd4f 269static int easy_vector_constant PARAMS ((rtx));
a91f63e4 270\f
271/* Default register names. */
272char rs6000_reg_names[][8] =
273{
359e408d 274 "0", "1", "2", "3", "4", "5", "6", "7",
275 "8", "9", "10", "11", "12", "13", "14", "15",
276 "16", "17", "18", "19", "20", "21", "22", "23",
277 "24", "25", "26", "27", "28", "29", "30", "31",
278 "0", "1", "2", "3", "4", "5", "6", "7",
279 "8", "9", "10", "11", "12", "13", "14", "15",
280 "16", "17", "18", "19", "20", "21", "22", "23",
281 "24", "25", "26", "27", "28", "29", "30", "31",
282 "mq", "lr", "ctr","ap",
283 "0", "1", "2", "3", "4", "5", "6", "7",
500c7157 284 "xer",
285 /* AltiVec registers. */
aca142b1 286 "0", "1", "2", "3", "4", "5", "6", "7",
287 "8", "9", "10", "11", "12", "13", "14", "15",
288 "16", "17", "18", "19", "20", "21", "22", "23",
289 "24", "25", "26", "27", "28", "29", "30", "31",
500c7157 290 "vrsave"
a91f63e4 291};
292
293#ifdef TARGET_REGNAMES
e99c3a1d 294static const char alt_reg_names[][8] =
a91f63e4 295{
359e408d 296 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
297 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
298 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
299 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
300 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
301 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
302 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
303 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
304 "mq", "lr", "ctr", "ap",
305 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
500c7157 306 "xer",
307 /* AltiVec registers. */
308 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
309 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
310 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
311 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
04b78509 312 "vrsave"
a91f63e4 313};
314#endif
d1bd513e 315\f
ceb26c2d 316#ifndef MASK_STRICT_ALIGN
317#define MASK_STRICT_ALIGN 0
318#endif
eb344f43 319
320/* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
321#define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
a767736d 322\f
323/* Initialize the GCC target structure. */
e3c541f0 324#undef TARGET_ATTRIBUTE_TABLE
325#define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
edd2f2ae 326#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
327#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
ceb26c2d 328
58356836 329#undef TARGET_ASM_ALIGNED_DI_OP
330#define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
331
332/* Default unaligned ops are only provided for ELF. Find the ops needed
333 for non-ELF systems. */
334#ifndef OBJECT_FORMAT_ELF
17fb2af4 335#if TARGET_XCOFF
65dce22d 336/* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
58356836 337 64-bit targets. */
338#undef TARGET_ASM_UNALIGNED_HI_OP
339#define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
340#undef TARGET_ASM_UNALIGNED_SI_OP
341#define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
342#undef TARGET_ASM_UNALIGNED_DI_OP
343#define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
344#else
345/* For Darwin. */
346#undef TARGET_ASM_UNALIGNED_HI_OP
347#define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
348#undef TARGET_ASM_UNALIGNED_SI_OP
349#define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
350#endif
351#endif
352
353/* This hook deals with fixups for relocatable code and DI-mode objects
354 in 64-bit code. */
355#undef TARGET_ASM_INTEGER
356#define TARGET_ASM_INTEGER rs6000_assemble_integer
357
2532673e 358#ifdef HAVE_GAS_HIDDEN
359#undef TARGET_ASM_ASSEMBLE_VISIBILITY
360#define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
361#endif
362
17d9b0c3 363#undef TARGET_ASM_FUNCTION_PROLOGUE
364#define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
365#undef TARGET_ASM_FUNCTION_EPILOGUE
366#define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
367
747af5e7 368#undef TARGET_SCHED_ISSUE_RATE
369#define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
370#undef TARGET_SCHED_ADJUST_COST
371#define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
372#undef TARGET_SCHED_ADJUST_PRIORITY
373#define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
374
500c7157 375#undef TARGET_INIT_BUILTINS
376#define TARGET_INIT_BUILTINS rs6000_init_builtins
377
378#undef TARGET_EXPAND_BUILTIN
379#define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
380
62afdbc8 381#undef TARGET_BINDS_LOCAL_P
382#define TARGET_BINDS_LOCAL_P rs6000_binds_local_p
383
eb344f43 384#undef TARGET_ASM_OUTPUT_MI_THUNK
385#define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
386
387/* ??? Should work everywhere, but ask dje@watson.ibm.com before
388 enabling for AIX. */
389#if TARGET_OBJECT_FORMAT != OBJECT_XCOFF
390#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
391#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
392#endif
bb78803e 393
805e22b2 394#undef TARGET_FUNCTION_OK_FOR_SIBCALL
395#define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
396
57e4bbfb 397struct gcc_target targetm = TARGET_INITIALIZER;
a767736d 398\f
2569277d 399/* Override command line options. Mostly we process the processor
400 type and sometimes adjust other TARGET_ options. */
401
402void
2c3f5685 403rs6000_override_options (default_cpu)
c0256c4b 404 const char *default_cpu;
2569277d 405{
a665c153 406 size_t i, j;
2c3f5685 407 struct rs6000_cpu_select *ptr;
2569277d 408
c7cb5c53 409 /* Simplify the entries below by making a mask for any POWER
410 variant and any PowerPC variant. */
411
fff5066c 412#define POWER_MASKS (MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING)
c65c09ab 413#define POWERPC_MASKS (MASK_POWERPC | MASK_PPC_GPOPT \
414 | MASK_PPC_GFXOPT | MASK_POWERPC64)
415#define POWERPC_OPT_MASKS (MASK_PPC_GPOPT | MASK_PPC_GFXOPT)
c7cb5c53 416
2569277d 417 static struct ptt
418 {
e99c3a1d 419 const char *const name; /* Canonical processor name. */
420 const enum processor_type processor; /* Processor type enum value. */
421 const int target_enable; /* Target flags to enable. */
422 const int target_disable; /* Target flags to disable. */
423 } const processor_target_table[]
8d21c488 424 = {{"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS,
425 POWER_MASKS | POWERPC_MASKS},
c67b68ed 426 {"power", PROCESSOR_POWER,
fff5066c 427 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
c67b68ed 428 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
2c3f5685 429 {"power2", PROCESSOR_POWER,
430 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
431 POWERPC_MASKS | MASK_NEW_MNEMONICS},
a737f54e 432 {"power3", PROCESSOR_PPC630,
433 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
434 POWER_MASKS | MASK_PPC_GPOPT},
72943b59 435 {"power4", PROCESSOR_POWER4,
436 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
437 POWER_MASKS | MASK_PPC_GPOPT},
c67b68ed 438 {"powerpc", PROCESSOR_POWERPC,
439 MASK_POWERPC | MASK_NEW_MNEMONICS,
c65c09ab 440 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
91452706 441 {"powerpc64", PROCESSOR_POWERPC64,
442 MASK_POWERPC | MASK_POWERPC64 | MASK_NEW_MNEMONICS,
443 POWER_MASKS | POWERPC_OPT_MASKS},
c67b68ed 444 {"rios", PROCESSOR_RIOS1,
fff5066c 445 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
c67b68ed 446 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
447 {"rios1", PROCESSOR_RIOS1,
fff5066c 448 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
c67b68ed 449 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
450 {"rsc", PROCESSOR_PPC601,
fff5066c 451 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
c67b68ed 452 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
453 {"rsc1", PROCESSOR_PPC601,
fff5066c 454 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
c67b68ed 455 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
456 {"rios2", PROCESSOR_RIOS2,
fff5066c 457 MASK_POWER | MASK_MULTIPLE | MASK_STRING | MASK_POWER2,
c67b68ed 458 POWERPC_MASKS | MASK_NEW_MNEMONICS},
91452706 459 {"rs64a", PROCESSOR_RS64A,
460 MASK_POWERPC | MASK_NEW_MNEMONICS,
461 POWER_MASKS | POWERPC_OPT_MASKS},
621b7779 462 {"401", PROCESSOR_PPC403,
463 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
464 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
c15e7feb 465 {"403", PROCESSOR_PPC403,
ceb26c2d 466 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS | MASK_STRICT_ALIGN,
c15e7feb 467 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
6a89e91c 468 {"405", PROCESSOR_PPC405,
469 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
470 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
805e22b2 471 {"405f", PROCESSOR_PPC405,
472 MASK_POWERPC | MASK_NEW_MNEMONICS,
473 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
8d21c488 474 {"505", PROCESSOR_MPCCORE,
475 MASK_POWERPC | MASK_NEW_MNEMONICS,
476 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
2569277d 477 {"601", PROCESSOR_PPC601,
fff5066c 478 MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_MULTIPLE | MASK_STRING,
c65c09ab 479 MASK_POWER2 | POWERPC_OPT_MASKS | MASK_POWERPC64},
946e39b5 480 {"602", PROCESSOR_PPC603,
8d21c488 481 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
482 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
2569277d 483 {"603", PROCESSOR_PPC603,
c65c09ab 484 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
485 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
6b02f2a5 486 {"603e", PROCESSOR_PPC603,
487 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
488 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
bdac61d7 489 {"ec603e", PROCESSOR_PPC603,
621b7779 490 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
491 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
2569277d 492 {"604", PROCESSOR_PPC604,
6b02f2a5 493 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
494 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
6533875e 495 {"604e", PROCESSOR_PPC604e,
856df8e6 496 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
497 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
6b02f2a5 498 {"620", PROCESSOR_PPC620,
c65c09ab 499 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
8cda90b9 500 POWER_MASKS | MASK_PPC_GPOPT},
91452706 501 {"630", PROCESSOR_PPC630,
502 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
503 POWER_MASKS | MASK_PPC_GPOPT},
932cf0bd 504 {"740", PROCESSOR_PPC750,
505 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
506 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
507 {"750", PROCESSOR_PPC750,
508 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
509 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
970e222f 510 {"7400", PROCESSOR_PPC7400,
511 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
512 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
513 {"7450", PROCESSOR_PPC7450,
514 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
515 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
f19493d5 516 {"8540", PROCESSOR_PPC8540,
517 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
518 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
856df8e6 519 {"801", PROCESSOR_MPCCORE,
520 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
521 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
8d21c488 522 {"821", PROCESSOR_MPCCORE,
523 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
524 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
856df8e6 525 {"823", PROCESSOR_MPCCORE,
526 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
527 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
8d21c488 528 {"860", PROCESSOR_MPCCORE,
529 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
530 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}};
2569277d 531
3585dac7 532 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
2569277d 533
970e222f 534 /* Save current -mmultiple/-mno-multiple status. */
535 int multiple = TARGET_MULTIPLE;
536 /* Save current -mstring/-mno-string status. */
537 int string = TARGET_STRING;
24b10a77 538
970e222f 539 /* Identify the processor type. */
2c3f5685 540 rs6000_select[0].string = default_cpu;
91452706 541 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2c3f5685 542
3098b2d3 543 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2569277d 544 {
2c3f5685 545 ptr = &rs6000_select[i];
546 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2569277d 547 {
2c3f5685 548 for (j = 0; j < ptt_size; j++)
549 if (! strcmp (ptr->string, processor_target_table[j].name))
550 {
551 if (ptr->set_tune_p)
552 rs6000_cpu = processor_target_table[j].processor;
553
554 if (ptr->set_arch_p)
555 {
556 target_flags |= processor_target_table[j].target_enable;
557 target_flags &= ~processor_target_table[j].target_disable;
558 }
559 break;
560 }
561
406c974e 562 if (j == ptt_size)
2c3f5685 563 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2569277d 564 }
565 }
24b10a77 566
f19493d5 567 if (rs6000_cpu == PROCESSOR_PPC8540)
568 rs6000_isel = 1;
569
f7be3040 570 /* If we are optimizing big endian systems for space, use the load/store
571 multiple and string instructions. */
030ca427 572 if (BYTES_BIG_ENDIAN && optimize_size)
f7be3040 573 target_flags |= MASK_MULTIPLE | MASK_STRING;
030ca427 574
24b10a77 575 /* If -mmultiple or -mno-multiple was explicitly used, don't
576 override with the processor default */
577 if (TARGET_MULTIPLE_SET)
578 target_flags = (target_flags & ~MASK_MULTIPLE) | multiple;
70309a38 579
970e222f 580 /* If -mstring or -mno-string was explicitly used, don't override
581 with the processor default. */
fff5066c 582 if (TARGET_STRING_SET)
3b873801 583 target_flags = (target_flags & ~MASK_STRING) | string;
fff5066c 584
970e222f 585 /* Don't allow -mmultiple or -mstring on little endian systems
586 unless the cpu is a 750, because the hardware doesn't support the
587 instructions used in little endian mode, and causes an alignment
588 trap. The 750 does not cause an alignment trap (except when the
589 target is unaligned). */
932cf0bd 590
5f87920d 591 if (! BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
70309a38 592 {
593 if (TARGET_MULTIPLE)
594 {
595 target_flags &= ~MASK_MULTIPLE;
596 if (TARGET_MULTIPLE_SET)
597 warning ("-mmultiple is not supported on little endian systems");
598 }
599
600 if (TARGET_STRING)
601 {
602 target_flags &= ~MASK_STRING;
fff5066c 603 if (TARGET_STRING_SET)
604 warning ("-mstring is not supported on little endian systems");
70309a38 605 }
606 }
b4b968a6 607
dcc77132 608 if (flag_pic != 0 && DEFAULT_ABI == ABI_AIX)
8cda90b9 609 {
62afdbc8 610 rs6000_flag_pic = flag_pic;
dcc77132 611 flag_pic = 0;
8cda90b9 612 }
613
4cc55ca5 614 /* For Darwin, always silently make -fpic and -fPIC identical. */
615 if (flag_pic == 1 && DEFAULT_ABI == ABI_DARWIN)
616 flag_pic = 2;
617
bda6fa4d 618 /* Set debug flags */
619 if (rs6000_debug_name)
620 {
5f87920d 621 if (! strcmp (rs6000_debug_name, "all"))
bda6fa4d 622 rs6000_debug_stack = rs6000_debug_arg = 1;
5f87920d 623 else if (! strcmp (rs6000_debug_name, "stack"))
bda6fa4d 624 rs6000_debug_stack = 1;
5f87920d 625 else if (! strcmp (rs6000_debug_name, "arg"))
bda6fa4d 626 rs6000_debug_arg = 1;
627 else
68435912 628 error ("unknown -mdebug-%s switch", rs6000_debug_name);
bda6fa4d 629 }
630
58a8d617 631 if (rs6000_traceback_name)
632 {
633 if (! strncmp (rs6000_traceback_name, "full", 4))
634 rs6000_traceback = traceback_full;
635 else if (! strncmp (rs6000_traceback_name, "part", 4))
636 rs6000_traceback = traceback_part;
637 else if (! strncmp (rs6000_traceback_name, "no", 2))
638 rs6000_traceback = traceback_none;
639 else
640 error ("unknown -mtraceback arg `%s'; expecting `full', `partial' or `none'",
641 rs6000_traceback_name);
642 }
643
5b53fefa 644 /* Set size of long double */
645 rs6000_long_double_type_size = 64;
646 if (rs6000_long_double_size_string)
647 {
648 char *tail;
649 int size = strtol (rs6000_long_double_size_string, &tail, 10);
650 if (*tail != '\0' || (size != 64 && size != 128))
651 error ("Unknown switch -mlong-double-%s",
652 rs6000_long_double_size_string);
653 else
654 rs6000_long_double_type_size = size;
655 }
656
500c7157 657 /* Handle -mabi= options. */
658 rs6000_parse_abi_options ();
659
10363e0e 660 /* Handle -mvrsave= option. */
661 rs6000_parse_vrsave_option ();
662
f19493d5 663 /* Handle -misel= option. */
664 rs6000_parse_isel_option ();
665
31d8e5da 666#ifdef SUBTARGET_OVERRIDE_OPTIONS
667 SUBTARGET_OVERRIDE_OPTIONS;
668#endif
669#ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
670 SUBSUBTARGET_OVERRIDE_OPTIONS;
671#endif
672
edd2f2ae 673 /* Handle -m(no-)longcall option. This is a bit of a cheap hack,
674 using TARGET_OPTIONS to handle a toggle switch, but we're out of
675 bits in target_flags so TARGET_SWITCHES cannot be used.
676 Assumption here is that rs6000_longcall_switch points into the
677 text of the complete option, rather than being a copy, so we can
678 scan back for the presence or absence of the no- modifier. */
679 if (rs6000_longcall_switch)
680 {
681 const char *base = rs6000_longcall_switch;
682 while (base[-1] != 'm') base--;
683
684 if (*rs6000_longcall_switch != '\0')
685 error ("invalid option `%s'", base);
686 rs6000_default_long_calls = (base[0] != 'n');
687 }
688
a91f63e4 689#ifdef TARGET_REGNAMES
970e222f 690 /* If the user desires alternate register names, copy in the
691 alternate names now. */
a91f63e4 692 if (TARGET_REGNAMES)
b1b63592 693 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
a91f63e4 694#endif
695
5b53fefa 696 /* Set TARGET_AIX_STRUCT_RET last, after the ABI is determined.
697 If -maix-struct-return or -msvr4-struct-return was explicitly
698 used, don't override with the ABI default. */
699 if (!(target_flags & MASK_AIX_STRUCT_RET_SET))
700 {
701 if (DEFAULT_ABI == ABI_V4 && !DRAFT_V4_STRUCT_RET)
702 target_flags = (target_flags & ~MASK_AIX_STRUCT_RET);
703 else
704 target_flags |= MASK_AIX_STRUCT_RET;
705 }
706
cf7d5bc7 707 if (TARGET_LONG_DOUBLE_128
708 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN))
709 real_format_for_mode[TFmode - QFmode] = &ibm_extended_format;
710
b36db59b 711 /* Register global variables with the garbage collector. */
712 rs6000_add_gc_roots ();
bbd21807 713
714 /* Allocate an alias set for register saves & restores from stack. */
715 rs6000_sr_alias_set = new_alias_set ();
716
717 if (TARGET_TOC)
718 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
8f474918 719
58356836 720 /* We can only guarantee the availability of DI pseudo-ops when
721 assembling for 64-bit targets. */
65dce22d 722 if (!TARGET_64BIT)
58356836 723 {
724 targetm.asm_out.aligned_op.di = NULL;
725 targetm.asm_out.unaligned_op.di = NULL;
726 }
727
8f474918 728 /* Arrange to save and restore machine status around nested functions. */
729 init_machine_status = rs6000_init_machine_status;
2569277d 730}
879c6e0a 731
f19493d5 732/* Handle -misel= option. */
733static void
734rs6000_parse_isel_option ()
735{
736 if (rs6000_isel_string == 0)
737 return;
738 else if (! strcmp (rs6000_isel_string, "yes"))
739 rs6000_isel = 1;
740 else if (! strcmp (rs6000_isel_string, "no"))
741 rs6000_isel = 0;
742 else
743 error ("unknown -misel= option specified: '%s'",
744 rs6000_isel_string);
745}
746
10363e0e 747/* Handle -mvrsave= options. */
748static void
749rs6000_parse_vrsave_option ()
750{
751 /* Generate VRSAVE instructions by default. */
752 if (rs6000_altivec_vrsave_string == 0
753 || ! strcmp (rs6000_altivec_vrsave_string, "yes"))
754 rs6000_altivec_vrsave = 1;
755 else if (! strcmp (rs6000_altivec_vrsave_string, "no"))
756 rs6000_altivec_vrsave = 0;
757 else
758 error ("unknown -mvrsave= option specified: '%s'",
759 rs6000_altivec_vrsave_string);
760}
761
500c7157 762/* Handle -mabi= options. */
bb78803e 763static void
764rs6000_parse_abi_options ()
500c7157 765{
766 if (rs6000_abi_string == 0)
767 return;
768 else if (! strcmp (rs6000_abi_string, "altivec"))
5b53fefa 769 rs6000_altivec_abi = 1;
04b78509 770 else if (! strcmp (rs6000_abi_string, "no-altivec"))
771 rs6000_altivec_abi = 0;
f19493d5 772 else if (! strcmp (rs6000_abi_string, "spe"))
773 rs6000_spe_abi = 1;
774 else if (! strcmp (rs6000_abi_string, "no-spe"))
775 rs6000_spe_abi = 0;
500c7157 776 else
68435912 777 error ("unknown ABI specified: '%s'", rs6000_abi_string);
500c7157 778}
779
879c6e0a 780void
781optimization_options (level, size)
30c5e279 782 int level ATTRIBUTE_UNUSED;
879c6e0a 783 int size ATTRIBUTE_UNUSED;
784{
879c6e0a 785}
8fa3bb0a 786\f
787/* Do anything needed at the start of the asm file. */
788
789void
790rs6000_file_start (file, default_cpu)
791 FILE *file;
c0256c4b 792 const char *default_cpu;
8fa3bb0a 793{
a665c153 794 size_t i;
8fa3bb0a 795 char buffer[80];
c0256c4b 796 const char *start = buffer;
8fa3bb0a 797 struct rs6000_cpu_select *ptr;
798
799 if (flag_verbose_asm)
800 {
801 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
802 rs6000_select[0].string = default_cpu;
803
3098b2d3 804 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
8fa3bb0a 805 {
806 ptr = &rs6000_select[i];
807 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
808 {
809 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
810 start = "";
811 }
812 }
813
327811ee 814#ifdef USING_ELFOS_H
8fa3bb0a 815 switch (rs6000_sdata)
816 {
817 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
818 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
819 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
820 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
821 }
822
823 if (rs6000_sdata && g_switch_value)
824 {
825 fprintf (file, "%s -G %d", start, g_switch_value);
826 start = "";
827 }
828#endif
829
830 if (*start == '\0')
1270d073 831 putc ('\n', file);
8fa3bb0a 832 }
833}
2569277d 834\f
e911aedf 835/* Return nonzero if this function is known to have a null epilogue. */
d1bd513e 836
837int
838direct_return ()
839{
a3bbc303 840 if (reload_completed)
841 {
842 rs6000_stack_t *info = rs6000_stack_info ();
843
844 if (info->first_gp_reg_save == 32
845 && info->first_fp_reg_save == 64
bb78803e 846 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
a516dd3a 847 && ! info->lr_save_p
848 && ! info->cr_save_p
bb78803e 849 && info->vrsave_mask == 0
a516dd3a 850 && ! info->push_p)
a3bbc303 851 return 1;
852 }
853
854 return 0;
d1bd513e 855}
856
857/* Returns 1 always. */
858
859int
860any_operand (op, mode)
773e893a 861 rtx op ATTRIBUTE_UNUSED;
600e851b 862 enum machine_mode mode ATTRIBUTE_UNUSED;
d1bd513e 863{
864 return 1;
865}
866
970e222f 867/* Returns 1 if op is the count register. */
bda6fa4d 868int
970e222f 869count_register_operand (op, mode)
773e893a 870 rtx op;
600e851b 871 enum machine_mode mode ATTRIBUTE_UNUSED;
6b02f2a5 872{
873 if (GET_CODE (op) != REG)
874 return 0;
875
876 if (REGNO (op) == COUNT_REGISTER_REGNUM)
877 return 1;
878
879 if (REGNO (op) > FIRST_PSEUDO_REGISTER)
880 return 1;
881
882 return 0;
883}
884
4625cc70 885/* Returns 1 if op is an altivec register. */
886int
887altivec_register_operand (op, mode)
888 rtx op;
889 enum machine_mode mode ATTRIBUTE_UNUSED;
890{
891
892 return (register_operand (op, mode)
893 && (GET_CODE (op) != REG
894 || REGNO (op) > FIRST_PSEUDO_REGISTER
895 || ALTIVEC_REGNO_P (REGNO (op))));
896}
897
bda6fa4d 898int
970e222f 899xer_operand (op, mode)
773e893a 900 rtx op;
600e851b 901 enum machine_mode mode ATTRIBUTE_UNUSED;
359e408d 902{
903 if (GET_CODE (op) != REG)
904 return 0;
905
bbd21807 906 if (XER_REGNO_P (REGNO (op)))
359e408d 907 return 1;
908
359e408d 909 return 0;
910}
911
ad3ed368 912/* Return 1 if OP is a signed 8-bit constant. Int multiplication
9df03d69 913 by such constants completes more quickly. */
ad3ed368 914
915int
916s8bit_cint_operand (op, mode)
917 rtx op;
918 enum machine_mode mode ATTRIBUTE_UNUSED;
919{
920 return ( GET_CODE (op) == CONST_INT
921 && (INTVAL (op) >= -128 && INTVAL (op) <= 127));
922}
923
d1bd513e 924/* Return 1 if OP is a constant that can fit in a D field. */
925
926int
927short_cint_operand (op, mode)
773e893a 928 rtx op;
600e851b 929 enum machine_mode mode ATTRIBUTE_UNUSED;
d1bd513e 930{
837b446a 931 return (GET_CODE (op) == CONST_INT
932 && CONST_OK_FOR_LETTER_P (INTVAL (op), 'I'));
d1bd513e 933}
934
45981c0a 935/* Similar for an unsigned D field. */
d1bd513e 936
937int
938u_short_cint_operand (op, mode)
773e893a 939 rtx op;
600e851b 940 enum machine_mode mode ATTRIBUTE_UNUSED;
d1bd513e 941{
7e065dae 942 return (GET_CODE (op) == CONST_INT
5785723a 943 && CONST_OK_FOR_LETTER_P (INTVAL (op) & GET_MODE_MASK (mode), 'K'));
d1bd513e 944}
945
48c6936b 946/* Return 1 if OP is a CONST_INT that cannot fit in a signed D field. */
947
948int
949non_short_cint_operand (op, mode)
773e893a 950 rtx op;
600e851b 951 enum machine_mode mode ATTRIBUTE_UNUSED;
48c6936b 952{
953 return (GET_CODE (op) == CONST_INT
71fe222a 954 && (unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) >= 0x10000);
48c6936b 955}
956
8eaf2dd1 957/* Returns 1 if OP is a CONST_INT that is a positive value
958 and an exact power of 2. */
959
960int
961exact_log2_cint_operand (op, mode)
773e893a 962 rtx op;
8eaf2dd1 963 enum machine_mode mode ATTRIBUTE_UNUSED;
964{
965 return (GET_CODE (op) == CONST_INT
966 && INTVAL (op) > 0
967 && exact_log2 (INTVAL (op)) >= 0);
968}
969
d1bd513e 970/* Returns 1 if OP is a register that is not special (i.e., not MQ,
971 ctr, or lr). */
972
973int
d9fd37c1 974gpc_reg_operand (op, mode)
773e893a 975 rtx op;
d1bd513e 976 enum machine_mode mode;
977{
978 return (register_operand (op, mode)
359e408d 979 && (GET_CODE (op) != REG
bbd21807 980 || (REGNO (op) >= ARG_POINTER_REGNUM
981 && !XER_REGNO_P (REGNO (op)))
982 || REGNO (op) < MQ_REGNO));
d1bd513e 983}
984
985/* Returns 1 if OP is either a pseudo-register or a register denoting a
986 CR field. */
987
988int
989cc_reg_operand (op, mode)
773e893a 990 rtx op;
d1bd513e 991 enum machine_mode mode;
992{
993 return (register_operand (op, mode)
994 && (GET_CODE (op) != REG
995 || REGNO (op) >= FIRST_PSEUDO_REGISTER
996 || CR_REGNO_P (REGNO (op))));
997}
998
9aba4661 999/* Returns 1 if OP is either a pseudo-register or a register denoting a
1000 CR field that isn't CR0. */
1001
1002int
1003cc_reg_not_cr0_operand (op, mode)
773e893a 1004 rtx op;
9aba4661 1005 enum machine_mode mode;
1006{
1007 return (register_operand (op, mode)
1008 && (GET_CODE (op) != REG
1009 || REGNO (op) >= FIRST_PSEUDO_REGISTER
1010 || CR_REGNO_NOT_CR0_P (REGNO (op))));
1011}
1012
970e222f 1013/* Returns 1 if OP is either a constant integer valid for a D-field or
1014 a non-special register. If a register, it must be in the proper
1015 mode unless MODE is VOIDmode. */
d1bd513e 1016
1017int
1018reg_or_short_operand (op, mode)
773e893a 1019 rtx op;
d1bd513e 1020 enum machine_mode mode;
1021{
ad418c6e 1022 return short_cint_operand (op, mode) || gpc_reg_operand (op, mode);
d1bd513e 1023}
1024
970e222f 1025/* Similar, except check if the negation of the constant would be
1026 valid for a D-field. */
d1bd513e 1027
1028int
1029reg_or_neg_short_operand (op, mode)
773e893a 1030 rtx op;
d1bd513e 1031 enum machine_mode mode;
1032{
1033 if (GET_CODE (op) == CONST_INT)
1034 return CONST_OK_FOR_LETTER_P (INTVAL (op), 'P');
1035
d9fd37c1 1036 return gpc_reg_operand (op, mode);
d1bd513e 1037}
1038
f86ef5aa 1039/* Returns 1 if OP is either a constant integer valid for a DS-field or
1040 a non-special register. If a register, it must be in the proper
1041 mode unless MODE is VOIDmode. */
1042
1043int
1044reg_or_aligned_short_operand (op, mode)
1045 rtx op;
1046 enum machine_mode mode;
1047{
1048 if (gpc_reg_operand (op, mode))
1049 return 1;
1050 else if (short_cint_operand (op, mode) && !(INTVAL (op) & 3))
1051 return 1;
1052
1053 return 0;
1054}
1055
1056
970e222f 1057/* Return 1 if the operand is either a register or an integer whose
1058 high-order 16 bits are zero. */
d1bd513e 1059
1060int
1061reg_or_u_short_operand (op, mode)
773e893a 1062 rtx op;
d1bd513e 1063 enum machine_mode mode;
1064{
17dfff62 1065 return u_short_cint_operand (op, mode) || gpc_reg_operand (op, mode);
d1bd513e 1066}
1067
1068/* Return 1 is the operand is either a non-special register or ANY
1069 constant integer. */
1070
1071int
1072reg_or_cint_operand (op, mode)
773e893a 1073 rtx op;
d1bd513e 1074 enum machine_mode mode;
1075{
970e222f 1076 return (GET_CODE (op) == CONST_INT || gpc_reg_operand (op, mode));
7802daa5 1077}
1078
1079/* Return 1 is the operand is either a non-special register or ANY
1080 32-bit signed constant integer. */
1081
1082int
1083reg_or_arith_cint_operand (op, mode)
773e893a 1084 rtx op;
7802daa5 1085 enum machine_mode mode;
1086{
970e222f 1087 return (gpc_reg_operand (op, mode)
1088 || (GET_CODE (op) == CONST_INT
7802daa5 1089#if HOST_BITS_PER_WIDE_INT != 32
970e222f 1090 && ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80000000)
1091 < (unsigned HOST_WIDE_INT) 0x100000000ll)
7802daa5 1092#endif
970e222f 1093 ));
d1bd513e 1094}
1095
8eaf2dd1 1096/* Return 1 is the operand is either a non-special register or a 32-bit
1097 signed constant integer valid for 64-bit addition. */
1098
1099int
1100reg_or_add_cint64_operand (op, mode)
773e893a 1101 rtx op;
8eaf2dd1 1102 enum machine_mode mode;
1103{
970e222f 1104 return (gpc_reg_operand (op, mode)
1105 || (GET_CODE (op) == CONST_INT
77638b48 1106#if HOST_BITS_PER_WIDE_INT == 32
970e222f 1107 && INTVAL (op) < 0x7fff8000
77638b48 1108#else
970e222f 1109 && ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80008000)
1110 < 0x100000000ll)
8eaf2dd1 1111#endif
970e222f 1112 ));
8eaf2dd1 1113}
1114
1115/* Return 1 is the operand is either a non-special register or a 32-bit
1116 signed constant integer valid for 64-bit subtraction. */
1117
1118int
1119reg_or_sub_cint64_operand (op, mode)
773e893a 1120 rtx op;
8eaf2dd1 1121 enum machine_mode mode;
1122{
970e222f 1123 return (gpc_reg_operand (op, mode)
1124 || (GET_CODE (op) == CONST_INT
77638b48 1125#if HOST_BITS_PER_WIDE_INT == 32
970e222f 1126 && (- INTVAL (op)) < 0x7fff8000
77638b48 1127#else
970e222f 1128 && ((unsigned HOST_WIDE_INT) ((- INTVAL (op)) + 0x80008000)
1129 < 0x100000000ll)
8eaf2dd1 1130#endif
970e222f 1131 ));
8eaf2dd1 1132}
1133
bbd21807 1134/* Return 1 is the operand is either a non-special register or ANY
1135 32-bit unsigned constant integer. */
1136
1137int
6167435d 1138reg_or_logical_cint_operand (op, mode)
773e893a 1139 rtx op;
bbd21807 1140 enum machine_mode mode;
1141{
6167435d 1142 if (GET_CODE (op) == CONST_INT)
1143 {
1144 if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT)
1145 {
1146 if (GET_MODE_BITSIZE (mode) <= 32)
970e222f 1147 abort ();
6167435d 1148
1149 if (INTVAL (op) < 0)
1150 return 0;
1151 }
1152
1153 return ((INTVAL (op) & GET_MODE_MASK (mode)
dde53c28 1154 & (~ (unsigned HOST_WIDE_INT) 0xffffffff)) == 0);
6167435d 1155 }
1156 else if (GET_CODE (op) == CONST_DOUBLE)
1157 {
1158 if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
1159 || mode != DImode)
970e222f 1160 abort ();
6167435d 1161
1162 return CONST_DOUBLE_HIGH (op) == 0;
1163 }
1164 else
1165 return gpc_reg_operand (op, mode);
bbd21807 1166}
1167
aefb3ee8 1168/* Return 1 if the operand is an operand that can be loaded via the GOT. */
ea6394e7 1169
1170int
1171got_operand (op, mode)
773e893a 1172 rtx op;
600e851b 1173 enum machine_mode mode ATTRIBUTE_UNUSED;
ea6394e7 1174{
1175 return (GET_CODE (op) == SYMBOL_REF
1176 || GET_CODE (op) == CONST
1177 || GET_CODE (op) == LABEL_REF);
1178}
1179
bda6fa4d 1180/* Return 1 if the operand is a simple references that can be loaded via
1181 the GOT (labels involving addition aren't allowed). */
1182
1183int
1184got_no_const_operand (op, mode)
773e893a 1185 rtx op;
600e851b 1186 enum machine_mode mode ATTRIBUTE_UNUSED;
bda6fa4d 1187{
1188 return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF);
1189}
1190
eaca156e 1191/* Return the number of instructions it takes to form a constant in an
1192 integer register. */
1193
1194static int
1195num_insns_constant_wide (value)
1196 HOST_WIDE_INT value;
1197{
1198 /* signed constant loadable with {cal|addi} */
837b446a 1199 if (CONST_OK_FOR_LETTER_P (value, 'I'))
c1f616f4 1200 return 1;
1201
eaca156e 1202 /* constant loadable with {cau|addis} */
837b446a 1203 else if (CONST_OK_FOR_LETTER_P (value, 'L'))
eaca156e 1204 return 1;
1205
837b446a 1206#if HOST_BITS_PER_WIDE_INT == 64
a516dd3a 1207 else if (TARGET_POWERPC64)
eaca156e 1208 {
77638b48 1209 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
1210 HOST_WIDE_INT high = value >> 31;
eaca156e 1211
77638b48 1212 if (high == 0 || high == -1)
eaca156e 1213 return 2;
1214
77638b48 1215 high >>= 1;
eaca156e 1216
77638b48 1217 if (low == 0)
eaca156e 1218 return num_insns_constant_wide (high) + 1;
eaca156e 1219 else
1220 return (num_insns_constant_wide (high)
f6f5e040 1221 + num_insns_constant_wide (low) + 1);
eaca156e 1222 }
1223#endif
1224
1225 else
1226 return 2;
1227}
1228
1229int
1230num_insns_constant (op, mode)
1231 rtx op;
1232 enum machine_mode mode;
1233{
eaca156e 1234 if (GET_CODE (op) == CONST_INT)
2b7de29b 1235 {
1236#if HOST_BITS_PER_WIDE_INT == 64
1351c3d7 1237 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
1238 && mask64_operand (op, mode))
2b7de29b 1239 return 2;
1240 else
1241#endif
1242 return num_insns_constant_wide (INTVAL (op));
1243 }
eaca156e 1244
0a59c6eb 1245 else if (GET_CODE (op) == CONST_DOUBLE && mode == SFmode)
1246 {
1247 long l;
1248 REAL_VALUE_TYPE rv;
1249
1250 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1251 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
3bc7190a 1252 return num_insns_constant_wide ((HOST_WIDE_INT) l);
0a59c6eb 1253 }
1254
4b61997d 1255 else if (GET_CODE (op) == CONST_DOUBLE)
eaca156e 1256 {
4b61997d 1257 HOST_WIDE_INT low;
1258 HOST_WIDE_INT high;
1259 long l[2];
1260 REAL_VALUE_TYPE rv;
1261 int endian = (WORDS_BIG_ENDIAN == 0);
eaca156e 1262
4b61997d 1263 if (mode == VOIDmode || mode == DImode)
1264 {
1265 high = CONST_DOUBLE_HIGH (op);
1266 low = CONST_DOUBLE_LOW (op);
1267 }
1268 else
1269 {
1270 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1271 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
1272 high = l[endian];
1273 low = l[1 - endian];
1274 }
eaca156e 1275
4b61997d 1276 if (TARGET_32BIT)
1277 return (num_insns_constant_wide (low)
1278 + num_insns_constant_wide (high));
eaca156e 1279
1280 else
4b61997d 1281 {
3bc7190a 1282 if (high == 0 && low >= 0)
4b61997d 1283 return num_insns_constant_wide (low);
1284
3bc7190a 1285 else if (high == -1 && low < 0)
4b61997d 1286 return num_insns_constant_wide (low);
1287
8cda90b9 1288 else if (mask64_operand (op, mode))
1289 return 2;
1290
4b61997d 1291 else if (low == 0)
1292 return num_insns_constant_wide (high) + 1;
1293
1294 else
1295 return (num_insns_constant_wide (high)
1296 + num_insns_constant_wide (low) + 1);
1297 }
eaca156e 1298 }
1299
1300 else
1301 abort ();
1302}
1303
970e222f 1304/* Return 1 if the operand is a CONST_DOUBLE and it can be put into a
1305 register with one instruction per word. We only do this if we can
1306 safely read CONST_DOUBLE_{LOW,HIGH}. */
d1bd513e 1307
1308int
1309easy_fp_constant (op, mode)
773e893a 1310 rtx op;
1311 enum machine_mode mode;
d1bd513e 1312{
d1bd513e 1313 if (GET_CODE (op) != CONST_DOUBLE
1314 || GET_MODE (op) != mode
eaca156e 1315 || (GET_MODE_CLASS (mode) != MODE_FLOAT && mode != DImode))
d1bd513e 1316 return 0;
1317
970e222f 1318 /* Consider all constants with -msoft-float to be easy. */
f19493d5 1319 if ((TARGET_SOFT_FLOAT || !TARGET_FPRS)
1320 && mode != DImode)
6b02f2a5 1321 return 1;
1322
970e222f 1323 /* If we are using V.4 style PIC, consider all constants to be hard. */
e7ce8542 1324 if (flag_pic && DEFAULT_ABI == ABI_V4)
9acfe4b8 1325 return 0;
1326
d6560d70 1327#ifdef TARGET_RELOCATABLE
970e222f 1328 /* Similarly if we are using -mrelocatable, consider all constants
1329 to be hard. */
d6560d70 1330 if (TARGET_RELOCATABLE)
1331 return 0;
1332#endif
1333
cf7d5bc7 1334 if (mode == TFmode)
1335 {
1336 long k[4];
1337 REAL_VALUE_TYPE rv;
1338
1339 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1340 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
1341
1342 return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1
1343 && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1
1344 && num_insns_constant_wide ((HOST_WIDE_INT) k[2]) == 1
1345 && num_insns_constant_wide ((HOST_WIDE_INT) k[3]) == 1);
1346 }
1347
1348 else if (mode == DFmode)
eb856d33 1349 {
1350 long k[2];
1351 REAL_VALUE_TYPE rv;
1352
1353 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1354 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
d1bd513e 1355
77638b48 1356 return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1
1357 && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1);
eb856d33 1358 }
eaca156e 1359
1360 else if (mode == SFmode)
eb856d33 1361 {
1362 long l;
1363 REAL_VALUE_TYPE rv;
1364
1365 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1366 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
d1bd513e 1367
eaca156e 1368 return num_insns_constant_wide (l) == 1;
eb856d33 1369 }
eaca156e 1370
8cda90b9 1371 else if (mode == DImode)
a516dd3a 1372 return ((TARGET_POWERPC64
8cda90b9 1373 && GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_LOW (op) == 0)
1374 || (num_insns_constant (op, DImode) <= 2));
eaca156e 1375
e2f08fad 1376 else if (mode == SImode)
1377 return 1;
eaca156e 1378 else
1379 abort ();
d1bd513e 1380}
5bdc4bd3 1381
886cfd4f 1382/* Return 1 if the operand is a CONST_INT and can be put into a
1383 register with one instruction. */
1384
1385static int
1386easy_vector_constant (op)
1387 rtx op;
1388{
1389 rtx elt;
1390 int units, i;
1391
1392 if (GET_CODE (op) != CONST_VECTOR)
1393 return 0;
1394
1395 units = CONST_VECTOR_NUNITS (op);
1396
1397 /* We can generate 0 easily. Look for that. */
1398 for (i = 0; i < units; ++i)
1399 {
1400 elt = CONST_VECTOR_ELT (op, i);
1401
1402 /* We could probably simplify this by just checking for equality
1403 with CONST0_RTX for the current mode, but let's be safe
1404 instead. */
1405
0ccb2687 1406 switch (GET_CODE (elt))
1407 {
1408 case CONST_INT:
1409 if (INTVAL (elt) != 0)
1410 return 0;
1411 break;
1412 case CONST_DOUBLE:
1413 if (CONST_DOUBLE_LOW (elt) != 0 || CONST_DOUBLE_HIGH (elt) != 0)
1414 return 0;
1415 break;
1416 default:
1417 return 0;
1418 }
886cfd4f 1419 }
1420
1421 /* We could probably generate a few other constants trivially, but
1422 gcc doesn't generate them yet. FIXME later. */
0ccb2687 1423 return 1;
886cfd4f 1424}
1425
1426/* Return 1 if the operand is the constant 0. This works for scalars
1427 as well as vectors. */
1428int
1429zero_constant (op, mode)
1430 rtx op;
1431 enum machine_mode mode;
1432{
1433 return op == CONST0_RTX (mode);
1434}
1435
ba261041 1436/* Return 1 if the operand is 0.0. */
1437int
1438zero_fp_constant (op, mode)
773e893a 1439 rtx op;
1440 enum machine_mode mode;
ba261041 1441{
1442 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
1443}
1444
970e222f 1445/* Return 1 if the operand is in volatile memory. Note that during
1446 the RTL generation phase, memory_operand does not return TRUE for
6b02f2a5 1447 volatile memory references. So this function allows us to
1448 recognize volatile references where its safe. */
1449
1450int
1451volatile_mem_operand (op, mode)
773e893a 1452 rtx op;
6b02f2a5 1453 enum machine_mode mode;
1454{
1455 if (GET_CODE (op) != MEM)
1456 return 0;
1457
1458 if (!MEM_VOLATILE_P (op))
1459 return 0;
1460
1461 if (mode != GET_MODE (op))
1462 return 0;
1463
1464 if (reload_completed)
1465 return memory_operand (op, mode);
1466
1467 if (reload_in_progress)
1468 return strict_memory_address_p (mode, XEXP (op, 0));
1469
1470 return memory_address_p (mode, XEXP (op, 0));
1471}
1472
6e087f88 1473/* Return 1 if the operand is an offsettable memory operand. */
4ceb3cb4 1474
1475int
6e087f88 1476offsettable_mem_operand (op, mode)
773e893a 1477 rtx op;
4ceb3cb4 1478 enum machine_mode mode;
1479{
6e087f88 1480 return ((GET_CODE (op) == MEM)
90fd96cb 1481 && offsettable_address_p (reload_completed || reload_in_progress,
6e087f88 1482 mode, XEXP (op, 0)));
4ceb3cb4 1483}
1484
d1bd513e 1485/* Return 1 if the operand is either an easy FP constant (see above) or
1486 memory. */
1487
1488int
1489mem_or_easy_const_operand (op, mode)
773e893a 1490 rtx op;
d1bd513e 1491 enum machine_mode mode;
1492{
1493 return memory_operand (op, mode) || easy_fp_constant (op, mode);
1494}
1495
1496/* Return 1 if the operand is either a non-special register or an item
837b446a 1497 that can be used as the operand of a `mode' add insn. */
d1bd513e 1498
1499int
1500add_operand (op, mode)
773e893a 1501 rtx op;
d1bd513e 1502 enum machine_mode mode;
1503{
8eaf2dd1 1504 if (GET_CODE (op) == CONST_INT)
3bc7190a 1505 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
1506 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
8eaf2dd1 1507
1508 return gpc_reg_operand (op, mode);
d1bd513e 1509}
1510
48c6936b 1511/* Return 1 if OP is a constant but not a valid add_operand. */
1512
1513int
1514non_add_cint_operand (op, mode)
773e893a 1515 rtx op;
600e851b 1516 enum machine_mode mode ATTRIBUTE_UNUSED;
48c6936b 1517{
1518 return (GET_CODE (op) == CONST_INT
3bc7190a 1519 && !CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
1520 && !CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
48c6936b 1521}
1522
d1bd513e 1523/* Return 1 if the operand is a non-special register or a constant that
1524 can be used as the operand of an OR or XOR insn on the RS/6000. */
1525
1526int
1527logical_operand (op, mode)
773e893a 1528 rtx op;
d1bd513e 1529 enum machine_mode mode;
1530{
1482a25d 1531 HOST_WIDE_INT opl, oph;
6167435d 1532
3454f5f0 1533 if (gpc_reg_operand (op, mode))
1534 return 1;
6167435d 1535
3454f5f0 1536 if (GET_CODE (op) == CONST_INT)
1482a25d 1537 {
1538 opl = INTVAL (op) & GET_MODE_MASK (mode);
1539
1540#if HOST_BITS_PER_WIDE_INT <= 32
1541 if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT && opl < 0)
1542 return 0;
1543#endif
1544 }
3454f5f0 1545 else if (GET_CODE (op) == CONST_DOUBLE)
1546 {
6167435d 1547 if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
1482a25d 1548 abort ();
6167435d 1549
1550 opl = CONST_DOUBLE_LOW (op);
1551 oph = CONST_DOUBLE_HIGH (op);
1482a25d 1552 if (oph != 0)
9335440a 1553 return 0;
3454f5f0 1554 }
1555 else
1556 return 0;
6167435d 1557
1482a25d 1558 return ((opl & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0
1559 || (opl & ~ (unsigned HOST_WIDE_INT) 0xffff0000) == 0);
d1bd513e 1560}
1561
48c6936b 1562/* Return 1 if C is a constant that is not a logical operand (as
6167435d 1563 above), but could be split into one. */
48c6936b 1564
1565int
1566non_logical_cint_operand (op, mode)
773e893a 1567 rtx op;
837b446a 1568 enum machine_mode mode;
48c6936b 1569{
3454f5f0 1570 return ((GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE)
6167435d 1571 && ! logical_operand (op, mode)
1572 && reg_or_logical_cint_operand (op, mode));
48c6936b 1573}
1574
73ddb23b 1575/* Return 1 if C is a constant that can be encoded in a 32-bit mask on the
d1bd513e 1576 RS/6000. It is if there are no more than two 1->0 or 0->1 transitions.
1577 Reject all ones and all zeros, since these should have been optimized
1578 away and confuse the making of MB and ME. */
1579
1580int
73ddb23b 1581mask_operand (op, mode)
773e893a 1582 rtx op;
73ddb23b 1583 enum machine_mode mode ATTRIBUTE_UNUSED;
d1bd513e 1584{
8dd59a84 1585 HOST_WIDE_INT c, lsb;
d1bd513e 1586
73ddb23b 1587 if (GET_CODE (op) != CONST_INT)
1588 return 0;
1589
1590 c = INTVAL (op);
1591
56f833c0 1592 /* Fail in 64-bit mode if the mask wraps around because the upper
1593 32-bits of the mask will all be 1s, contrary to GCC's internal view. */
1594 if (TARGET_POWERPC64 && (c & 0x80000001) == 0x80000001)
1595 return 0;
1596
8ba93479 1597 /* We don't change the number of transitions by inverting,
1598 so make sure we start with the LS bit zero. */
1599 if (c & 1)
1600 c = ~c;
1601
1602 /* Reject all zeros or all ones. */
1603 if (c == 0)
d1bd513e 1604 return 0;
1605
8ba93479 1606 /* Find the first transition. */
1607 lsb = c & -c;
1608
1609 /* Invert to look for a second transition. */
1610 c = ~c;
d1bd513e 1611
8ba93479 1612 /* Erase first transition. */
1613 c &= -lsb;
d1bd513e 1614
8ba93479 1615 /* Find the second transition (if any). */
1616 lsb = c & -c;
1617
1618 /* Match if all the bits above are 1's (or c is zero). */
1619 return c == -lsb;
d1bd513e 1620}
1621
59a5187e 1622/* Return 1 for the PowerPC64 rlwinm corner case. */
1623
1624int
1625mask_operand_wrap (op, mode)
1626 rtx op;
1627 enum machine_mode mode ATTRIBUTE_UNUSED;
1628{
1629 HOST_WIDE_INT c, lsb;
1630
1631 if (GET_CODE (op) != CONST_INT)
1632 return 0;
1633
1634 c = INTVAL (op);
1635
1636 if ((c & 0x80000001) != 0x80000001)
1637 return 0;
1638
1639 c = ~c;
1640 if (c == 0)
1641 return 0;
1642
1643 lsb = c & -c;
1644 c = ~c;
1645 c &= -lsb;
1646 lsb = c & -c;
1647 return c == -lsb;
1648}
1649
8cda90b9 1650/* Return 1 if the operand is a constant that is a PowerPC64 mask.
1651 It is if there are no more than one 1->0 or 0->1 transitions.
59a5187e 1652 Reject all zeros, since zero should have been optimized away and
1653 confuses the making of MB and ME. */
d1bd513e 1654
1655int
8cda90b9 1656mask64_operand (op, mode)
773e893a 1657 rtx op;
59a5187e 1658 enum machine_mode mode ATTRIBUTE_UNUSED;
8cda90b9 1659{
1660 if (GET_CODE (op) == CONST_INT)
1661 {
8dd59a84 1662 HOST_WIDE_INT c, lsb;
8cda90b9 1663
8ba93479 1664 c = INTVAL (op);
8cda90b9 1665
59a5187e 1666 /* Reject all zeros. */
8ba93479 1667 if (c == 0)
30c5e279 1668 return 0;
1669
59a5187e 1670 /* We don't change the number of transitions by inverting,
1671 so make sure we start with the LS bit zero. */
1672 if (c & 1)
1673 c = ~c;
1674
8ba93479 1675 /* Find the transition, and check that all bits above are 1's. */
1676 lsb = c & -c;
1677 return c == -lsb;
30c5e279 1678 }
59a5187e 1679 return 0;
1680}
1681
1682/* Like mask64_operand, but allow up to three transitions. This
1683 predicate is used by insn patterns that generate two rldicl or
1684 rldicr machine insns. */
1685
1686int
1687mask64_2_operand (op, mode)
1688 rtx op;
1689 enum machine_mode mode ATTRIBUTE_UNUSED;
1690{
1691 if (GET_CODE (op) == CONST_INT)
8cda90b9 1692 {
59a5187e 1693 HOST_WIDE_INT c, lsb;
8cda90b9 1694
59a5187e 1695 c = INTVAL (op);
8cda90b9 1696
59a5187e 1697 /* Disallow all zeros. */
1698 if (c == 0)
1699 return 0;
8cda90b9 1700
59a5187e 1701 /* We don't change the number of transitions by inverting,
1702 so make sure we start with the LS bit zero. */
1703 if (c & 1)
1704 c = ~c;
8cda90b9 1705
59a5187e 1706 /* Find the first transition. */
1707 lsb = c & -c;
8cda90b9 1708
59a5187e 1709 /* Invert to look for a second transition. */
1710 c = ~c;
1711
1712 /* Erase first transition. */
1713 c &= -lsb;
1714
1715 /* Find the second transition. */
1716 lsb = c & -c;
1717
1718 /* Invert to look for a third transition. */
1719 c = ~c;
1720
1721 /* Erase second transition. */
1722 c &= -lsb;
1723
1724 /* Find the third transition (if any). */
1725 lsb = c & -c;
1726
1727 /* Match if all the bits above are 1's (or c is zero). */
1728 return c == -lsb;
1729 }
1730 return 0;
1731}
1732
1733/* Generates shifts and masks for a pair of rldicl or rldicr insns to
1734 implement ANDing by the mask IN. */
1735void
1736build_mask64_2_operands (in, out)
1737 rtx in;
1738 rtx *out;
1739{
1740#if HOST_BITS_PER_WIDE_INT >= 64
1741 unsigned HOST_WIDE_INT c, lsb, m1, m2;
1742 int shift;
1743
1744 if (GET_CODE (in) != CONST_INT)
1745 abort ();
1746
1747 c = INTVAL (in);
1748 if (c & 1)
1749 {
1750 /* Assume c initially something like 0x00fff000000fffff. The idea
1751 is to rotate the word so that the middle ^^^^^^ group of zeros
1752 is at the MS end and can be cleared with an rldicl mask. We then
1753 rotate back and clear off the MS ^^ group of zeros with a
1754 second rldicl. */
1755 c = ~c; /* c == 0xff000ffffff00000 */
1756 lsb = c & -c; /* lsb == 0x0000000000100000 */
1757 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
1758 c = ~c; /* c == 0x00fff000000fffff */
1759 c &= -lsb; /* c == 0x00fff00000000000 */
1760 lsb = c & -c; /* lsb == 0x0000100000000000 */
1761 c = ~c; /* c == 0xff000fffffffffff */
1762 c &= -lsb; /* c == 0xff00000000000000 */
1763 shift = 0;
1764 while ((lsb >>= 1) != 0)
1765 shift++; /* shift == 44 on exit from loop */
1766 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
1767 m1 = ~m1; /* m1 == 0x000000ffffffffff */
1768 m2 = ~c; /* m2 == 0x00ffffffffffffff */
8cda90b9 1769 }
1770 else
59a5187e 1771 {
1772 /* Assume c initially something like 0xff000f0000000000. The idea
1773 is to rotate the word so that the ^^^ middle group of zeros
1774 is at the LS end and can be cleared with an rldicr mask. We then
1775 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
1776 a second rldicr. */
1777 lsb = c & -c; /* lsb == 0x0000010000000000 */
1778 m2 = -lsb; /* m2 == 0xffffff0000000000 */
1779 c = ~c; /* c == 0x00fff0ffffffffff */
1780 c &= -lsb; /* c == 0x00fff00000000000 */
1781 lsb = c & -c; /* lsb == 0x0000100000000000 */
1782 c = ~c; /* c == 0xff000fffffffffff */
1783 c &= -lsb; /* c == 0xff00000000000000 */
1784 shift = 0;
1785 while ((lsb >>= 1) != 0)
1786 shift++; /* shift == 44 on exit from loop */
1787 m1 = ~c; /* m1 == 0x00ffffffffffffff */
1788 m1 >>= shift; /* m1 == 0x0000000000000fff */
1789 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
1790 }
1791
1792 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
1793 masks will be all 1's. We are guaranteed more than one transition. */
1794 out[0] = GEN_INT (64 - shift);
1795 out[1] = GEN_INT (m1);
1796 out[2] = GEN_INT (shift);
1797 out[3] = GEN_INT (m2);
1798#else
741b56d8 1799 (void)in;
1800 (void)out;
59a5187e 1801 abort ();
1802#endif
8cda90b9 1803}
1804
1805/* Return 1 if the operand is either a non-special register or a constant
1806 that can be used as the operand of a PowerPC64 logical AND insn. */
1807
1808int
1809and64_operand (op, mode)
773e893a 1810 rtx op;
d1bd513e 1811 enum machine_mode mode;
1812{
970e222f 1813 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
1e644b45 1814 return (gpc_reg_operand (op, mode) || mask64_operand (op, mode));
1815
1816 return (logical_operand (op, mode) || mask64_operand (op, mode));
d1bd513e 1817}
1818
59a5187e 1819/* Like the above, but also match constants that can be implemented
1820 with two rldicl or rldicr insns. */
1821
1822int
1823and64_2_operand (op, mode)
1824 rtx op;
1825 enum machine_mode mode;
1826{
1827 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
1828 return gpc_reg_operand (op, mode) || mask64_2_operand (op, mode);
1829
1830 return logical_operand (op, mode) || mask64_2_operand (op, mode);
1831}
1832
8cda90b9 1833/* Return 1 if the operand is either a non-special register or a
1834 constant that can be used as the operand of an RS/6000 logical AND insn. */
48c6936b 1835
1836int
8cda90b9 1837and_operand (op, mode)
773e893a 1838 rtx op;
8cda90b9 1839 enum machine_mode mode;
48c6936b 1840{
970e222f 1841 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
1e644b45 1842 return (gpc_reg_operand (op, mode) || mask_operand (op, mode));
1843
1844 return (logical_operand (op, mode) || mask_operand (op, mode));
48c6936b 1845}
1846
d1bd513e 1847/* Return 1 if the operand is a general register or memory operand. */
1848
1849int
1850reg_or_mem_operand (op, mode)
773e893a 1851 rtx op;
1852 enum machine_mode mode;
d1bd513e 1853{
6b02f2a5 1854 return (gpc_reg_operand (op, mode)
1855 || memory_operand (op, mode)
1856 || volatile_mem_operand (op, mode));
d1bd513e 1857}
1858
2e95ea59 1859/* Return 1 if the operand is a general register or memory operand without
91452706 1860 pre_inc or pre_dec which produces invalid form of PowerPC lwa
2e95ea59 1861 instruction. */
1862
1863int
1864lwa_operand (op, mode)
773e893a 1865 rtx op;
1866 enum machine_mode mode;
2e95ea59 1867{
1868 rtx inner = op;
1869
1870 if (reload_completed && GET_CODE (inner) == SUBREG)
1871 inner = SUBREG_REG (inner);
1872
1873 return gpc_reg_operand (inner, mode)
1874 || (memory_operand (inner, mode)
1875 && GET_CODE (XEXP (inner, 0)) != PRE_INC
5eb75ffc 1876 && GET_CODE (XEXP (inner, 0)) != PRE_DEC
1877 && (GET_CODE (XEXP (inner, 0)) != PLUS
9325238d 1878 || GET_CODE (XEXP (XEXP (inner, 0), 1)) != CONST_INT
1879 || INTVAL (XEXP (XEXP (inner, 0), 1)) % 4 == 0));
2e95ea59 1880}
1881
2c290e47 1882/* Return 1 if the operand, used inside a MEM, is a SYMBOL_REF. */
1883
1884int
1885symbol_ref_operand (op, mode)
1886 rtx op;
1887 enum machine_mode mode;
1888{
1889 if (mode != VOIDmode && GET_MODE (op) != mode)
1890 return 0;
1891
1892 return (GET_CODE (op) == SYMBOL_REF);
1893}
1894
d1bd513e 1895/* Return 1 if the operand, used inside a MEM, is a valid first argument
2c290e47 1896 to CALL. This is a SYMBOL_REF, a pseudo-register, LR or CTR. */
d1bd513e 1897
1898int
1899call_operand (op, mode)
773e893a 1900 rtx op;
d1bd513e 1901 enum machine_mode mode;
1902{
1903 if (mode != VOIDmode && GET_MODE (op) != mode)
1904 return 0;
1905
1906 return (GET_CODE (op) == SYMBOL_REF
2c290e47 1907 || (GET_CODE (op) == REG
1908 && (REGNO (op) == LINK_REGISTER_REGNUM
1909 || REGNO (op) == COUNT_REGISTER_REGNUM
1910 || REGNO (op) >= FIRST_PSEUDO_REGISTER)));
d1bd513e 1911}
1912
7251a905 1913/* Return 1 if the operand is a SYMBOL_REF for a function known to be in
970e222f 1914 this file and the function is not weakly defined. */
7251a905 1915
1916int
1917current_file_function_operand (op, mode)
773e893a 1918 rtx op;
600e851b 1919 enum machine_mode mode ATTRIBUTE_UNUSED;
7251a905 1920{
1921 return (GET_CODE (op) == SYMBOL_REF
1922 && (SYMBOL_REF_FLAG (op)
5d0a68f9 1923 || (op == XEXP (DECL_RTL (current_function_decl), 0)
a516dd3a 1924 && ! DECL_WEAK (current_function_decl))));
7251a905 1925}
1926
d1bd513e 1927/* Return 1 if this operand is a valid input for a move insn. */
1928
1929int
1930input_operand (op, mode)
773e893a 1931 rtx op;
d1bd513e 1932 enum machine_mode mode;
1933{
0ad041cc 1934 /* Memory is always valid. */
d1bd513e 1935 if (memory_operand (op, mode))
1936 return 1;
1937
5c73b1eb 1938 /* Only a tiny bit of handling for CONSTANT_P_RTX is necessary. */
6bc988cd 1939 if (GET_CODE (op) == CONSTANT_P_RTX)
5c73b1eb 1940 return 1;
1941
0ad041cc 1942 /* For floating-point, easy constants are valid. */
1943 if (GET_MODE_CLASS (mode) == MODE_FLOAT
1944 && CONSTANT_P (op)
1945 && easy_fp_constant (op, mode))
1946 return 1;
1947
eaca156e 1948 /* Allow any integer constant. */
1949 if (GET_MODE_CLASS (mode) == MODE_INT
17dfff62 1950 && (GET_CODE (op) == CONST_INT
17dfff62 1951 || GET_CODE (op) == CONST_DOUBLE))
eaca156e 1952 return 1;
1953
0ad041cc 1954 /* For floating-point or multi-word mode, the only remaining valid type
1955 is a register. */
d1bd513e 1956 if (GET_MODE_CLASS (mode) == MODE_FLOAT
1957 || GET_MODE_SIZE (mode) > UNITS_PER_WORD)
0ad041cc 1958 return register_operand (op, mode);
d1bd513e 1959
785bad46 1960 /* The only cases left are integral modes one word or smaller (we
1961 do not get called for MODE_CC values). These can be in any
1962 register. */
1963 if (register_operand (op, mode))
dac3ecde 1964 return 1;
785bad46 1965
c7bc657d 1966 /* A SYMBOL_REF referring to the TOC is valid. */
8658a129 1967 if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (op))
c7bc657d 1968 return 1;
1969
bbd21807 1970 /* A constant pool expression (relative to the TOC) is valid */
1971 if (TOC_RELATIVE_EXPR_P (op))
6b02f2a5 1972 return 1;
1973
b85a3443 1974 /* V.4 allows SYMBOL_REFs and CONSTs that are in the small data region
1975 to be valid. */
e7ce8542 1976 if (DEFAULT_ABI == ABI_V4
b85a3443 1977 && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST)
1978 && small_data_operand (op, Pmode))
1979 return 1;
1980
eb856d33 1981 return 0;
d1bd513e 1982}
7a2fc9d6 1983
970e222f 1984/* Return 1 for an operand in small memory on V.4/eabi. */
7a2fc9d6 1985
1986int
1987small_data_operand (op, mode)
600e851b 1988 rtx op ATTRIBUTE_UNUSED;
1989 enum machine_mode mode ATTRIBUTE_UNUSED;
7a2fc9d6 1990{
bda6fa4d 1991#if TARGET_ELF
837b446a 1992 rtx sym_ref;
7a2fc9d6 1993
d72e2a6e 1994 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
31433e3f 1995 return 0;
31433e3f 1996
e7ce8542 1997 if (DEFAULT_ABI != ABI_V4)
7a2fc9d6 1998 return 0;
1999
b85a3443 2000 if (GET_CODE (op) == SYMBOL_REF)
2001 sym_ref = op;
2002
2003 else if (GET_CODE (op) != CONST
2004 || GET_CODE (XEXP (op, 0)) != PLUS
2005 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
2006 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
7a2fc9d6 2007 return 0;
2008
b85a3443 2009 else
e1e10dd9 2010 {
2011 rtx sum = XEXP (op, 0);
2012 HOST_WIDE_INT summand;
2013
2014 /* We have to be careful here, because it is the referenced address
2015 that must be 32k from _SDA_BASE_, not just the symbol. */
2016 summand = INTVAL (XEXP (sum, 1));
2017 if (summand < 0 || summand > g_switch_value)
2018 return 0;
2019
2020 sym_ref = XEXP (sum, 0);
2021 }
b85a3443 2022
2023 if (*XSTR (sym_ref, 0) != '@')
7a2fc9d6 2024 return 0;
2025
2026 return 1;
d72e2a6e 2027
2028#else
2029 return 0;
2030#endif
7a2fc9d6 2031}
bbd21807 2032\f
2033static int
2034constant_pool_expr_1 (op, have_sym, have_toc)
2035 rtx op;
2036 int *have_sym;
2037 int *have_toc;
2038{
2039 switch (GET_CODE(op))
2040 {
2041 case SYMBOL_REF:
970e222f 2042 if (CONSTANT_POOL_ADDRESS_P (op))
2043 {
2044 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op), Pmode))
2045 {
2046 *have_sym = 1;
2047 return 1;
2048 }
2049 else
2050 return 0;
2051 }
2052 else if (! strcmp (XSTR (op, 0), toc_label_name))
2053 {
2054 *have_toc = 1;
2055 return 1;
2056 }
2057 else
2058 return 0;
bbd21807 2059 case PLUS:
2060 case MINUS:
5785723a 2061 return (constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc)
2062 && constant_pool_expr_1 (XEXP (op, 1), have_sym, have_toc));
bbd21807 2063 case CONST:
970e222f 2064 return constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc);
bbd21807 2065 case CONST_INT:
970e222f 2066 return 1;
bbd21807 2067 default:
970e222f 2068 return 0;
bbd21807 2069 }
2070}
2071
2072int
2073constant_pool_expr_p (op)
2074 rtx op;
2075{
2076 int have_sym = 0;
2077 int have_toc = 0;
2078 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym;
2079}
2080
2081int
2082toc_relative_expr_p (op)
2083 rtx op;
2084{
2085 int have_sym = 0;
2086 int have_toc = 0;
2087 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
2088}
2089
2090/* Try machine-dependent ways of modifying an illegitimate address
2091 to be legitimate. If we find one, return the new, valid address.
2092 This is used from only one place: `memory_address' in explow.c.
2093
970e222f 2094 OLDX is the address as it was before break_out_memory_refs was
2095 called. In some cases it is useful to look at this to decide what
2096 needs to be done.
bbd21807 2097
970e222f 2098 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
bbd21807 2099
970e222f 2100 It is always safe for this function to do nothing. It exists to
2101 recognize opportunities to optimize the output.
bbd21807 2102
2103 On RS/6000, first check for the sum of a register with a constant
2104 integer that is out of range. If so, generate code to add the
2105 constant with the low-order 16 bits masked to the register and force
2106 this result into another register (this can be done with `cau').
2107 Then generate an address of REG+(CONST&0xffff), allowing for the
2108 possibility of bit 16 being a one.
2109
2110 Then check for the sum of a register and something not constant, try to
2111 load the other things into a register and return the sum. */
2112rtx
2113rs6000_legitimize_address (x, oldx, mode)
2114 rtx x;
2115 rtx oldx ATTRIBUTE_UNUSED;
2116 enum machine_mode mode;
500c7157 2117{
bbd21807 2118 if (GET_CODE (x) == PLUS
2119 && GET_CODE (XEXP (x, 0)) == REG
2120 && GET_CODE (XEXP (x, 1)) == CONST_INT
2121 && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) >= 0x10000)
2122 {
2123 HOST_WIDE_INT high_int, low_int;
2124 rtx sum;
77638b48 2125 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
2126 high_int = INTVAL (XEXP (x, 1)) - low_int;
bbd21807 2127 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
2128 GEN_INT (high_int)), 0);
2129 return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));
2130 }
2131 else if (GET_CODE (x) == PLUS
2132 && GET_CODE (XEXP (x, 0)) == REG
2133 && GET_CODE (XEXP (x, 1)) != CONST_INT
733ea2b6 2134 && GET_MODE_NUNITS (mode) == 1
f19493d5 2135 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
2136 || TARGET_POWERPC64
cf7d5bc7 2137 || (mode != DFmode && mode != TFmode))
bbd21807 2138 && (TARGET_POWERPC64 || mode != DImode)
2139 && mode != TImode)
2140 {
2141 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
2142 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
2143 }
500c7157 2144 else if (ALTIVEC_VECTOR_MODE (mode))
2145 {
2146 rtx reg;
2147
2148 /* Make sure both operands are registers. */
2149 if (GET_CODE (x) == PLUS)
5cedec5c 2150 return gen_rtx_PLUS (Pmode, force_reg (Pmode, XEXP (x, 0)),
500c7157 2151 force_reg (Pmode, XEXP (x, 1)));
2152
2153 reg = force_reg (Pmode, x);
2154 return reg;
2155 }
f19493d5 2156 else if (SPE_VECTOR_MODE (mode))
2157 {
2158 /* We accept [reg + reg] and [reg + OFFSET]. */
2159
2160 if (GET_CODE (x) == PLUS)
2161 {
2162 rtx op1 = XEXP (x, 0);
2163 rtx op2 = XEXP (x, 1);
2164
2165 op1 = force_reg (Pmode, op1);
2166
2167 if (GET_CODE (op2) != REG
2168 && (GET_CODE (op2) != CONST_INT
2169 || !SPE_CONST_OFFSET_OK (INTVAL (op2))))
2170 op2 = force_reg (Pmode, op2);
2171
2172 return gen_rtx_PLUS (Pmode, op1, op2);
2173 }
2174
2175 return force_reg (Pmode, x);
2176 }
bbd21807 2177 else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC && ! flag_pic
2178 && GET_CODE (x) != CONST_INT
2179 && GET_CODE (x) != CONST_DOUBLE
2180 && CONSTANT_P (x)
733ea2b6 2181 && GET_MODE_NUNITS (mode) == 1
2182 && (GET_MODE_BITSIZE (mode) <= 32
f19493d5 2183 || ((TARGET_HARD_FLOAT && TARGET_FPRS) && mode == DFmode)))
bbd21807 2184 {
2185 rtx reg = gen_reg_rtx (Pmode);
2186 emit_insn (gen_elf_high (reg, (x)));
2187 return gen_rtx_LO_SUM (Pmode, reg, (x));
2188 }
80d725d7 2189 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
2190 && ! flag_pic
2191 && GET_CODE (x) != CONST_INT
2192 && GET_CODE (x) != CONST_DOUBLE
2193 && CONSTANT_P (x)
f19493d5 2194 && ((TARGET_HARD_FLOAT && TARGET_FPRS) || mode != DFmode)
80d725d7 2195 && mode != DImode
2196 && mode != TImode)
2197 {
2198 rtx reg = gen_reg_rtx (Pmode);
2199 emit_insn (gen_macho_high (reg, (x)));
2200 return gen_rtx_LO_SUM (Pmode, reg, (x));
2201 }
bbd21807 2202 else if (TARGET_TOC
2203 && CONSTANT_POOL_EXPR_P (x)
e2f08fad 2204 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
bbd21807 2205 {
2206 return create_TOC_reference (x);
2207 }
2208 else
2209 return NULL_RTX;
2210}
4bbdf529 2211
e3374f82 2212/* The convention appears to be to define this wherever it is used.
2213 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
2214 is now used here. */
2215#ifndef REG_MODE_OK_FOR_BASE_P
2216#define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
2217#endif
2218
2219/* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
2220 replace the input X, or the original X if no replacement is called for.
2221 The output parameter *WIN is 1 if the calling macro should goto WIN,
2222 0 if it should not.
2223
2224 For RS/6000, we wish to handle large displacements off a base
2225 register by splitting the addend across an addiu/addis and the mem insn.
2226 This cuts number of extra insns needed from 3 to 1.
2227
2228 On Darwin, we use this to generate code for floating point constants.
2229 A movsf_low is generated so we wind up with 2 instructions rather than 3.
2230 The Darwin code is inside #if TARGET_MACHO because only then is
2231 machopic_function_base_name() defined. */
2232rtx
2233rs6000_legitimize_reload_address (x, mode, opnum, type, ind_levels, win)
2234 rtx x;
2235 enum machine_mode mode;
2236 int opnum;
2237 int type;
2238 int ind_levels ATTRIBUTE_UNUSED;
2239 int *win;
2240{
2241 /* We must recognize output that we have already generated ourselves. */
2242 if (GET_CODE (x) == PLUS
2243 && GET_CODE (XEXP (x, 0)) == PLUS
2244 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
2245 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
2246 && GET_CODE (XEXP (x, 1)) == CONST_INT)
2247 {
2248 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2249 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
2250 opnum, (enum reload_type)type);
2251 *win = 1;
2252 return x;
2253 }
391c48ec 2254
e3374f82 2255#if TARGET_MACHO
2256 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
2257 && GET_CODE (x) == LO_SUM
2258 && GET_CODE (XEXP (x, 0)) == PLUS
2259 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
2260 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
2261 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == CONST
2262 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
2263 && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
2264 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
2265 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF)
2266 {
2267 /* Result of previous invocation of this function on Darwin
9df03d69 2268 floating point constant. */
e3374f82 2269 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2270 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
2271 opnum, (enum reload_type)type);
2272 *win = 1;
2273 return x;
2274 }
2275#endif
2276 if (GET_CODE (x) == PLUS
2277 && GET_CODE (XEXP (x, 0)) == REG
2278 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
2279 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
a0222b01 2280 && GET_CODE (XEXP (x, 1)) == CONST_INT
2532673e 2281 && !SPE_VECTOR_MODE (mode)
a0222b01 2282 && !ALTIVEC_VECTOR_MODE (mode))
e3374f82 2283 {
2284 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
2285 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
2286 HOST_WIDE_INT high
2287 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
2288
2289 /* Check for 32-bit overflow. */
2290 if (high + low != val)
2291 {
2292 *win = 0;
2293 return x;
2294 }
2295
2296 /* Reload the high part into a base reg; leave the low part
2297 in the mem directly. */
2298
2299 x = gen_rtx_PLUS (GET_MODE (x),
2300 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
2301 GEN_INT (high)),
2302 GEN_INT (low));
2303
2304 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2305 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
2306 opnum, (enum reload_type)type);
2307 *win = 1;
2308 return x;
2309 }
2310#if TARGET_MACHO
2311 if (GET_CODE (x) == SYMBOL_REF
2312 && DEFAULT_ABI == ABI_DARWIN
886cfd4f 2313 && !ALTIVEC_VECTOR_MODE (mode)
e3374f82 2314 && flag_pic)
2315 {
2316 /* Darwin load of floating point constant. */
2317 rtx offset = gen_rtx (CONST, Pmode,
2318 gen_rtx (MINUS, Pmode, x,
2319 gen_rtx (SYMBOL_REF, Pmode,
2320 machopic_function_base_name ())));
2321 x = gen_rtx (LO_SUM, GET_MODE (x),
2322 gen_rtx (PLUS, Pmode, pic_offset_table_rtx,
2323 gen_rtx (HIGH, Pmode, offset)), offset);
2324 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2325 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
2326 opnum, (enum reload_type)type);
2327 *win = 1;
2328 return x;
2329 }
2330#endif
2331 if (TARGET_TOC
5785723a 2332 && CONSTANT_POOL_EXPR_P (x)
2333 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
e3374f82 2334 {
2335 (x) = create_TOC_reference (x);
2336 *win = 1;
2337 return x;
2338 }
2339 *win = 0;
2340 return x;
2341}
2342
4bbdf529 2343/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
2344 that is a valid memory address for an instruction.
2345 The MODE argument is the machine mode for the MEM expression
2346 that wants to use this address.
2347
2348 On the RS/6000, there are four valid address: a SYMBOL_REF that
2349 refers to a constant pool entry of an address (or the sum of it
2350 plus a constant), a short (16-bit signed) constant plus a register,
2351 the sum of two registers, or a register indirect, possibly with an
2352 auto-increment. For DFmode and DImode with an constant plus register,
2353 we must ensure that both words are addressable or PowerPC64 with offset
2354 word aligned.
2355
2356 For modes spanning multiple registers (DFmode in 32-bit GPRs,
2357 32-bit DImode, TImode), indexed addressing cannot be used because
2358 adjacent memory cells are accessed by adding word-sized offsets
2359 during assembly output. */
2360int
2361rs6000_legitimate_address (mode, x, reg_ok_strict)
2362 enum machine_mode mode;
2363 rtx x;
2364 int reg_ok_strict;
2365{
2366 if (LEGITIMATE_INDIRECT_ADDRESS_P (x, reg_ok_strict))
2367 return 1;
2368 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
5f500529 2369 && !ALTIVEC_VECTOR_MODE (mode)
f19493d5 2370 && !SPE_VECTOR_MODE (mode)
4bbdf529 2371 && TARGET_UPDATE
2372 && LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (x, 0), reg_ok_strict))
2373 return 1;
2374 if (LEGITIMATE_SMALL_DATA_P (mode, x))
2375 return 1;
2376 if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
2377 return 1;
2378 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
2379 if (! reg_ok_strict
2380 && GET_CODE (x) == PLUS
2381 && GET_CODE (XEXP (x, 0)) == REG
2382 && XEXP (x, 0) == virtual_stack_vars_rtx
2383 && GET_CODE (XEXP (x, 1)) == CONST_INT)
2384 return 1;
2385 if (LEGITIMATE_OFFSET_ADDRESS_P (mode, x, reg_ok_strict))
2386 return 1;
2387 if (mode != TImode
f19493d5 2388 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
2389 || TARGET_POWERPC64
cf7d5bc7 2390 || (mode != DFmode && mode != TFmode))
4bbdf529 2391 && (TARGET_POWERPC64 || mode != DImode)
2392 && LEGITIMATE_INDEXED_ADDRESS_P (x, reg_ok_strict))
2393 return 1;
2394 if (LEGITIMATE_LO_SUM_ADDRESS_P (mode, x, reg_ok_strict))
2395 return 1;
2396 return 0;
2397}
5b6c6a8e 2398\f
970e222f 2399/* Try to output insns to set TARGET equal to the constant C if it can
2400 be done in less than N insns. Do all computations in MODE.
2401 Returns the place where the output has been placed if it can be
2402 done and the insns have been emitted. If it would take more than N
2403 insns, zero is returned and no insns and emitted. */
8eaf2dd1 2404
2405rtx
2406rs6000_emit_set_const (dest, mode, source, n)
2407 rtx dest, source;
2408 enum machine_mode mode;
2409 int n ATTRIBUTE_UNUSED;
2410{
e34d9322 2411 rtx result, insn, set;
8eaf2dd1 2412 HOST_WIDE_INT c0, c1;
2413
e34d9322 2414 if (mode == QImode || mode == HImode)
8eaf2dd1 2415 {
2416 if (dest == NULL)
2417 dest = gen_reg_rtx (mode);
2418 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
2419 return dest;
2420 }
e34d9322 2421 else if (mode == SImode)
8eaf2dd1 2422 {
e34d9322 2423 result = no_new_pseudos ? dest : gen_reg_rtx (SImode);
2424
2425 emit_insn (gen_rtx_SET (VOIDmode, result,
2426 GEN_INT (INTVAL (source)
2427 & (~ (HOST_WIDE_INT) 0xffff))));
2428 emit_insn (gen_rtx_SET (VOIDmode, dest,
2429 gen_rtx_IOR (SImode, result,
2430 GEN_INT (INTVAL (source) & 0xffff))));
2431 result = dest;
8eaf2dd1 2432 }
e34d9322 2433 else if (mode == DImode)
8eaf2dd1 2434 {
e34d9322 2435 if (GET_CODE (source) == CONST_INT)
2436 {
2437 c0 = INTVAL (source);
2438 c1 = -(c0 < 0);
2439 }
2440 else if (GET_CODE (source) == CONST_DOUBLE)
2441 {
8eaf2dd1 2442#if HOST_BITS_PER_WIDE_INT >= 64
e34d9322 2443 c0 = CONST_DOUBLE_LOW (source);
2444 c1 = -(c0 < 0);
8eaf2dd1 2445#else
e34d9322 2446 c0 = CONST_DOUBLE_LOW (source);
2447 c1 = CONST_DOUBLE_HIGH (source);
8eaf2dd1 2448#endif
e34d9322 2449 }
2450 else
2451 abort ();
2452
2453 result = rs6000_emit_set_long_const (dest, c0, c1);
8eaf2dd1 2454 }
2455 else
970e222f 2456 abort ();
8eaf2dd1 2457
e34d9322 2458 insn = get_last_insn ();
2459 set = single_set (insn);
2460 if (! CONSTANT_P (SET_SRC (set)))
2461 set_unique_reg_note (insn, REG_EQUAL, source);
2462
2463 return result;
8eaf2dd1 2464}
2465
2466/* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
2467 fall back to a straight forward decomposition. We do this to avoid
2468 exponential run times encountered when looking for longer sequences
2469 with rs6000_emit_set_const. */
2470static rtx
2471rs6000_emit_set_long_const (dest, c1, c2)
2472 rtx dest;
2473 HOST_WIDE_INT c1, c2;
2474{
2475 if (!TARGET_POWERPC64)
2476 {
2477 rtx operand1, operand2;
2478
2479 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
2480 DImode);
2481 operand2 = operand_subword_force (dest, WORDS_BIG_ENDIAN != 0,
2482 DImode);
2483 emit_move_insn (operand1, GEN_INT (c1));
2484 emit_move_insn (operand2, GEN_INT (c2));
2485 }
2486 else
2487 {
f5fe5de2 2488 HOST_WIDE_INT ud1, ud2, ud3, ud4;
60d2983e 2489
f5fe5de2 2490 ud1 = c1 & 0xffff;
2491 ud2 = (c1 & 0xffff0000) >> 16;
8eaf2dd1 2492#if HOST_BITS_PER_WIDE_INT >= 64
f5fe5de2 2493 c2 = c1 >> 32;
8eaf2dd1 2494#endif
f5fe5de2 2495 ud3 = c2 & 0xffff;
2496 ud4 = (c2 & 0xffff0000) >> 16;
8eaf2dd1 2497
f5fe5de2 2498 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
2499 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
8eaf2dd1 2500 {
f5fe5de2 2501 if (ud1 & 0x8000)
2502 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
2503 else
2504 emit_move_insn (dest, GEN_INT (ud1));
8eaf2dd1 2505 }
8eaf2dd1 2506
f5fe5de2 2507 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
2508 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
60d2983e 2509 {
f5fe5de2 2510 if (ud2 & 0x8000)
2511 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
2512 - 0x80000000));
60d2983e 2513 else
f5fe5de2 2514 emit_move_insn (dest, GEN_INT (ud2 << 16));
2515 if (ud1 != 0)
2516 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
60d2983e 2517 }
f5fe5de2 2518 else if ((ud4 == 0xffff && (ud3 & 0x8000))
2519 || (ud4 == 0 && ! (ud3 & 0x8000)))
2520 {
2521 if (ud3 & 0x8000)
2522 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
2523 - 0x80000000));
2524 else
2525 emit_move_insn (dest, GEN_INT (ud3 << 16));
2526
2527 if (ud2 != 0)
2528 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud2)));
2529 emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (16)));
2530 if (ud1 != 0)
2531 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
2532 }
2533 else
2534 {
2535 if (ud4 & 0x8000)
2536 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
2537 - 0x80000000));
2538 else
2539 emit_move_insn (dest, GEN_INT (ud4 << 16));
2540
2541 if (ud3 != 0)
2542 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud3)));
8eaf2dd1 2543
f5fe5de2 2544 emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32)));
2545 if (ud2 != 0)
2546 emit_move_insn (dest, gen_rtx_IOR (DImode, dest,
2547 GEN_INT (ud2 << 16)));
2548 if (ud1 != 0)
2549 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
2550 }
2551 }
8eaf2dd1 2552 return dest;
2553}
2554
5b6c6a8e 2555/* Emit a move from SOURCE to DEST in mode MODE. */
2556void
2557rs6000_emit_move (dest, source, mode)
2558 rtx dest;
2559 rtx source;
2560 enum machine_mode mode;
2561{
2562 rtx operands[2];
2563 operands[0] = dest;
2564 operands[1] = source;
2565
2566 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
2567 if (GET_CODE (operands[1]) == CONST_DOUBLE
2568 && ! FLOAT_MODE_P (mode)
2569 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
2570 {
2571 /* FIXME. This should never happen. */
2572 /* Since it seems that it does, do the safe thing and convert
2573 to a CONST_INT. */
2d232d05 2574 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
5b6c6a8e 2575 }
2576 if (GET_CODE (operands[1]) == CONST_DOUBLE
2577 && ! FLOAT_MODE_P (mode)
2578 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2579 && CONST_DOUBLE_LOW (operands[1]) >= 0)
2580 || (CONST_DOUBLE_HIGH (operands[1]) == -1
2581 && CONST_DOUBLE_LOW (operands[1]) < 0)))
2582 abort ();
88f55321 2583
2584 /* Check if GCC is setting up a block move that will end up using FP
2585 registers as temporaries. We must make sure this is acceptable. */
2586 if (GET_CODE (operands[0]) == MEM
2587 && GET_CODE (operands[1]) == MEM
2588 && mode == DImode
36198b23 2589 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
2590 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
2591 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
2592 ? 32 : MEM_ALIGN (operands[0])))
2593 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
2594 ? 32
2595 : MEM_ALIGN (operands[1]))))
2596 && ! MEM_VOLATILE_P (operands [0])
2597 && ! MEM_VOLATILE_P (operands [1]))
88f55321 2598 {
36198b23 2599 emit_move_insn (adjust_address (operands[0], SImode, 0),
2600 adjust_address (operands[1], SImode, 0));
2601 emit_move_insn (adjust_address (operands[0], SImode, 4),
2602 adjust_address (operands[1], SImode, 4));
88f55321 2603 return;
2604 }
5b6c6a8e 2605
5ffa81d9 2606 if (!no_new_pseudos)
2607 {
2608 if (GET_CODE (operands[1]) == MEM && optimize > 0
2609 && (mode == QImode || mode == HImode || mode == SImode)
2610 && GET_MODE_SIZE (mode) < GET_MODE_SIZE (word_mode))
2611 {
2612 rtx reg = gen_reg_rtx (word_mode);
2613
2614 emit_insn (gen_rtx_SET (word_mode, reg,
2615 gen_rtx_ZERO_EXTEND (word_mode,
2616 operands[1])));
2617 operands[1] = gen_lowpart (mode, reg);
2618 }
2619 if (GET_CODE (operands[0]) != REG)
2620 operands[1] = force_reg (mode, operands[1]);
2621 }
e2f08fad 2622
f19493d5 2623 if (mode == SFmode && ! TARGET_POWERPC
2624 && TARGET_HARD_FLOAT && TARGET_FPRS
39bda59f 2625 && GET_CODE (operands[0]) == MEM)
5b6c6a8e 2626 {
39bda59f 2627 int regnum;
2628
2629 if (reload_in_progress || reload_completed)
2630 regnum = true_regnum (operands[1]);
2631 else if (GET_CODE (operands[1]) == REG)
2632 regnum = REGNO (operands[1]);
2633 else
2634 regnum = -1;
5b6c6a8e 2635
2636 /* If operands[1] is a register, on POWER it may have
2637 double-precision data in it, so truncate it to single
2638 precision. */
2639 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
2640 {
2641 rtx newreg;
2642 newreg = (no_new_pseudos ? operands[1] : gen_reg_rtx (mode));
2643 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
2644 operands[1] = newreg;
2645 }
2646 }
2647
e2f08fad 2648 /* Handle the case where reload calls us with an invalid address;
2649 and the case of CONSTANT_P_RTX. */
018ca13c 2650 if (!ALTIVEC_VECTOR_MODE (mode)
886cfd4f 2651 && (! general_operand (operands[1], mode)
2652 || ! nonimmediate_operand (operands[0], mode)
2653 || GET_CODE (operands[1]) == CONSTANT_P_RTX))
5b6c6a8e 2654 {
2655 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2656 return;
2657 }
e2f08fad 2658
5b6c6a8e 2659 /* FIXME: In the long term, this switch statement should go away
2660 and be replaced by a sequence of tests based on things like
2661 mode == Pmode. */
2662 switch (mode)
2663 {
2664 case HImode:
2665 case QImode:
2666 if (CONSTANT_P (operands[1])
2667 && GET_CODE (operands[1]) != CONST_INT)
e2f08fad 2668 operands[1] = force_const_mem (mode, operands[1]);
5b6c6a8e 2669 break;
2670
5c0586b9 2671 case TFmode:
5b6c6a8e 2672 case DFmode:
2673 case SFmode:
2674 if (CONSTANT_P (operands[1])
2675 && ! easy_fp_constant (operands[1], mode))
e2f08fad 2676 operands[1] = force_const_mem (mode, operands[1]);
5b6c6a8e 2677 break;
2678
500c7157 2679 case V16QImode:
2680 case V8HImode:
2681 case V4SFmode:
2682 case V4SImode:
f19493d5 2683 case V4HImode:
2684 case V2SFmode:
2685 case V2SImode:
25d17dbc 2686 case V1DImode:
886cfd4f 2687 if (CONSTANT_P (operands[1])
2688 && !easy_vector_constant (operands[1]))
500c7157 2689 operands[1] = force_const_mem (mode, operands[1]);
2690 break;
2691
5b6c6a8e 2692 case SImode:
e2f08fad 2693 case DImode:
5b6c6a8e 2694 /* Use default pattern for address of ELF small data */
2695 if (TARGET_ELF
e2f08fad 2696 && mode == Pmode
e7ce8542 2697 && DEFAULT_ABI == ABI_V4
e2f08fad 2698 && (GET_CODE (operands[1]) == SYMBOL_REF
2699 || GET_CODE (operands[1]) == CONST)
2700 && small_data_operand (operands[1], mode))
5b6c6a8e 2701 {
2702 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2703 return;
2704 }
2705
e7ce8542 2706 if (DEFAULT_ABI == ABI_V4
e2f08fad 2707 && mode == Pmode && mode == SImode
2708 && flag_pic == 1 && got_operand (operands[1], mode))
5b6c6a8e 2709 {
2710 emit_insn (gen_movsi_got (operands[0], operands[1]));
2711 return;
2712 }
2713
80d725d7 2714 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
2715 && TARGET_NO_TOC && ! flag_pic
e2f08fad 2716 && mode == Pmode
5b6c6a8e 2717 && CONSTANT_P (operands[1])
2718 && GET_CODE (operands[1]) != HIGH
2719 && GET_CODE (operands[1]) != CONST_INT)
2720 {
e2f08fad 2721 rtx target = (no_new_pseudos ? operands[0] : gen_reg_rtx (mode));
5b6c6a8e 2722
2723 /* If this is a function address on -mcall-aixdesc,
2724 convert it to the address of the descriptor. */
2725 if (DEFAULT_ABI == ABI_AIX
2726 && GET_CODE (operands[1]) == SYMBOL_REF
2727 && XSTR (operands[1], 0)[0] == '.')
2728 {
2729 const char *name = XSTR (operands[1], 0);
2730 rtx new_ref;
2731 while (*name == '.')
2732 name++;
2733 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
2734 CONSTANT_POOL_ADDRESS_P (new_ref)
2735 = CONSTANT_POOL_ADDRESS_P (operands[1]);
2736 SYMBOL_REF_FLAG (new_ref) = SYMBOL_REF_FLAG (operands[1]);
2737 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
2738 operands[1] = new_ref;
2739 }
7a2fc9d6 2740
80d725d7 2741 if (DEFAULT_ABI == ABI_DARWIN)
2742 {
2743 emit_insn (gen_macho_high (target, operands[1]));
2744 emit_insn (gen_macho_low (operands[0], target, operands[1]));
2745 return;
2746 }
2747
5b6c6a8e 2748 emit_insn (gen_elf_high (target, operands[1]));
2749 emit_insn (gen_elf_low (operands[0], target, operands[1]));
2750 return;
2751 }
2752
e2f08fad 2753 /* If this is a SYMBOL_REF that refers to a constant pool entry,
2754 and we have put it in the TOC, we just need to make a TOC-relative
2755 reference to it. */
2756 if (TARGET_TOC
2757 && GET_CODE (operands[1]) == SYMBOL_REF
2758 && CONSTANT_POOL_EXPR_P (operands[1])
2759 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
2760 get_pool_mode (operands[1])))
5b6c6a8e 2761 {
e2f08fad 2762 operands[1] = create_TOC_reference (operands[1]);
5b6c6a8e 2763 }
e2f08fad 2764 else if (mode == Pmode
2765 && CONSTANT_P (operands[1])
9335440a 2766 && ((GET_CODE (operands[1]) != CONST_INT
2767 && ! easy_fp_constant (operands[1], mode))
2768 || (GET_CODE (operands[1]) == CONST_INT
2769 && num_insns_constant (operands[1], mode) > 2)
2770 || (GET_CODE (operands[0]) == REG
2771 && FP_REGNO_P (REGNO (operands[0]))))
e2f08fad 2772 && GET_CODE (operands[1]) != HIGH
2773 && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1])
2774 && ! TOC_RELATIVE_EXPR_P (operands[1]))
5b6c6a8e 2775 {
2776 /* Emit a USE operation so that the constant isn't deleted if
2777 expensive optimizations are turned on because nobody
2778 references it. This should only be done for operands that
2779 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
2780 This should not be done for operands that contain LABEL_REFs.
2781 For now, we just handle the obvious case. */
2782 if (GET_CODE (operands[1]) != LABEL_REF)
2783 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
2784
ad3ed368 2785#if TARGET_MACHO
80d725d7 2786 /* Darwin uses a special PIC legitimizer. */
2787 if (DEFAULT_ABI == ABI_DARWIN && flag_pic)
2788 {
80d725d7 2789 operands[1] =
2790 rs6000_machopic_legitimize_pic_address (operands[1], mode,
ad3ed368 2791 operands[0]);
2792 if (operands[0] != operands[1])
2793 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
80d725d7 2794 return;
2795 }
ad3ed368 2796#endif
80d725d7 2797
5b6c6a8e 2798 /* If we are to limit the number of things we put in the TOC and
2799 this is a symbol plus a constant we can add in one insn,
2800 just put the symbol in the TOC and add the constant. Don't do
2801 this if reload is in progress. */
2802 if (GET_CODE (operands[1]) == CONST
2803 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
2804 && GET_CODE (XEXP (operands[1], 0)) == PLUS
e2f08fad 2805 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
5b6c6a8e 2806 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
2807 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
2808 && ! side_effects_p (operands[0]))
2809 {
970e222f 2810 rtx sym =
2811 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
5b6c6a8e 2812 rtx other = XEXP (XEXP (operands[1], 0), 1);
2813
e2f08fad 2814 sym = force_reg (mode, sym);
2815 if (mode == SImode)
2816 emit_insn (gen_addsi3 (operands[0], sym, other));
2817 else
2818 emit_insn (gen_adddi3 (operands[0], sym, other));
5b6c6a8e 2819 return;
2820 }
2821
e2f08fad 2822 operands[1] = force_const_mem (mode, operands[1]);
5b6c6a8e 2823
2824 if (TARGET_TOC
7c22a04d 2825 && CONSTANT_POOL_EXPR_P (XEXP (operands[1], 0))
2826 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
2827 get_pool_constant (XEXP (operands[1], 0)),
2828 get_pool_mode (XEXP (operands[1], 0))))
e2f08fad 2829 {
ab6ab77e 2830 operands[1]
2831 = gen_rtx_MEM (mode,
2832 create_TOC_reference (XEXP (operands[1], 0)));
2833 set_mem_alias_set (operands[1], get_TOC_alias_set ());
5b6c6a8e 2834 RTX_UNCHANGING_P (operands[1]) = 1;
e2f08fad 2835 }
5b6c6a8e 2836 }
2837 break;
e2f08fad 2838
5b6c6a8e 2839 case TImode:
2840 if (GET_CODE (operands[0]) == MEM
2841 && GET_CODE (XEXP (operands[0], 0)) != REG
2842 && ! reload_in_progress)
537ffcfc 2843 operands[0]
2844 = replace_equiv_address (operands[0],
2845 copy_addr_to_reg (XEXP (operands[0], 0)));
5b6c6a8e 2846
2847 if (GET_CODE (operands[1]) == MEM
2848 && GET_CODE (XEXP (operands[1], 0)) != REG
2849 && ! reload_in_progress)
537ffcfc 2850 operands[1]
2851 = replace_equiv_address (operands[1],
2852 copy_addr_to_reg (XEXP (operands[1], 0)));
5b6c6a8e 2853 break;
2854
2855 default:
2856 abort ();
2857 }
2858
e2f08fad 2859 /* Above, we may have called force_const_mem which may have returned
2860 an invalid address. If we can, fix this up; otherwise, reload will
2861 have to deal with it. */
2862 if (GET_CODE (operands[1]) == MEM
2863 && ! memory_address_p (mode, XEXP (operands[1], 0))
2864 && ! reload_in_progress)
e513d163 2865 operands[1] = adjust_address (operands[1], mode, 0);
e2f08fad 2866
5b6c6a8e 2867 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
a7f32c2d 2868 return;
5b6c6a8e 2869}
a3bbc303 2870\f
2871/* Initialize a variable CUM of type CUMULATIVE_ARGS
2872 for a call to a function whose data type is FNTYPE.
2873 For a library call, FNTYPE is 0.
2874
2875 For incoming args we set the number of arguments in the prototype large
7fd6c6b9 2876 so we never return a PARALLEL. */
a3bbc303 2877
2878void
2879init_cumulative_args (cum, fntype, libname, incoming)
2880 CUMULATIVE_ARGS *cum;
2881 tree fntype;
600e851b 2882 rtx libname ATTRIBUTE_UNUSED;
a3bbc303 2883 int incoming;
2884{
2885 static CUMULATIVE_ARGS zero_cumulative;
2886
2887 *cum = zero_cumulative;
2888 cum->words = 0;
2889 cum->fregno = FP_ARG_MIN_REG;
500c7157 2890 cum->vregno = ALTIVEC_ARG_MIN_REG;
a3bbc303 2891 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
7a2fc9d6 2892 cum->call_cookie = CALL_NORMAL;
036c1d46 2893 cum->sysv_gregno = GP_ARG_MIN_REG;
a3bbc303 2894
2895 if (incoming)
b5c77702 2896 cum->nargs_prototype = 1000; /* don't return a PARALLEL */
a3bbc303 2897
2898 else if (cum->prototype)
2899 cum->nargs_prototype = (list_length (TYPE_ARG_TYPES (fntype)) - 1
2900 + (TYPE_MODE (TREE_TYPE (fntype)) == BLKmode
2901 || RETURN_IN_MEMORY (TREE_TYPE (fntype))));
2902
2903 else
2904 cum->nargs_prototype = 0;
2905
2906 cum->orig_nargs = cum->nargs_prototype;
7a2fc9d6 2907
edd2f2ae 2908 /* Check for a longcall attribute. */
2909 if (fntype
2910 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
2911 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype)))
fed06885 2912 cum->call_cookie = CALL_LONG;
2913
a3bbc303 2914 if (TARGET_DEBUG_ARG)
2915 {
2916 fprintf (stderr, "\ninit_cumulative_args:");
2917 if (fntype)
2918 {
2919 tree ret_type = TREE_TYPE (fntype);
2920 fprintf (stderr, " ret code = %s,",
2921 tree_code_name[ (int)TREE_CODE (ret_type) ]);
2922 }
2923
fed06885 2924 if (cum->call_cookie & CALL_LONG)
2925 fprintf (stderr, " longcall,");
2926
a3bbc303 2927 fprintf (stderr, " proto = %d, nargs = %d\n",
2928 cum->prototype, cum->nargs_prototype);
2929 }
2930}
2931\f
030a4821 2932/* If defined, a C expression which determines whether, and in which
2933 direction, to pad out an argument with extra space. The value
2934 should be of type `enum direction': either `upward' to pad above
2935 the argument, `downward' to pad below, or `none' to inhibit
2936 padding.
2937
2938 For the AIX ABI structs are always stored left shifted in their
2939 argument slot. */
2940
bbd21807 2941enum direction
030a4821 2942function_arg_padding (mode, type)
2943 enum machine_mode mode;
2944 tree type;
2945{
220345e0 2946 if (type != 0 && AGGREGATE_TYPE_P (type))
bbd21807 2947 return upward;
030a4821 2948
2949 /* This is the default definition. */
2950 return (! BYTES_BIG_ENDIAN
bbd21807 2951 ? upward
030a4821 2952 : ((mode == BLKmode
2953 ? (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
2954 && int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT))
2955 : GET_MODE_BITSIZE (mode) < PARM_BOUNDARY)
bbd21807 2956 ? downward : upward));
030a4821 2957}
2958
6b02f2a5 2959/* If defined, a C expression that gives the alignment boundary, in bits,
2960 of an argument with the specified mode and type. If it is not defined,
2961 PARM_BOUNDARY is used for all arguments.
2962
a9a47ad3 2963 V.4 wants long longs to be double word aligned. */
6b02f2a5 2964
2965int
2966function_arg_boundary (mode, type)
2967 enum machine_mode mode;
bbd21807 2968 tree type ATTRIBUTE_UNUSED;
6b02f2a5 2969{
e7ce8542 2970 if (DEFAULT_ABI == ABI_V4 && (mode == DImode || mode == DFmode))
d24794a5 2971 return 64;
f19493d5 2972 else if (SPE_VECTOR_MODE (mode))
2973 return 64;
500c7157 2974 else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
2975 return 128;
bbd21807 2976 else
6b02f2a5 2977 return PARM_BOUNDARY;
6b02f2a5 2978}
2979\f
a3bbc303 2980/* Update the data in CUM to advance over an argument
2981 of mode MODE and data type TYPE.
2982 (TYPE is null for libcalls where that information may not be available.) */
2983
2984void
2985function_arg_advance (cum, mode, type, named)
2986 CUMULATIVE_ARGS *cum;
2987 enum machine_mode mode;
2988 tree type;
2989 int named;
2990{
2991 cum->nargs_prototype--;
2992
500c7157 2993 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
2994 {
2995 if (cum->vregno <= ALTIVEC_ARG_MAX_REG && cum->nargs_prototype >= 0)
2996 cum->vregno++;
2997 else
2998 cum->words += RS6000_ARG_SIZE (mode, type);
2999 }
af3757ef 3000 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
3001 && named && cum->sysv_gregno <= GP_ARG_MAX_REG)
3002 cum->sysv_gregno++;
e7ce8542 3003 else if (DEFAULT_ABI == ABI_V4)
a3bbc303 3004 {
f19493d5 3005 if (TARGET_HARD_FLOAT && TARGET_FPRS
036c1d46 3006 && (mode == SFmode || mode == DFmode))
a3bbc303 3007 {
036c1d46 3008 if (cum->fregno <= FP_ARG_V4_MAX_REG)
3009 cum->fregno++;
3010 else
3011 {
3012 if (mode == DFmode)
3013 cum->words += cum->words & 1;
7c22a04d 3014 cum->words += RS6000_ARG_SIZE (mode, type);
036c1d46 3015 }
a3bbc303 3016 }
036c1d46 3017 else
3018 {
3019 int n_words;
3020 int gregno = cum->sysv_gregno;
3021
3022 /* Aggregates and IEEE quad get passed by reference. */
3023 if ((type && AGGREGATE_TYPE_P (type))
3024 || mode == TFmode)
3025 n_words = 1;
3026 else
7c22a04d 3027 n_words = RS6000_ARG_SIZE (mode, type);
036c1d46 3028
af3757ef 3029 /* Long long and SPE vectors are put in odd registers. */
036c1d46 3030 if (n_words == 2 && (gregno & 1) == 0)
3031 gregno += 1;
3032
af3757ef 3033 /* Long long and SPE vectors are not split between registers
3034 and stack. */
036c1d46 3035 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
3036 {
3037 /* Long long is aligned on the stack. */
3038 if (n_words == 2)
3039 cum->words += cum->words & 1;
3040 cum->words += n_words;
3041 }
a3bbc303 3042
036c1d46 3043 /* Note: continuing to accumulate gregno past when we've started
3044 spilling to the stack indicates the fact that we've started
3045 spilling to the stack to expand_builtin_saveregs. */
3046 cum->sysv_gregno = gregno + n_words;
3047 }
a3bbc303 3048
036c1d46 3049 if (TARGET_DEBUG_ARG)
3050 {
3051 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
3052 cum->words, cum->fregno);
3053 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
3054 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
3055 fprintf (stderr, "mode = %4s, named = %d\n",
3056 GET_MODE_NAME (mode), named);
3057 }
a3bbc303 3058 }
3059 else
036c1d46 3060 {
3061 int align = (TARGET_32BIT && (cum->words & 1) != 0
3062 && function_arg_boundary (mode, type) == 64) ? 1 : 0;
970e222f 3063
7c22a04d 3064 cum->words += align + RS6000_ARG_SIZE (mode, type);
a3bbc303 3065
f19493d5 3066 if (GET_MODE_CLASS (mode) == MODE_FLOAT
3067 && TARGET_HARD_FLOAT && TARGET_FPRS)
cf7d5bc7 3068 cum->fregno += (mode == TFmode ? 2 : 1);
036c1d46 3069
3070 if (TARGET_DEBUG_ARG)
3071 {
3072 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
3073 cum->words, cum->fregno);
3074 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
3075 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
3076 fprintf (stderr, "named = %d, align = %d\n", named, align);
3077 }
3078 }
a3bbc303 3079}
3080\f
3081/* Determine where to put an argument to a function.
3082 Value is zero to push the argument on the stack,
3083 or a hard register in which to store the argument.
3084
3085 MODE is the argument's machine mode.
3086 TYPE is the data type of the argument (as a tree).
3087 This is null for libcalls where that information may
3088 not be available.
3089 CUM is a variable of type CUMULATIVE_ARGS which gives info about
3090 the preceding args and about the function being called.
3091 NAMED is nonzero if this argument is a named parameter
3092 (otherwise it is an extra parameter matching an ellipsis).
3093
3094 On RS/6000 the first eight words of non-FP are normally in registers
3095 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
3096 Under V.4, the first 8 FP args are in registers.
3097
3098 If this is floating-point and no prototype is specified, we use
3099 both an FP and integer register (or possibly FP reg and stack). Library
3100 functions (when TYPE is zero) always have the proper types for args,
3101 so we can pass the FP value just in one register. emit_library_function
7fd6c6b9 3102 doesn't support PARALLEL anyway. */
a3bbc303 3103
3104struct rtx_def *
3105function_arg (cum, mode, type, named)
3106 CUMULATIVE_ARGS *cum;
3107 enum machine_mode mode;
3108 tree type;
d51e4c9d 3109 int named;
a3bbc303 3110{
036c1d46 3111 enum rs6000_abi abi = DEFAULT_ABI;
a3bbc303 3112
970e222f 3113 /* Return a marker to indicate whether CR1 needs to set or clear the
3114 bit that V.4 uses to say fp args were passed in registers.
3115 Assume that we don't need the marker for software floating point,
3116 or compiler generated library calls. */
a3bbc303 3117 if (mode == VOIDmode)
3118 {
e7ce8542 3119 if (abi == ABI_V4
7a2fc9d6 3120 && cum->nargs_prototype < 0
a3bbc303 3121 && type && (cum->prototype || TARGET_NO_PROTOTYPE))
7a2fc9d6 3122 {
f19493d5 3123 /* For the SPE, we need to crxor CR6 always. */
3124 if (TARGET_SPE_ABI)
3125 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
3126 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
3127 return GEN_INT (cum->call_cookie
3128 | ((cum->fregno == FP_ARG_MIN_REG)
3129 ? CALL_V4_SET_FP_ARGS
3130 : CALL_V4_CLEAR_FP_ARGS));
7a2fc9d6 3131 }
a3bbc303 3132
7a2fc9d6 3133 return GEN_INT (cum->call_cookie);
a3bbc303 3134 }
3135
500c7157 3136 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
3137 {
d51e4c9d 3138 if (named && cum->vregno <= ALTIVEC_ARG_MAX_REG)
500c7157 3139 return gen_rtx_REG (mode, cum->vregno);
3140 else
3141 return NULL;
3142 }
af3757ef 3143 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode) && named)
f19493d5 3144 {
af3757ef 3145 if (cum->sysv_gregno <= GP_ARG_MAX_REG)
f19493d5 3146 return gen_rtx_REG (mode, cum->sysv_gregno);
3147 else
3148 return NULL;
3149 }
e7ce8542 3150 else if (abi == ABI_V4)
a3bbc303 3151 {
f19493d5 3152 if (TARGET_HARD_FLOAT && TARGET_FPRS
036c1d46 3153 && (mode == SFmode || mode == DFmode))
3154 {
3155 if (cum->fregno <= FP_ARG_V4_MAX_REG)
3156 return gen_rtx_REG (mode, cum->fregno);
3157 else
3158 return NULL;
3159 }
3160 else
3161 {
3162 int n_words;
3163 int gregno = cum->sysv_gregno;
3164
3165 /* Aggregates and IEEE quad get passed by reference. */
3166 if ((type && AGGREGATE_TYPE_P (type))
3167 || mode == TFmode)
3168 n_words = 1;
3169 else
7c22a04d 3170 n_words = RS6000_ARG_SIZE (mode, type);
036c1d46 3171
af3757ef 3172 /* Long long and SPE vectors are put in odd registers. */
036c1d46 3173 if (n_words == 2 && (gregno & 1) == 0)
3174 gregno += 1;
3175
af3757ef 3176 /* Long long and SPE vectors are not split between registers
3177 and stack. */
036c1d46 3178 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
af3757ef 3179 {
3180 /* SPE vectors in ... get split into 2 registers. */
3181 if (TARGET_SPE && TARGET_SPE_ABI
3182 && SPE_VECTOR_MODE (mode) && !named)
3183 {
3184 rtx r1, r2;
7b043227 3185 enum machine_mode m = SImode;
10a529ae 3186
af3757ef 3187 r1 = gen_rtx_REG (m, gregno);
3188 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
3189 r2 = gen_rtx_REG (m, gregno + 1);
3190 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
3191 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
3192 }
3193 return gen_rtx_REG (mode, gregno);
3194 }
036c1d46 3195 else
3196 return NULL;
3197 }
a3bbc303 3198 }
036c1d46 3199 else
3200 {
3201 int align = (TARGET_32BIT && (cum->words & 1) != 0
3202 && function_arg_boundary (mode, type) == 64) ? 1 : 0;
3203 int align_words = cum->words + align;
a3bbc303 3204
036c1d46 3205 if (type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
3206 return NULL_RTX;
3207
3208 if (USE_FP_FOR_ARG_P (*cum, mode, type))
3209 {
3210 if (! type
3211 || ((cum->nargs_prototype > 0)
3212 /* IBM AIX extended its linkage convention definition always
3213 to require FP args after register save area hole on the
3214 stack. */
3215 && (DEFAULT_ABI != ABI_AIX
3216 || ! TARGET_XL_CALL
3217 || (align_words < GP_ARG_NUM_REG))))
3218 return gen_rtx_REG (mode, cum->fregno);
3219
3220 return gen_rtx_PARALLEL (mode,
3221 gen_rtvec (2,
3469a3e2 3222 gen_rtx_EXPR_LIST (VOIDmode,
7fd6c6b9 3223 ((align_words >= GP_ARG_NUM_REG)
3224 ? NULL_RTX
3225 : (align_words
7c22a04d 3226 + RS6000_ARG_SIZE (mode, type)
7fd6c6b9 3227 > GP_ARG_NUM_REG
3228 /* If this is partially on the stack, then
3229 we only include the portion actually
3230 in registers here. */
3469a3e2 3231 ? gen_rtx_REG (SImode,
7fd6c6b9 3232 GP_ARG_MIN_REG + align_words)
3469a3e2 3233 : gen_rtx_REG (mode,
7fd6c6b9 3234 GP_ARG_MIN_REG + align_words))),
3235 const0_rtx),
3469a3e2 3236 gen_rtx_EXPR_LIST (VOIDmode,
3237 gen_rtx_REG (mode, cum->fregno),
7fd6c6b9 3238 const0_rtx)));
036c1d46 3239 }
3240 else if (align_words < GP_ARG_NUM_REG)
3241 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
3242 else
3243 return NULL_RTX;
a3bbc303 3244 }
a3bbc303 3245}
3246\f
3247/* For an arg passed partly in registers and partly in memory,
3248 this is the number of registers used.
3249 For args passed entirely in registers or entirely in memory, zero. */
3250
3251int
3252function_arg_partial_nregs (cum, mode, type, named)
3253 CUMULATIVE_ARGS *cum;
3254 enum machine_mode mode;
3255 tree type;
7c22a04d 3256 int named ATTRIBUTE_UNUSED;
a3bbc303 3257{
e7ce8542 3258 if (DEFAULT_ABI == ABI_V4)
a3bbc303 3259 return 0;
a3bbc303 3260
500c7157 3261 if (USE_FP_FOR_ARG_P (*cum, mode, type)
3262 || USE_ALTIVEC_FOR_ARG_P (*cum, mode, type))
a3bbc303 3263 {
3264 if (cum->nargs_prototype >= 0)
3265 return 0;
3266 }
3267
3268 if (cum->words < GP_ARG_NUM_REG
7c22a04d 3269 && GP_ARG_NUM_REG < (cum->words + RS6000_ARG_SIZE (mode, type)))
a3bbc303 3270 {
3271 int ret = GP_ARG_NUM_REG - cum->words;
3272 if (ret && TARGET_DEBUG_ARG)
3273 fprintf (stderr, "function_arg_partial_nregs: %d\n", ret);
3274
3275 return ret;
3276 }
3277
3278 return 0;
3279}
3280\f
3281/* A C expression that indicates when an argument must be passed by
3282 reference. If nonzero for an argument, a copy of that argument is
3283 made in memory and a pointer to the argument is passed instead of
3284 the argument itself. The pointer is passed in whatever way is
3285 appropriate for passing a pointer to that type.
3286
3287 Under V.4, structures and unions are passed by reference. */
3288
3289int
3290function_arg_pass_by_reference (cum, mode, type, named)
600e851b 3291 CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
3292 enum machine_mode mode ATTRIBUTE_UNUSED;
a3bbc303 3293 tree type;
600e851b 3294 int named ATTRIBUTE_UNUSED;
a3bbc303 3295{
e7ce8542 3296 if (DEFAULT_ABI == ABI_V4
036c1d46 3297 && ((type && AGGREGATE_TYPE_P (type))
3298 || mode == TFmode))
a3bbc303 3299 {
3300 if (TARGET_DEBUG_ARG)
3301 fprintf (stderr, "function_arg_pass_by_reference: aggregate\n");
3302
3303 return 1;
3304 }
a3bbc303 3305
3306 return 0;
3307}
a3bbc303 3308\f
3309/* Perform any needed actions needed for a function that is receiving a
3310 variable number of arguments.
3311
3312 CUM is as above.
3313
3314 MODE and TYPE are the mode and type of the current parameter.
3315
3316 PRETEND_SIZE is a variable that should be set to the amount of stack
3317 that must be pushed by the prolog to pretend that our caller pushed
3318 it.
3319
3320 Normally, this macro will push all remaining incoming registers on the
3321 stack and set PRETEND_SIZE to the length of the registers pushed. */
3322
3323void
3324setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
3325 CUMULATIVE_ARGS *cum;
3326 enum machine_mode mode;
3327 tree type;
3328 int *pretend_size;
3329 int no_rtl;
3330
3331{
036c1d46 3332 CUMULATIVE_ARGS next_cum;
3333 int reg_size = TARGET_32BIT ? 4 : 8;
8cf2f1a9 3334 rtx save_area = NULL_RTX, mem;
7da94773 3335 int first_reg_offset, set;
7c22a04d 3336 tree fntype;
3337 int stdarg_p;
a3bbc303 3338
7c22a04d 3339 fntype = TREE_TYPE (current_function_decl);
3340 stdarg_p = (TYPE_ARG_TYPES (fntype) != 0
3341 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3342 != void_type_node));
036c1d46 3343
7c22a04d 3344 /* For varargs, we do not want to skip the dummy va_dcl argument.
3345 For stdargs, we do want to skip the last named argument. */
3346 next_cum = *cum;
3347 if (stdarg_p)
3348 function_arg_advance (&next_cum, mode, type, 1);
036c1d46 3349
e7ce8542 3350 if (DEFAULT_ABI == ABI_V4)
7c22a04d 3351 {
036c1d46 3352 /* Indicate to allocate space on the stack for varargs save area. */
0912a6a2 3353 cfun->machine->sysv_varargs_p = 1;
454dcb1d 3354 if (! no_rtl)
ccefda8d 3355 save_area = plus_constant (virtual_stack_vars_rtx,
b5c77702 3356 - RS6000_VARARGS_SIZE);
036c1d46 3357
3358 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
a3bbc303 3359 }
454dcb1d 3360 else
a3bbc303 3361 {
7c22a04d 3362 first_reg_offset = next_cum.words;
036c1d46 3363 save_area = virtual_incoming_args_rtx;
0912a6a2 3364 cfun->machine->sysv_varargs_p = 0;
a3bbc303 3365
3366 if (MUST_PASS_IN_STACK (mode, type))
7c22a04d 3367 first_reg_offset += RS6000_ARG_SIZE (TYPE_MODE (type), type);
036c1d46 3368 }
a3bbc303 3369
7da94773 3370 set = get_varargs_alias_set ();
a516dd3a 3371 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG)
036c1d46 3372 {
7da94773 3373 mem = gen_rtx_MEM (BLKmode,
3374 plus_constant (save_area,
3375 first_reg_offset * reg_size)),
ab6ab77e 3376 set_mem_alias_set (mem, set);
2a631e19 3377 set_mem_align (mem, BITS_PER_WORD);
7da94773 3378
036c1d46 3379 move_block_from_reg
7da94773 3380 (GP_ARG_MIN_REG + first_reg_offset, mem,
036c1d46 3381 GP_ARG_NUM_REG - first_reg_offset,
3382 (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD);
3383
3384 /* ??? Does ABI_V4 need this at all? */
a3bbc303 3385 *pretend_size = (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD;
3386 }
3387
a3bbc303 3388 /* Save FP registers if needed. */
e7ce8542 3389 if (DEFAULT_ABI == ABI_V4
f19493d5 3390 && TARGET_HARD_FLOAT && TARGET_FPRS
3391 && ! no_rtl
036c1d46 3392 && next_cum.fregno <= FP_ARG_V4_MAX_REG)
a3bbc303 3393 {
036c1d46 3394 int fregno = next_cum.fregno;
bbd21807 3395 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
036c1d46 3396 rtx lab = gen_label_rtx ();
3397 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG) * 8);
a3bbc303 3398
036c1d46 3399 emit_jump_insn (gen_rtx_SET (VOIDmode,
a3bbc303 3400 pc_rtx,
3469a3e2 3401 gen_rtx_IF_THEN_ELSE (VOIDmode,
036c1d46 3402 gen_rtx_NE (VOIDmode, cr1,
3403 const0_rtx),
3469a3e2 3404 gen_rtx_LABEL_REF (VOIDmode, lab),
a3bbc303 3405 pc_rtx)));
3406
036c1d46 3407 while (fregno <= FP_ARG_V4_MAX_REG)
3408 {
7da94773 3409 mem = gen_rtx_MEM (DFmode, plus_constant (save_area, off));
ab6ab77e 3410 set_mem_alias_set (mem, set);
7da94773 3411 emit_move_insn (mem, gen_rtx_REG (DFmode, fregno));
036c1d46 3412 fregno++;
3413 off += 8;
a3bbc303 3414 }
036c1d46 3415
3416 emit_label (lab);
a3bbc303 3417 }
a3bbc303 3418}
a3bbc303 3419
7da94773 3420/* Create the va_list data type. */
ccefda8d 3421
7da94773 3422tree
3423rs6000_build_va_list ()
3424{
df81f26a 3425 tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
a3bbc303 3426
bbd21807 3427 /* For AIX, prefer 'char *' because that's what the system
3428 header files like. */
e7ce8542 3429 if (DEFAULT_ABI != ABI_V4)
bbd21807 3430 return build_pointer_type (char_type_node);
7da94773 3431
a1f71e15 3432 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
df81f26a 3433 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
15a4d364 3434
bbd21807 3435 f_gpr = build_decl (FIELD_DECL, get_identifier ("gpr"),
3436 unsigned_char_type_node);
3437 f_fpr = build_decl (FIELD_DECL, get_identifier ("fpr"),
3438 unsigned_char_type_node);
7da94773 3439 f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"),
3440 ptr_type_node);
3441 f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
3442 ptr_type_node);
3443
3444 DECL_FIELD_CONTEXT (f_gpr) = record;
3445 DECL_FIELD_CONTEXT (f_fpr) = record;
3446 DECL_FIELD_CONTEXT (f_ovf) = record;
3447 DECL_FIELD_CONTEXT (f_sav) = record;
3448
df81f26a 3449 TREE_CHAIN (record) = type_decl;
3450 TYPE_NAME (record) = type_decl;
7da94773 3451 TYPE_FIELDS (record) = f_gpr;
3452 TREE_CHAIN (f_gpr) = f_fpr;
3453 TREE_CHAIN (f_fpr) = f_ovf;
3454 TREE_CHAIN (f_ovf) = f_sav;
3455
3456 layout_type (record);
3457
3458 /* The correct type is an array type of one element. */
3459 return build_array_type (record, build_index_type (size_zero_node));
3460}
3461
3462/* Implement va_start. */
3463
3464void
7df226a2 3465rs6000_va_start (valist, nextarg)
7da94773 3466 tree valist;
3467 rtx nextarg;
a3bbc303 3468{
7da94773 3469 HOST_WIDE_INT words, n_gpr, n_fpr;
3470 tree f_gpr, f_fpr, f_ovf, f_sav;
3471 tree gpr, fpr, ovf, sav, t;
ccefda8d 3472
7da94773 3473 /* Only SVR4 needs something special. */
e7ce8542 3474 if (DEFAULT_ABI != ABI_V4)
7da94773 3475 {
7df226a2 3476 std_expand_builtin_va_start (valist, nextarg);
7da94773 3477 return;
3478 }
3479
6cd005c9 3480 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
7da94773 3481 f_fpr = TREE_CHAIN (f_gpr);
3482 f_ovf = TREE_CHAIN (f_fpr);
3483 f_sav = TREE_CHAIN (f_ovf);
3484
11a61dea 3485 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
7da94773 3486 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
3487 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
3488 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
3489 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
3490
3491 /* Count number of gp and fp argument registers used. */
036c1d46 3492 words = current_function_args_info.words;
7da94773 3493 n_gpr = current_function_args_info.sysv_gregno - GP_ARG_MIN_REG;
3494 n_fpr = current_function_args_info.fregno - FP_ARG_MIN_REG;
3495
3496 if (TARGET_DEBUG_ARG)
42aeaad8 3497 {
3498 fputs ("va_start: words = ", stderr);
3499 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, words);
3500 fputs (", n_gpr = ", stderr);
3501 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, n_gpr);
3502 fputs (", n_fpr = ", stderr);
3503 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, n_fpr);
3504 putc ('\n', stderr);
3505 }
7da94773 3506
3507 t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, build_int_2 (n_gpr, 0));
3508 TREE_SIDE_EFFECTS (t) = 1;
3509 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3510
3511 t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr, build_int_2 (n_fpr, 0));
3512 TREE_SIDE_EFFECTS (t) = 1;
3513 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3514
3515 /* Find the overflow area. */
3516 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
3517 if (words != 0)
3518 t = build (PLUS_EXPR, TREE_TYPE (ovf), t,
3519 build_int_2 (words * UNITS_PER_WORD, 0));
3520 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
3521 TREE_SIDE_EFFECTS (t) = 1;
3522 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3523
3524 /* Find the register save area. */
3525 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
3526 t = build (PLUS_EXPR, TREE_TYPE (sav), t,
3527 build_int_2 (-RS6000_VARARGS_SIZE, -1));
3528 t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
3529 TREE_SIDE_EFFECTS (t) = 1;
3530 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3531}
3532
3533/* Implement va_arg. */
3534
3535rtx
3536rs6000_va_arg (valist, type)
3537 tree valist, type;
3538{
3539 tree f_gpr, f_fpr, f_ovf, f_sav;
3540 tree gpr, fpr, ovf, sav, reg, t, u;
3541 int indirect_p, size, rsize, n_reg, sav_ofs, sav_scale;
3542 rtx lab_false, lab_over, addr_rtx, r;
3543
e7ce8542 3544 if (DEFAULT_ABI != ABI_V4)
04c6ce8b 3545 return std_expand_builtin_va_arg (valist, type);
7da94773 3546
6cd005c9 3547 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
7da94773 3548 f_fpr = TREE_CHAIN (f_gpr);
3549 f_ovf = TREE_CHAIN (f_fpr);
3550 f_sav = TREE_CHAIN (f_ovf);
3551
11a61dea 3552 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
7da94773 3553 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
3554 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
3555 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
3556 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
3557
3558 size = int_size_in_bytes (type);
3559 rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
036c1d46 3560
7da94773 3561 if (AGGREGATE_TYPE_P (type) || TYPE_MODE (type) == TFmode)
036c1d46 3562 {
7da94773 3563 /* Aggregates and long doubles are passed by reference. */
3564 indirect_p = 1;
3565 reg = gpr;
3566 n_reg = 1;
3567 sav_ofs = 0;
3568 sav_scale = 4;
72c94675 3569 size = UNITS_PER_WORD;
3570 rsize = 1;
7da94773 3571 }
f19493d5 3572 else if (FLOAT_TYPE_P (type) && TARGET_HARD_FLOAT && TARGET_FPRS)
7da94773 3573 {
3574 /* FP args go in FP registers, if present. */
3575 indirect_p = 0;
3576 reg = fpr;
3577 n_reg = 1;
3578 sav_ofs = 8*4;
3579 sav_scale = 8;
036c1d46 3580 }
7da94773 3581 else
3582 {
3583 /* Otherwise into GP registers. */
3584 indirect_p = 0;
3585 reg = gpr;
3586 n_reg = rsize;
3587 sav_ofs = 0;
3588 sav_scale = 4;
3589 }
3590
970e222f 3591 /* Pull the value out of the saved registers ... */
7da94773 3592
3593 lab_false = gen_label_rtx ();
3594 lab_over = gen_label_rtx ();
3595 addr_rtx = gen_reg_rtx (Pmode);
3596
018ca13c 3597 /* AltiVec vectors never go in registers. */
3598 if (!TARGET_ALTIVEC || TREE_CODE (type) != VECTOR_TYPE)
ccefda8d 3599 {
ceed8fc4 3600 TREE_THIS_VOLATILE (reg) = 1;
3601 emit_cmp_and_jump_insns
3602 (expand_expr (reg, NULL_RTX, QImode, EXPAND_NORMAL),
3603 GEN_INT (8 - n_reg + 1), GE, const1_rtx, QImode, 1,
3604 lab_false);
7da94773 3605
ceed8fc4 3606 /* Long long is aligned in the registers. */
3607 if (n_reg > 1)
3608 {
3609 u = build (BIT_AND_EXPR, TREE_TYPE (reg), reg,
3610 build_int_2 (n_reg - 1, 0));
3611 u = build (PLUS_EXPR, TREE_TYPE (reg), reg, u);
3612 u = build (MODIFY_EXPR, TREE_TYPE (reg), reg, u);
3613 TREE_SIDE_EFFECTS (u) = 1;
3614 expand_expr (u, const0_rtx, VOIDmode, EXPAND_NORMAL);
3615 }
ccefda8d 3616
ceed8fc4 3617 if (sav_ofs)
3618 t = build (PLUS_EXPR, ptr_type_node, sav, build_int_2 (sav_ofs, 0));
3619 else
3620 t = sav;
ccefda8d 3621
ceed8fc4 3622 u = build (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg,
3623 build_int_2 (n_reg, 0));
3624 TREE_SIDE_EFFECTS (u) = 1;
ccefda8d 3625
ceed8fc4 3626 u = build1 (CONVERT_EXPR, integer_type_node, u);
3627 TREE_SIDE_EFFECTS (u) = 1;
7da94773 3628
ceed8fc4 3629 u = build (MULT_EXPR, integer_type_node, u, build_int_2 (sav_scale, 0));
3630 TREE_SIDE_EFFECTS (u) = 1;
7da94773 3631
ceed8fc4 3632 t = build (PLUS_EXPR, ptr_type_node, t, u);
3633 TREE_SIDE_EFFECTS (t) = 1;
3634
3635 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
3636 if (r != addr_rtx)
3637 emit_move_insn (addr_rtx, r);
3638
3639 emit_jump_insn (gen_jump (lab_over));
3640 emit_barrier ();
3641 }
7da94773 3642
7da94773 3643 emit_label (lab_false);
3644
970e222f 3645 /* ... otherwise out of the overflow area. */
7da94773 3646
ceed8fc4 3647 /* Make sure we don't find reg 7 for the next int arg.
3648
3649 All AltiVec vectors go in the overflow area. So in the AltiVec
3650 case we need to get the vectors from the overflow area, but
3651 remember where the GPRs and FPRs are. */
018ca13c 3652 if (n_reg > 1 && (TREE_CODE (type) != VECTOR_TYPE
3653 || !TARGET_ALTIVEC))
7da94773 3654 {
3655 t = build (MODIFY_EXPR, TREE_TYPE (reg), reg, build_int_2 (8, 0));
3656 TREE_SIDE_EFFECTS (t) = 1;
3657 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3658 }
3659
3660 /* Care for on-stack alignment if needed. */
3661 if (rsize <= 1)
3662 t = ovf;
3663 else
3664 {
ceed8fc4 3665 int align;
3666
018ca13c 3667 /* AltiVec vectors are 16 byte aligned. */
3668 if (TARGET_ALTIVEC && TREE_CODE (type) == VECTOR_TYPE)
ceed8fc4 3669 align = 15;
3670 else
3671 align = 7;
3672
3673 t = build (PLUS_EXPR, TREE_TYPE (ovf), ovf, build_int_2 (align, 0));
3674 t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align-1, -1));
7da94773 3675 }
3676 t = save_expr (t);
3677
3678 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
3679 if (r != addr_rtx)
3680 emit_move_insn (addr_rtx, r);
3681
3682 t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (size, 0));
3683 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
3684 TREE_SIDE_EFFECTS (t) = 1;
3685 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3686
3687 emit_label (lab_over);
3688
3689 if (indirect_p)
3690 {
3691 r = gen_rtx_MEM (Pmode, addr_rtx);
ab6ab77e 3692 set_mem_alias_set (r, get_varargs_alias_set ());
7da94773 3693 emit_move_insn (addr_rtx, r);
3694 }
3695
3696 return addr_rtx;
a3bbc303 3697}
500c7157 3698
3699/* Builtins. */
3700
a06abcfb 3701#define def_builtin(MASK, NAME, TYPE, CODE) \
3702do { \
3703 if ((MASK) & target_flags) \
3704 builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
3705 NULL, NULL_TREE); \
500c7157 3706} while (0)
3707
fe889181 3708/* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
3709
a8b720b1 3710static const struct builtin_description bdesc_3arg[] =
fe889181 3711{
3712 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
3713 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
3714 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
3715 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
3716 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
3717 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
3718 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
3719 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
3720 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
3721 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
3722 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
3723 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
3724 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
3725 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
3726 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_16qi, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
3727 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
3728 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
3729 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
3730 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
3731 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
3732 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
3733 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
3734 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
3735};
a8b720b1 3736
87ebe3d2 3737/* DST operations: void foo (void *, const int, const char). */
3738
3739static const struct builtin_description bdesc_dst[] =
3740{
3741 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
3742 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
3743 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
3744 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT }
3745};
3746
a8b720b1 3747/* Simple binary operations: VECc = foo (VECa, VECb). */
fe889181 3748
f19493d5 3749static struct builtin_description bdesc_2arg[] =
500c7157 3750{
fc0a3bf8 3751 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
3752 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
3753 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
3754 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
500c7157 3755 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
3756 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
3757 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
3758 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
3759 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
3760 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
3761 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
fc0a3bf8 3762 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
500c7157 3763 { MASK_ALTIVEC, CODE_FOR_altivec_vandc, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
3764 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
3765 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
3766 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
3767 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
3768 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
3769 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
f12a08b5 3770 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
3771 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
500c7157 3772 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
3773 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequb, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
3774 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequh, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
3775 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequw, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
3776 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpeqfp, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
3777 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgefp, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
3778 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtub, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
3779 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsb, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
3780 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuh, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
3781 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsh, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
3782 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuw, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
3783 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsw, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
3784 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtfp, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
f12a08b5 3785 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
3786 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
fc0a3bf8 3787 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
3788 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
c1c8d456 3789 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
3790 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
3791 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
3792 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
3793 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
500c7157 3794 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
3795 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
3796 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
3797 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
3798 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
3799 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
fc0a3bf8 3800 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
3801 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
3802 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
3803 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
3804 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
3805 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
3806 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
500c7157 3807 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
3808 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
3809 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
3810 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
3811 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
3812 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
3813 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
3814 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
3815 { MASK_ALTIVEC, CODE_FOR_altivec_vnor, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
fc0a3bf8 3816 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
500c7157 3817 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
3818 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
3819 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
3820 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhss, "__builtin_altivec_vpkuhss", ALTIVEC_BUILTIN_VPKUHSS },
3821 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
3822 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwss, "__builtin_altivec_vpkuwss", ALTIVEC_BUILTIN_VPKUWSS },
3823 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
3824 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
3825 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
3826 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
3827 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
3828 { MASK_ALTIVEC, CODE_FOR_altivec_vrlb, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
3829 { MASK_ALTIVEC, CODE_FOR_altivec_vrlh, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
3830 { MASK_ALTIVEC, CODE_FOR_altivec_vrlw, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
3831 { MASK_ALTIVEC, CODE_FOR_altivec_vslb, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
3832 { MASK_ALTIVEC, CODE_FOR_altivec_vslh, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
3833 { MASK_ALTIVEC, CODE_FOR_altivec_vslw, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
3834 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
3835 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
a8b720b1 3836 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
3837 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
3838 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
500c7157 3839 { MASK_ALTIVEC, CODE_FOR_altivec_vsrb, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
fc0a3bf8 3840 { MASK_ALTIVEC, CODE_FOR_altivec_vsrh, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
3841 { MASK_ALTIVEC, CODE_FOR_altivec_vsrw, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
500c7157 3842 { MASK_ALTIVEC, CODE_FOR_altivec_vsrab, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
3843 { MASK_ALTIVEC, CODE_FOR_altivec_vsrah, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
3844 { MASK_ALTIVEC, CODE_FOR_altivec_vsraw, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
3845 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
3846 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
fc0a3bf8 3847 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
3848 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
3849 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
3850 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
500c7157 3851 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
3852 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
3853 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
3854 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
3855 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
3856 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
3857 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
3858 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
3859 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
3860 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
3861 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
3862 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
fc0a3bf8 3863 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
f19493d5 3864
3865 /* Place holder, leave as first spe builtin. */
3866 { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
3867 { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
3868 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
3869 { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
3870 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
3871 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
3872 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
3873 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
3874 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
3875 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
3876 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
3877 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
3878 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
3879 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
3880 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
3881 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
3882 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
3883 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
3884 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
3885 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
3886 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
3887 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
3888 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
3889 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
3890 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
3891 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
3892 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
3893 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
3894 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
3895 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
3896 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
3897 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
3898 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
3899 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
3900 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
3901 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
3902 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
3903 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
3904 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
3905 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
3906 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
3907 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
3908 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
3909 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
3910 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
3911 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
3912 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
3913 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
3914 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
3915 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
3916 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
3917 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
3918 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
3919 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
3920 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
3921 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
3922 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
3923 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
3924 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
3925 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
3926 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
3927 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
3928 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
3929 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
3930 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
3931 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
3932 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
3933 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
3934 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
3935 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
3936 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
3937 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
3938 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
3939 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
f19493d5 3940 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
3941 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
f19493d5 3942 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
3943 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
3944 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
3945 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
3946 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
3947 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
3948 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
3949 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
3950 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
3951 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
3952 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
3953 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
3954 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
3955 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
3956 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
3957 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
3958 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
3959 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
3960 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
3961 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
3962 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
3963 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
3964 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
3965 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
3966 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
3967 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
3968 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
3969 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
3970 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
3971 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
3972 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
3973 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
3974 { 0, CODE_FOR_spe_evsubfw, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
3975
3976 /* SPE binary operations expecting a 5-bit unsigned literal. */
3977 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
3978
3979 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
3980 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
3981 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
3982 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
3983 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
3984 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
3985 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
3986 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
3987 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
3988 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
3989 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
3990 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
3991 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
3992 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
3993 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
3994 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
3995 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
3996 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
3997 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
3998 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
3999 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
4000 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
4001 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
4002 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
4003 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
4004 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
4005
4006 /* Place-holder. Leave as last binary SPE builtin. */
4007 { 0, CODE_FOR_spe_evxor, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR },
15e5a1c8 4008};
4009
4010/* AltiVec predicates. */
4011
4012struct builtin_description_predicates
4013{
4014 const unsigned int mask;
4015 const enum insn_code icode;
4016 const char *opcode;
4017 const char *const name;
4018 const enum rs6000_builtins code;
4019};
4020
4021static const struct builtin_description_predicates bdesc_altivec_preds[] =
4022{
4023 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P },
4024 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
4025 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
4026 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
4027 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P },
4028 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P },
4029 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P },
4030 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P },
4031 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P },
4032 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P },
4033 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P },
4034 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P },
4035 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P }
500c7157 4036};
fe889181 4037
f19493d5 4038/* SPE predicates. */
4039static struct builtin_description bdesc_spe_predicates[] =
4040{
4041 /* Place-holder. Leave as first. */
4042 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
4043 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
4044 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
4045 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
4046 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
4047 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
4048 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
4049 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
4050 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
4051 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
4052 /* Place-holder. Leave as last. */
4053 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
4054};
4055
4056/* SPE evsel predicates. */
4057static struct builtin_description bdesc_spe_evsel[] =
4058{
4059 /* Place-holder. Leave as first. */
4060 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
4061 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
4062 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
4063 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
4064 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
4065 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
4066 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
4067 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
4068 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
4069 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
4070 /* Place-holder. Leave as last. */
4071 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
4072};
4073
3971c992 4074/* ABS* opreations. */
4075
4076static const struct builtin_description bdesc_abs[] =
4077{
4078 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
4079 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
4080 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
4081 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
4082 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
4083 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
4084 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI }
4085};
4086
f12a08b5 4087/* Simple unary operations: VECb = foo (unsigned literal) or VECb =
4088 foo (VECa). */
fe889181 4089
f19493d5 4090static struct builtin_description bdesc_1arg[] =
a8b720b1 4091{
f12a08b5 4092 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
4093 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
4094 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
4095 { MASK_ALTIVEC, CODE_FOR_altivec_vrfim, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
4096 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
4097 { MASK_ALTIVEC, CODE_FOR_altivec_vrfip, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
4098 { MASK_ALTIVEC, CODE_FOR_ftruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
4099 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
a8b720b1 4100 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
4101 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
4102 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
e931e2d9 4103 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
4104 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
4105 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
4106 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
4107 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
4108 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
f19493d5 4109
4110 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
4111 end with SPE_BUILTIN_EVSUBFUSIAAW. */
4112 { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
4113 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
4114 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
4115 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
4116 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
4117 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
4118 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
4119 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
4120 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
4121 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
4122 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
4123 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
4124 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
4125 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
4126 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
4127 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
4128 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
4129 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
4130 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
4131 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
4132 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
4133 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
4134 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
4135 { 0, CODE_FOR_spe_evneg, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
4136 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
4137 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
4138 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
4139 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
4140 { 0, CODE_FOR_spe_evsplatfi, "__builtin_spe_evsplatfi", SPE_BUILTIN_EVSPLATFI },
4141 { 0, CODE_FOR_spe_evsplati, "__builtin_spe_evsplati", SPE_BUILTIN_EVSPLATI },
4142
4143 /* Place-holder. Leave as last unary SPE builtin. */
4144 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
a8b720b1 4145};
4146
4147static rtx
6d829a46 4148rs6000_expand_unop_builtin (icode, arglist, target)
a8b720b1 4149 enum insn_code icode;
4150 tree arglist;
4151 rtx target;
4152{
4153 rtx pat;
4154 tree arg0 = TREE_VALUE (arglist);
4155 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4156 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4157 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4158
8ec32caf 4159 if (icode == CODE_FOR_nothing)
4160 /* Builtin not supported on this processor. */
4161 return 0;
4162
e931e2d9 4163 /* If we got invalid arguments bail out before generating bad rtl. */
4164 if (arg0 == error_mark_node)
0b70ff0f 4165 return const0_rtx;
e931e2d9 4166
8ec32caf 4167 if (icode == CODE_FOR_altivec_vspltisb
4168 || icode == CODE_FOR_altivec_vspltish
4169 || icode == CODE_FOR_altivec_vspltisw
4170 || icode == CODE_FOR_spe_evsplatfi
4171 || icode == CODE_FOR_spe_evsplati)
f4454ccb 4172 {
4173 /* Only allow 5-bit *signed* literals. */
f4454ccb 4174 if (GET_CODE (op0) != CONST_INT
4175 || INTVAL (op0) > 0x1f
4176 || INTVAL (op0) < -0x1f)
4177 {
4178 error ("argument 1 must be a 5-bit signed literal");
0b70ff0f 4179 return const0_rtx;
f4454ccb 4180 }
f4454ccb 4181 }
4182
965c179a 4183 if (target == 0
a8b720b1 4184 || GET_MODE (target) != tmode
4185 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4186 target = gen_reg_rtx (tmode);
4187
4188 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4189 op0 = copy_to_mode_reg (mode0, op0);
4190
4191 pat = GEN_FCN (icode) (target, op0);
4192 if (! pat)
4193 return 0;
4194 emit_insn (pat);
500c7157 4195
a8b720b1 4196 return target;
4197}
15e5a1c8 4198
3971c992 4199static rtx
4200altivec_expand_abs_builtin (icode, arglist, target)
4201 enum insn_code icode;
4202 tree arglist;
4203 rtx target;
4204{
4205 rtx pat, scratch1, scratch2;
4206 tree arg0 = TREE_VALUE (arglist);
4207 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4208 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4209 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4210
4211 /* If we have invalid arguments, bail out before generating bad rtl. */
4212 if (arg0 == error_mark_node)
0b70ff0f 4213 return const0_rtx;
3971c992 4214
4215 if (target == 0
4216 || GET_MODE (target) != tmode
4217 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4218 target = gen_reg_rtx (tmode);
4219
4220 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4221 op0 = copy_to_mode_reg (mode0, op0);
4222
4223 scratch1 = gen_reg_rtx (mode0);
4224 scratch2 = gen_reg_rtx (mode0);
4225
4226 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
4227 if (! pat)
4228 return 0;
4229 emit_insn (pat);
4230
4231 return target;
4232}
4233
500c7157 4234static rtx
6d829a46 4235rs6000_expand_binop_builtin (icode, arglist, target)
500c7157 4236 enum insn_code icode;
4237 tree arglist;
4238 rtx target;
4239{
4240 rtx pat;
4241 tree arg0 = TREE_VALUE (arglist);
4242 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4243 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4244 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4245 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4246 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4247 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4248
8ec32caf 4249 if (icode == CODE_FOR_nothing)
4250 /* Builtin not supported on this processor. */
4251 return 0;
4252
e931e2d9 4253 /* If we got invalid arguments bail out before generating bad rtl. */
4254 if (arg0 == error_mark_node || arg1 == error_mark_node)
0b70ff0f 4255 return const0_rtx;
e931e2d9 4256
8ec32caf 4257 if (icode == CODE_FOR_altivec_vcfux
4258 || icode == CODE_FOR_altivec_vcfsx
4259 || icode == CODE_FOR_altivec_vctsxs
4260 || icode == CODE_FOR_altivec_vctuxs
4261 || icode == CODE_FOR_altivec_vspltb
4262 || icode == CODE_FOR_altivec_vsplth
4263 || icode == CODE_FOR_altivec_vspltw
4264 || icode == CODE_FOR_spe_evaddiw
4265 || icode == CODE_FOR_spe_evldd
4266 || icode == CODE_FOR_spe_evldh
4267 || icode == CODE_FOR_spe_evldw
4268 || icode == CODE_FOR_spe_evlhhesplat
4269 || icode == CODE_FOR_spe_evlhhossplat
4270 || icode == CODE_FOR_spe_evlhhousplat
4271 || icode == CODE_FOR_spe_evlwhe
4272 || icode == CODE_FOR_spe_evlwhos
4273 || icode == CODE_FOR_spe_evlwhou
4274 || icode == CODE_FOR_spe_evlwhsplat
4275 || icode == CODE_FOR_spe_evlwwsplat
4276 || icode == CODE_FOR_spe_evrlwi
4277 || icode == CODE_FOR_spe_evslwi
4278 || icode == CODE_FOR_spe_evsrwis
4279 || icode == CODE_FOR_spe_evsrwiu)
f4454ccb 4280 {
4281 /* Only allow 5-bit unsigned literals. */
f4454ccb 4282 if (TREE_CODE (arg1) != INTEGER_CST
4283 || TREE_INT_CST_LOW (arg1) & ~0x1f)
4284 {
4285 error ("argument 2 must be a 5-bit unsigned literal");
0b70ff0f 4286 return const0_rtx;
f4454ccb 4287 }
f4454ccb 4288 }
4289
965c179a 4290 if (target == 0
500c7157 4291 || GET_MODE (target) != tmode
4292 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4293 target = gen_reg_rtx (tmode);
4294
4295 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4296 op0 = copy_to_mode_reg (mode0, op0);
4297 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4298 op1 = copy_to_mode_reg (mode1, op1);
4299
4300 pat = GEN_FCN (icode) (target, op0, op1);
4301 if (! pat)
4302 return 0;
4303 emit_insn (pat);
4304
4305 return target;
4306}
9f710c67 4307
15e5a1c8 4308static rtx
4309altivec_expand_predicate_builtin (icode, opcode, arglist, target)
4310 enum insn_code icode;
4311 const char *opcode;
4312 tree arglist;
4313 rtx target;
4314{
4315 rtx pat, scratch;
4316 tree cr6_form = TREE_VALUE (arglist);
4317 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
4318 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4319 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4320 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4321 enum machine_mode tmode = SImode;
4322 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4323 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4324 int cr6_form_int;
4325
4326 if (TREE_CODE (cr6_form) != INTEGER_CST)
4327 {
4328 error ("argument 1 of __builtin_altivec_predicate must be a constant");
0b70ff0f 4329 return const0_rtx;
15e5a1c8 4330 }
4331 else
4332 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
4333
4334 if (mode0 != mode1)
4335 abort ();
4336
4337 /* If we have invalid arguments, bail out before generating bad rtl. */
4338 if (arg0 == error_mark_node || arg1 == error_mark_node)
0b70ff0f 4339 return const0_rtx;
15e5a1c8 4340
4341 if (target == 0
4342 || GET_MODE (target) != tmode
4343 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4344 target = gen_reg_rtx (tmode);
4345
4346 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4347 op0 = copy_to_mode_reg (mode0, op0);
4348 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4349 op1 = copy_to_mode_reg (mode1, op1);
4350
4351 scratch = gen_reg_rtx (mode0);
4352
4353 pat = GEN_FCN (icode) (scratch, op0, op1,
4354 gen_rtx (SYMBOL_REF, Pmode, opcode));
4355 if (! pat)
4356 return 0;
4357 emit_insn (pat);
4358
4359 /* The vec_any* and vec_all* predicates use the same opcodes for two
4360 different operations, but the bits in CR6 will be different
4361 depending on what information we want. So we have to play tricks
4362 with CR6 to get the right bits out.
4363
4364 If you think this is disgusting, look at the specs for the
4365 AltiVec predicates. */
4366
4367 switch (cr6_form_int)
4368 {
4369 case 0:
4370 emit_insn (gen_cr6_test_for_zero (target));
4371 break;
4372 case 1:
4373 emit_insn (gen_cr6_test_for_zero_reverse (target));
4374 break;
4375 case 2:
4376 emit_insn (gen_cr6_test_for_lt (target));
4377 break;
4378 case 3:
4379 emit_insn (gen_cr6_test_for_lt_reverse (target));
4380 break;
4381 default:
4382 error ("argument 1 of __builtin_altivec_predicate is out of range");
4383 break;
4384 }
4385
4386 return target;
4387}
4388
9f710c67 4389static rtx
4390altivec_expand_stv_builtin (icode, arglist)
4391 enum insn_code icode;
4392 tree arglist;
4393{
4394 tree arg0 = TREE_VALUE (arglist);
4395 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4396 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4397 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4398 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4399 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4400 rtx pat;
4401 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
4402 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
4403 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
4404
4405 /* Invalid arguments. Bail before doing anything stoopid! */
4406 if (arg0 == error_mark_node
4407 || arg1 == error_mark_node
4408 || arg2 == error_mark_node)
0b70ff0f 4409 return const0_rtx;
9f710c67 4410
4411 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
4412 op0 = copy_to_mode_reg (mode2, op0);
4413 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
4414 op1 = copy_to_mode_reg (mode0, op1);
4415 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
4416 op2 = copy_to_mode_reg (mode1, op2);
4417
4418 pat = GEN_FCN (icode) (op1, op2, op0);
4419 if (pat)
4420 emit_insn (pat);
4421 return NULL_RTX;
4422}
4423
a8b720b1 4424static rtx
6d829a46 4425rs6000_expand_ternop_builtin (icode, arglist, target)
a8b720b1 4426 enum insn_code icode;
4427 tree arglist;
4428 rtx target;
4429{
4430 rtx pat;
4431 tree arg0 = TREE_VALUE (arglist);
4432 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4433 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4434 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4435 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4436 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4437 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4438 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4439 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4440 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
500c7157 4441
14c03a87 4442 if (icode == CODE_FOR_nothing)
4443 /* Builtin not supported on this processor. */
4444 return 0;
4445
e931e2d9 4446 /* If we got invalid arguments bail out before generating bad rtl. */
4447 if (arg0 == error_mark_node
4448 || arg1 == error_mark_node
4449 || arg2 == error_mark_node)
0b70ff0f 4450 return const0_rtx;
e931e2d9 4451
14c03a87 4452 if (icode == CODE_FOR_altivec_vsldoi_4sf
4453 || icode == CODE_FOR_altivec_vsldoi_4si
4454 || icode == CODE_FOR_altivec_vsldoi_8hi
4455 || icode == CODE_FOR_altivec_vsldoi_16qi)
f4454ccb 4456 {
4457 /* Only allow 4-bit unsigned literals. */
f4454ccb 4458 if (TREE_CODE (arg2) != INTEGER_CST
4459 || TREE_INT_CST_LOW (arg2) & ~0xf)
4460 {
4461 error ("argument 3 must be a 4-bit unsigned literal");
7d3f4cb0 4462 return const0_rtx;
f4454ccb 4463 }
f4454ccb 4464 }
4465
965c179a 4466 if (target == 0
a8b720b1 4467 || GET_MODE (target) != tmode
4468 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4469 target = gen_reg_rtx (tmode);
4470
4471 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4472 op0 = copy_to_mode_reg (mode0, op0);
4473 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4474 op1 = copy_to_mode_reg (mode1, op1);
4475 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
4476 op2 = copy_to_mode_reg (mode2, op2);
4477
4478 pat = GEN_FCN (icode) (target, op0, op1, op2);
4479 if (! pat)
4480 return 0;
4481 emit_insn (pat);
4482
4483 return target;
4484}
6d829a46 4485
ae1526b2 4486/* Expand the lvx builtins. */
500c7157 4487static rtx
ae1526b2 4488altivec_expand_ld_builtin (exp, target, expandedp)
500c7157 4489 tree exp;
4490 rtx target;
6d829a46 4491 bool *expandedp;
500c7157 4492{
500c7157 4493 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4494 tree arglist = TREE_OPERAND (exp, 1);
500c7157 4495 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
ae1526b2 4496 tree arg0;
4497 enum machine_mode tmode, mode0;
51ac2e1f 4498 rtx pat, op0;
ae1526b2 4499 enum insn_code icode;
6d829a46 4500
500c7157 4501 switch (fcode)
4502 {
fc0a3bf8 4503 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
4504 icode = CODE_FOR_altivec_lvx_16qi;
ae1526b2 4505 break;
fc0a3bf8 4506 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
4507 icode = CODE_FOR_altivec_lvx_8hi;
ae1526b2 4508 break;
4509 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
4510 icode = CODE_FOR_altivec_lvx_4si;
4511 break;
4512 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
4513 icode = CODE_FOR_altivec_lvx_4sf;
4514 break;
4515 default:
4516 *expandedp = false;
4517 return NULL_RTX;
4518 }
500c7157 4519
ae1526b2 4520 *expandedp = true;
fc0a3bf8 4521
ae1526b2 4522 arg0 = TREE_VALUE (arglist);
4523 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4524 tmode = insn_data[icode].operand[0].mode;
4525 mode0 = insn_data[icode].operand[1].mode;
fc0a3bf8 4526
ae1526b2 4527 if (target == 0
4528 || GET_MODE (target) != tmode
4529 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4530 target = gen_reg_rtx (tmode);
fe889181 4531
ae1526b2 4532 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4533 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
fc0a3bf8 4534
ae1526b2 4535 pat = GEN_FCN (icode) (target, op0);
4536 if (! pat)
4537 return 0;
4538 emit_insn (pat);
4539 return target;
4540}
fc0a3bf8 4541
ae1526b2 4542/* Expand the stvx builtins. */
4543static rtx
4544altivec_expand_st_builtin (exp, target, expandedp)
4545 tree exp;
51ac2e1f 4546 rtx target ATTRIBUTE_UNUSED;
ae1526b2 4547 bool *expandedp;
4548{
4549 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4550 tree arglist = TREE_OPERAND (exp, 1);
4551 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4552 tree arg0, arg1;
4553 enum machine_mode mode0, mode1;
51ac2e1f 4554 rtx pat, op0, op1;
ae1526b2 4555 enum insn_code icode;
fc0a3bf8 4556
ae1526b2 4557 switch (fcode)
4558 {
4559 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
4560 icode = CODE_FOR_altivec_stvx_16qi;
4561 break;
4562 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
4563 icode = CODE_FOR_altivec_stvx_8hi;
4564 break;
4565 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
4566 icode = CODE_FOR_altivec_stvx_4si;
4567 break;
4568 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
4569 icode = CODE_FOR_altivec_stvx_4sf;
4570 break;
4571 default:
4572 *expandedp = false;
4573 return NULL_RTX;
4574 }
fe889181 4575
ae1526b2 4576 arg0 = TREE_VALUE (arglist);
4577 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4578 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4579 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4580 mode0 = insn_data[icode].operand[0].mode;
4581 mode1 = insn_data[icode].operand[1].mode;
fc0a3bf8 4582
ae1526b2 4583 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4584 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
4585 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
4586 op1 = copy_to_mode_reg (mode1, op1);
fc0a3bf8 4587
ae1526b2 4588 pat = GEN_FCN (icode) (op0, op1);
4589 if (pat)
4590 emit_insn (pat);
fc0a3bf8 4591
ae1526b2 4592 *expandedp = true;
4593 return NULL_RTX;
4594}
fc0a3bf8 4595
ae1526b2 4596/* Expand the dst builtins. */
4597static rtx
4598altivec_expand_dst_builtin (exp, target, expandedp)
4599 tree exp;
51ac2e1f 4600 rtx target ATTRIBUTE_UNUSED;
ae1526b2 4601 bool *expandedp;
4602{
4603 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4604 tree arglist = TREE_OPERAND (exp, 1);
4605 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4606 tree arg0, arg1, arg2;
4607 enum machine_mode mode0, mode1, mode2;
51ac2e1f 4608 rtx pat, op0, op1, op2;
ae1526b2 4609 struct builtin_description *d;
f19493d5 4610 size_t i;
fc0a3bf8 4611
ae1526b2 4612 *expandedp = false;
fc0a3bf8 4613
ae1526b2 4614 /* Handle DST variants. */
4615 d = (struct builtin_description *) bdesc_dst;
4616 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
4617 if (d->code == fcode)
4618 {
4619 arg0 = TREE_VALUE (arglist);
4620 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4621 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4622 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4623 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4624 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4625 mode0 = insn_data[d->icode].operand[0].mode;
4626 mode1 = insn_data[d->icode].operand[1].mode;
4627 mode2 = insn_data[d->icode].operand[2].mode;
fe889181 4628
ae1526b2 4629 /* Invalid arguments, bail out before generating bad rtl. */
4630 if (arg0 == error_mark_node
4631 || arg1 == error_mark_node
4632 || arg2 == error_mark_node)
4633 return const0_rtx;
fc0a3bf8 4634
ae1526b2 4635 if (TREE_CODE (arg2) != INTEGER_CST
4636 || TREE_INT_CST_LOW (arg2) & ~0x3)
4637 {
4638 error ("argument to `%s' must be a 2-bit unsigned literal", d->name);
4639 return const0_rtx;
4640 }
fc0a3bf8 4641
ae1526b2 4642 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
4643 op0 = copy_to_mode_reg (mode0, op0);
4644 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
4645 op1 = copy_to_mode_reg (mode1, op1);
fe889181 4646
ae1526b2 4647 pat = GEN_FCN (d->icode) (op0, op1, op2);
4648 if (pat != 0)
4649 emit_insn (pat);
fc0a3bf8 4650
ae1526b2 4651 *expandedp = true;
4652 return NULL_RTX;
4653 }
fc0a3bf8 4654
ae1526b2 4655 return NULL_RTX;
4656}
fe889181 4657
ae1526b2 4658/* Expand the builtin in EXP and store the result in TARGET. Store
4659 true in *EXPANDEDP if we found a builtin to expand. */
4660static rtx
4661altivec_expand_builtin (exp, target, expandedp)
4662 tree exp;
4663 rtx target;
4664 bool *expandedp;
4665{
4666 struct builtin_description *d;
4667 struct builtin_description_predicates *dp;
4668 size_t i;
4669 enum insn_code icode;
4670 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4671 tree arglist = TREE_OPERAND (exp, 1);
51ac2e1f 4672 tree arg0;
4673 rtx op0, pat;
4674 enum machine_mode tmode, mode0;
ae1526b2 4675 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
500c7157 4676
ae1526b2 4677 target = altivec_expand_ld_builtin (exp, target, expandedp);
4678 if (*expandedp)
4679 return target;
500c7157 4680
ae1526b2 4681 target = altivec_expand_st_builtin (exp, target, expandedp);
4682 if (*expandedp)
4683 return target;
4684
4685 target = altivec_expand_dst_builtin (exp, target, expandedp);
4686 if (*expandedp)
4687 return target;
4688
4689 *expandedp = true;
87ebe3d2 4690
ae1526b2 4691 switch (fcode)
4692 {
9f710c67 4693 case ALTIVEC_BUILTIN_STVX:
4694 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, arglist);
4695 case ALTIVEC_BUILTIN_STVEBX:
4696 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, arglist);
4697 case ALTIVEC_BUILTIN_STVEHX:
4698 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, arglist);
4699 case ALTIVEC_BUILTIN_STVEWX:
4700 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, arglist);
4701 case ALTIVEC_BUILTIN_STVXL:
4702 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, arglist);
ae1526b2 4703
87ebe3d2 4704 case ALTIVEC_BUILTIN_MFVSCR:
4705 icode = CODE_FOR_altivec_mfvscr;
4706 tmode = insn_data[icode].operand[0].mode;
4707
4708 if (target == 0
4709 || GET_MODE (target) != tmode
4710 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4711 target = gen_reg_rtx (tmode);
4712
4713 pat = GEN_FCN (icode) (target);
500c7157 4714 if (! pat)
4715 return 0;
4716 emit_insn (pat);
87ebe3d2 4717 return target;
4718
4719 case ALTIVEC_BUILTIN_MTVSCR:
4720 icode = CODE_FOR_altivec_mtvscr;
4721 arg0 = TREE_VALUE (arglist);
4722 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4723 mode0 = insn_data[icode].operand[0].mode;
4724
4725 /* If we got invalid arguments bail out before generating bad rtl. */
4726 if (arg0 == error_mark_node)
0b70ff0f 4727 return const0_rtx;
87ebe3d2 4728
4729 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4730 op0 = copy_to_mode_reg (mode0, op0);
4731
4732 pat = GEN_FCN (icode) (op0);
4733 if (pat)
4734 emit_insn (pat);
4735 return NULL_RTX;
ae1526b2 4736
87ebe3d2 4737 case ALTIVEC_BUILTIN_DSSALL:
4738 emit_insn (gen_altivec_dssall ());
4739 return NULL_RTX;
4740
4741 case ALTIVEC_BUILTIN_DSS:
4742 icode = CODE_FOR_altivec_dss;
4743 arg0 = TREE_VALUE (arglist);
4744 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4745 mode0 = insn_data[icode].operand[0].mode;
4746
4747 /* If we got invalid arguments bail out before generating bad rtl. */
4748 if (arg0 == error_mark_node)
0b70ff0f 4749 return const0_rtx;
87ebe3d2 4750
f4454ccb 4751 if (TREE_CODE (arg0) != INTEGER_CST
4752 || TREE_INT_CST_LOW (arg0) & ~0x3)
4753 {
4754 error ("argument to dss must be a 2-bit unsigned literal");
0b70ff0f 4755 return const0_rtx;
f4454ccb 4756 }
4757
87ebe3d2 4758 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4759 op0 = copy_to_mode_reg (mode0, op0);
4760
4761 emit_insn (gen_altivec_dss (op0));
500c7157 4762 return NULL_RTX;
4763 }
fe889181 4764
3971c992 4765 /* Expand abs* operations. */
4766 d = (struct builtin_description *) bdesc_abs;
3585dac7 4767 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
3971c992 4768 if (d->code == fcode)
4769 return altivec_expand_abs_builtin (d->icode, arglist, target);
4770
15e5a1c8 4771 /* Expand the AltiVec predicates. */
4772 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
3585dac7 4773 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
15e5a1c8 4774 if (dp->code == fcode)
4775 return altivec_expand_predicate_builtin (dp->icode, dp->opcode, arglist, target);
4776
9f710c67 4777 /* LV* are funky. We initialized them differently. */
4778 switch (fcode)
4779 {
4780 case ALTIVEC_BUILTIN_LVSL:
6d829a46 4781 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvsl,
9f710c67 4782 arglist, target);
4783 case ALTIVEC_BUILTIN_LVSR:
6d829a46 4784 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvsr,
4785 arglist, target);
9f710c67 4786 case ALTIVEC_BUILTIN_LVEBX:
6d829a46 4787 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvebx,
4788 arglist, target);
9f710c67 4789 case ALTIVEC_BUILTIN_LVEHX:
6d829a46 4790 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvehx,
4791 arglist, target);
9f710c67 4792 case ALTIVEC_BUILTIN_LVEWX:
6d829a46 4793 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvewx,
4794 arglist, target);
9f710c67 4795 case ALTIVEC_BUILTIN_LVXL:
6d829a46 4796 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvxl,
4797 arglist, target);
9f710c67 4798 case ALTIVEC_BUILTIN_LVX:
6d829a46 4799 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvx,
4800 arglist, target);
9f710c67 4801 default:
4802 break;
4803 /* Fall through. */
4804 }
87ebe3d2 4805
6d829a46 4806 *expandedp = false;
500c7157 4807 return NULL_RTX;
4808}
4809
f19493d5 4810/* Binops that need to be initialized manually, but can be expanded
4811 automagically by rs6000_expand_binop_builtin. */
4812static struct builtin_description bdesc_2arg_spe[] =
4813{
4814 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
4815 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
4816 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
4817 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
4818 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
4819 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
4820 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
4821 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
4822 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
4823 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
4824 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
4825 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
4826 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
4827 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
4828 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
4829 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
4830 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
4831 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
4832 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
4833 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
4834 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
4835 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
4836};
4837
4838/* Expand the builtin in EXP and store the result in TARGET. Store
4839 true in *EXPANDEDP if we found a builtin to expand.
4840
4841 This expands the SPE builtins that are not simple unary and binary
4842 operations. */
4843static rtx
4844spe_expand_builtin (exp, target, expandedp)
4845 tree exp;
4846 rtx target;
4847 bool *expandedp;
4848{
4849 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4850 tree arglist = TREE_OPERAND (exp, 1);
4851 tree arg1, arg0;
4852 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4853 enum insn_code icode;
4854 enum machine_mode tmode, mode0;
4855 rtx pat, op0;
4856 struct builtin_description *d;
4857 size_t i;
4858
4859 *expandedp = true;
4860
4861 /* Syntax check for a 5-bit unsigned immediate. */
4862 switch (fcode)
4863 {
4864 case SPE_BUILTIN_EVSTDD:
4865 case SPE_BUILTIN_EVSTDH:
4866 case SPE_BUILTIN_EVSTDW:
4867 case SPE_BUILTIN_EVSTWHE:
4868 case SPE_BUILTIN_EVSTWHO:
4869 case SPE_BUILTIN_EVSTWWE:
4870 case SPE_BUILTIN_EVSTWWO:
4871 arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4872 if (TREE_CODE (arg1) != INTEGER_CST
4873 || TREE_INT_CST_LOW (arg1) & ~0x1f)
4874 {
4875 error ("argument 2 must be a 5-bit unsigned literal");
4876 return const0_rtx;
4877 }
4878 break;
4879 default:
4880 break;
4881 }
4882
4883 d = (struct builtin_description *) bdesc_2arg_spe;
4884 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
4885 if (d->code == fcode)
4886 return rs6000_expand_binop_builtin (d->icode, arglist, target);
4887
4888 d = (struct builtin_description *) bdesc_spe_predicates;
4889 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
4890 if (d->code == fcode)
4891 return spe_expand_predicate_builtin (d->icode, arglist, target);
4892
4893 d = (struct builtin_description *) bdesc_spe_evsel;
4894 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
4895 if (d->code == fcode)
4896 return spe_expand_evsel_builtin (d->icode, arglist, target);
4897
4898 switch (fcode)
4899 {
4900 case SPE_BUILTIN_EVSTDDX:
4901 return altivec_expand_stv_builtin (CODE_FOR_spe_evstddx, arglist);
4902 case SPE_BUILTIN_EVSTDHX:
4903 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdhx, arglist);
4904 case SPE_BUILTIN_EVSTDWX:
4905 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdwx, arglist);
4906 case SPE_BUILTIN_EVSTWHEX:
4907 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhex, arglist);
4908 case SPE_BUILTIN_EVSTWHOX:
4909 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhox, arglist);
4910 case SPE_BUILTIN_EVSTWWEX:
4911 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwex, arglist);
4912 case SPE_BUILTIN_EVSTWWOX:
4913 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwox, arglist);
4914 case SPE_BUILTIN_EVSTDD:
4915 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdd, arglist);
4916 case SPE_BUILTIN_EVSTDH:
4917 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdh, arglist);
4918 case SPE_BUILTIN_EVSTDW:
4919 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdw, arglist);
4920 case SPE_BUILTIN_EVSTWHE:
4921 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhe, arglist);
4922 case SPE_BUILTIN_EVSTWHO:
4923 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwho, arglist);
4924 case SPE_BUILTIN_EVSTWWE:
4925 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwe, arglist);
4926 case SPE_BUILTIN_EVSTWWO:
4927 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwo, arglist);
4928 case SPE_BUILTIN_MFSPEFSCR:
4929 icode = CODE_FOR_spe_mfspefscr;
4930 tmode = insn_data[icode].operand[0].mode;
4931
4932 if (target == 0
4933 || GET_MODE (target) != tmode
4934 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4935 target = gen_reg_rtx (tmode);
4936
4937 pat = GEN_FCN (icode) (target);
4938 if (! pat)
4939 return 0;
4940 emit_insn (pat);
4941 return target;
4942 case SPE_BUILTIN_MTSPEFSCR:
4943 icode = CODE_FOR_spe_mtspefscr;
4944 arg0 = TREE_VALUE (arglist);
4945 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4946 mode0 = insn_data[icode].operand[0].mode;
4947
4948 if (arg0 == error_mark_node)
4949 return const0_rtx;
4950
4951 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4952 op0 = copy_to_mode_reg (mode0, op0);
4953
4954 pat = GEN_FCN (icode) (op0);
4955 if (pat)
4956 emit_insn (pat);
4957 return NULL_RTX;
4958 default:
4959 break;
4960 }
4961
4962 *expandedp = false;
4963 return NULL_RTX;
4964}
4965
4966static rtx
4967spe_expand_predicate_builtin (icode, arglist, target)
4968 enum insn_code icode;
4969 tree arglist;
4970 rtx target;
4971{
4972 rtx pat, scratch, tmp;
4973 tree form = TREE_VALUE (arglist);
4974 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
4975 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4976 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4977 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4978 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4979 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4980 int form_int;
4981 enum rtx_code code;
4982
4983 if (TREE_CODE (form) != INTEGER_CST)
4984 {
4985 error ("argument 1 of __builtin_spe_predicate must be a constant");
4986 return const0_rtx;
4987 }
4988 else
4989 form_int = TREE_INT_CST_LOW (form);
4990
4991 if (mode0 != mode1)
4992 abort ();
4993
4994 if (arg0 == error_mark_node || arg1 == error_mark_node)
4995 return const0_rtx;
4996
4997 if (target == 0
4998 || GET_MODE (target) != SImode
4999 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
5000 target = gen_reg_rtx (SImode);
5001
5002 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
5003 op0 = copy_to_mode_reg (mode0, op0);
5004 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
5005 op1 = copy_to_mode_reg (mode1, op1);
5006
5007 scratch = gen_reg_rtx (CCmode);
5008
5009 pat = GEN_FCN (icode) (scratch, op0, op1);
5010 if (! pat)
5011 return const0_rtx;
5012 emit_insn (pat);
5013
5014 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
5015 _lower_. We use one compare, but look in different bits of the
5016 CR for each variant.
5017
5018 There are 2 elements in each SPE simd type (upper/lower). The CR
5019 bits are set as follows:
5020
5021 BIT0 | BIT 1 | BIT 2 | BIT 3
5022 U | L | (U | L) | (U & L)
5023
5024 So, for an "all" relationship, BIT 3 would be set.
5025 For an "any" relationship, BIT 2 would be set. Etc.
5026
5027 Following traditional nomenclature, these bits map to:
5028
5029 BIT0 | BIT 1 | BIT 2 | BIT 3
5030 LT | GT | EQ | OV
5031
5032 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
5033 */
5034
5035 switch (form_int)
5036 {
5037 /* All variant. OV bit. */
5038 case 0:
5039 /* We need to get to the OV bit, which is the ORDERED bit. We
5040 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
5041 that's ugly and will trigger a validate_condition_mode abort.
5042 So let's just use another pattern. */
5043 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
5044 return target;
5045 /* Any variant. EQ bit. */
5046 case 1:
5047 code = EQ;
5048 break;
5049 /* Upper variant. LT bit. */
5050 case 2:
5051 code = LT;
5052 break;
5053 /* Lower variant. GT bit. */
5054 case 3:
5055 code = GT;
5056 break;
5057 default:
5058 error ("argument 1 of __builtin_spe_predicate is out of range");
5059 return const0_rtx;
5060 }
5061
5062 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
5063 emit_move_insn (target, tmp);
5064
5065 return target;
5066}
5067
5068/* The evsel builtins look like this:
5069
5070 e = __builtin_spe_evsel_OP (a, b, c, d);
5071
5072 and work like this:
5073
5074 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
5075 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
5076*/
5077
5078static rtx
5079spe_expand_evsel_builtin (icode, arglist, target)
5080 enum insn_code icode;
5081 tree arglist;
5082 rtx target;
5083{
5084 rtx pat, scratch;
5085 tree arg0 = TREE_VALUE (arglist);
5086 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
5087 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
5088 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
5089 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
5090 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
5091 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
5092 rtx op3 = expand_expr (arg3, NULL_RTX, VOIDmode, 0);
5093 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
5094 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
5095
5096 if (mode0 != mode1)
5097 abort ();
5098
5099 if (arg0 == error_mark_node || arg1 == error_mark_node
5100 || arg2 == error_mark_node || arg3 == error_mark_node)
5101 return const0_rtx;
5102
5103 if (target == 0
5104 || GET_MODE (target) != mode0
5105 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
5106 target = gen_reg_rtx (mode0);
5107
5108 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
5109 op0 = copy_to_mode_reg (mode0, op0);
5110 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
5111 op1 = copy_to_mode_reg (mode0, op1);
5112 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
5113 op2 = copy_to_mode_reg (mode0, op2);
5114 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
5115 op3 = copy_to_mode_reg (mode0, op3);
5116
5117 /* Generate the compare. */
5118 scratch = gen_reg_rtx (CCmode);
5119 pat = GEN_FCN (icode) (scratch, op0, op1);
5120 if (! pat)
5121 return const0_rtx;
5122 emit_insn (pat);
5123
5124 if (mode0 == V2SImode)
5125 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
5126 else
5127 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
5128
5129 return target;
5130}
5131
500c7157 5132/* Expand an expression EXP that calls a built-in function,
5133 with result going to TARGET if that's convenient
5134 (and in mode MODE if that's convenient).
5135 SUBTARGET may be used as the target for computing one of EXP's operands.
5136 IGNORE is nonzero if the value is to be ignored. */
5137
5138static rtx
5139rs6000_expand_builtin (exp, target, subtarget, mode, ignore)
5140 tree exp;
5141 rtx target;
bb78803e 5142 rtx subtarget ATTRIBUTE_UNUSED;
5143 enum machine_mode mode ATTRIBUTE_UNUSED;
5144 int ignore ATTRIBUTE_UNUSED;
500c7157 5145{
6d829a46 5146 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
5147 tree arglist = TREE_OPERAND (exp, 1);
5148 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
5149 struct builtin_description *d;
5150 size_t i;
5151 rtx ret;
5152 bool success;
5153
500c7157 5154 if (TARGET_ALTIVEC)
6d829a46 5155 {
5156 ret = altivec_expand_builtin (exp, target, &success);
5157
f19493d5 5158 if (success)
5159 return ret;
5160 }
5161 if (TARGET_SPE)
5162 {
5163 ret = spe_expand_builtin (exp, target, &success);
5164
6d829a46 5165 if (success)
5166 return ret;
5167 }
5168
8ec32caf 5169 if (TARGET_ALTIVEC || TARGET_SPE)
5170 {
5171 /* Handle simple unary operations. */
5172 d = (struct builtin_description *) bdesc_1arg;
5173 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
5174 if (d->code == fcode)
5175 return rs6000_expand_unop_builtin (d->icode, arglist, target);
5176
5177 /* Handle simple binary operations. */
5178 d = (struct builtin_description *) bdesc_2arg;
5179 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
5180 if (d->code == fcode)
5181 return rs6000_expand_binop_builtin (d->icode, arglist, target);
5182
5183 /* Handle simple ternary operations. */
5184 d = (struct builtin_description *) bdesc_3arg;
5185 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
5186 if (d->code == fcode)
5187 return rs6000_expand_ternop_builtin (d->icode, arglist, target);
5188 }
500c7157 5189
5190 abort ();
6d829a46 5191 return NULL_RTX;
500c7157 5192}
5193
5194static void
5b53fefa 5195rs6000_init_builtins ()
500c7157 5196{
f19493d5 5197 if (TARGET_SPE)
5198 spe_init_builtins ();
500c7157 5199 if (TARGET_ALTIVEC)
5200 altivec_init_builtins ();
8ec32caf 5201 if (TARGET_ALTIVEC || TARGET_SPE)
5202 rs6000_common_init_builtins ();
500c7157 5203}
5204
f19493d5 5205/* Search through a set of builtins and enable the mask bits.
5206 DESC is an array of builtins.
5207 SIZE is the totaly number of builtins.
5208 START is the builtin enum at which to start.
5209 END is the builtin enum at which to end. */
500c7157 5210static void
f19493d5 5211enable_mask_for_builtins (desc, size, start, end)
5212 struct builtin_description *desc;
5213 int size;
5214 enum rs6000_builtins start, end;
5215{
5216 int i;
5217
5218 for (i = 0; i < size; ++i)
5219 if (desc[i].code == start)
5220 break;
5221
5222 if (i == size)
5223 return;
5224
5225 for (; i < size; ++i)
5226 {
5227 /* Flip all the bits on. */
5228 desc[i].mask = target_flags;
5229 if (desc[i].code == end)
5230 break;
5231 }
5232}
5233
5234static void
daa988f5 5235spe_init_builtins ()
500c7157 5236{
f19493d5 5237 tree endlink = void_list_node;
5238 tree puint_type_node = build_pointer_type (unsigned_type_node);
5239 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
5240 tree pv2si_type_node = build_pointer_type (V2SI_type_node);
15e5a1c8 5241 struct builtin_description *d;
500c7157 5242 size_t i;
5243
f19493d5 5244 tree v2si_ftype_4_v2si
5245 = build_function_type
5246 (V2SI_type_node,
5247 tree_cons (NULL_TREE, V2SI_type_node,
5248 tree_cons (NULL_TREE, V2SI_type_node,
5249 tree_cons (NULL_TREE, V2SI_type_node,
5250 tree_cons (NULL_TREE, V2SI_type_node,
5251 endlink)))));
5252
5253 tree v2sf_ftype_4_v2sf
5254 = build_function_type
5255 (V2SF_type_node,
5256 tree_cons (NULL_TREE, V2SF_type_node,
5257 tree_cons (NULL_TREE, V2SF_type_node,
5258 tree_cons (NULL_TREE, V2SF_type_node,
5259 tree_cons (NULL_TREE, V2SF_type_node,
5260 endlink)))));
5261
5262 tree int_ftype_int_v2si_v2si
5263 = build_function_type
5264 (integer_type_node,
5265 tree_cons (NULL_TREE, integer_type_node,
5266 tree_cons (NULL_TREE, V2SI_type_node,
5267 tree_cons (NULL_TREE, V2SI_type_node,
5268 endlink))));
5269
5270 tree int_ftype_int_v2sf_v2sf
5271 = build_function_type
5272 (integer_type_node,
5273 tree_cons (NULL_TREE, integer_type_node,
5274 tree_cons (NULL_TREE, V2SF_type_node,
5275 tree_cons (NULL_TREE, V2SF_type_node,
5276 endlink))));
5277
5278 tree void_ftype_v2si_puint_int
5279 = build_function_type (void_type_node,
5280 tree_cons (NULL_TREE, V2SI_type_node,
5281 tree_cons (NULL_TREE, puint_type_node,
5282 tree_cons (NULL_TREE,
5283 integer_type_node,
5284 endlink))));
5285
5286 tree void_ftype_v2si_puint_char
5287 = build_function_type (void_type_node,
5288 tree_cons (NULL_TREE, V2SI_type_node,
5289 tree_cons (NULL_TREE, puint_type_node,
5290 tree_cons (NULL_TREE,
5291 char_type_node,
5292 endlink))));
5293
5294 tree void_ftype_v2si_pv2si_int
5295 = build_function_type (void_type_node,
5296 tree_cons (NULL_TREE, V2SI_type_node,
5297 tree_cons (NULL_TREE, pv2si_type_node,
5298 tree_cons (NULL_TREE,
5299 integer_type_node,
5300 endlink))));
5301
5302 tree void_ftype_v2si_pv2si_char
5303 = build_function_type (void_type_node,
5304 tree_cons (NULL_TREE, V2SI_type_node,
5305 tree_cons (NULL_TREE, pv2si_type_node,
5306 tree_cons (NULL_TREE,
5307 char_type_node,
5308 endlink))));
5309
5310 tree void_ftype_int
5311 = build_function_type (void_type_node,
5312 tree_cons (NULL_TREE, integer_type_node, endlink));
5313
5314 tree int_ftype_void
5315 = build_function_type (integer_type_node,
5316 tree_cons (NULL_TREE, void_type_node, endlink));
5317
5318 tree v2si_ftype_pv2si_int
5319 = build_function_type (V2SI_type_node,
5320 tree_cons (NULL_TREE, pv2si_type_node,
5321 tree_cons (NULL_TREE, integer_type_node,
5322 endlink)));
5323
5324 tree v2si_ftype_puint_int
5325 = build_function_type (V2SI_type_node,
5326 tree_cons (NULL_TREE, puint_type_node,
5327 tree_cons (NULL_TREE, integer_type_node,
5328 endlink)));
5329
5330 tree v2si_ftype_pushort_int
5331 = build_function_type (V2SI_type_node,
5332 tree_cons (NULL_TREE, pushort_type_node,
5333 tree_cons (NULL_TREE, integer_type_node,
5334 endlink)));
5335
5336 /* The initialization of the simple binary and unary builtins is
5337 done in rs6000_common_init_builtins, but we have to enable the
5338 mask bits here manually because we have run out of `target_flags'
5339 bits. We really need to redesign this mask business. */
5340
5341 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
5342 ARRAY_SIZE (bdesc_2arg),
5343 SPE_BUILTIN_EVADDW,
5344 SPE_BUILTIN_EVXOR);
5345 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
5346 ARRAY_SIZE (bdesc_1arg),
5347 SPE_BUILTIN_EVABS,
5348 SPE_BUILTIN_EVSUBFUSIAAW);
5349 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
5350 ARRAY_SIZE (bdesc_spe_predicates),
5351 SPE_BUILTIN_EVCMPEQ,
5352 SPE_BUILTIN_EVFSTSTLT);
5353 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
5354 ARRAY_SIZE (bdesc_spe_evsel),
5355 SPE_BUILTIN_EVSEL_CMPGTS,
5356 SPE_BUILTIN_EVSEL_FSTSTEQ);
5357
5358 /* Initialize irregular SPE builtins. */
5359
5360 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
5361 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
5362 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
5363 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
5364 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
5365 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
5366 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
5367 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
5368 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
5369 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
5370 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
5371 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
5372 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
5373 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
5374 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
5375 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
5376
5377 /* Loads. */
5378 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
5379 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
5380 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
5381 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
5382 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
5383 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
5384 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
5385 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
5386 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
5387 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
5388 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
5389 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
5390 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
5391 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
5392 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
5393 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
5394 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
5395 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
5396 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
5397 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
5398 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
5399 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
5400
5401 /* Predicates. */
5402 d = (struct builtin_description *) bdesc_spe_predicates;
5403 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
5404 {
5405 tree type;
5406
5407 switch (insn_data[d->icode].operand[1].mode)
5408 {
5409 case V2SImode:
5410 type = int_ftype_int_v2si_v2si;
5411 break;
5412 case V2SFmode:
5413 type = int_ftype_int_v2sf_v2sf;
5414 break;
5415 default:
5416 abort ();
5417 }
5418
5419 def_builtin (d->mask, d->name, type, d->code);
5420 }
5421
5422 /* Evsel predicates. */
5423 d = (struct builtin_description *) bdesc_spe_evsel;
5424 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
5425 {
5426 tree type;
5427
5428 switch (insn_data[d->icode].operand[1].mode)
5429 {
5430 case V2SImode:
5431 type = v2si_ftype_4_v2si;
5432 break;
5433 case V2SFmode:
5434 type = v2sf_ftype_4_v2sf;
5435 break;
5436 default:
5437 abort ();
5438 }
5439
5440 def_builtin (d->mask, d->name, type, d->code);
5441 }
5442}
5443
5444static void
daa988f5 5445altivec_init_builtins ()
f19493d5 5446{
5447 struct builtin_description *d;
5448 struct builtin_description_predicates *dp;
5449 size_t i;
5450 tree pfloat_type_node = build_pointer_type (float_type_node);
5451 tree pint_type_node = build_pointer_type (integer_type_node);
5452 tree pshort_type_node = build_pointer_type (short_integer_type_node);
5453 tree pchar_type_node = build_pointer_type (char_type_node);
5454
5455 tree pvoid_type_node = build_pointer_type (void_type_node);
5456
d5db08c7 5457 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
5458 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
5459 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
5460 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
5461
5462 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
5463
f19493d5 5464 tree int_ftype_int_v4si_v4si
5465 = build_function_type_list (integer_type_node,
5466 integer_type_node, V4SI_type_node,
5467 V4SI_type_node, NULL_TREE);
d5db08c7 5468 tree v4sf_ftype_pcfloat
5469 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
f19493d5 5470 tree void_ftype_pfloat_v4sf
8b55c4ba 5471 = build_function_type_list (void_type_node,
f19493d5 5472 pfloat_type_node, V4SF_type_node, NULL_TREE);
d5db08c7 5473 tree v4si_ftype_pcint
5474 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
5475 tree void_ftype_pint_v4si
8b55c4ba 5476 = build_function_type_list (void_type_node,
5477 pint_type_node, V4SI_type_node, NULL_TREE);
d5db08c7 5478 tree v8hi_ftype_pcshort
5479 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
fc0a3bf8 5480 tree void_ftype_pshort_v8hi
8b55c4ba 5481 = build_function_type_list (void_type_node,
5482 pshort_type_node, V8HI_type_node, NULL_TREE);
d5db08c7 5483 tree v16qi_ftype_pcchar
5484 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
fc0a3bf8 5485 tree void_ftype_pchar_v16qi
8b55c4ba 5486 = build_function_type_list (void_type_node,
5487 pchar_type_node, V16QI_type_node, NULL_TREE);
87ebe3d2 5488 tree void_ftype_v4si
8b55c4ba 5489 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
f19493d5 5490 tree v8hi_ftype_void
5491 = build_function_type (V8HI_type_node, void_list_node);
5492 tree void_ftype_void
5493 = build_function_type (void_type_node, void_list_node);
5494 tree void_ftype_qi
5495 = build_function_type_list (void_type_node, char_type_node, NULL_TREE);
d5db08c7 5496
5497 tree v16qi_ftype_int_pcvoid
f19493d5 5498 = build_function_type_list (V16QI_type_node,
d5db08c7 5499 integer_type_node, pcvoid_type_node, NULL_TREE);
5500 tree v8hi_ftype_int_pcvoid
f19493d5 5501 = build_function_type_list (V8HI_type_node,
d5db08c7 5502 integer_type_node, pcvoid_type_node, NULL_TREE);
5503 tree v4si_ftype_int_pcvoid
f19493d5 5504 = build_function_type_list (V4SI_type_node,
d5db08c7 5505 integer_type_node, pcvoid_type_node, NULL_TREE);
5506
9f7956fb 5507 tree void_ftype_v4si_int_pvoid
8b55c4ba 5508 = build_function_type_list (void_type_node,
5509 V4SI_type_node, integer_type_node,
5510 pvoid_type_node, NULL_TREE);
9f710c67 5511 tree void_ftype_v16qi_int_pvoid
8b55c4ba 5512 = build_function_type_list (void_type_node,
5513 V16QI_type_node, integer_type_node,
5514 pvoid_type_node, NULL_TREE);
9f710c67 5515 tree void_ftype_v8hi_int_pvoid
8b55c4ba 5516 = build_function_type_list (void_type_node,
5517 V8HI_type_node, integer_type_node,
5518 pvoid_type_node, NULL_TREE);
f19493d5 5519 tree int_ftype_int_v8hi_v8hi
5520 = build_function_type_list (integer_type_node,
5521 integer_type_node, V8HI_type_node,
5522 V8HI_type_node, NULL_TREE);
5523 tree int_ftype_int_v16qi_v16qi
5524 = build_function_type_list (integer_type_node,
5525 integer_type_node, V16QI_type_node,
5526 V16QI_type_node, NULL_TREE);
5527 tree int_ftype_int_v4sf_v4sf
5528 = build_function_type_list (integer_type_node,
5529 integer_type_node, V4SF_type_node,
5530 V4SF_type_node, NULL_TREE);
5531 tree v4si_ftype_v4si
5532 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
5533 tree v8hi_ftype_v8hi
5534 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
5535 tree v16qi_ftype_v16qi
5536 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
5537 tree v4sf_ftype_v4sf
5538 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
d5db08c7 5539 tree void_ftype_pcvoid_int_char
f19493d5 5540 = build_function_type_list (void_type_node,
d5db08c7 5541 pcvoid_type_node, integer_type_node,
f19493d5 5542 char_type_node, NULL_TREE);
d5db08c7 5543
5544 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
5545 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
5546 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
5547 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
5548 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
5549 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
5550 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
5551 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
5552 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
5553 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
5554 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
5555 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
5556 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
5557 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
5558 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
5559 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
f19493d5 5560 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
5561 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
5562 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
5563 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_qi, ALTIVEC_BUILTIN_DSS);
d5db08c7 5564 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVSL);
5565 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVSR);
5566 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVEBX);
5567 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVEHX);
5568 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVEWX);
5569 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVXL);
5570 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVX);
f19493d5 5571 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVX);
5572 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVEWX);
5573 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVXL);
5574 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_int_pvoid, ALTIVEC_BUILTIN_STVEBX);
5575 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_int_pvoid, ALTIVEC_BUILTIN_STVEHX);
5576
5577 /* Add the DST variants. */
5578 d = (struct builtin_description *) bdesc_dst;
5579 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
d5db08c7 5580 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_char, d->code);
f19493d5 5581
5582 /* Initialize the predicates. */
5583 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
5584 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
5585 {
5586 enum machine_mode mode1;
5587 tree type;
5588
5589 mode1 = insn_data[dp->icode].operand[1].mode;
5590
5591 switch (mode1)
5592 {
5593 case V4SImode:
5594 type = int_ftype_int_v4si_v4si;
5595 break;
5596 case V8HImode:
5597 type = int_ftype_int_v8hi_v8hi;
5598 break;
5599 case V16QImode:
5600 type = int_ftype_int_v16qi_v16qi;
5601 break;
5602 case V4SFmode:
5603 type = int_ftype_int_v4sf_v4sf;
5604 break;
5605 default:
5606 abort ();
5607 }
5608
5609 def_builtin (dp->mask, dp->name, type, dp->code);
5610 }
5611
5612 /* Initialize the abs* operators. */
5613 d = (struct builtin_description *) bdesc_abs;
5614 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
5615 {
5616 enum machine_mode mode0;
5617 tree type;
5618
5619 mode0 = insn_data[d->icode].operand[0].mode;
5620
5621 switch (mode0)
5622 {
5623 case V4SImode:
5624 type = v4si_ftype_v4si;
5625 break;
5626 case V8HImode:
5627 type = v8hi_ftype_v8hi;
5628 break;
5629 case V16QImode:
5630 type = v16qi_ftype_v16qi;
5631 break;
5632 case V4SFmode:
5633 type = v4sf_ftype_v4sf;
5634 break;
5635 default:
5636 abort ();
5637 }
5638
5639 def_builtin (d->mask, d->name, type, d->code);
5640 }
5641}
5642
5643static void
daa988f5 5644rs6000_common_init_builtins ()
f19493d5 5645{
5646 struct builtin_description *d;
5647 size_t i;
5648
5649 tree v4sf_ftype_v4sf_v4sf_v16qi
5650 = build_function_type_list (V4SF_type_node,
5651 V4SF_type_node, V4SF_type_node,
5652 V16QI_type_node, NULL_TREE);
5653 tree v4si_ftype_v4si_v4si_v16qi
5654 = build_function_type_list (V4SI_type_node,
5655 V4SI_type_node, V4SI_type_node,
5656 V16QI_type_node, NULL_TREE);
5657 tree v8hi_ftype_v8hi_v8hi_v16qi
5658 = build_function_type_list (V8HI_type_node,
5659 V8HI_type_node, V8HI_type_node,
5660 V16QI_type_node, NULL_TREE);
5661 tree v16qi_ftype_v16qi_v16qi_v16qi
5662 = build_function_type_list (V16QI_type_node,
5663 V16QI_type_node, V16QI_type_node,
5664 V16QI_type_node, NULL_TREE);
5665 tree v4si_ftype_char
5666 = build_function_type_list (V4SI_type_node, char_type_node, NULL_TREE);
5667 tree v8hi_ftype_char
5668 = build_function_type_list (V8HI_type_node, char_type_node, NULL_TREE);
5669 tree v16qi_ftype_char
5670 = build_function_type_list (V16QI_type_node, char_type_node, NULL_TREE);
5671 tree v8hi_ftype_v16qi
5672 = build_function_type_list (V8HI_type_node, V16QI_type_node, NULL_TREE);
5673 tree v4sf_ftype_v4sf
5674 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
5675
5676 tree v2si_ftype_v2si_v2si
5677 = build_function_type_list (V2SI_type_node,
5678 V2SI_type_node, V2SI_type_node, NULL_TREE);
5679
5680 tree v2sf_ftype_v2sf_v2sf
5681 = build_function_type_list (V2SF_type_node,
5682 V2SF_type_node, V2SF_type_node, NULL_TREE);
5683
5684 tree v2si_ftype_int_int
5685 = build_function_type_list (V2SI_type_node,
5686 integer_type_node, integer_type_node,
5687 NULL_TREE);
5688
5689 tree v2si_ftype_v2si
5690 = build_function_type_list (V2SI_type_node, V2SI_type_node, NULL_TREE);
5691
5692 tree v2sf_ftype_v2sf
5693 = build_function_type_list (V2SF_type_node,
5694 V2SF_type_node, NULL_TREE);
5695
5696 tree v2sf_ftype_v2si
5697 = build_function_type_list (V2SF_type_node,
5698 V2SI_type_node, NULL_TREE);
5699
5700 tree v2si_ftype_v2sf
5701 = build_function_type_list (V2SI_type_node,
5702 V2SF_type_node, NULL_TREE);
5703
5704 tree v2si_ftype_v2si_char
5705 = build_function_type_list (V2SI_type_node,
5706 V2SI_type_node, char_type_node, NULL_TREE);
5707
5708 tree v2si_ftype_int_char
5709 = build_function_type_list (V2SI_type_node,
5710 integer_type_node, char_type_node, NULL_TREE);
5711
5712 tree v2si_ftype_char
5713 = build_function_type_list (V2SI_type_node, char_type_node, NULL_TREE);
5714
5715 tree int_ftype_int_int
5716 = build_function_type_list (integer_type_node,
5717 integer_type_node, integer_type_node,
5718 NULL_TREE);
87ebe3d2 5719
500c7157 5720 tree v4si_ftype_v4si_v4si
8b55c4ba 5721 = build_function_type_list (V4SI_type_node,
5722 V4SI_type_node, V4SI_type_node, NULL_TREE);
f12a08b5 5723 tree v4sf_ftype_v4si_char
8b55c4ba 5724 = build_function_type_list (V4SF_type_node,
5725 V4SI_type_node, char_type_node, NULL_TREE);
f12a08b5 5726 tree v4si_ftype_v4sf_char
8b55c4ba 5727 = build_function_type_list (V4SI_type_node,
5728 V4SF_type_node, char_type_node, NULL_TREE);
a8b720b1 5729 tree v4si_ftype_v4si_char
8b55c4ba 5730 = build_function_type_list (V4SI_type_node,
5731 V4SI_type_node, char_type_node, NULL_TREE);
a8b720b1 5732 tree v8hi_ftype_v8hi_char
8b55c4ba 5733 = build_function_type_list (V8HI_type_node,
5734 V8HI_type_node, char_type_node, NULL_TREE);
a8b720b1 5735 tree v16qi_ftype_v16qi_char
8b55c4ba 5736 = build_function_type_list (V16QI_type_node,
5737 V16QI_type_node, char_type_node, NULL_TREE);
fe889181 5738 tree v16qi_ftype_v16qi_v16qi_char
8b55c4ba 5739 = build_function_type_list (V16QI_type_node,
5740 V16QI_type_node, V16QI_type_node,
5741 char_type_node, NULL_TREE);
fe889181 5742 tree v8hi_ftype_v8hi_v8hi_char
8b55c4ba 5743 = build_function_type_list (V8HI_type_node,
5744 V8HI_type_node, V8HI_type_node,
5745 char_type_node, NULL_TREE);
fe889181 5746 tree v4si_ftype_v4si_v4si_char
8b55c4ba 5747 = build_function_type_list (V4SI_type_node,
5748 V4SI_type_node, V4SI_type_node,
5749 char_type_node, NULL_TREE);
fe889181 5750 tree v4sf_ftype_v4sf_v4sf_char
8b55c4ba 5751 = build_function_type_list (V4SF_type_node,
5752 V4SF_type_node, V4SF_type_node,
5753 char_type_node, NULL_TREE);
500c7157 5754 tree v4sf_ftype_v4sf_v4sf
8b55c4ba 5755 = build_function_type_list (V4SF_type_node,
5756 V4SF_type_node, V4SF_type_node, NULL_TREE);
f12a08b5 5757 tree v4sf_ftype_v4sf_v4sf_v4si
8b55c4ba 5758 = build_function_type_list (V4SF_type_node,
5759 V4SF_type_node, V4SF_type_node,
5760 V4SI_type_node, NULL_TREE);
a8b720b1 5761 tree v4sf_ftype_v4sf_v4sf_v4sf
8b55c4ba 5762 = build_function_type_list (V4SF_type_node,
5763 V4SF_type_node, V4SF_type_node,
5764 V4SF_type_node, NULL_TREE);
f12a08b5 5765 tree v4si_ftype_v4si_v4si_v4si
8b55c4ba 5766 = build_function_type_list (V4SI_type_node,
5767 V4SI_type_node, V4SI_type_node,
5768 V4SI_type_node, NULL_TREE);
500c7157 5769 tree v8hi_ftype_v8hi_v8hi
8b55c4ba 5770 = build_function_type_list (V8HI_type_node,
5771 V8HI_type_node, V8HI_type_node, NULL_TREE);
a8b720b1 5772 tree v8hi_ftype_v8hi_v8hi_v8hi
8b55c4ba 5773 = build_function_type_list (V8HI_type_node,
5774 V8HI_type_node, V8HI_type_node,
5775 V8HI_type_node, NULL_TREE);
a8b720b1 5776 tree v4si_ftype_v8hi_v8hi_v4si
8b55c4ba 5777 = build_function_type_list (V4SI_type_node,
5778 V8HI_type_node, V8HI_type_node,
5779 V4SI_type_node, NULL_TREE);
a8b720b1 5780 tree v4si_ftype_v16qi_v16qi_v4si
8b55c4ba 5781 = build_function_type_list (V4SI_type_node,
5782 V16QI_type_node, V16QI_type_node,
5783 V4SI_type_node, NULL_TREE);
500c7157 5784 tree v16qi_ftype_v16qi_v16qi
8b55c4ba 5785 = build_function_type_list (V16QI_type_node,
5786 V16QI_type_node, V16QI_type_node, NULL_TREE);
500c7157 5787 tree v4si_ftype_v4sf_v4sf
8b55c4ba 5788 = build_function_type_list (V4SI_type_node,
5789 V4SF_type_node, V4SF_type_node, NULL_TREE);
500c7157 5790 tree v8hi_ftype_v16qi_v16qi
8b55c4ba 5791 = build_function_type_list (V8HI_type_node,
5792 V16QI_type_node, V16QI_type_node, NULL_TREE);
500c7157 5793 tree v4si_ftype_v8hi_v8hi
8b55c4ba 5794 = build_function_type_list (V4SI_type_node,
5795 V8HI_type_node, V8HI_type_node, NULL_TREE);
500c7157 5796 tree v8hi_ftype_v4si_v4si
8b55c4ba 5797 = build_function_type_list (V8HI_type_node,
5798 V4SI_type_node, V4SI_type_node, NULL_TREE);
500c7157 5799 tree v16qi_ftype_v8hi_v8hi
8b55c4ba 5800 = build_function_type_list (V16QI_type_node,
5801 V8HI_type_node, V8HI_type_node, NULL_TREE);
500c7157 5802 tree v4si_ftype_v16qi_v4si
8b55c4ba 5803 = build_function_type_list (V4SI_type_node,
5804 V16QI_type_node, V4SI_type_node, NULL_TREE);
41b843a7 5805 tree v4si_ftype_v16qi_v16qi
8b55c4ba 5806 = build_function_type_list (V4SI_type_node,
5807 V16QI_type_node, V16QI_type_node, NULL_TREE);
500c7157 5808 tree v4si_ftype_v8hi_v4si
8b55c4ba 5809 = build_function_type_list (V4SI_type_node,
5810 V8HI_type_node, V4SI_type_node, NULL_TREE);
f19493d5 5811 tree v4si_ftype_v8hi
5812 = build_function_type_list (V4SI_type_node, V8HI_type_node, NULL_TREE);
5813 tree int_ftype_v4si_v4si
5814 = build_function_type_list (integer_type_node,
5815 V4SI_type_node, V4SI_type_node, NULL_TREE);
5816 tree int_ftype_v4sf_v4sf
5817 = build_function_type_list (integer_type_node,
5818 V4SF_type_node, V4SF_type_node, NULL_TREE);
5819 tree int_ftype_v16qi_v16qi
5820 = build_function_type_list (integer_type_node,
5821 V16QI_type_node, V16QI_type_node, NULL_TREE);
500c7157 5822 tree int_ftype_v8hi_v8hi
8b55c4ba 5823 = build_function_type_list (integer_type_node,
5824 V8HI_type_node, V8HI_type_node, NULL_TREE);
500c7157 5825
9df03d69 5826 /* Add the simple ternary operators. */
a8b720b1 5827 d = (struct builtin_description *) bdesc_3arg;
3585dac7 5828 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
a8b720b1 5829 {
5830
5831 enum machine_mode mode0, mode1, mode2, mode3;
5832 tree type;
5833
8ec32caf 5834 if (d->name == 0 || d->icode == CODE_FOR_nothing)
a8b720b1 5835 continue;
5836
5837 mode0 = insn_data[d->icode].operand[0].mode;
5838 mode1 = insn_data[d->icode].operand[1].mode;
5839 mode2 = insn_data[d->icode].operand[2].mode;
5840 mode3 = insn_data[d->icode].operand[3].mode;
5841
5842 /* When all four are of the same mode. */
5843 if (mode0 == mode1 && mode1 == mode2 && mode2 == mode3)
5844 {
5845 switch (mode0)
5846 {
f12a08b5 5847 case V4SImode:
5848 type = v4si_ftype_v4si_v4si_v4si;
5849 break;
a8b720b1 5850 case V4SFmode:
5851 type = v4sf_ftype_v4sf_v4sf_v4sf;
5852 break;
5853 case V8HImode:
5854 type = v8hi_ftype_v8hi_v8hi_v8hi;
5855 break;
5856 case V16QImode:
5857 type = v16qi_ftype_v16qi_v16qi_v16qi;
5858 break;
5859 default:
5860 abort();
5861 }
5862 }
5863 else if (mode0 == mode1 && mode1 == mode2 && mode3 == V16QImode)
5864 {
5865 switch (mode0)
5866 {
5867 case V4SImode:
5868 type = v4si_ftype_v4si_v4si_v16qi;
5869 break;
5870 case V4SFmode:
5871 type = v4sf_ftype_v4sf_v4sf_v16qi;
5872 break;
5873 case V8HImode:
5874 type = v8hi_ftype_v8hi_v8hi_v16qi;
5875 break;
5876 case V16QImode:
5877 type = v16qi_ftype_v16qi_v16qi_v16qi;
5878 break;
5879 default:
5880 abort();
5881 }
5882 }
5883 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode
5884 && mode3 == V4SImode)
fe889181 5885 type = v4si_ftype_v16qi_v16qi_v4si;
a8b720b1 5886 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode
5887 && mode3 == V4SImode)
fe889181 5888 type = v4si_ftype_v8hi_v8hi_v4si;
f12a08b5 5889 else if (mode0 == V4SFmode && mode1 == V4SFmode && mode2 == V4SFmode
5890 && mode3 == V4SImode)
fe889181 5891 type = v4sf_ftype_v4sf_v4sf_v4si;
5892
5893 /* vchar, vchar, vchar, 4 bit literal. */
5894 else if (mode0 == V16QImode && mode1 == mode0 && mode2 == mode0
5895 && mode3 == QImode)
5896 type = v16qi_ftype_v16qi_v16qi_char;
5897
5898 /* vshort, vshort, vshort, 4 bit literal. */
5899 else if (mode0 == V8HImode && mode1 == mode0 && mode2 == mode0
5900 && mode3 == QImode)
5901 type = v8hi_ftype_v8hi_v8hi_char;
5902
5903 /* vint, vint, vint, 4 bit literal. */
5904 else if (mode0 == V4SImode && mode1 == mode0 && mode2 == mode0
5905 && mode3 == QImode)
5906 type = v4si_ftype_v4si_v4si_char;
5907
5908 /* vfloat, vfloat, vfloat, 4 bit literal. */
5909 else if (mode0 == V4SFmode && mode1 == mode0 && mode2 == mode0
5910 && mode3 == QImode)
5911 type = v4sf_ftype_v4sf_v4sf_char;
5912
a8b720b1 5913 else
5914 abort ();
5915
5916 def_builtin (d->mask, d->name, type, d->code);
5917 }
5918
500c7157 5919 /* Add the simple binary operators. */
bb78803e 5920 d = (struct builtin_description *) bdesc_2arg;
3585dac7 5921 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
500c7157 5922 {
5923 enum machine_mode mode0, mode1, mode2;
5924 tree type;
5925
8ec32caf 5926 if (d->name == 0 || d->icode == CODE_FOR_nothing)
500c7157 5927 continue;
5928
5929 mode0 = insn_data[d->icode].operand[0].mode;
5930 mode1 = insn_data[d->icode].operand[1].mode;
5931 mode2 = insn_data[d->icode].operand[2].mode;
5932
5933 /* When all three operands are of the same mode. */
5934 if (mode0 == mode1 && mode1 == mode2)
5935 {
5936 switch (mode0)
5937 {
5938 case V4SFmode:
5939 type = v4sf_ftype_v4sf_v4sf;
5940 break;
5941 case V4SImode:
5942 type = v4si_ftype_v4si_v4si;
5943 break;
5944 case V16QImode:
5945 type = v16qi_ftype_v16qi_v16qi;
5946 break;
5947 case V8HImode:
5948 type = v8hi_ftype_v8hi_v8hi;
5949 break;
f19493d5 5950 case V2SImode:
5951 type = v2si_ftype_v2si_v2si;
5952 break;
5953 case V2SFmode:
5954 type = v2sf_ftype_v2sf_v2sf;
5955 break;
5956 case SImode:
5957 type = int_ftype_int_int;
5958 break;
500c7157 5959 default:
5960 abort ();
5961 }
5962 }
5963
5964 /* A few other combos we really don't want to do manually. */
5965
5966 /* vint, vfloat, vfloat. */
5967 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
5968 type = v4si_ftype_v4sf_v4sf;
5969
5970 /* vshort, vchar, vchar. */
5971 else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
5972 type = v8hi_ftype_v16qi_v16qi;
5973
5974 /* vint, vshort, vshort. */
5975 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
5976 type = v4si_ftype_v8hi_v8hi;
5977
5978 /* vshort, vint, vint. */
5979 else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
5980 type = v8hi_ftype_v4si_v4si;
5981
5982 /* vchar, vshort, vshort. */
5983 else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
5984 type = v16qi_ftype_v8hi_v8hi;
5985
5986 /* vint, vchar, vint. */
5987 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
5988 type = v4si_ftype_v16qi_v4si;
5989
41b843a7 5990 /* vint, vchar, vchar. */
5991 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode)
5992 type = v4si_ftype_v16qi_v16qi;
5993
500c7157 5994 /* vint, vshort, vint. */
5995 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
5996 type = v4si_ftype_v8hi_v4si;
a8b720b1 5997
5998 /* vint, vint, 5 bit literal. */
5999 else if (mode0 == V4SImode && mode1 == V4SImode && mode2 == QImode)
6000 type = v4si_ftype_v4si_char;
6001
6002 /* vshort, vshort, 5 bit literal. */
6003 else if (mode0 == V8HImode && mode1 == V8HImode && mode2 == QImode)
6004 type = v8hi_ftype_v8hi_char;
6005
6006 /* vchar, vchar, 5 bit literal. */
6007 else if (mode0 == V16QImode && mode1 == V16QImode && mode2 == QImode)
6008 type = v16qi_ftype_v16qi_char;
500c7157 6009
f12a08b5 6010 /* vfloat, vint, 5 bit literal. */
6011 else if (mode0 == V4SFmode && mode1 == V4SImode && mode2 == QImode)
6012 type = v4sf_ftype_v4si_char;
6013
6014 /* vint, vfloat, 5 bit literal. */
6015 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == QImode)
6016 type = v4si_ftype_v4sf_char;
6017
f19493d5 6018 else if (mode0 == V2SImode && mode1 == SImode && mode2 == SImode)
6019 type = v2si_ftype_int_int;
6020
6021 else if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
6022 type = v2si_ftype_v2si_char;
6023
6024 else if (mode0 == V2SImode && mode1 == SImode && mode2 == QImode)
6025 type = v2si_ftype_int_char;
6026
500c7157 6027 /* int, x, x. */
6028 else if (mode0 == SImode)
6029 {
6030 switch (mode1)
6031 {
6032 case V4SImode:
6033 type = int_ftype_v4si_v4si;
6034 break;
6035 case V4SFmode:
6036 type = int_ftype_v4sf_v4sf;
6037 break;
6038 case V16QImode:
6039 type = int_ftype_v16qi_v16qi;
6040 break;
6041 case V8HImode:
6042 type = int_ftype_v8hi_v8hi;
6043 break;
6044 default:
6045 abort ();
6046 }
6047 }
6048
6049 else
6050 abort ();
6051
a8b720b1 6052 def_builtin (d->mask, d->name, type, d->code);
6053 }
fe889181 6054
a8b720b1 6055 /* Add the simple unary operators. */
6056 d = (struct builtin_description *) bdesc_1arg;
3585dac7 6057 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
a8b720b1 6058 {
6059 enum machine_mode mode0, mode1;
6060 tree type;
6061
8ec32caf 6062 if (d->name == 0 || d->icode == CODE_FOR_nothing)
a8b720b1 6063 continue;
6064
6065 mode0 = insn_data[d->icode].operand[0].mode;
6066 mode1 = insn_data[d->icode].operand[1].mode;
6067
6068 if (mode0 == V4SImode && mode1 == QImode)
6069 type = v4si_ftype_char;
6070 else if (mode0 == V8HImode && mode1 == QImode)
6071 type = v8hi_ftype_char;
6072 else if (mode0 == V16QImode && mode1 == QImode)
6073 type = v16qi_ftype_char;
f12a08b5 6074 else if (mode0 == V4SFmode && mode1 == V4SFmode)
6075 type = v4sf_ftype_v4sf;
e931e2d9 6076 else if (mode0 == V8HImode && mode1 == V16QImode)
6077 type = v8hi_ftype_v16qi;
6078 else if (mode0 == V4SImode && mode1 == V8HImode)
6079 type = v4si_ftype_v8hi;
f19493d5 6080 else if (mode0 == V2SImode && mode1 == V2SImode)
6081 type = v2si_ftype_v2si;
6082 else if (mode0 == V2SFmode && mode1 == V2SFmode)
6083 type = v2sf_ftype_v2sf;
6084 else if (mode0 == V2SFmode && mode1 == V2SImode)
6085 type = v2sf_ftype_v2si;
6086 else if (mode0 == V2SImode && mode1 == V2SFmode)
6087 type = v2si_ftype_v2sf;
6088 else if (mode0 == V2SImode && mode1 == QImode)
6089 type = v2si_ftype_char;
a8b720b1 6090 else
6091 abort ();
6092
500c7157 6093 def_builtin (d->mask, d->name, type, d->code);
6094 }
6095}
6096
f0500469 6097\f
70309a38 6098/* Expand a block move operation, and return 1 if successful. Return 0
6099 if we should let the compiler generate normal code.
6100
6101 operands[0] is the destination
6102 operands[1] is the source
6103 operands[2] is the length
6104 operands[3] is the alignment */
6105
b4b968a6 6106#define MAX_MOVE_REG 4
6107
70309a38 6108int
6109expand_block_move (operands)
6110 rtx operands[];
6111{
6b02f2a5 6112 rtx orig_dest = operands[0];
6113 rtx orig_src = operands[1];
70309a38 6114 rtx bytes_rtx = operands[2];
70309a38 6115 rtx align_rtx = operands[3];
b4b968a6 6116 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
0d9647cc 6117 int align;
b4b968a6 6118 int bytes;
6119 int offset;
70309a38 6120 int move_bytes;
6121
b4b968a6 6122 /* If this is not a fixed size move, just call memcpy */
cbe8f515 6123 if (! constp)
b4b968a6 6124 return 0;
6125
0d9647cc 6126 /* If this is not a fixed size alignment, abort */
6127 if (GET_CODE (align_rtx) != CONST_INT)
6128 abort ();
6129 align = INTVAL (align_rtx);
6130
70309a38 6131 /* Anything to move? */
b4b968a6 6132 bytes = INTVAL (bytes_rtx);
6133 if (bytes <= 0)
70309a38 6134 return 1;
6135
c60abcf0 6136 /* store_one_arg depends on expand_block_move to handle at least the size of
9df03d69 6137 reg_parm_stack_space. */
c60abcf0 6138 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
70309a38 6139 return 0;
6140
b4b968a6 6141 if (TARGET_STRING) /* string instructions are available */
70309a38 6142 {
f0500469 6143 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
70309a38 6144 {
f0500469 6145 union {
6146 rtx (*movstrsi) PARAMS ((rtx, rtx, rtx, rtx));
6147 rtx (*mov) PARAMS ((rtx, rtx));
6148 } gen_func;
6149 enum machine_mode mode = BLKmode;
6150 rtx src, dest;
6151
b4b968a6 6152 if (bytes > 24 /* move up to 32 bytes at a time */
cbe8f515 6153 && ! fixed_regs[5]
6154 && ! fixed_regs[6]
6155 && ! fixed_regs[7]
6156 && ! fixed_regs[8]
6157 && ! fixed_regs[9]
6158 && ! fixed_regs[10]
6159 && ! fixed_regs[11]
6160 && ! fixed_regs[12])
b4b968a6 6161 {
6162 move_bytes = (bytes > 32) ? 32 : bytes;
f0500469 6163 gen_func.movstrsi = gen_movstrsi_8reg;
b4b968a6 6164 }
6165 else if (bytes > 16 /* move up to 24 bytes at a time */
8b16d5f9 6166 && ! fixed_regs[5]
6167 && ! fixed_regs[6]
cbe8f515 6168 && ! fixed_regs[7]
6169 && ! fixed_regs[8]
6170 && ! fixed_regs[9]
8b16d5f9 6171 && ! fixed_regs[10])
b4b968a6 6172 {
6173 move_bytes = (bytes > 24) ? 24 : bytes;
f0500469 6174 gen_func.movstrsi = gen_movstrsi_6reg;
b4b968a6 6175 }
6176 else if (bytes > 8 /* move up to 16 bytes at a time */
8b16d5f9 6177 && ! fixed_regs[5]
6178 && ! fixed_regs[6]
6179 && ! fixed_regs[7]
6180 && ! fixed_regs[8])
b4b968a6 6181 {
6182 move_bytes = (bytes > 16) ? 16 : bytes;
f0500469 6183 gen_func.movstrsi = gen_movstrsi_4reg;
b4b968a6 6184 }
03bb02b5 6185 else if (bytes >= 8 && TARGET_POWERPC64
970e222f 6186 /* 64-bit loads and stores require word-aligned
7c721ad4 6187 displacements. */
970e222f 6188 && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
03bb02b5 6189 {
6190 move_bytes = 8;
f0500469 6191 mode = DImode;
6192 gen_func.mov = gen_movdi;
03bb02b5 6193 }
f0c730df 6194 else if (bytes > 4 && !TARGET_POWERPC64)
b4b968a6 6195 { /* move up to 8 bytes at a time */
6196 move_bytes = (bytes > 8) ? 8 : bytes;
f0500469 6197 gen_func.movstrsi = gen_movstrsi_2reg;
b4b968a6 6198 }
cbe8f515 6199 else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
b4b968a6 6200 { /* move 4 bytes */
6201 move_bytes = 4;
f0500469 6202 mode = SImode;
6203 gen_func.mov = gen_movsi;
b4b968a6 6204 }
cbe8f515 6205 else if (bytes == 2 && (align >= 2 || ! STRICT_ALIGNMENT))
b4b968a6 6206 { /* move 2 bytes */
6207 move_bytes = 2;
f0500469 6208 mode = HImode;
6209 gen_func.mov = gen_movhi;
b4b968a6 6210 }
6211 else if (bytes == 1) /* move 1 byte */
6212 {
6213 move_bytes = 1;
f0500469 6214 mode = QImode;
6215 gen_func.mov = gen_movqi;
b4b968a6 6216 }
6217 else
6218 { /* move up to 4 bytes at a time */
6219 move_bytes = (bytes > 4) ? 4 : bytes;
f0500469 6220 gen_func.movstrsi = gen_movstrsi_1reg;
b4b968a6 6221 }
397ac502 6222
f0500469 6223 src = adjust_address (orig_src, mode, offset);
6224 dest = adjust_address (orig_dest, mode, offset);
6225
6226 if (mode == BLKmode)
8e79f33c 6227 {
f0500469 6228 /* Move the address into scratch registers. The movstrsi
6229 patterns require zero offset. */
6230 if (!REG_P (XEXP (src, 0)))
cbe8f515 6231 {
f0500469 6232 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
6233 src = replace_equiv_address (src, src_reg);
cbe8f515 6234 }
f0500469 6235 set_mem_size (src, GEN_INT (move_bytes));
6236
6237 if (!REG_P (XEXP (dest, 0)))
cbe8f515 6238 {
f0500469 6239 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
6240 dest = replace_equiv_address (dest, dest_reg);
cbe8f515 6241 }
f0500469 6242 set_mem_size (dest, GEN_INT (move_bytes));
6243
6244 emit_insn ((*gen_func.movstrsi) (dest, src,
6245 GEN_INT (move_bytes & 31),
6246 align_rtx));
6247 }
6248 else
6249 {
6250 rtx tmp_reg = gen_reg_rtx (mode);
6251
6252 emit_insn ((*gen_func.mov) (tmp_reg, src));
6253 emit_insn ((*gen_func.mov) (dest, tmp_reg));
8e79f33c 6254 }
397ac502 6255 }
b4b968a6 6256 }
6257
6258 else /* string instructions not available */
6259 {
f0500469 6260 rtx stores[MAX_MOVE_REG];
6261 int num_reg = 0;
6262 int i;
6263
6264 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
70309a38 6265 {
f0500469 6266 rtx (*gen_mov_func) PARAMS ((rtx, rtx));
6267 enum machine_mode mode;
6268 rtx src, dest, tmp_reg;
b4b968a6 6269
cbe8f515 6270 /* Generate the appropriate load and store, saving the stores
6271 for later. */
6272 if (bytes >= 8 && TARGET_POWERPC64
970e222f 6273 /* 64-bit loads and stores require word-aligned
6274 displacements. */
cbe8f515 6275 && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
6b02f2a5 6276 {
6277 move_bytes = 8;
f0500469 6278 mode = DImode;
6279 gen_mov_func = gen_movdi;
6b02f2a5 6280 }
cbe8f515 6281 else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
b4b968a6 6282 {
6283 move_bytes = 4;
f0500469 6284 mode = SImode;
6285 gen_mov_func = gen_movsi;
b4b968a6 6286 }
cbe8f515 6287 else if (bytes >= 2 && (align >= 2 || ! STRICT_ALIGNMENT))
b4b968a6 6288 {
6289 move_bytes = 2;
f0500469 6290 mode = HImode;
6291 gen_mov_func = gen_movhi;
b4b968a6 6292 }
6293 else
6294 {
6295 move_bytes = 1;
f0500469 6296 mode = QImode;
6297 gen_mov_func = gen_movqi;
b4b968a6 6298 }
6299
f0500469 6300 src = adjust_address (orig_src, mode, offset);
6301 dest = adjust_address (orig_dest, mode, offset);
6302 tmp_reg = gen_reg_rtx (mode);
6303
6304 emit_insn ((*gen_mov_func) (tmp_reg, src));
6305 stores[num_reg++] = (*gen_mov_func) (dest, tmp_reg);
6306
b4b968a6 6307 if (num_reg >= MAX_MOVE_REG)
6308 {
6309 for (i = 0; i < num_reg; i++)
6310 emit_insn (stores[i]);
6311 num_reg = 0;
70309a38 6312 }
6313 }
b4b968a6 6314
6b02f2a5 6315 for (i = 0; i < num_reg; i++)
6316 emit_insn (stores[i]);
70309a38 6317 }
6318
6319 return 1;
6320}
6321
d1bd513e 6322\f
6323/* Return 1 if OP is a load multiple operation. It is known to be a
6324 PARALLEL and the first section will be tested. */
6325
6326int
6327load_multiple_operation (op, mode)
6328 rtx op;
600e851b 6329 enum machine_mode mode ATTRIBUTE_UNUSED;
d1bd513e 6330{
6331 int count = XVECLEN (op, 0);
30c5e279 6332 unsigned int dest_regno;
d1bd513e 6333 rtx src_addr;
6334 int i;
6335
6336 /* Perform a quick check so we don't blow up below. */
6337 if (count <= 1
6338 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6339 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
6340 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
6341 return 0;
6342
6343 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6344 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
6345
6346 for (i = 1; i < count; i++)
6347 {
6348 rtx elt = XVECEXP (op, 0, i);
6349
6350 if (GET_CODE (elt) != SET
6351 || GET_CODE (SET_DEST (elt)) != REG
6352 || GET_MODE (SET_DEST (elt)) != SImode
6353 || REGNO (SET_DEST (elt)) != dest_regno + i
6354 || GET_CODE (SET_SRC (elt)) != MEM
6355 || GET_MODE (SET_SRC (elt)) != SImode
6356 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
6357 || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
6358 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
6359 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4)
6360 return 0;
6361 }
6362
6363 return 1;
6364}
6365
6366/* Similar, but tests for store multiple. Here, the second vector element
6367 is a CLOBBER. It will be tested later. */
6368
6369int
6370store_multiple_operation (op, mode)
6371 rtx op;
600e851b 6372 enum machine_mode mode ATTRIBUTE_UNUSED;
d1bd513e 6373{
6374 int count = XVECLEN (op, 0) - 1;
30c5e279 6375 unsigned int src_regno;
d1bd513e 6376 rtx dest_addr;
6377 int i;
6378
6379 /* Perform a quick check so we don't blow up below. */
6380 if (count <= 1
6381 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6382 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
6383 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
6384 return 0;
6385
6386 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6387 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
6388
6389 for (i = 1; i < count; i++)
6390 {
6391 rtx elt = XVECEXP (op, 0, i + 1);
6392
6393 if (GET_CODE (elt) != SET
6394 || GET_CODE (SET_SRC (elt)) != REG
6395 || GET_MODE (SET_SRC (elt)) != SImode
6396 || REGNO (SET_SRC (elt)) != src_regno + i
6397 || GET_CODE (SET_DEST (elt)) != MEM
6398 || GET_MODE (SET_DEST (elt)) != SImode
6399 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
6400 || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
6401 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
6402 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4)
6403 return 0;
6404 }
6405
6406 return 1;
6407}
bbd21807 6408
4fc6182c 6409/* Return a string to perform a load_multiple operation.
6410 operands[0] is the vector.
6411 operands[1] is the source address.
6412 operands[2] is the first destination register. */
6413
6414const char *
6415rs6000_output_load_multiple (operands)
5808379b 6416 rtx operands[3];
4fc6182c 6417{
6418 /* We have to handle the case where the pseudo used to contain the address
6419 is assigned to one of the output registers. */
6420 int i, j;
6421 int words = XVECLEN (operands[0], 0);
6422 rtx xop[10];
6423
6424 if (XVECLEN (operands[0], 0) == 1)
6425 return "{l|lwz} %2,0(%1)";
6426
6427 for (i = 0; i < words; i++)
6428 if (refers_to_regno_p (REGNO (operands[2]) + i,
6429 REGNO (operands[2]) + i + 1, operands[1], 0))
6430 {
6431 if (i == words-1)
6432 {
6433 xop[0] = GEN_INT (4 * (words-1));
6434 xop[1] = operands[1];
6435 xop[2] = operands[2];
6436 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
6437 return "";
6438 }
6439 else if (i == 0)
6440 {
6441 xop[0] = GEN_INT (4 * (words-1));
6442 xop[1] = operands[1];
6443 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
6444 output_asm_insn ("{cal %1,4(%1)|addi %1,%1,4}\n\t{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,-4(%1)", xop);
6445 return "";
6446 }
6447 else
6448 {
6449 for (j = 0; j < words; j++)
6450 if (j != i)
6451 {
6452 xop[0] = GEN_INT (j * 4);
6453 xop[1] = operands[1];
6454 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
6455 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
6456 }
6457 xop[0] = GEN_INT (i * 4);
6458 xop[1] = operands[1];
6459 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
6460 return "";
6461 }
6462 }
6463
6464 return "{lsi|lswi} %2,%1,%N0";
6465}
6466
bb78803e 6467/* Return 1 for a parallel vrsave operation. */
6468
6469int
6470vrsave_operation (op, mode)
6471 rtx op;
6472 enum machine_mode mode ATTRIBUTE_UNUSED;
6473{
6474 int count = XVECLEN (op, 0);
6475 unsigned int dest_regno, src_regno;
6476 int i;
6477
6478 if (count <= 1
6479 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6480 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
3affb0ca 6481 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC_VOLATILE)
bb78803e 6482 return 0;
6483
6484 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6485 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6486
6487 if (dest_regno != VRSAVE_REGNO
6488 && src_regno != VRSAVE_REGNO)
6489 return 0;
6490
6491 for (i = 1; i < count; i++)
6492 {
6493 rtx elt = XVECEXP (op, 0, i);
6494
43b7e951 6495 if (GET_CODE (elt) != CLOBBER
6496 && GET_CODE (elt) != SET)
bb78803e 6497 return 0;
6498 }
6499
6500 return 1;
6501}
6502
970e222f 6503/* Return 1 for an PARALLEL suitable for mtcrf. */
bbd21807 6504
6505int
6506mtcrf_operation (op, mode)
6507 rtx op;
6508 enum machine_mode mode ATTRIBUTE_UNUSED;
6509{
6510 int count = XVECLEN (op, 0);
6511 int i;
bbd21807 6512 rtx src_reg;
6513
6514 /* Perform a quick check so we don't blow up below. */
90e1e7af 6515 if (count < 1
6516 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6517 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC
6518 || XVECLEN (SET_SRC (XVECEXP (op, 0, 0)), 0) != 2)
bbd21807 6519 return 0;
90e1e7af 6520 src_reg = XVECEXP (SET_SRC (XVECEXP (op, 0, 0)), 0, 0);
bbd21807 6521
6522 if (GET_CODE (src_reg) != REG
6523 || GET_MODE (src_reg) != SImode
6524 || ! INT_REGNO_P (REGNO (src_reg)))
6525 return 0;
6526
90e1e7af 6527 for (i = 0; i < count; i++)
bbd21807 6528 {
6529 rtx exp = XVECEXP (op, 0, i);
6530 rtx unspec;
6531 int maskval;
6532
6533 if (GET_CODE (exp) != SET
6534 || GET_CODE (SET_DEST (exp)) != REG
6535 || GET_MODE (SET_DEST (exp)) != CCmode
6536 || ! CR_REGNO_P (REGNO (SET_DEST (exp))))
6537 return 0;
6538 unspec = SET_SRC (exp);
6539 maskval = 1 << (MAX_CR_REGNO - REGNO (SET_DEST (exp)));
bbd21807 6540
6541 if (GET_CODE (unspec) != UNSPEC
6542 || XINT (unspec, 1) != 20
6543 || XVECLEN (unspec, 0) != 2
6544 || XVECEXP (unspec, 0, 0) != src_reg
6545 || GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT
6546 || INTVAL (XVECEXP (unspec, 0, 1)) != maskval)
6547 return 0;
6548 }
90e1e7af 6549 return 1;
bbd21807 6550}
6551
970e222f 6552/* Return 1 for an PARALLEL suitable for lmw. */
bbd21807 6553
6554int
6555lmw_operation (op, mode)
6556 rtx op;
6557 enum machine_mode mode ATTRIBUTE_UNUSED;
6558{
6559 int count = XVECLEN (op, 0);
30c5e279 6560 unsigned int dest_regno;
bbd21807 6561 rtx src_addr;
30c5e279 6562 unsigned int base_regno;
bbd21807 6563 HOST_WIDE_INT offset;
6564 int i;
6565
6566 /* Perform a quick check so we don't blow up below. */
6567 if (count <= 1
6568 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6569 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
6570 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
6571 return 0;
6572
6573 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6574 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
6575
6576 if (dest_regno > 31
30c5e279 6577 || count != 32 - (int) dest_regno)
bbd21807 6578 return 0;
6579
4bbdf529 6580 if (LEGITIMATE_INDIRECT_ADDRESS_P (src_addr, 0))
bbd21807 6581 {
6582 offset = 0;
6583 base_regno = REGNO (src_addr);
6584 if (base_regno == 0)
6585 return 0;
6586 }
4bbdf529 6587 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, src_addr, 0))
bbd21807 6588 {
6589 offset = INTVAL (XEXP (src_addr, 1));
6590 base_regno = REGNO (XEXP (src_addr, 0));
6591 }
6592 else
6593 return 0;
6594
6595 for (i = 0; i < count; i++)
6596 {
6597 rtx elt = XVECEXP (op, 0, i);
6598 rtx newaddr;
6599 rtx addr_reg;
6600 HOST_WIDE_INT newoffset;
6601
6602 if (GET_CODE (elt) != SET
6603 || GET_CODE (SET_DEST (elt)) != REG
6604 || GET_MODE (SET_DEST (elt)) != SImode
6605 || REGNO (SET_DEST (elt)) != dest_regno + i
6606 || GET_CODE (SET_SRC (elt)) != MEM
6607 || GET_MODE (SET_SRC (elt)) != SImode)
6608 return 0;
6609 newaddr = XEXP (SET_SRC (elt), 0);
4bbdf529 6610 if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
bbd21807 6611 {
6612 newoffset = 0;
6613 addr_reg = newaddr;
6614 }
4bbdf529 6615 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
bbd21807 6616 {
6617 addr_reg = XEXP (newaddr, 0);
6618 newoffset = INTVAL (XEXP (newaddr, 1));
6619 }
6620 else
6621 return 0;
6622 if (REGNO (addr_reg) != base_regno
6623 || newoffset != offset + 4 * i)
6624 return 0;
6625 }
6626
6627 return 1;
6628}
6629
970e222f 6630/* Return 1 for an PARALLEL suitable for stmw. */
bbd21807 6631
6632int
6633stmw_operation (op, mode)
6634 rtx op;
6635 enum machine_mode mode ATTRIBUTE_UNUSED;
6636{
6637 int count = XVECLEN (op, 0);
30c5e279 6638 unsigned int src_regno;
bbd21807 6639 rtx dest_addr;
30c5e279 6640 unsigned int base_regno;
bbd21807 6641 HOST_WIDE_INT offset;
6642 int i;
6643
6644 /* Perform a quick check so we don't blow up below. */
6645 if (count <= 1
6646 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6647 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
6648 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
6649 return 0;
6650
6651 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6652 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
6653
6654 if (src_regno > 31
30c5e279 6655 || count != 32 - (int) src_regno)
bbd21807 6656 return 0;
6657
4bbdf529 6658 if (LEGITIMATE_INDIRECT_ADDRESS_P (dest_addr, 0))
bbd21807 6659 {
6660 offset = 0;
6661 base_regno = REGNO (dest_addr);
6662 if (base_regno == 0)
6663 return 0;
6664 }
4bbdf529 6665 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, dest_addr, 0))
bbd21807 6666 {
6667 offset = INTVAL (XEXP (dest_addr, 1));
6668 base_regno = REGNO (XEXP (dest_addr, 0));
6669 }
6670 else
6671 return 0;
6672
6673 for (i = 0; i < count; i++)
6674 {
6675 rtx elt = XVECEXP (op, 0, i);
6676 rtx newaddr;
6677 rtx addr_reg;
6678 HOST_WIDE_INT newoffset;
6679
6680 if (GET_CODE (elt) != SET
6681 || GET_CODE (SET_SRC (elt)) != REG
6682 || GET_MODE (SET_SRC (elt)) != SImode
6683 || REGNO (SET_SRC (elt)) != src_regno + i
6684 || GET_CODE (SET_DEST (elt)) != MEM
6685 || GET_MODE (SET_DEST (elt)) != SImode)
6686 return 0;
6687 newaddr = XEXP (SET_DEST (elt), 0);
4bbdf529 6688 if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
bbd21807 6689 {
6690 newoffset = 0;
6691 addr_reg = newaddr;
6692 }
4bbdf529 6693 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
bbd21807 6694 {
6695 addr_reg = XEXP (newaddr, 0);
6696 newoffset = INTVAL (XEXP (newaddr, 1));
6697 }
6698 else
6699 return 0;
6700 if (REGNO (addr_reg) != base_regno
6701 || newoffset != offset + 4 * i)
6702 return 0;
6703 }
6704
6705 return 1;
6706}
d1bd513e 6707\f
970e222f 6708/* A validation routine: say whether CODE, a condition code, and MODE
6709 match. The other alternatives either don't make sense or should
6710 never be generated. */
ac313e39 6711
ac313e39 6712static void
6713validate_condition_mode (code, mode)
6714 enum rtx_code code;
6715 enum machine_mode mode;
6716{
6717 if (GET_RTX_CLASS (code) != '<'
6718 || GET_MODE_CLASS (mode) != MODE_CC)
6719 abort ();
6720
6721 /* These don't make sense. */
6722 if ((code == GT || code == LT || code == GE || code == LE)
6723 && mode == CCUNSmode)
6724 abort ();
6725
6726 if ((code == GTU || code == LTU || code == GEU || code == LEU)
6727 && mode != CCUNSmode)
6728 abort ();
6729
6730 if (mode != CCFPmode
6731 && (code == ORDERED || code == UNORDERED
6732 || code == UNEQ || code == LTGT
6733 || code == UNGT || code == UNLT
6734 || code == UNGE || code == UNLE))
970e222f 6735 abort ();
ac313e39 6736
7f3be425 6737 /* These should never be generated except for
2849611a 6738 flag_unsafe_math_optimizations and flag_finite_math_only. */
ac313e39 6739 if (mode == CCFPmode
7f3be425 6740 && ! flag_unsafe_math_optimizations
2849611a 6741 && ! flag_finite_math_only
ac313e39 6742 && (code == LE || code == GE
6743 || code == UNEQ || code == LTGT
6744 || code == UNGT || code == UNLT))
6745 abort ();
6746
6747 /* These are invalid; the information is not there. */
6748 if (mode == CCEQmode
6749 && code != EQ && code != NE)
6750 abort ();
6751}
6752
d1bd513e 6753/* Return 1 if OP is a comparison operation that is valid for a branch insn.
6754 We only check the opcode against the mode of the CC value here. */
6755
6756int
6757branch_comparison_operator (op, mode)
773e893a 6758 rtx op;
600e851b 6759 enum machine_mode mode ATTRIBUTE_UNUSED;
d1bd513e 6760{
6761 enum rtx_code code = GET_CODE (op);
6762 enum machine_mode cc_mode;
6763
6764 if (GET_RTX_CLASS (code) != '<')
6765 return 0;
6766
6767 cc_mode = GET_MODE (XEXP (op, 0));
6768 if (GET_MODE_CLASS (cc_mode) != MODE_CC)
6769 return 0;
6770
ac313e39 6771 validate_condition_mode (code, cc_mode);
d1bd513e 6772
ac313e39 6773 return 1;
6774}
6775
6776/* Return 1 if OP is a comparison operation that is valid for a branch
6777 insn and which is true if the corresponding bit in the CC register
6778 is set. */
6779
6780int
6781branch_positive_comparison_operator (op, mode)
773e893a 6782 rtx op;
ac313e39 6783 enum machine_mode mode;
6784{
6785 enum rtx_code code;
6786
6787 if (! branch_comparison_operator (op, mode))
d1bd513e 6788 return 0;
6789
ac313e39 6790 code = GET_CODE (op);
6791 return (code == EQ || code == LT || code == GT
f19493d5 6792 || (TARGET_SPE && TARGET_HARD_FLOAT && !TARGET_FPRS && code == NE)
ac313e39 6793 || code == LTU || code == GTU
6794 || code == UNORDERED);
d1bd513e 6795}
6796
6797/* Return 1 if OP is a comparison operation that is valid for an scc insn.
6798 We check the opcode against the mode of the CC value and disallow EQ or
6799 NE comparisons for integers. */
6800
6801int
6802scc_comparison_operator (op, mode)
773e893a 6803 rtx op;
d1bd513e 6804 enum machine_mode mode;
6805{
6806 enum rtx_code code = GET_CODE (op);
6807 enum machine_mode cc_mode;
6808
6809 if (GET_MODE (op) != mode && mode != VOIDmode)
6810 return 0;
6811
6812 if (GET_RTX_CLASS (code) != '<')
6813 return 0;
6814
6815 cc_mode = GET_MODE (XEXP (op, 0));
6816 if (GET_MODE_CLASS (cc_mode) != MODE_CC)
6817 return 0;
6818
ac313e39 6819 validate_condition_mode (code, cc_mode);
d1bd513e 6820
ac313e39 6821 if (code == NE && cc_mode != CCFPmode)
3b82fbed 6822 return 0;
6823
d1bd513e 6824 return 1;
6825}
9e5192ed 6826
6827int
6828trap_comparison_operator (op, mode)
6829 rtx op;
6830 enum machine_mode mode;
6831{
6832 if (mode != VOIDmode && mode != GET_MODE (op))
6833 return 0;
ac313e39 6834 return GET_RTX_CLASS (GET_CODE (op)) == '<';
9e5192ed 6835}
3454f5f0 6836
6837int
6838boolean_operator (op, mode)
6839 rtx op;
6840 enum machine_mode mode ATTRIBUTE_UNUSED;
6841{
6842 enum rtx_code code = GET_CODE (op);
6843 return (code == AND || code == IOR || code == XOR);
6844}
6167435d 6845
6846int
6847boolean_or_operator (op, mode)
6848 rtx op;
6849 enum machine_mode mode ATTRIBUTE_UNUSED;
6850{
6851 enum rtx_code code = GET_CODE (op);
6852 return (code == IOR || code == XOR);
6853}
ba261041 6854
6855int
6856min_max_operator (op, mode)
6857 rtx op;
6858 enum machine_mode mode ATTRIBUTE_UNUSED;
6859{
6860 enum rtx_code code = GET_CODE (op);
6861 return (code == SMIN || code == SMAX || code == UMIN || code == UMAX);
6862}
d1bd513e 6863\f
6864/* Return 1 if ANDOP is a mask that has no bits on that are not in the
6865 mask required to convert the result of a rotate insn into a shift
6007cde0 6866 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
d1bd513e 6867
6868int
6869includes_lshift_p (shiftop, andop)
773e893a 6870 rtx shiftop;
6871 rtx andop;
d1bd513e 6872{
30c5e279 6873 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
6874
6875 shift_mask <<= INTVAL (shiftop);
d1bd513e 6876
6007cde0 6877 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
d1bd513e 6878}
6879
6880/* Similar, but for right shift. */
6881
6882int
6883includes_rshift_p (shiftop, andop)
773e893a 6884 rtx shiftop;
6885 rtx andop;
d1bd513e 6886{
71fe222a 6887 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
d1bd513e 6888
6889 shift_mask >>= INTVAL (shiftop);
6890
6007cde0 6891 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
30c5e279 6892}
6893
8ba93479 6894/* Return 1 if ANDOP is a mask suitable for use with an rldic insn
6895 to perform a left shift. It must have exactly SHIFTOP least
6896 signifigant 0's, then one or more 1's, then zero or more 0's. */
30c5e279 6897
6898int
8ba93479 6899includes_rldic_lshift_p (shiftop, andop)
773e893a 6900 rtx shiftop;
6901 rtx andop;
30c5e279 6902{
8ba93479 6903 if (GET_CODE (andop) == CONST_INT)
6904 {
8dd59a84 6905 HOST_WIDE_INT c, lsb, shift_mask;
30c5e279 6906
8ba93479 6907 c = INTVAL (andop);
8dd59a84 6908 if (c == 0 || c == ~0)
8ba93479 6909 return 0;
30c5e279 6910
8dd59a84 6911 shift_mask = ~0;
8ba93479 6912 shift_mask <<= INTVAL (shiftop);
6913
6914 /* Find the least signifigant one bit. */
6915 lsb = c & -c;
6916
6917 /* It must coincide with the LSB of the shift mask. */
6918 if (-lsb != shift_mask)
6919 return 0;
30c5e279 6920
8ba93479 6921 /* Invert to look for the next transition (if any). */
6922 c = ~c;
6923
6924 /* Remove the low group of ones (originally low group of zeros). */
6925 c &= -lsb;
6926
6927 /* Again find the lsb, and check we have all 1's above. */
6928 lsb = c & -c;
6929 return c == -lsb;
6930 }
6931 else if (GET_CODE (andop) == CONST_DOUBLE
6932 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
6933 {
8dd59a84 6934 HOST_WIDE_INT low, high, lsb;
6935 HOST_WIDE_INT shift_mask_low, shift_mask_high;
8ba93479 6936
6937 low = CONST_DOUBLE_LOW (andop);
6938 if (HOST_BITS_PER_WIDE_INT < 64)
6939 high = CONST_DOUBLE_HIGH (andop);
6940
6941 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
8dd59a84 6942 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
8ba93479 6943 return 0;
6944
6945 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
6946 {
8dd59a84 6947 shift_mask_high = ~0;
8ba93479 6948 if (INTVAL (shiftop) > 32)
6949 shift_mask_high <<= INTVAL (shiftop) - 32;
6950
6951 lsb = high & -high;
6952
6953 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
6954 return 0;
6955
6956 high = ~high;
6957 high &= -lsb;
6958
6959 lsb = high & -high;
6960 return high == -lsb;
6961 }
6962
8dd59a84 6963 shift_mask_low = ~0;
8ba93479 6964 shift_mask_low <<= INTVAL (shiftop);
6965
6966 lsb = low & -low;
6967
6968 if (-lsb != shift_mask_low)
6969 return 0;
6970
6971 if (HOST_BITS_PER_WIDE_INT < 64)
6972 high = ~high;
6973 low = ~low;
6974 low &= -lsb;
6975
6976 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
6977 {
6978 lsb = high & -high;
6979 return high == -lsb;
6980 }
6981
6982 lsb = low & -low;
6983 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
6984 }
6985 else
6986 return 0;
6987}
30c5e279 6988
8ba93479 6989/* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
6990 to perform a left shift. It must have SHIFTOP or more least
6991 signifigant 0's, with the remainder of the word 1's. */
30c5e279 6992
8ba93479 6993int
6994includes_rldicr_lshift_p (shiftop, andop)
773e893a 6995 rtx shiftop;
6996 rtx andop;
8ba93479 6997{
30c5e279 6998 if (GET_CODE (andop) == CONST_INT)
8ba93479 6999 {
8dd59a84 7000 HOST_WIDE_INT c, lsb, shift_mask;
8ba93479 7001
8dd59a84 7002 shift_mask = ~0;
8ba93479 7003 shift_mask <<= INTVAL (shiftop);
7004 c = INTVAL (andop);
7005
7006 /* Find the least signifigant one bit. */
7007 lsb = c & -c;
7008
7009 /* It must be covered by the shift mask.
970e222f 7010 This test also rejects c == 0. */
8ba93479 7011 if ((lsb & shift_mask) == 0)
7012 return 0;
7013
7014 /* Check we have all 1's above the transition, and reject all 1's. */
7015 return c == -lsb && lsb != 1;
7016 }
7017 else if (GET_CODE (andop) == CONST_DOUBLE
7018 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
7019 {
8dd59a84 7020 HOST_WIDE_INT low, lsb, shift_mask_low;
8ba93479 7021
7022 low = CONST_DOUBLE_LOW (andop);
7023
7024 if (HOST_BITS_PER_WIDE_INT < 64)
7025 {
8dd59a84 7026 HOST_WIDE_INT high, shift_mask_high;
8ba93479 7027
7028 high = CONST_DOUBLE_HIGH (andop);
7029
7030 if (low == 0)
7031 {
8dd59a84 7032 shift_mask_high = ~0;
8ba93479 7033 if (INTVAL (shiftop) > 32)
7034 shift_mask_high <<= INTVAL (shiftop) - 32;
7035
7036 lsb = high & -high;
7037
7038 if ((lsb & shift_mask_high) == 0)
7039 return 0;
7040
7041 return high == -lsb;
7042 }
7043 if (high != ~0)
7044 return 0;
7045 }
7046
8dd59a84 7047 shift_mask_low = ~0;
8ba93479 7048 shift_mask_low <<= INTVAL (shiftop);
7049
7050 lsb = low & -low;
7051
7052 if ((lsb & shift_mask_low) == 0)
7053 return 0;
7054
7055 return low == -lsb && lsb != 1;
7056 }
30c5e279 7057 else
8ba93479 7058 return 0;
d1bd513e 7059}
2b5ad2e9 7060
7061/* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
7062 for lfq and stfq insns.
7063
7064 Note reg1 and reg2 *must* be hard registers. To be sure we will
7065 abort if we are passed pseudo registers. */
7066
7067int
7068registers_ok_for_quad_peep (reg1, reg2)
7069 rtx reg1, reg2;
7070{
7071 /* We might have been passed a SUBREG. */
7072 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
7073 return 0;
7074
7075 return (REGNO (reg1) == REGNO (reg2) - 1);
7076}
7077
970e222f 7078/* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
7079 addr1 and addr2 must be in consecutive memory locations
7080 (addr2 == addr1 + 8). */
2b5ad2e9 7081
7082int
7083addrs_ok_for_quad_peep (addr1, addr2)
773e893a 7084 rtx addr1;
7085 rtx addr2;
2b5ad2e9 7086{
30c5e279 7087 unsigned int reg1;
2b5ad2e9 7088 int offset1;
7089
7090 /* Extract an offset (if used) from the first addr. */
7091 if (GET_CODE (addr1) == PLUS)
7092 {
7093 /* If not a REG, return zero. */
7094 if (GET_CODE (XEXP (addr1, 0)) != REG)
7095 return 0;
7096 else
7097 {
7098 reg1 = REGNO (XEXP (addr1, 0));
7099 /* The offset must be constant! */
7100 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
7101 return 0;
7102 offset1 = INTVAL (XEXP (addr1, 1));
7103 }
7104 }
7105 else if (GET_CODE (addr1) != REG)
7106 return 0;
7107 else
7108 {
7109 reg1 = REGNO (addr1);
7110 /* This was a simple (mem (reg)) expression. Offset is 0. */
7111 offset1 = 0;
7112 }
7113
03bb02b5 7114 /* Make sure the second address is a (mem (plus (reg) (const_int))). */
2b5ad2e9 7115 if (GET_CODE (addr2) != PLUS)
7116 return 0;
7117
7118 if (GET_CODE (XEXP (addr2, 0)) != REG
7119 || GET_CODE (XEXP (addr2, 1)) != CONST_INT)
7120 return 0;
7121
7122 if (reg1 != REGNO (XEXP (addr2, 0)))
7123 return 0;
7124
7125 /* The offset for the second addr must be 8 more than the first addr. */
7126 if (INTVAL (XEXP (addr2, 1)) != offset1 + 8)
7127 return 0;
7128
7129 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
7130 instructions. */
7131 return 1;
7132}
d1bd513e 7133\f
7134/* Return the register class of a scratch register needed to copy IN into
7135 or out of a register in CLASS in MODE. If it can be done directly,
7136 NO_REGS is returned. */
7137
7138enum reg_class
7139secondary_reload_class (class, mode, in)
7140 enum reg_class class;
600e851b 7141 enum machine_mode mode ATTRIBUTE_UNUSED;
d1bd513e 7142 rtx in;
7143{
879c6e0a 7144 int regno;
d1bd513e 7145
be723adf 7146 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN && flag_pic))
7147 {
7148 /* We cannot copy a symbolic operand directly into anything
7149 other than BASE_REGS for TARGET_ELF. So indicate that a
7150 register from BASE_REGS is needed as an intermediate
7151 register.
7152
7153 On Darwin, pic addresses require a load from memory, which
7154 needs a base register. */
7155 if (class != BASE_REGS
7156 && (GET_CODE (in) == SYMBOL_REF
7157 || GET_CODE (in) == HIGH
7158 || GET_CODE (in) == LABEL_REF
7159 || GET_CODE (in) == CONST))
7160 return BASE_REGS;
7161 }
8cffd78a 7162
879c6e0a 7163 if (GET_CODE (in) == REG)
7164 {
7165 regno = REGNO (in);
7166 if (regno >= FIRST_PSEUDO_REGISTER)
7167 {
7168 regno = true_regnum (in);
7169 if (regno >= FIRST_PSEUDO_REGISTER)
7170 regno = -1;
7171 }
7172 }
7173 else if (GET_CODE (in) == SUBREG)
7174 {
7175 regno = true_regnum (in);
7176 if (regno >= FIRST_PSEUDO_REGISTER)
7177 regno = -1;
7178 }
7179 else
7180 regno = -1;
7181
d1bd513e 7182 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
7183 into anything. */
7184 if (class == GENERAL_REGS || class == BASE_REGS
7185 || (regno >= 0 && INT_REGNO_P (regno)))
7186 return NO_REGS;
7187
7188 /* Constants, memory, and FP registers can go into FP registers. */
7189 if ((regno == -1 || FP_REGNO_P (regno))
7190 && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
7191 return NO_REGS;
7192
500c7157 7193 /* Memory, and AltiVec registers can go into AltiVec registers. */
7194 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
7195 && class == ALTIVEC_REGS)
7196 return NO_REGS;
7197
d1bd513e 7198 /* We can copy among the CR registers. */
7199 if ((class == CR_REGS || class == CR0_REGS)
7200 && regno >= 0 && CR_REGNO_P (regno))
7201 return NO_REGS;
7202
7203 /* Otherwise, we need GENERAL_REGS. */
7204 return GENERAL_REGS;
7205}
7206\f
7207/* Given a comparison operation, return the bit number in CCR to test. We
7208 know this is a valid comparison.
7209
7210 SCC_P is 1 if this is for an scc. That means that %D will have been
7211 used instead of %C, so the bits will be in different places.
7212
bdf74c8a 7213 Return -1 if OP isn't a valid comparison for some reason. */
d1bd513e 7214
7215int
7216ccr_bit (op, scc_p)
773e893a 7217 rtx op;
d1bd513e 7218 int scc_p;
7219{
7220 enum rtx_code code = GET_CODE (op);
7221 enum machine_mode cc_mode;
7222 int cc_regnum;
7223 int base_bit;
bbd21807 7224 rtx reg;
d1bd513e 7225
7226 if (GET_RTX_CLASS (code) != '<')
7227 return -1;
7228
bbd21807 7229 reg = XEXP (op, 0);
7230
7231 if (GET_CODE (reg) != REG
7232 || ! CR_REGNO_P (REGNO (reg)))
7233 abort ();
7234
7235 cc_mode = GET_MODE (reg);
7236 cc_regnum = REGNO (reg);
7237 base_bit = 4 * (cc_regnum - CR0_REGNO);
d1bd513e 7238
ac313e39 7239 validate_condition_mode (code, cc_mode);
3b82fbed 7240
d1bd513e 7241 switch (code)
7242 {
7243 case NE:
f19493d5 7244 if (TARGET_SPE && TARGET_HARD_FLOAT && cc_mode == CCFPmode)
7245 return base_bit + 1;
d1bd513e 7246 return scc_p ? base_bit + 3 : base_bit + 2;
7247 case EQ:
f19493d5 7248 if (TARGET_SPE && TARGET_HARD_FLOAT && cc_mode == CCFPmode)
7249 return base_bit + 1;
d1bd513e 7250 return base_bit + 2;
1cf15572 7251 case GT: case GTU: case UNLE:
d1bd513e 7252 return base_bit + 1;
1cf15572 7253 case LT: case LTU: case UNGE:
d1bd513e 7254 return base_bit;
1cf15572 7255 case ORDERED: case UNORDERED:
7256 return base_bit + 3;
d1bd513e 7257
7258 case GE: case GEU:
ac313e39 7259 /* If scc, we will have done a cror to put the bit in the
d1bd513e 7260 unordered position. So test that bit. For integer, this is ! LT
7261 unless this is an scc insn. */
ac313e39 7262 return scc_p ? base_bit + 3 : base_bit;
d1bd513e 7263
7264 case LE: case LEU:
ac313e39 7265 return scc_p ? base_bit + 3 : base_bit + 1;
1cf15572 7266
d1bd513e 7267 default:
7268 abort ();
7269 }
7270}
1e1ee4b0 7271\f
38794c37 7272/* Return the GOT register. */
1e1ee4b0 7273
7274struct rtx_def *
7275rs6000_got_register (value)
837b446a 7276 rtx value ATTRIBUTE_UNUSED;
1e1ee4b0 7277{
970e222f 7278 /* The second flow pass currently (June 1999) can't update
7279 regs_ever_live without disturbing other parts of the compiler, so
7280 update it here to make the prolog/epilogue code happy. */
479d644a 7281 if (no_new_pseudos && ! regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM])
7282 regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
1e1ee4b0 7283
38794c37 7284 current_function_uses_pic_offset_table = 1;
91452706 7285
1e1ee4b0 7286 return pic_offset_table_rtx;
7287}
33e46abb 7288\f
1f3233d1 7289/* Function to init struct machine_function.
7290 This will be called, via a pointer variable,
7291 from push_function_context. */
33e46abb 7292
1f3233d1 7293static struct machine_function *
7294rs6000_init_machine_status ()
33e46abb 7295{
1f3233d1 7296 return ggc_alloc_cleared (sizeof (machine_function));
33e46abb 7297}
d1bd513e 7298\f
59a5187e 7299/* These macros test for integers and extract the low-order bits. */
7300#define INT_P(X) \
7301((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
7302 && GET_MODE (X) == VOIDmode)
7303
7304#define INT_LOWPART(X) \
7305 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
7306
7307int
7308extract_MB (op)
7309 rtx op;
7310{
7311 int i;
7312 unsigned long val = INT_LOWPART (op);
7313
7314 /* If the high bit is zero, the value is the first 1 bit we find
7315 from the left. */
7316 if ((val & 0x80000000) == 0)
7317 {
7318 if ((val & 0xffffffff) == 0)
7319 abort ();
7320
7321 i = 1;
7322 while (((val <<= 1) & 0x80000000) == 0)
7323 ++i;
7324 return i;
7325 }
7326
7327 /* If the high bit is set and the low bit is not, or the mask is all
7328 1's, the value is zero. */
7329 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
7330 return 0;
7331
7332 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
7333 from the right. */
7334 i = 31;
7335 while (((val >>= 1) & 1) != 0)
7336 --i;
7337
7338 return i;
7339}
7340
7341int
7342extract_ME (op)
7343 rtx op;
7344{
7345 int i;
7346 unsigned long val = INT_LOWPART (op);
7347
7348 /* If the low bit is zero, the value is the first 1 bit we find from
7349 the right. */
7350 if ((val & 1) == 0)
7351 {
7352 if ((val & 0xffffffff) == 0)
7353 abort ();
7354
7355 i = 30;
7356 while (((val >>= 1) & 1) == 0)
7357 --i;
7358
7359 return i;
7360 }
7361
7362 /* If the low bit is set and the high bit is not, or the mask is all
7363 1's, the value is 31. */
7364 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
7365 return 31;
7366
7367 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
7368 from the left. */
7369 i = 0;
7370 while (((val <<= 1) & 0x80000000) != 0)
7371 ++i;
7372
7373 return i;
7374}
7375
d1bd513e 7376/* Print an operand. Recognize special options, documented below. */
7377
bda6fa4d 7378#if TARGET_ELF
d72e2a6e 7379#define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
4aab7421 7380#define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
1c9c4ece 7381#else
7382#define SMALL_DATA_RELOC "sda21"
4aab7421 7383#define SMALL_DATA_REG 0
1c9c4ece 7384#endif
7385
d1bd513e 7386void
7387print_operand (file, x, code)
7388 FILE *file;
7389 rtx x;
bbd21807 7390 int code;
d1bd513e 7391{
7392 int i;
8cda90b9 7393 HOST_WIDE_INT val;
59a5187e 7394 unsigned HOST_WIDE_INT uval;
d1bd513e 7395
7396 switch (code)
7397 {
dac3ecde 7398 case '.':
84f16e0b 7399 /* Write out an instruction after the call which may be replaced
7400 with glue code by the loader. This depends on the AIX version. */
7401 asm_fprintf (file, RS6000_CALL_GLUE);
dac3ecde 7402 return;
7403
4056df14 7404 /* %a is output_address. */
7405
e8555574 7406 case 'A':
7407 /* If X is a constant integer whose low-order 5 bits are zero,
7408 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
cba9c9bb 7409 in the AIX assembler where "sri" with a zero shift count
e931e2d9 7410 writes a trash instruction. */
e8555574 7411 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
cba9c9bb 7412 putc ('l', file);
e8555574 7413 else
cba9c9bb 7414 putc ('r', file);
e8555574 7415 return;
7416
7417 case 'b':
30c5e279 7418 /* If constant, low-order 16 bits of constant, unsigned.
7419 Otherwise, write normally. */
7420 if (INT_P (x))
7421 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
7422 else
7423 print_operand (file, x, 0);
7fb789c3 7424 return;
7425
8cda90b9 7426 case 'B':
7427 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
7428 for 64-bit mask direction. */
600e851b 7429 putc (((INT_LOWPART(x) & 1) == 0 ? 'r' : 'l'), file);
7e016b0b 7430 return;
8cda90b9 7431
4056df14 7432 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
7433 output_operand. */
7434
e8555574 7435 case 'D':
ac313e39 7436 /* There used to be a comment for 'C' reading "This is an
7437 optional cror needed for certain floating-point
7438 comparisons. Otherwise write nothing." */
7439
e8555574 7440 /* Similar, except that this is for an scc, so we must be able to
7441 encode the test in a single bit that is one. We do the above
7442 for any LE, GE, GEU, or LEU and invert the bit for NE. */
7443 if (GET_CODE (x) == LE || GET_CODE (x) == GE
7444 || GET_CODE (x) == LEU || GET_CODE (x) == GEU)
7445 {
bbd21807 7446 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
e8555574 7447
7448 fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3,
7449 base_bit + 2,
7450 base_bit + (GET_CODE (x) == GE || GET_CODE (x) == GEU));
7451 }
7452
7453 else if (GET_CODE (x) == NE)
7454 {
bbd21807 7455 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
e8555574 7456
7457 fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 3,
7458 base_bit + 2, base_bit + 2);
7459 }
f19493d5 7460 else if (TARGET_SPE && TARGET_HARD_FLOAT
7461 && GET_CODE (x) == EQ
7462 && GET_MODE (XEXP (x, 0)) == CCFPmode)
7463 {
7464 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
7465
7466 fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 1,
7467 base_bit + 1, base_bit + 1);
7468 }
e8555574 7469 return;
7470
7471 case 'E':
ac313e39 7472 /* X is a CR register. Print the number of the EQ bit of the CR */
e8555574 7473 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7474 output_operand_lossage ("invalid %%E value");
bd4d5fb5 7475 else
ac313e39 7476 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
84f16e0b 7477 return;
e8555574 7478
7479 case 'f':
7480 /* X is a CR register. Print the shift count needed to move it
7481 to the high-order four bits. */
7482 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7483 output_operand_lossage ("invalid %%f value");
7484 else
bbd21807 7485 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
e8555574 7486 return;
7487
7488 case 'F':
7489 /* Similar, but print the count for the rotate in the opposite
7490 direction. */
7491 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7492 output_operand_lossage ("invalid %%F value");
7493 else
bbd21807 7494 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
e8555574 7495 return;
7496
7497 case 'G':
7498 /* X is a constant integer. If it is negative, print "m",
28c2d844 7499 otherwise print "z". This is to make an aze or ame insn. */
e8555574 7500 if (GET_CODE (x) != CONST_INT)
7501 output_operand_lossage ("invalid %%G value");
7502 else if (INTVAL (x) >= 0)
cba9c9bb 7503 putc ('z', file);
e8555574 7504 else
cba9c9bb 7505 putc ('m', file);
e8555574 7506 return;
30c5e279 7507
d1bd513e 7508 case 'h':
970e222f 7509 /* If constant, output low-order five bits. Otherwise, write
7510 normally. */
d1bd513e 7511 if (INT_P (x))
837b446a 7512 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
d1bd513e 7513 else
7514 print_operand (file, x, 0);
7515 return;
7516
514fc272 7517 case 'H':
970e222f 7518 /* If constant, output low-order six bits. Otherwise, write
7519 normally. */
514fc272 7520 if (INT_P (x))
837b446a 7521 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
514fc272 7522 else
7523 print_operand (file, x, 0);
7524 return;
7525
e8555574 7526 case 'I':
7527 /* Print `i' if this is a constant, else nothing. */
d1bd513e 7528 if (INT_P (x))
cba9c9bb 7529 putc ('i', file);
d1bd513e 7530 return;
7531
e8555574 7532 case 'j':
7533 /* Write the bit number in CCR for jump. */
7534 i = ccr_bit (x, 0);
7535 if (i == -1)
7536 output_operand_lossage ("invalid %%j code");
d1bd513e 7537 else
e8555574 7538 fprintf (file, "%d", i);
d1bd513e 7539 return;
7540
e8555574 7541 case 'J':
7542 /* Similar, but add one for shift count in rlinm for scc and pass
7543 scc flag to `ccr_bit'. */
7544 i = ccr_bit (x, 1);
7545 if (i == -1)
7546 output_operand_lossage ("invalid %%J code");
7547 else
7a913256 7548 /* If we want bit 31, write a shift count of zero, not 32. */
7549 fprintf (file, "%d", i == 31 ? 0 : i + 1);
d1bd513e 7550 return;
7551
e8555574 7552 case 'k':
7553 /* X must be a constant. Write the 1's complement of the
7554 constant. */
d1bd513e 7555 if (! INT_P (x))
e8555574 7556 output_operand_lossage ("invalid %%k value");
30c5e279 7557 else
7558 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
d1bd513e 7559 return;
7560
4056df14 7561 case 'K':
bbd21807 7562 /* X must be a symbolic constant on ELF. Write an
7563 expression suitable for an 'addi' that adds in the low 16
7564 bits of the MEM. */
7565 if (GET_CODE (x) != CONST)
7566 {
7567 print_operand_address (file, x);
7568 fputs ("@l", file);
7569 }
7570 else
7571 {
7572 if (GET_CODE (XEXP (x, 0)) != PLUS
7573 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
7574 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
7575 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
c1bdf4c1 7576 output_operand_lossage ("invalid %%K value");
bbd21807 7577 print_operand_address (file, XEXP (XEXP (x, 0), 0));
7578 fputs ("@l", file);
cb5c5698 7579 /* For GNU as, there must be a non-alphanumeric character
7580 between 'l' and the number. The '-' is added by
7581 print_operand() already. */
7582 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
7583 fputs ("+", file);
bbd21807 7584 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
7585 }
4056df14 7586 return;
7587
7588 /* %l is output_asm_label. */
bbd21807 7589
e8555574 7590 case 'L':
7591 /* Write second word of DImode or DFmode reference. Works on register
7592 or non-indexed memory only. */
7593 if (GET_CODE (x) == REG)
00f76201 7594 fprintf (file, "%s", reg_names[REGNO (x) + 1]);
e8555574 7595 else if (GET_CODE (x) == MEM)
7596 {
7597 /* Handle possible auto-increment. Since it is pre-increment and
39a51f35 7598 we have already done it, we can just use an offset of word. */
e8555574 7599 if (GET_CODE (XEXP (x, 0)) == PRE_INC
7600 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
b244d4c7 7601 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
7602 UNITS_PER_WORD));
e8555574 7603 else
73680ce4 7604 output_address (XEXP (adjust_address_nv (x, SImode,
7605 UNITS_PER_WORD),
7606 0));
b244d4c7 7607
1c9c4ece 7608 if (small_data_operand (x, GET_MODE (x)))
4aab7421 7609 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7610 reg_names[SMALL_DATA_REG]);
e8555574 7611 }
d1bd513e 7612 return;
e8555574 7613
d1bd513e 7614 case 'm':
7615 /* MB value for a mask operand. */
6007cde0 7616 if (! mask_operand (x, SImode))
d1bd513e 7617 output_operand_lossage ("invalid %%m value");
7618
59a5187e 7619 fprintf (file, "%d", extract_MB (x));
d1bd513e 7620 return;
7621
7622 case 'M':
7623 /* ME value for a mask operand. */
6007cde0 7624 if (! mask_operand (x, SImode))
8cda90b9 7625 output_operand_lossage ("invalid %%M value");
d1bd513e 7626
59a5187e 7627 fprintf (file, "%d", extract_ME (x));
d1bd513e 7628 return;
7629
4056df14 7630 /* %n outputs the negative of its operand. */
7631
d1bd513e 7632 case 'N':
7633 /* Write the number of elements in the vector times 4. */
7634 if (GET_CODE (x) != PARALLEL)
7635 output_operand_lossage ("invalid %%N value");
30c5e279 7636 else
7637 fprintf (file, "%d", XVECLEN (x, 0) * 4);
d1bd513e 7638 return;
7639
7640 case 'O':
7641 /* Similar, but subtract 1 first. */
7642 if (GET_CODE (x) != PARALLEL)
39a51f35 7643 output_operand_lossage ("invalid %%O value");
30c5e279 7644 else
7645 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
d1bd513e 7646 return;
7647
e8555574 7648 case 'p':
7649 /* X is a CONST_INT that is a power of two. Output the logarithm. */
7650 if (! INT_P (x)
8eaf2dd1 7651 || INT_LOWPART (x) < 0
e8555574 7652 || (i = exact_log2 (INT_LOWPART (x))) < 0)
7653 output_operand_lossage ("invalid %%p value");
30c5e279 7654 else
7655 fprintf (file, "%d", i);
e8555574 7656 return;
7657
d1bd513e 7658 case 'P':
7659 /* The operand must be an indirect memory reference. The result
970e222f 7660 is the register number. */
d1bd513e 7661 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
7662 || REGNO (XEXP (x, 0)) >= 32)
7663 output_operand_lossage ("invalid %%P value");
30c5e279 7664 else
7665 fprintf (file, "%d", REGNO (XEXP (x, 0)));
d1bd513e 7666 return;
7667
3454f5f0 7668 case 'q':
7669 /* This outputs the logical code corresponding to a boolean
7670 expression. The expression may have one or both operands
ac313e39 7671 negated (if one, only the first one). For condition register
7672 logical operations, it will also treat the negated
7673 CR codes as NOTs, but not handle NOTs of them. */
3454f5f0 7674 {
256d47d0 7675 const char *const *t = 0;
3454f5f0 7676 const char *s;
7677 enum rtx_code code = GET_CODE (x);
7678 static const char * const tbl[3][3] = {
7679 { "and", "andc", "nor" },
7680 { "or", "orc", "nand" },
7681 { "xor", "eqv", "xor" } };
7682
7683 if (code == AND)
7684 t = tbl[0];
7685 else if (code == IOR)
7686 t = tbl[1];
7687 else if (code == XOR)
7688 t = tbl[2];
7689 else
7690 output_operand_lossage ("invalid %%q value");
7691
7692 if (GET_CODE (XEXP (x, 0)) != NOT)
7693 s = t[0];
7694 else
7695 {
7696 if (GET_CODE (XEXP (x, 1)) == NOT)
7697 s = t[2];
7698 else
7699 s = t[1];
7700 }
7701
7702 fputs (s, file);
7703 }
7704 return;
7705
e8555574 7706 case 'R':
7707 /* X is a CR register. Print the mask for `mtcrf'. */
7708 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7709 output_operand_lossage ("invalid %%R value");
7710 else
bbd21807 7711 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
d1bd513e 7712 return;
e8555574 7713
7714 case 's':
7715 /* Low 5 bits of 32 - value */
7716 if (! INT_P (x))
7717 output_operand_lossage ("invalid %%s value");
30c5e279 7718 else
7719 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
d1bd513e 7720 return;
e8555574 7721
8cda90b9 7722 case 'S':
59a5187e 7723 /* PowerPC64 mask position. All 0's is excluded.
8cda90b9 7724 CONST_INT 32-bit mask is considered sign-extended so any
7725 transition must occur within the CONST_INT, not on the boundary. */
6007cde0 7726 if (! mask64_operand (x, DImode))
8cda90b9 7727 output_operand_lossage ("invalid %%S value");
7728
59a5187e 7729 uval = INT_LOWPART (x);
8cda90b9 7730
59a5187e 7731 if (uval & 1) /* Clear Left */
8cda90b9 7732 {
59a5187e 7733 uval &= ((unsigned HOST_WIDE_INT) 1 << 63 << 1) - 1;
7734 i = 64;
8cda90b9 7735 }
59a5187e 7736 else /* Clear Right */
8cda90b9 7737 {
59a5187e 7738 uval = ~uval;
7739 uval &= ((unsigned HOST_WIDE_INT) 1 << 63 << 1) - 1;
7740 i = 63;
8cda90b9 7741 }
59a5187e 7742 while (uval != 0)
7743 --i, uval >>= 1;
7744 if (i < 0)
7745 abort ();
7746 fprintf (file, "%d", i);
7747 return;
8cda90b9 7748
f19493d5 7749 case 't':
7750 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
7751 if (GET_CODE (x) != REG || GET_MODE (x) != CCmode)
7752 abort ();
7753
7754 /* Bit 3 is OV bit. */
7755 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
7756
7757 /* If we want bit 31, write a shift count of zero, not 32. */
7758 fprintf (file, "%d", i == 31 ? 0 : i + 1);
7759 return;
7760
9a625988 7761 case 'T':
7762 /* Print the symbolic name of a branch target register. */
7763 if (GET_CODE (x) != REG || (REGNO (x) != LINK_REGISTER_REGNUM
7764 && REGNO (x) != COUNT_REGISTER_REGNUM))
7765 output_operand_lossage ("invalid %%T value");
30c5e279 7766 else if (REGNO (x) == LINK_REGISTER_REGNUM)
9a625988 7767 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
7768 else
7769 fputs ("ctr", file);
7770 return;
7771
e8555574 7772 case 'u':
359e408d 7773 /* High-order 16 bits of constant for use in unsigned operand. */
e8555574 7774 if (! INT_P (x))
7775 output_operand_lossage ("invalid %%u value");
30c5e279 7776 else
7777 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
7778 (INT_LOWPART (x) >> 16) & 0xffff);
d1bd513e 7779 return;
7780
359e408d 7781 case 'v':
7782 /* High-order 16 bits of constant for use in signed operand. */
7783 if (! INT_P (x))
7784 output_operand_lossage ("invalid %%v value");
30c5e279 7785 else
9ed2dda6 7786 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
7787 (INT_LOWPART (x) >> 16) & 0xffff);
7788 return;
359e408d 7789
e8555574 7790 case 'U':
7791 /* Print `u' if this has an auto-increment or auto-decrement. */
7792 if (GET_CODE (x) == MEM
7793 && (GET_CODE (XEXP (x, 0)) == PRE_INC
7794 || GET_CODE (XEXP (x, 0)) == PRE_DEC))
cba9c9bb 7795 putc ('u', file);
e8555574 7796 return;
d1bd513e 7797
9e5192ed 7798 case 'V':
7799 /* Print the trap code for this operand. */
7800 switch (GET_CODE (x))
7801 {
7802 case EQ:
7803 fputs ("eq", file); /* 4 */
7804 break;
7805 case NE:
7806 fputs ("ne", file); /* 24 */
7807 break;
7808 case LT:
7809 fputs ("lt", file); /* 16 */
7810 break;
7811 case LE:
7812 fputs ("le", file); /* 20 */
7813 break;
7814 case GT:
7815 fputs ("gt", file); /* 8 */
7816 break;
7817 case GE:
7818 fputs ("ge", file); /* 12 */
7819 break;
7820 case LTU:
7821 fputs ("llt", file); /* 2 */
7822 break;
7823 case LEU:
7824 fputs ("lle", file); /* 6 */
7825 break;
7826 case GTU:
7827 fputs ("lgt", file); /* 1 */
7828 break;
7829 case GEU:
7830 fputs ("lge", file); /* 5 */
7831 break;
7832 default:
7833 abort ();
7834 }
7835 break;
7836
e8555574 7837 case 'w':
7838 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
7839 normally. */
7840 if (INT_P (x))
837b446a 7841 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
7842 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
e8555574 7843 else
7844 print_operand (file, x, 0);
d1bd513e 7845 return;
7846
e8555574 7847 case 'W':
30c5e279 7848 /* MB value for a PowerPC64 rldic operand. */
30c5e279 7849 val = (GET_CODE (x) == CONST_INT
7850 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
7851
7852 if (val < 0)
7853 i = -1;
e8555574 7854 else
30c5e279 7855 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
7856 if ((val <<= 1) < 0)
7857 break;
7858
7859#if HOST_BITS_PER_WIDE_INT == 32
7860 if (GET_CODE (x) == CONST_INT && i >= 0)
7861 i += 32; /* zero-extend high-part was all 0's */
7862 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
7863 {
7864 val = CONST_DOUBLE_LOW (x);
7865
7866 if (val == 0)
970e222f 7867 abort ();
30c5e279 7868 else if (val < 0)
7869 --i;
7870 else
7871 for ( ; i < 64; i++)
7872 if ((val <<= 1) < 0)
7873 break;
7874 }
7875#endif
7876
7877 fprintf (file, "%d", i + 1);
e8555574 7878 return;
d1bd513e 7879
e8555574 7880 case 'X':
7881 if (GET_CODE (x) == MEM
4bbdf529 7882 && LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0), 0))
cba9c9bb 7883 putc ('x', file);
e8555574 7884 return;
d1bd513e 7885
e8555574 7886 case 'Y':
7887 /* Like 'L', for third word of TImode */
7888 if (GET_CODE (x) == REG)
00f76201 7889 fprintf (file, "%s", reg_names[REGNO (x) + 2]);
e8555574 7890 else if (GET_CODE (x) == MEM)
d1bd513e 7891 {
e8555574 7892 if (GET_CODE (XEXP (x, 0)) == PRE_INC
7893 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
31433e3f 7894 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
e8555574 7895 else
73680ce4 7896 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
1c9c4ece 7897 if (small_data_operand (x, GET_MODE (x)))
4aab7421 7898 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7899 reg_names[SMALL_DATA_REG]);
d1bd513e 7900 }
7901 return;
e8555574 7902
d1bd513e 7903 case 'z':
bdf74c8a 7904 /* X is a SYMBOL_REF. Write out the name preceded by a
7905 period and without any trailing data in brackets. Used for function
5a81dade 7906 names. If we are configured for System V (or the embedded ABI) on
7907 the PowerPC, do not emit the period, since those systems do not use
7908 TOCs and the like. */
d1bd513e 7909 if (GET_CODE (x) != SYMBOL_REF)
7910 abort ();
7911
6b02f2a5 7912 if (XSTR (x, 0)[0] != '.')
7913 {
7914 switch (DEFAULT_ABI)
7915 {
7916 default:
7917 abort ();
7918
7919 case ABI_AIX:
7920 putc ('.', file);
7921 break;
7922
7923 case ABI_V4:
7924 case ABI_AIX_NODESC:
80d725d7 7925 case ABI_DARWIN:
6b02f2a5 7926 break;
6b02f2a5 7927 }
7928 }
018718de 7929#if TARGET_AIX
7930 RS6000_OUTPUT_BASENAME (file, XSTR (x, 0));
7931#else
bbd21807 7932 assemble_name (file, XSTR (x, 0));
018718de 7933#endif
d1bd513e 7934 return;
7935
e8555574 7936 case 'Z':
7937 /* Like 'L', for last word of TImode. */
7938 if (GET_CODE (x) == REG)
00f76201 7939 fprintf (file, "%s", reg_names[REGNO (x) + 3]);
e8555574 7940 else if (GET_CODE (x) == MEM)
7941 {
7942 if (GET_CODE (XEXP (x, 0)) == PRE_INC
7943 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
31433e3f 7944 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
e8555574 7945 else
73680ce4 7946 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
1c9c4ece 7947 if (small_data_operand (x, GET_MODE (x)))
4aab7421 7948 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7949 reg_names[SMALL_DATA_REG]);
e8555574 7950 }
00489052 7951 return;
500c7157 7952
f19493d5 7953 /* Print AltiVec or SPE memory operand. */
500c7157 7954 case 'y':
7955 {
7956 rtx tmp;
7957
7958 if (GET_CODE (x) != MEM)
7959 abort ();
7960
7961 tmp = XEXP (x, 0);
7962
f19493d5 7963 if (TARGET_SPE)
7964 {
7965 /* Handle [reg]. */
7966 if (GET_CODE (tmp) == REG)
7967 {
7968 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
7969 break;
7970 }
7971 /* Handle [reg+UIMM]. */
7972 else if (GET_CODE (tmp) == PLUS &&
7973 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
7974 {
7975 int x;
7976
7977 if (GET_CODE (XEXP (tmp, 0)) != REG)
7978 abort ();
7979
7980 x = INTVAL (XEXP (tmp, 1));
7981 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
7982 break;
7983 }
7984
7985 /* Fall through. Must be [reg+reg]. */
7986 }
500c7157 7987 if (GET_CODE (tmp) == REG)
965c179a 7988 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
500c7157 7989 else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
7990 {
7991 if (REGNO (XEXP (tmp, 0)) == 0)
7992 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
7993 reg_names[ REGNO (XEXP (tmp, 0)) ]);
7994 else
7995 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
7996 reg_names[ REGNO (XEXP (tmp, 1)) ]);
7997 }
7998 else
7999 abort ();
8000 break;
8001 }
e8555574 8002
d1bd513e 8003 case 0:
8004 if (GET_CODE (x) == REG)
8005 fprintf (file, "%s", reg_names[REGNO (x)]);
8006 else if (GET_CODE (x) == MEM)
8007 {
8008 /* We need to handle PRE_INC and PRE_DEC here, since we need to
8009 know the width from the mode. */
8010 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
8751e999 8011 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
8012 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
d1bd513e 8013 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
8751e999 8014 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
8015 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
d1bd513e 8016 else
31433e3f 8017 output_address (XEXP (x, 0));
d1bd513e 8018 }
8019 else
31433e3f 8020 output_addr_const (file, x);
84f16e0b 8021 return;
d1bd513e 8022
8023 default:
8024 output_operand_lossage ("invalid %%xn code");
8025 }
8026}
8027\f
8028/* Print the address of an operand. */
8029
8030void
8031print_operand_address (file, x)
8032 FILE *file;
773e893a 8033 rtx x;
d1bd513e 8034{
8035 if (GET_CODE (x) == REG)
a3bbc303 8036 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
bbd21807 8037 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
8038 || GET_CODE (x) == LABEL_REF)
d1bd513e 8039 {
8040 output_addr_const (file, x);
1c9c4ece 8041 if (small_data_operand (x, GET_MODE (x)))
4aab7421 8042 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
8043 reg_names[SMALL_DATA_REG]);
bbd21807 8044 else if (TARGET_TOC)
970e222f 8045 abort ();
d1bd513e 8046 }
8047 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
8048 {
8049 if (REGNO (XEXP (x, 0)) == 0)
a3bbc303 8050 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
8051 reg_names[ REGNO (XEXP (x, 0)) ]);
d1bd513e 8052 else
a3bbc303 8053 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
8054 reg_names[ REGNO (XEXP (x, 1)) ]);
d1bd513e 8055 }
8056 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
837b446a 8057 {
8058 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (XEXP (x, 1)));
8059 fprintf (file, "(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
8060 }
91452706 8061#if TARGET_ELF
8062 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
8063 && CONSTANT_P (XEXP (x, 1)))
a3bbc303 8064 {
8065 output_addr_const (file, XEXP (x, 1));
8066 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
8067 }
ad3ed368 8068#endif
8069#if TARGET_MACHO
8070 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
8071 && CONSTANT_P (XEXP (x, 1)))
8072 {
8073 fprintf (file, "lo16(");
8074 output_addr_const (file, XEXP (x, 1));
8075 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
8076 }
91452706 8077#endif
bbd21807 8078 else if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
8079 {
8eaf2dd1 8080 if (TARGET_AIX && (!TARGET_ELF || !TARGET_MINIMAL_TOC))
bbd21807 8081 {
8eaf2dd1 8082 rtx contains_minus = XEXP (x, 1);
8083 rtx minus, symref;
8084 const char *name;
bbd21807 8085
8086 /* Find the (minus (sym) (toc)) buried in X, and temporarily
970e222f 8087 turn it into (sym) for output_addr_const. */
bbd21807 8088 while (GET_CODE (XEXP (contains_minus, 0)) != MINUS)
8089 contains_minus = XEXP (contains_minus, 0);
8090
8eaf2dd1 8091 minus = XEXP (contains_minus, 0);
8092 symref = XEXP (minus, 0);
8093 XEXP (contains_minus, 0) = symref;
8094 if (TARGET_ELF)
8095 {
8096 char *newname;
8097
8098 name = XSTR (symref, 0);
8099 newname = alloca (strlen (name) + sizeof ("@toc"));
8100 strcpy (newname, name);
8101 strcat (newname, "@toc");
8102 XSTR (symref, 0) = newname;
8103 }
8104 output_addr_const (file, XEXP (x, 1));
8105 if (TARGET_ELF)
8106 XSTR (symref, 0) = name;
bbd21807 8107 XEXP (contains_minus, 0) = minus;
8108 }
8109 else
8110 output_addr_const (file, XEXP (x, 1));
8111
8112 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
8113 }
d1bd513e 8114 else
8115 abort ();
8116}
8117\f
c8515df4 8118/* Target hook for assembling integer objects. The PowerPC version has
58356836 8119 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
8120 is defined. It also needs to handle DI-mode objects on 64-bit
8121 targets. */
8122
8123static bool
8124rs6000_assemble_integer (x, size, aligned_p)
8125 rtx x;
8126 unsigned int size;
8127 int aligned_p;
8128{
8129#ifdef RELOCATABLE_NEEDS_FIXUP
8130 /* Special handling for SI values. */
8131 if (size == 4 && aligned_p)
8132 {
8133 extern int in_toc_section PARAMS ((void));
8134 static int recurse = 0;
8135
8136 /* For -mrelocatable, we mark all addresses that need to be fixed up
8137 in the .fixup section. */
8138 if (TARGET_RELOCATABLE
8139 && !in_toc_section ()
8140 && !in_text_section ()
8141 && !recurse
8142 && GET_CODE (x) != CONST_INT
8143 && GET_CODE (x) != CONST_DOUBLE
8144 && CONSTANT_P (x))
8145 {
8146 char buf[256];
8147
8148 recurse = 1;
8149 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
8150 fixuplabelno++;
8151 ASM_OUTPUT_LABEL (asm_out_file, buf);
8152 fprintf (asm_out_file, "\t.long\t(");
8153 output_addr_const (asm_out_file, x);
8154 fprintf (asm_out_file, ")@fixup\n");
8155 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
8156 ASM_OUTPUT_ALIGN (asm_out_file, 2);
8157 fprintf (asm_out_file, "\t.long\t");
8158 assemble_name (asm_out_file, buf);
8159 fprintf (asm_out_file, "\n\t.previous\n");
8160 recurse = 0;
8161 return true;
8162 }
8163 /* Remove initial .'s to turn a -mcall-aixdesc function
8164 address into the address of the descriptor, not the function
8165 itself. */
8166 else if (GET_CODE (x) == SYMBOL_REF
8167 && XSTR (x, 0)[0] == '.'
8168 && DEFAULT_ABI == ABI_AIX)
8169 {
8170 const char *name = XSTR (x, 0);
8171 while (*name == '.')
8172 name++;
8173
8174 fprintf (asm_out_file, "\t.long\t%s\n", name);
8175 return true;
8176 }
8177 }
8178#endif /* RELOCATABLE_NEEDS_FIXUP */
8179 return default_assemble_integer (x, size, aligned_p);
8180}
2532673e 8181
8182#ifdef HAVE_GAS_HIDDEN
8183/* Emit an assembler directive to set symbol visibility for DECL to
8184 VISIBILITY_TYPE. */
8185
d3e1259a 8186static void
8cf34b34 8187rs6000_assemble_visibility (decl, vis)
2532673e 8188 tree decl;
8cf34b34 8189 int vis;
2532673e 8190{
2532673e 8191 /* Functions need to have their entry point symbol visibility set as
8192 well as their descriptor symbol visibility. */
8193 if (DEFAULT_ABI == ABI_AIX && TREE_CODE (decl) == FUNCTION_DECL)
8194 {
8cf34b34 8195 static const char * const visibility_types[] = {
8196 NULL, "internal", "hidden", "protected"
8197 };
8198
8199 const char *name, *type;
2532673e 8200
8201 name = ((* targetm.strip_name_encoding)
8202 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
8cf34b34 8203 type = visibility_types[vis];
2532673e 8204
8cf34b34 8205 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
8206 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
2532673e 8207 }
8cf34b34 8208 else
8209 default_assemble_visibility (decl, vis);
2532673e 8210}
8211#endif
58356836 8212\f
ac313e39 8213enum rtx_code
8214rs6000_reverse_condition (mode, code)
8215 enum machine_mode mode;
8216 enum rtx_code code;
8217{
8218 /* Reversal of FP compares takes care -- an ordered compare
8219 becomes an unordered compare and vice versa. */
df86a43a 8220 if (mode == CCFPmode && !flag_unsafe_math_optimizations)
94ae07ba 8221 return reverse_condition_maybe_unordered (code);
ac313e39 8222 else
94ae07ba 8223 return reverse_condition (code);
ac313e39 8224}
8225
ac313e39 8226/* Generate a compare for CODE. Return a brand-new rtx that
8227 represents the result of the compare. */
970e222f 8228
ac313e39 8229static rtx
8230rs6000_generate_compare (code)
8231 enum rtx_code code;
8232{
8233 enum machine_mode comp_mode;
8234 rtx compare_result;
8235
8236 if (rs6000_compare_fp_p)
8237 comp_mode = CCFPmode;
8238 else if (code == GTU || code == LTU
8239 || code == GEU || code == LEU)
8240 comp_mode = CCUNSmode;
8241 else
8242 comp_mode = CCmode;
8243
8244 /* First, the compare. */
8245 compare_result = gen_reg_rtx (comp_mode);
f19493d5 8246
8247 /* SPE FP compare instructions on the GPRs. Yuck! */
8248 if ((TARGET_SPE && TARGET_HARD_FLOAT) && rs6000_compare_fp_p)
8249 {
8250 rtx cmp, or1, or2, or_result, compare_result2;
8251
8252 switch (code)
8253 {
8254 case EQ:
8255 case UNEQ:
8256 case NE:
8257 case LTGT:
8258 cmp = flag_unsafe_math_optimizations
8259 ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
8260 rs6000_compare_op1)
8261 : gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
8262 rs6000_compare_op1);
8263 break;
8264 case GT:
8265 case GTU:
8266 case UNGT:
8267 case UNGE:
8268 case GE:
8269 case GEU:
8270 cmp = flag_unsafe_math_optimizations
8271 ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
8272 rs6000_compare_op1)
8273 : gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
8274 rs6000_compare_op1);
8275 break;
8276 case LT:
8277 case LTU:
8278 case UNLT:
8279 case UNLE:
8280 case LE:
8281 case LEU:
8282 cmp = flag_unsafe_math_optimizations
8283 ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
8284 rs6000_compare_op1)
8285 : gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
8286 rs6000_compare_op1);
8287 break;
8288 default:
8289 abort ();
8290 }
8291
8292 /* Synthesize LE and GE from LT/GT || EQ. */
8293 if (code == LE || code == GE || code == LEU || code == GEU)
8294 {
8295 /* Synthesize GE/LE frome GT/LT || EQ. */
8296
8297 emit_insn (cmp);
8298
8299 switch (code)
8300 {
8301 case LE: code = LT; break;
8302 case GE: code = GT; break;
8303 case LEU: code = LT; break;
8304 case GEU: code = GT; break;
8305 default: abort ();
8306 }
8307
8308 or1 = gen_reg_rtx (SImode);
8309 or2 = gen_reg_rtx (SImode);
8310 or_result = gen_reg_rtx (CCEQmode);
8311 compare_result2 = gen_reg_rtx (CCFPmode);
8312
8313 /* Do the EQ. */
8314 cmp = flag_unsafe_math_optimizations
8315 ? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
8316 rs6000_compare_op1)
8317 : gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0,
8318 rs6000_compare_op1);
8319 emit_insn (cmp);
8320
8321 /* The MC8540 FP compare instructions set the CR bits
8322 differently than other PPC compare instructions. For
8323 that matter, there is no generic test instruction, but a
8324 testgt, testlt, and testeq. For a true condition, bit 2
8325 is set (x1xx) in the CR. Following the traditional CR
8326 values:
8327
8328 LT GT EQ OV
8329 bit3 bit2 bit1 bit0
8330
8331 ... bit 2 would be a GT CR alias, so later on we
8332 look in the GT bits for the branch instructins.
8333 However, we must be careful to emit correct RTL in
8334 the meantime, so optimizations don't get confused. */
8335
8336 or1 = gen_rtx (NE, SImode, compare_result, const0_rtx);
8337 or2 = gen_rtx (NE, SImode, compare_result2, const0_rtx);
8338
8339 /* OR them together. */
8340 cmp = gen_rtx_SET (VOIDmode, or_result,
8341 gen_rtx_COMPARE (CCEQmode,
8342 gen_rtx_IOR (SImode, or1, or2),
8343 const_true_rtx));
8344 compare_result = or_result;
8345 code = EQ;
8346 }
8347 else
8348 {
8349 /* We only care about 1 bit (x1xx), so map everything to NE to
8350 maintain rtl sanity. We'll get to the right bit (x1xx) at
8351 code output time. */
8352 if (code == NE || code == LTGT)
8353 /* Do the inverse here because we have no cmpne
8354 instruction. We use the cmpeq instruction and expect
8355 to get a 0 instead. */
8356 code = EQ;
8357 else
8358 code = NE;
8359 }
8360
8361 emit_insn (cmp);
8362 }
8363 else
8364 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
8365 gen_rtx_COMPARE (comp_mode,
8366 rs6000_compare_op0,
8367 rs6000_compare_op1)));
ac313e39 8368
8cf2f1a9 8369 /* Some kinds of FP comparisons need an OR operation;
7f3be425 8370 except for flag_unsafe_math_optimizations we don't bother. */
ac313e39 8371 if (rs6000_compare_fp_p
7f3be425 8372 && ! flag_unsafe_math_optimizations
f19493d5 8373 && ! (TARGET_HARD_FLOAT && TARGET_SPE)
ac313e39 8374 && (code == LE || code == GE
8375 || code == UNEQ || code == LTGT
8376 || code == UNGT || code == UNLT))
8377 {
8378 enum rtx_code or1, or2;
8379 rtx or1_rtx, or2_rtx, compare2_rtx;
8380 rtx or_result = gen_reg_rtx (CCEQmode);
8381
8382 switch (code)
8383 {
8384 case LE: or1 = LT; or2 = EQ; break;
8385 case GE: or1 = GT; or2 = EQ; break;
8386 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
8387 case LTGT: or1 = LT; or2 = GT; break;
8388 case UNGT: or1 = UNORDERED; or2 = GT; break;
8389 case UNLT: or1 = UNORDERED; or2 = LT; break;
8390 default: abort ();
8391 }
8392 validate_condition_mode (or1, comp_mode);
8393 validate_condition_mode (or2, comp_mode);
8394 or1_rtx = gen_rtx (or1, SImode, compare_result, const0_rtx);
8395 or2_rtx = gen_rtx (or2, SImode, compare_result, const0_rtx);
8396 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
8397 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
8398 const_true_rtx);
8399 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
8400
8401 compare_result = or_result;
8402 code = EQ;
8403 }
8404
8405 validate_condition_mode (code, GET_MODE (compare_result));
8406
8407 return gen_rtx (code, VOIDmode, compare_result, const0_rtx);
8408}
8409
8410
8411/* Emit the RTL for an sCOND pattern. */
8412
8413void
8414rs6000_emit_sCOND (code, result)
8415 enum rtx_code code;
8416 rtx result;
8417{
8418 rtx condition_rtx;
8419 enum machine_mode op_mode;
8420
8421 condition_rtx = rs6000_generate_compare (code);
8422
8423 op_mode = GET_MODE (rs6000_compare_op0);
8424 if (op_mode == VOIDmode)
8425 op_mode = GET_MODE (rs6000_compare_op1);
8426
8427 if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p))
8428 {
8429 PUT_MODE (condition_rtx, DImode);
8430 convert_move (result, condition_rtx, 0);
8431 }
8432 else
8433 {
8434 PUT_MODE (condition_rtx, SImode);
8435 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
8436 }
8437}
8438
ac313e39 8439/* Emit a branch of kind CODE to location LOC. */
8440
8441void
8442rs6000_emit_cbranch (code, loc)
8443 enum rtx_code code;
8444 rtx loc;
8445{
8446 rtx condition_rtx, loc_ref;
8447
8448 condition_rtx = rs6000_generate_compare (code);
8449 loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
8450 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
8451 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
8452 loc_ref, pc_rtx)));
8453}
8454
2b3dfdb8 8455/* Return the string to output a conditional branch to LABEL, which is
8456 the operand number of the label, or -1 if the branch is really a
8457 conditional return.
8458
8459 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
8460 condition code register and its mode specifies what kind of
8461 comparison we made.
8462
e911aedf 8463 REVERSED is nonzero if we should reverse the sense of the comparison.
2b3dfdb8 8464
8465 INSN is the insn. */
8466
8467char *
8468output_cbranch (op, label, reversed, insn)
8469 rtx op;
8470 const char * label;
8471 int reversed;
8472 rtx insn;
8473{
8474 static char string[64];
8475 enum rtx_code code = GET_CODE (op);
8476 rtx cc_reg = XEXP (op, 0);
8477 enum machine_mode mode = GET_MODE (cc_reg);
8478 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
ac313e39 8479 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
2b3dfdb8 8480 int really_reversed = reversed ^ need_longbranch;
8481 char *s = string;
8482 const char *ccode;
8483 const char *pred;
8484 rtx note;
8485
ac313e39 8486 validate_condition_mode (code, mode);
8487
8488 /* Work out which way this really branches. We could use
8489 reverse_condition_maybe_unordered here always but this
8490 makes the resulting assembler clearer. */
2b3dfdb8 8491 if (really_reversed)
df86a43a 8492 {
8493 /* Reversal of FP compares takes care -- an ordered compare
8494 becomes an unordered compare and vice versa. */
8495 if (mode == CCFPmode)
8496 code = reverse_condition_maybe_unordered (code);
8497 else
8498 code = reverse_condition (code);
8499 }
2b3dfdb8 8500
f19493d5 8501 if ((TARGET_SPE && TARGET_HARD_FLOAT) && mode == CCFPmode)
8502 {
8503 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
8504 to the GT bit. */
8505 if (code == EQ)
8506 /* Opposite of GT. */
8507 code = UNLE;
8508 else if (code == NE)
8509 code = GT;
8510 else
8511 abort ();
8512 }
8513
ac313e39 8514 switch (code)
2b3dfdb8 8515 {
8516 /* Not all of these are actually distinct opcodes, but
8517 we distinguish them for clarity of the resulting assembler. */
ba261041 8518 case NE: case LTGT:
8519 ccode = "ne"; break;
8520 case EQ: case UNEQ:
8521 ccode = "eq"; break;
8522 case GE: case GEU:
8523 ccode = "ge"; break;
8524 case GT: case GTU: case UNGT:
8525 ccode = "gt"; break;
8526 case LE: case LEU:
8527 ccode = "le"; break;
8528 case LT: case LTU: case UNLT:
8529 ccode = "lt"; break;
2b3dfdb8 8530 case UNORDERED: ccode = "un"; break;
8531 case ORDERED: ccode = "nu"; break;
8532 case UNGE: ccode = "nl"; break;
8533 case UNLE: ccode = "ng"; break;
8534 default:
970e222f 8535 abort ();
2b3dfdb8 8536 }
8537
a5fba622 8538 /* Maybe we have a guess as to how likely the branch is.
8539 The old mnemonics don't have a way to specify this information. */
92bc608f 8540 pred = "";
2b3dfdb8 8541 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
8542 if (note != NULL_RTX)
8543 {
8544 /* PROB is the difference from 50%. */
8545 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
92bc608f 8546 bool always_hint = rs6000_cpu != PROCESSOR_POWER4;
8547
8548 /* Only hint for highly probable/improbable branches on newer
8549 cpus as static prediction overrides processor dynamic
8550 prediction. For older cpus we may as well always hint, but
8551 assume not taken for branches that are very close to 50% as a
8552 mispredicted taken branch is more expensive than a
8553 mispredicted not-taken branch. */
8554 if (always_hint
8555 || abs (prob) > REG_BR_PROB_BASE / 100 * 48)
8556 {
8557 if (abs (prob) > REG_BR_PROB_BASE / 20
8558 && ((prob > 0) ^ need_longbranch))
8559 pred = "+";
8560 else
8561 pred = "-";
8562 }
2b3dfdb8 8563 }
2b3dfdb8 8564
8565 if (label == NULL)
a5fba622 8566 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
2b3dfdb8 8567 else
a5fba622 8568 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
2b3dfdb8 8569
c4f5458b 8570 /* We need to escape any '%' characters in the reg_names string.
8571 Assume they'd only be the first character... */
8572 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
8573 *s++ = '%';
a5fba622 8574 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
2b3dfdb8 8575
8576 if (label != NULL)
8577 {
8578 /* If the branch distance was too far, we may have to use an
8579 unconditional branch to go the distance. */
8580 if (need_longbranch)
68066de3 8581 s += sprintf (s, ",$+8\n\tb %s", label);
2b3dfdb8 8582 else
8583 s += sprintf (s, ",%s", label);
8584 }
8585
8586 return string;
8587}
ba261041 8588
8589/* Emit a conditional move: move TRUE_COND to DEST if OP of the
8590 operands of the last comparison is nonzero/true, FALSE_COND if it
8591 is zero/false. Return 0 if the hardware has no such operation. */
970e222f 8592
ba261041 8593int
8594rs6000_emit_cmove (dest, op, true_cond, false_cond)
8595 rtx dest;
8596 rtx op;
8597 rtx true_cond;
8598 rtx false_cond;
8599{
8600 enum rtx_code code = GET_CODE (op);
8601 rtx op0 = rs6000_compare_op0;
8602 rtx op1 = rs6000_compare_op1;
8603 REAL_VALUE_TYPE c1;
3d0385fb 8604 enum machine_mode compare_mode = GET_MODE (op0);
8605 enum machine_mode result_mode = GET_MODE (dest);
ba261041 8606 rtx temp;
8607
3d0385fb 8608 /* These modes should always match. */
f19493d5 8609 if (GET_MODE (op1) != compare_mode
8610 /* In the isel case however, we can use a compare immediate, so
8611 op1 may be a small constant. */
8612 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
3d0385fb 8613 return 0;
9f781781 8614 if (GET_MODE (true_cond) != result_mode)
3d0385fb 8615 return 0;
9f781781 8616 if (GET_MODE (false_cond) != result_mode)
3d0385fb 8617 return 0;
8618
ba261041 8619 /* First, work out if the hardware can do this at all, or
8620 if it's too slow... */
ba261041 8621 if (! rs6000_compare_fp_p)
f19493d5 8622 {
8623 if (TARGET_ISEL)
8624 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
8625 return 0;
8626 }
ba261041 8627
8628 /* Eliminate half of the comparisons by switching operands, this
8629 makes the remaining code simpler. */
8630 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
8631 || code == LTGT || code == LT)
8632 {
8633 code = reverse_condition_maybe_unordered (code);
8634 temp = true_cond;
8635 true_cond = false_cond;
8636 false_cond = temp;
8637 }
8638
8639 /* UNEQ and LTGT take four instructions for a comparison with zero,
8640 it'll probably be faster to use a branch here too. */
8641 if (code == UNEQ)
8642 return 0;
8643
8644 if (GET_CODE (op1) == CONST_DOUBLE)
8645 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
8646
8647 /* We're going to try to implement comparions by performing
8648 a subtract, then comparing against zero. Unfortunately,
8649 Inf - Inf is NaN which is not zero, and so if we don't
d30e015b 8650 know that the operand is finite and the comparison
ba261041 8651 would treat EQ different to UNORDERED, we can't do it. */
8652 if (! flag_unsafe_math_optimizations
8653 && code != GT && code != UNGE
741b56d8 8654 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
ba261041 8655 /* Constructs of the form (a OP b ? a : b) are safe. */
8656 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
8657 || (! rtx_equal_p (op0, true_cond)
8658 && ! rtx_equal_p (op1, true_cond))))
8659 return 0;
8660 /* At this point we know we can use fsel. */
8661
8662 /* Reduce the comparison to a comparison against zero. */
3d0385fb 8663 temp = gen_reg_rtx (compare_mode);
ba261041 8664 emit_insn (gen_rtx_SET (VOIDmode, temp,
3d0385fb 8665 gen_rtx_MINUS (compare_mode, op0, op1)));
ba261041 8666 op0 = temp;
3d0385fb 8667 op1 = CONST0_RTX (compare_mode);
ba261041 8668
8669 /* If we don't care about NaNs we can reduce some of the comparisons
8670 down to faster ones. */
8671 if (flag_unsafe_math_optimizations)
8672 switch (code)
8673 {
8674 case GT:
8675 code = LE;
8676 temp = true_cond;
8677 true_cond = false_cond;
8678 false_cond = temp;
8679 break;
8680 case UNGE:
8681 code = GE;
8682 break;
8683 case UNEQ:
8684 code = EQ;
8685 break;
8686 default:
8687 break;
8688 }
8689
8690 /* Now, reduce everything down to a GE. */
8691 switch (code)
8692 {
8693 case GE:
8694 break;
8695
8696 case LE:
3d0385fb 8697 temp = gen_reg_rtx (compare_mode);
8698 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
ba261041 8699 op0 = temp;
8700 break;
8701
8702 case ORDERED:
3d0385fb 8703 temp = gen_reg_rtx (compare_mode);
8704 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
ba261041 8705 op0 = temp;
8706 break;
8707
8708 case EQ:
3d0385fb 8709 temp = gen_reg_rtx (compare_mode);
ba261041 8710 emit_insn (gen_rtx_SET (VOIDmode, temp,
3d0385fb 8711 gen_rtx_NEG (compare_mode,
8712 gen_rtx_ABS (compare_mode, op0))));
ba261041 8713 op0 = temp;
8714 break;
8715
8716 case UNGE:
3d0385fb 8717 temp = gen_reg_rtx (result_mode);
ba261041 8718 emit_insn (gen_rtx_SET (VOIDmode, temp,
3d0385fb 8719 gen_rtx_IF_THEN_ELSE (result_mode,
ba261041 8720 gen_rtx_GE (VOIDmode,
8721 op0, op1),
8722 true_cond, false_cond)));
8723 false_cond = temp;
8724 true_cond = false_cond;
8725
3d0385fb 8726 temp = gen_reg_rtx (compare_mode);
8727 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
ba261041 8728 op0 = temp;
8729 break;
8730
8731 case GT:
3d0385fb 8732 temp = gen_reg_rtx (result_mode);
ba261041 8733 emit_insn (gen_rtx_SET (VOIDmode, temp,
3d0385fb 8734 gen_rtx_IF_THEN_ELSE (result_mode,
ba261041 8735 gen_rtx_GE (VOIDmode,
8736 op0, op1),
8737 true_cond, false_cond)));
8738 true_cond = temp;
8739 false_cond = true_cond;
8740
3d0385fb 8741 temp = gen_reg_rtx (compare_mode);
8742 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
ba261041 8743 op0 = temp;
8744 break;
8745
8746 default:
8747 abort ();
8748 }
8749
8750 emit_insn (gen_rtx_SET (VOIDmode, dest,
3d0385fb 8751 gen_rtx_IF_THEN_ELSE (result_mode,
ba261041 8752 gen_rtx_GE (VOIDmode,
8753 op0, op1),
8754 true_cond, false_cond)));
8755 return 1;
8756}
8757
f19493d5 8758/* Same as above, but for ints (isel). */
8759
8760static int
8761rs6000_emit_int_cmove (dest, op, true_cond, false_cond)
8762 rtx dest;
8763 rtx op;
8764 rtx true_cond;
8765 rtx false_cond;
8766{
8767 rtx condition_rtx, cr;
8768
8769 /* All isel implementations thus far are 32-bits. */
8770 if (GET_MODE (rs6000_compare_op0) != SImode)
8771 return 0;
8772
8773 /* We still have to do the compare, because isel doesn't do a
8774 compare, it just looks at the CRx bits set by a previous compare
8775 instruction. */
8776 condition_rtx = rs6000_generate_compare (GET_CODE (op));
8777 cr = XEXP (condition_rtx, 0);
8778
8779 if (GET_MODE (cr) == CCmode)
8780 emit_insn (gen_isel_signed (dest, condition_rtx,
8781 true_cond, false_cond, cr));
8782 else
8783 emit_insn (gen_isel_unsigned (dest, condition_rtx,
8784 true_cond, false_cond, cr));
8785
8786 return 1;
8787}
8788
8789const char *
8790output_isel (operands)
8791 rtx *operands;
8792{
8793 enum rtx_code code;
8794
8795 code = GET_CODE (operands[1]);
8796 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
8797 {
8798 PUT_CODE (operands[1], reverse_condition (code));
8799 return "isel %0,%3,%2,%j1";
8800 }
8801 else
8802 return "isel %0,%2,%3,%j1";
8803}
8804
ba261041 8805void
8806rs6000_emit_minmax (dest, code, op0, op1)
8807 rtx dest;
8808 enum rtx_code code;
8809 rtx op0;
8810 rtx op1;
8811{
8812 enum machine_mode mode = GET_MODE (op0);
f52502f8 8813 enum rtx_code c;
ba261041 8814 rtx target;
f52502f8 8815
8816 if (code == SMAX || code == SMIN)
8817 c = GE;
8818 else
8819 c = GEU;
8820
ba261041 8821 if (code == SMAX || code == UMAX)
f52502f8 8822 target = emit_conditional_move (dest, c, op0, op1, mode,
ba261041 8823 op0, op1, mode, 0);
8824 else
f52502f8 8825 target = emit_conditional_move (dest, c, op0, op1, mode,
ba261041 8826 op1, op0, mode, 0);
8827 if (target == NULL_RTX)
8828 abort ();
8829 if (target != dest)
8830 emit_move_insn (dest, target);
8831}
2b3dfdb8 8832\f
970e222f 8833/* This page contains routines that are used to determine what the
8834 function prologue and epilogue code will do and write them out. */
d1bd513e 8835
970e222f 8836/* Return the first fixed-point register that is required to be
8837 saved. 32 if none. */
d1bd513e 8838
8839int
8840first_reg_to_save ()
8841{
8842 int first_reg;
8843
8844 /* Find lowest numbered live register. */
8845 for (first_reg = 13; first_reg <= 31; first_reg++)
cb03e5c1 8846 if (regs_ever_live[first_reg]
8847 && (! call_used_regs[first_reg]
479d644a 8848 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
e7ce8542 8849 && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
8850 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)))))
d1bd513e 8851 break;
8852
80d725d7 8853#if TARGET_MACHO
2532673e 8854 if (flag_pic
8855 && current_function_uses_pic_offset_table
8856 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
479d644a 8857 return RS6000_PIC_OFFSET_TABLE_REGNUM;
80d725d7 8858#endif
8859
d1bd513e 8860 return first_reg;
8861}
8862
8863/* Similar, for FP regs. */
8864
8865int
8866first_fp_reg_to_save ()
8867{
8868 int first_reg;
8869
8870 /* Find lowest numbered live register. */
8871 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
8872 if (regs_ever_live[first_reg])
8873 break;
8874
8875 return first_reg;
8876}
bb78803e 8877
8878/* Similar, for AltiVec regs. */
8879
8880static int
8881first_altivec_reg_to_save ()
8882{
8883 int i;
8884
8885 /* Stack frame remains as is unless we are in AltiVec ABI. */
8886 if (! TARGET_ALTIVEC_ABI)
8887 return LAST_ALTIVEC_REGNO + 1;
8888
8889 /* Find lowest numbered live register. */
8890 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
8891 if (regs_ever_live[i])
8892 break;
8893
8894 return i;
8895}
8896
8897/* Return a 32-bit mask of the AltiVec registers we need to set in
8898 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
8899 the 32-bit word is 0. */
8900
8901static unsigned int
8902compute_vrsave_mask ()
8903{
8904 unsigned int i, mask = 0;
8905
8906 /* First, find out if we use _any_ altivec registers. */
8907 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
8908 if (regs_ever_live[i])
8909 mask |= ALTIVEC_REG_BIT (i);
8910
8911 if (mask == 0)
8912 return mask;
8913
8914 /* Next, add all registers that are call-clobbered. We do this
8915 because post-reload register optimizers such as regrename_optimize
8916 may choose to use them. They never change the register class
8917 chosen by reload, so cannot create new uses of altivec registers
8918 if there were none before, so the early exit above is safe. */
8919 /* ??? Alternately, we could define HARD_REGNO_RENAME_OK to disallow
8920 altivec registers not saved in the mask, which might well make the
8921 adjustments below more effective in eliding the save/restore of
8922 VRSAVE in small functions. */
8923 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
8924 if (call_used_regs[i])
8925 mask |= ALTIVEC_REG_BIT (i);
8926
8927 /* Next, remove the argument registers from the set. These must
8928 be in the VRSAVE mask set by the caller, so we don't need to add
8929 them in again. More importantly, the mask we compute here is
8930 used to generate CLOBBERs in the set_vrsave insn, and we do not
8931 wish the argument registers to die. */
8932 for (i = cfun->args_info.vregno; i >= ALTIVEC_ARG_MIN_REG; --i)
8933 mask &= ~ALTIVEC_REG_BIT (i);
8934
8935 /* Similarly, remove the return value from the set. */
8936 {
8937 bool yes = false;
8938 diddle_return_value (is_altivec_return_reg, &yes);
8939 if (yes)
8940 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
8941 }
8942
8943 return mask;
8944}
8945
8946static void
8947is_altivec_return_reg (reg, xyes)
8948 rtx reg;
8949 void *xyes;
8950{
8951 bool *yes = (bool *) xyes;
8952 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
8953 *yes = true;
8954}
8955
a3bbc303 8956\f
8957/* Calculate the stack information for the current function. This is
8958 complicated by having two separate calling sequences, the AIX calling
8959 sequence and the V.4 calling sequence.
8960
773e893a 8961 AIX (and Darwin/Mac OS X) stack frames look like:
8cda90b9 8962 32-bit 64-bit
a3bbc303 8963 SP----> +---------------------------------------+
8cda90b9 8964 | back chain to caller | 0 0
a3bbc303 8965 +---------------------------------------+
8cda90b9 8966 | saved CR | 4 8 (8-11)
a3bbc303 8967 +---------------------------------------+
8cda90b9 8968 | saved LR | 8 16
a3bbc303 8969 +---------------------------------------+
8cda90b9 8970 | reserved for compilers | 12 24
a3bbc303 8971 +---------------------------------------+
8cda90b9 8972 | reserved for binders | 16 32
a3bbc303 8973 +---------------------------------------+
8cda90b9 8974 | saved TOC pointer | 20 40
a3bbc303 8975 +---------------------------------------+
8cda90b9 8976 | Parameter save area (P) | 24 48
a3bbc303 8977 +---------------------------------------+
8cda90b9 8978 | Alloca space (A) | 24+P etc.
359e408d 8979 +---------------------------------------+
33e46abb 8980 | Local variable space (L) | 24+P+A
a3bbc303 8981 +---------------------------------------+
33e46abb 8982 | Float/int conversion temporary (X) | 24+P+A+L
a3bbc303 8983 +---------------------------------------+
bb78803e 8984 | Save area for AltiVec registers (W) | 24+P+A+L+X
8985 +---------------------------------------+
8986 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
8987 +---------------------------------------+
8988 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
a3bbc303 8989 +---------------------------------------+
bb78803e 8990 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
8991 +---------------------------------------+
8992 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
a3bbc303 8993 +---------------------------------------+
8994 old SP->| back chain to caller's caller |
8995 +---------------------------------------+
8996
6b41a2e8 8997 The required alignment for AIX configurations is two words (i.e., 8
8998 or 16 bytes).
8999
9000
a3bbc303 9001 V.4 stack frames look like:
9002
9003 SP----> +---------------------------------------+
9004 | back chain to caller | 0
9005 +---------------------------------------+
5e3d52dc 9006 | caller's saved LR | 4
a3bbc303 9007 +---------------------------------------+
9008 | Parameter save area (P) | 8
9009 +---------------------------------------+
33e46abb 9010 | Alloca space (A) | 8+P
9011 +---------------------------------------+
9012 | Varargs save area (V) | 8+P+A
9013 +---------------------------------------+
9014 | Local variable space (L) | 8+P+A+V
9015 +---------------------------------------+
9016 | Float/int conversion temporary (X) | 8+P+A+V+L
a3bbc303 9017 +---------------------------------------+
bb78803e 9018 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
9019 +---------------------------------------+
9020 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
9021 +---------------------------------------+
9022 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
9023 +---------------------------------------+
f19493d5 9024 | SPE: area for 64-bit GP registers |
9025 +---------------------------------------+
9026 | SPE alignment padding |
9027 +---------------------------------------+
bb78803e 9028 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
33e46abb 9029 +---------------------------------------+
bb78803e 9030 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
33e46abb 9031 +---------------------------------------+
bb78803e 9032 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
a3bbc303 9033 +---------------------------------------+
9034 old SP->| back chain to caller's caller |
9035 +---------------------------------------+
6b02f2a5 9036
6b41a2e8 9037 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
9038 given. (But note below and in sysv4.h that we require only 8 and
9039 may round up the size of our stack frame anyways. The historical
9040 reason is early versions of powerpc-linux which didn't properly
9041 align the stack at program startup. A happy side-effect is that
9042 -mno-eabi libraries can be used with -meabi programs.)
9043
6b41a2e8 9044 The EABI configuration defaults to the V.4 layout, unless
9045 -mcall-aix is used, in which case the AIX layout is used. However,
9046 the stack alignment requirements may differ. If -mno-eabi is not
9047 given, the required stack alignment is 8 bytes; if -mno-eabi is
9048 given, the required alignment is 16 bytes. (But see V.4 comment
9049 above.) */
a3bbc303 9050
9be96edc 9051#ifndef ABI_STACK_BOUNDARY
9052#define ABI_STACK_BOUNDARY STACK_BOUNDARY
9053#endif
9054
a3bbc303 9055rs6000_stack_t *
9056rs6000_stack_info ()
9057{
9058 static rs6000_stack_t info, zero_info;
9059 rs6000_stack_t *info_ptr = &info;
bbd21807 9060 int reg_size = TARGET_POWERPC64 ? 8 : 4;
7db9c9c6 9061 enum rs6000_abi abi;
4ce33b7f 9062 int ehrd_size;
6b02f2a5 9063 int total_raw_size;
a3bbc303 9064
970e222f 9065 /* Zero all fields portably. */
a3bbc303 9066 info = zero_info;
9067
970e222f 9068 /* Select which calling sequence. */
6b02f2a5 9069 info_ptr->abi = abi = DEFAULT_ABI;
d1bd513e 9070
970e222f 9071 /* Calculate which registers need to be saved & save area size. */
a3bbc303 9072 info_ptr->first_gp_reg_save = first_reg_to_save ();
479d644a 9073 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
a2d03447 9074 even if it currently looks like we won't. */
8eaf2dd1 9075 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
e7ce8542 9076 || (flag_pic == 1 && abi == ABI_V4)
9077 || (flag_pic && abi == ABI_DARWIN))
479d644a 9078 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
9079 info_ptr->gp_size = reg_size * (32 - RS6000_PIC_OFFSET_TABLE_REGNUM);
a2d03447 9080 else
9081 info_ptr->gp_size = reg_size * (32 - info_ptr->first_gp_reg_save);
a3bbc303 9082
f19493d5 9083 /* For the SPE, we have an additional upper 32-bits on each GPR.
9084 Ideally we should save the entire 64-bits only when the upper
9085 half is used in SIMD instructions. Since we only record
9086 registers live (not the size they are used in), this proves
9087 difficult because we'd have to traverse the instruction chain at
9088 the right time, taking reload into account. This is a real pain,
9089 so we opt to save the GPRs in 64-bits always. Anyone overly
9090 concerned with frame size can fix this. ;-).
9091
9092 So... since we save all GPRs (except the SP) in 64-bits, the
9093 traditional GP save area will be empty. */
9094 if (TARGET_SPE_ABI)
9095 info_ptr->gp_size = 0;
9096
a3bbc303 9097 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
9098 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
9099
bb78803e 9100 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
9101 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
9102 - info_ptr->first_altivec_reg_save);
9103
773e893a 9104 /* Does this function call anything? */
8f474918 9105 info_ptr->calls_p = (! current_function_is_leaf
9106 || cfun->machine->ra_needs_full_frame);
6b02f2a5 9107
970e222f 9108 /* Determine if we need to save the link register. */
8f474918 9109 if (rs6000_ra_ever_killed ()
7811c823 9110 || (DEFAULT_ABI == ABI_AIX && current_function_profile)
a3bbc303 9111#ifdef TARGET_RELOCATABLE
9112 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
9113#endif
9114 || (info_ptr->first_fp_reg_save != 64
9115 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
bb78803e 9116 || info_ptr->first_altivec_reg_save <= LAST_ALTIVEC_REGNO
7db9c9c6 9117 || (abi == ABI_V4 && current_function_calls_alloca)
970e222f 9118 || (DEFAULT_ABI == ABI_DARWIN
9119 && flag_pic
9120 && current_function_uses_pic_offset_table)
a3bbc303 9121 || info_ptr->calls_p)
9122 {
9123 info_ptr->lr_save_p = 1;
bbd21807 9124 regs_ever_live[LINK_REGISTER_REGNUM] = 1;
a3bbc303 9125 }
9126
bbd21807 9127 /* Determine if we need to save the condition code registers. */
9128 if (regs_ever_live[CR2_REGNO]
9129 || regs_ever_live[CR3_REGNO]
9130 || regs_ever_live[CR4_REGNO])
a3bbc303 9131 {
9132 info_ptr->cr_save_p = 1;
e7ce8542 9133 if (abi == ABI_V4)
a3bbc303 9134 info_ptr->cr_size = reg_size;
9135 }
9136
4ce33b7f 9137 /* If the current function calls __builtin_eh_return, then we need
9138 to allocate stack space for registers that will hold data for
9139 the exception handler. */
9140 if (current_function_calls_eh_return)
9141 {
9142 unsigned int i;
9143 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
9144 continue;
f19493d5 9145
9146 /* SPE saves EH registers in 64-bits. */
9147 ehrd_size = i * (TARGET_SPE_ABI ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
4ce33b7f 9148 }
9149 else
9150 ehrd_size = 0;
9151
773e893a 9152 /* Determine various sizes. */
a3bbc303 9153 info_ptr->reg_size = reg_size;
9154 info_ptr->fixed_size = RS6000_SAVE_AREA;
9155 info_ptr->varargs_size = RS6000_VARARGS_AREA;
8a3b8dfd 9156 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
970e222f 9157 info_ptr->parm_size = RS6000_ALIGN (current_function_outgoing_args_size,
9158 8);
bb78803e 9159
f19493d5 9160 if (TARGET_SPE_ABI)
9161 info_ptr->spe_gp_size = 8 * (32 - info_ptr->first_gp_reg_save);
9162 else
9163 info_ptr->spe_gp_size = 0;
9164
10363e0e 9165 if (TARGET_ALTIVEC_ABI && TARGET_ALTIVEC_VRSAVE)
bb78803e 9166 {
9167 info_ptr->vrsave_mask = compute_vrsave_mask ();
9168 info_ptr->vrsave_size = info_ptr->vrsave_mask ? 4 : 0;
9169 }
9170 else
9171 {
9172 info_ptr->vrsave_mask = 0;
9173 info_ptr->vrsave_size = 0;
9174 }
6b02f2a5 9175
773e893a 9176 /* Calculate the offsets. */
7db9c9c6 9177 switch (abi)
a3bbc303 9178 {
6b02f2a5 9179 case ABI_NONE:
7db9c9c6 9180 default:
6b02f2a5 9181 abort ();
9182
9183 case ABI_AIX:
9184 case ABI_AIX_NODESC:
80d725d7 9185 case ABI_DARWIN:
6b02f2a5 9186 info_ptr->fp_save_offset = - info_ptr->fp_size;
9187 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
bb78803e 9188
9189 if (TARGET_ALTIVEC_ABI)
9190 {
9191 info_ptr->vrsave_save_offset
9192 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
9193
9194 /* Align stack so vector save area is on a quadword boundary. */
9195 if (info_ptr->altivec_size != 0)
9196 info_ptr->altivec_padding_size
9197 = 16 - (-info_ptr->vrsave_save_offset % 16);
9198 else
9199 info_ptr->altivec_padding_size = 0;
9200
9201 info_ptr->altivec_save_offset
9202 = info_ptr->vrsave_save_offset
9203 - info_ptr->altivec_padding_size
9204 - info_ptr->altivec_size;
9205
9206 /* Adjust for AltiVec case. */
9207 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
9208 }
9209 else
9210 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
8cda90b9 9211 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
9212 info_ptr->lr_save_offset = 2*reg_size;
7db9c9c6 9213 break;
9214
9215 case ABI_V4:
6b02f2a5 9216 info_ptr->fp_save_offset = - info_ptr->fp_size;
9217 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
33e46abb 9218 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
bb78803e 9219
f19493d5 9220 if (TARGET_SPE_ABI)
9221 {
9222 /* Align stack so SPE GPR save area is aligned on a
9223 double-word boundary. */
9224 if (info_ptr->spe_gp_size != 0)
9225 info_ptr->spe_padding_size
9226 = 8 - (-info_ptr->cr_save_offset % 8);
9227 else
9228 info_ptr->spe_padding_size = 0;
9229
9230 info_ptr->spe_gp_save_offset
9231 = info_ptr->cr_save_offset
9232 - info_ptr->spe_padding_size
9233 - info_ptr->spe_gp_size;
9234
9235 /* Adjust for SPE case. */
9236 info_ptr->toc_save_offset
9237 = info_ptr->spe_gp_save_offset - info_ptr->toc_size;
9238 }
9239 else if (TARGET_ALTIVEC_ABI)
bb78803e 9240 {
9241 info_ptr->vrsave_save_offset
9242 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
9243
9244 /* Align stack so vector save area is on a quadword boundary. */
9245 if (info_ptr->altivec_size != 0)
9246 info_ptr->altivec_padding_size
9247 = 16 - (-info_ptr->vrsave_save_offset % 16);
9248 else
9249 info_ptr->altivec_padding_size = 0;
9250
9251 info_ptr->altivec_save_offset
9252 = info_ptr->vrsave_save_offset
9253 - info_ptr->altivec_padding_size
9254 - info_ptr->altivec_size;
9255
9256 /* Adjust for AltiVec case. */
9257 info_ptr->toc_save_offset
9258 = info_ptr->altivec_save_offset - info_ptr->toc_size;
9259 }
9260 else
9261 info_ptr->toc_save_offset = info_ptr->cr_save_offset - info_ptr->toc_size;
4ce33b7f 9262 info_ptr->ehrd_offset = info_ptr->toc_save_offset - ehrd_size;
6b02f2a5 9263 info_ptr->lr_save_offset = reg_size;
9264 break;
a3bbc303 9265 }
9266
bb78803e 9267 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
9268 + info_ptr->gp_size
9269 + info_ptr->altivec_size
9270 + info_ptr->altivec_padding_size
9271 + info_ptr->vrsave_size
f19493d5 9272 + info_ptr->spe_gp_size
9273 + info_ptr->spe_padding_size
bb78803e 9274 + ehrd_size
9275 + info_ptr->cr_size
9276 + info_ptr->lr_size
9277 + info_ptr->vrsave_size
9278 + info_ptr->toc_size,
9279 (TARGET_ALTIVEC_ABI || ABI_DARWIN)
9280 ? 16 : 8);
9281
1a6e5ea0 9282 total_raw_size = (info_ptr->vars_size
9283 + info_ptr->parm_size
1a6e5ea0 9284 + info_ptr->save_size
9285 + info_ptr->varargs_size
9286 + info_ptr->fixed_size);
9287
970e222f 9288 info_ptr->total_size =
9289 RS6000_ALIGN (total_raw_size, ABI_STACK_BOUNDARY / BITS_PER_UNIT);
1a6e5ea0 9290
9291 /* Determine if we need to allocate any stack frame:
9292
970e222f 9293 For AIX we need to push the stack if a frame pointer is needed
9294 (because the stack might be dynamically adjusted), if we are
9295 debugging, if we make calls, or if the sum of fp_save, gp_save,
9296 and local variables are more than the space needed to save all
9297 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
9298 + 18*8 = 288 (GPR13 reserved).
1a6e5ea0 9299
970e222f 9300 For V.4 we don't have the stack cushion that AIX uses, but assume
9301 that the debugger can handle stackless frames. */
1a6e5ea0 9302
9303 if (info_ptr->calls_p)
9304 info_ptr->push_p = 1;
9305
e7ce8542 9306 else if (abi == ABI_V4)
3bc7190a 9307 info_ptr->push_p = total_raw_size > info_ptr->fixed_size;
1a6e5ea0 9308
9309 else
9310 info_ptr->push_p = (frame_pointer_needed
80d725d7 9311 || (abi != ABI_DARWIN && write_symbols != NO_DEBUG)
1a6e5ea0 9312 || ((total_raw_size - info_ptr->fixed_size)
5f87920d 9313 > (TARGET_32BIT ? 220 : 288)));
1a6e5ea0 9314
970e222f 9315 /* Zero offsets if we're not saving those registers. */
1924028c 9316 if (info_ptr->fp_size == 0)
a3bbc303 9317 info_ptr->fp_save_offset = 0;
9318
1924028c 9319 if (info_ptr->gp_size == 0)
a3bbc303 9320 info_ptr->gp_save_offset = 0;
9321
bb78803e 9322 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
9323 info_ptr->altivec_save_offset = 0;
9324
9325 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
9326 info_ptr->vrsave_save_offset = 0;
9327
f19493d5 9328 if (! TARGET_SPE_ABI || info_ptr->spe_gp_size == 0)
9329 info_ptr->spe_gp_save_offset = 0;
9330
a516dd3a 9331 if (! info_ptr->lr_save_p)
a3bbc303 9332 info_ptr->lr_save_offset = 0;
9333
a516dd3a 9334 if (! info_ptr->cr_save_p)
a3bbc303 9335 info_ptr->cr_save_offset = 0;
9336
a516dd3a 9337 if (! info_ptr->toc_save_p)
6b02f2a5 9338 info_ptr->toc_save_offset = 0;
9339
a3bbc303 9340 return info_ptr;
9341}
9342
9343void
9344debug_stack_info (info)
9345 rs6000_stack_t *info;
d1bd513e 9346{
c0256c4b 9347 const char *abi_string;
7db9c9c6 9348
a516dd3a 9349 if (! info)
a3bbc303 9350 info = rs6000_stack_info ();
9351
9352 fprintf (stderr, "\nStack information for function %s:\n",
9353 ((current_function_decl && DECL_NAME (current_function_decl))
9354 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
9355 : "<unknown>"));
9356
7db9c9c6 9357 switch (info->abi)
9358 {
6b02f2a5 9359 default: abi_string = "Unknown"; break;
9360 case ABI_NONE: abi_string = "NONE"; break;
e7ce8542 9361 case ABI_AIX:
6b02f2a5 9362 case ABI_AIX_NODESC: abi_string = "AIX"; break;
80d725d7 9363 case ABI_DARWIN: abi_string = "Darwin"; break;
6b02f2a5 9364 case ABI_V4: abi_string = "V.4"; break;
7db9c9c6 9365 }
9366
9367 fprintf (stderr, "\tABI = %5s\n", abi_string);
9368
bb78803e 9369 if (TARGET_ALTIVEC_ABI)
9370 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
9371
f19493d5 9372 if (TARGET_SPE_ABI)
9373 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
9374
a3bbc303 9375 if (info->first_gp_reg_save != 32)
9376 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
9377
9378 if (info->first_fp_reg_save != 64)
9379 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
d1bd513e 9380
bb78803e 9381 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
9382 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
9383 info->first_altivec_reg_save);
9384
a3bbc303 9385 if (info->lr_save_p)
9386 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
d1bd513e 9387
a3bbc303 9388 if (info->cr_save_p)
9389 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
9390
6b02f2a5 9391 if (info->toc_save_p)
9392 fprintf (stderr, "\ttoc_save_p = %5d\n", info->toc_save_p);
9393
bb78803e 9394 if (info->vrsave_mask)
9395 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
9396
a3bbc303 9397 if (info->push_p)
9398 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
9399
9400 if (info->calls_p)
9401 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
9402
a3bbc303 9403 if (info->gp_save_offset)
9404 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
9405
9406 if (info->fp_save_offset)
9407 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
9408
bb78803e 9409 if (info->altivec_save_offset)
9410 fprintf (stderr, "\taltivec_save_offset = %5d\n",
9411 info->altivec_save_offset);
9412
f19493d5 9413 if (info->spe_gp_save_offset)
9414 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
9415 info->spe_gp_save_offset);
9416
bb78803e 9417 if (info->vrsave_save_offset)
9418 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
9419 info->vrsave_save_offset);
9420
a3bbc303 9421 if (info->lr_save_offset)
9422 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
9423
9424 if (info->cr_save_offset)
9425 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
9426
6b02f2a5 9427 if (info->toc_save_offset)
9428 fprintf (stderr, "\ttoc_save_offset = %5d\n", info->toc_save_offset);
9429
a3bbc303 9430 if (info->varargs_save_offset)
9431 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
9432
9433 if (info->total_size)
9434 fprintf (stderr, "\ttotal_size = %5d\n", info->total_size);
9435
9436 if (info->varargs_size)
9437 fprintf (stderr, "\tvarargs_size = %5d\n", info->varargs_size);
9438
9439 if (info->vars_size)
9440 fprintf (stderr, "\tvars_size = %5d\n", info->vars_size);
9441
9442 if (info->parm_size)
9443 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
9444
9445 if (info->fixed_size)
9446 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
9447
9448 if (info->gp_size)
9449 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
9450
f19493d5 9451 if (info->spe_gp_size)
9452 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
9453
a3bbc303 9454 if (info->fp_size)
9455 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
9456
bb78803e 9457 if (info->altivec_size)
9458 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
9459
9460 if (info->vrsave_size)
9461 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
9462
9463 if (info->altivec_padding_size)
9464 fprintf (stderr, "\taltivec_padding_size= %5d\n",
9465 info->altivec_padding_size);
9466
f19493d5 9467 if (info->spe_padding_size)
9468 fprintf (stderr, "\tspe_padding_size = %5d\n",
9469 info->spe_padding_size);
9470
970e222f 9471 if (info->lr_size)
979b4d09 9472 fprintf (stderr, "\tlr_size = %5d\n", info->lr_size);
6b02f2a5 9473
a3bbc303 9474 if (info->cr_size)
9475 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
9476
970e222f 9477 if (info->toc_size)
6b02f2a5 9478 fprintf (stderr, "\ttoc_size = %5d\n", info->toc_size);
9479
a3bbc303 9480 if (info->save_size)
9481 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
9482
9483 if (info->reg_size != 4)
9484 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
9485
9486 fprintf (stderr, "\n");
d1bd513e 9487}
8f474918 9488
9489rtx
9490rs6000_return_addr (count, frame)
9491 int count;
9492 rtx frame;
9493{
970e222f 9494 /* Currently we don't optimize very well between prolog and body
9495 code and for PIC code the code can be actually quite bad, so
9496 don't try to be too clever here. */
fc54b737 9497 if (count != 0 || flag_pic != 0)
8f474918 9498 {
9499 cfun->machine->ra_needs_full_frame = 1;
2a631e19 9500
9501 return
9502 gen_rtx_MEM
9503 (Pmode,
9504 memory_address
9505 (Pmode,
9506 plus_constant (copy_to_reg
9507 (gen_rtx_MEM (Pmode,
9508 memory_address (Pmode, frame))),
9509 RETURN_ADDRESS_OFFSET)));
8f474918 9510 }
9511
01d08833 9512 return get_hard_reg_initial_val (Pmode, LINK_REGISTER_REGNUM);
8f474918 9513}
9514
f7915167 9515/* Say whether a function is a candidate for sibcall handling or not.
9516 We do not allow indirect calls to be optimized into sibling calls.
9517 Also, we can't do it if there are any vector parameters; there's
9518 nowhere to put the VRsave code so it works; note that functions with
9519 vector parameters are required to have a prototype, so the argument
9520 type info must be available here. (The tail recursion case can work
9521 with vector parameters, but there's no way to distinguish here.) */
805e22b2 9522static bool
9523rs6000_function_ok_for_sibcall (decl, exp)
9524 tree decl;
9525 tree exp ATTRIBUTE_UNUSED;
f7915167 9526{
9527 tree type;
805e22b2 9528 if (decl)
f7915167 9529 {
9530 if (TARGET_ALTIVEC_VRSAVE)
9531 {
805e22b2 9532 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
f7915167 9533 type; type = TREE_CHAIN (type))
9534 {
c45eb3fc 9535 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
805e22b2 9536 return false;
f7915167 9537 }
9538 }
9539 if (DEFAULT_ABI == ABI_DARWIN
805e22b2 9540 || (*targetm.binds_local_p) (decl))
4e06ed1d 9541 {
805e22b2 9542 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
4e06ed1d 9543
9544 if (!lookup_attribute ("longcall", attr_list)
9545 || lookup_attribute ("shortcall", attr_list))
805e22b2 9546 return true;
4e06ed1d 9547 }
f7915167 9548 }
805e22b2 9549 return false;
f7915167 9550}
9551
8f474918 9552static int
9553rs6000_ra_ever_killed ()
9554{
9555 rtx top;
f7915167 9556 rtx reg;
9557 rtx insn;
8f474918 9558
eb344f43 9559 /* Irritatingly, there are two kinds of thunks -- those created with
9560 TARGET_ASM_OUTPUT_MI_THUNK and those with DECL_THUNK_P that go
9561 through the regular part of the compiler. This is a very hacky
9562 way to tell them apart. */
9563 if (current_function_is_thunk && !no_new_pseudos)
8f474918 9564 return 0;
e7f5e241 9565
a2041fb6 9566 /* regs_ever_live has LR marked as used if any sibcalls are present,
9567 but this should not force saving and restoring in the
9568 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
9569 clobbers LR, so that is inappropriate. */
9570
f7915167 9571 /* Also, the prologue can generate a store into LR that
9572 doesn't really count, like this:
a2041fb6 9573
f7915167 9574 move LR->R0
9575 bcl to set PIC register
9576 move LR->R31
9577 move R0->LR
a2041fb6 9578
9579 When we're called from the epilogue, we need to avoid counting
9580 this as a store. */
f7915167 9581
8f474918 9582 push_topmost_sequence ();
9583 top = get_insns ();
9584 pop_topmost_sequence ();
f7915167 9585 reg = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
8f474918 9586
f7915167 9587 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
9588 {
9589 if (INSN_P (insn))
9590 {
9591 if (FIND_REG_INC_NOTE (insn, reg))
9592 return 1;
9593 else if (GET_CODE (insn) == CALL_INSN
c45eb3fc 9594 && !SIBLING_CALL_P (insn))
f7915167 9595 return 1;
a2041fb6 9596 else if (set_of (reg, insn) != NULL_RTX
9597 && !prologue_epilogue_contains (insn))
f7915167 9598 return 1;
9599 }
9600 }
9601 return 0;
8f474918 9602}
a3bbc303 9603\f
efc2922d 9604/* Add a REG_MAYBE_DEAD note to the insn. */
9605static void
9606rs6000_maybe_dead (insn)
9607 rtx insn;
9608{
9609 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,
9610 const0_rtx,
9611 REG_NOTES (insn));
9612}
9613
bbd21807 9614/* Emit instructions needed to load the TOC register.
3f0190d6 9615 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
bbd21807 9616 a constant pool; or for SVR4 -fpic. */
3f0190d6 9617
9618void
bbd21807 9619rs6000_emit_load_toc_table (fromprolog)
9620 int fromprolog;
3f0190d6 9621{
bbd21807 9622 rtx dest;
479d644a 9623 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
3f0190d6 9624
9f6ef744 9625 if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
9626 {
9627 rtx temp = (fromprolog
9628 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
9629 : gen_reg_rtx (Pmode));
9630 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_pic_si (temp)));
9631 rs6000_maybe_dead (emit_move_insn (dest, temp));
9632 }
9633 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
9634 {
9635 char buf[30];
9636 rtx tempLR = (fromprolog
9637 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
9638 : gen_reg_rtx (Pmode));
9639 rtx temp0 = (fromprolog
9640 ? gen_rtx_REG (Pmode, 0)
9641 : gen_reg_rtx (Pmode));
9642 rtx symF;
9643
9644 /* possibly create the toc section */
9645 if (! toc_initialized)
bda6fa4d 9646 {
9f6ef744 9647 toc_section ();
9648 function_section (current_function_decl);
bda6fa4d 9649 }
bbd21807 9650
9f6ef744 9651 if (fromprolog)
9652 {
9653 rtx symL;
bda6fa4d 9654
9f6ef744 9655 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
9656 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
bbd21807 9657
9f6ef744 9658 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
9659 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9660
9661 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1 (tempLR,
9662 symF)));
9663 rs6000_maybe_dead (emit_move_insn (dest, tempLR));
9664 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest,
9665 symL,
9666 symF)));
bbd21807 9667 }
9668 else
9f6ef744 9669 {
9670 rtx tocsym;
9671 static int reload_toc_labelno = 0;
9672
9673 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
9674
9675 ASM_GENERATE_INTERNAL_LABEL (buf, "LCG", reload_toc_labelno++);
9676 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9677
9678 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1b (tempLR,
9679 symF,
9680 tocsym)));
9681 rs6000_maybe_dead (emit_move_insn (dest, tempLR));
9682 rs6000_maybe_dead (emit_move_insn (temp0,
9683 gen_rtx_MEM (Pmode, dest)));
9684 }
9685 rs6000_maybe_dead (emit_insn (gen_addsi3 (dest, temp0, dest)));
bbd21807 9686 }
9f6ef744 9687 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
9688 {
9689 /* This is for AIX code running in non-PIC ELF32. */
9690 char buf[30];
9691 rtx realsym;
9692 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
9693 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9694
9695 rs6000_maybe_dead (emit_insn (gen_elf_high (dest, realsym)));
9696 rs6000_maybe_dead (emit_insn (gen_elf_low (dest, dest, realsym)));
9697 }
9698 else if (DEFAULT_ABI == ABI_AIX)
bbd21807 9699 {
9700 if (TARGET_32BIT)
9f6ef744 9701 rs6000_maybe_dead (emit_insn (gen_load_toc_aix_si (dest)));
bbd21807 9702 else
9f6ef744 9703 rs6000_maybe_dead (emit_insn (gen_load_toc_aix_di (dest)));
bbd21807 9704 }
9f6ef744 9705 else
9706 abort ();
bbd21807 9707}
9708
9709int
9710get_TOC_alias_set ()
9711{
9712 static int set = -1;
9713 if (set == -1)
9714 set = new_alias_set ();
9715 return set;
9716}
9717
9718/* This retuns nonzero if the current function uses the TOC. This is
9719 determined by the presence of (unspec ... 7), which is generated by
9720 the various load_toc_* patterns. */
970e222f 9721
bbd21807 9722int
9723uses_TOC ()
9724{
9725 rtx insn;
bda6fa4d 9726
bbd21807 9727 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
9204e736 9728 if (INSN_P (insn))
bbd21807 9729 {
9730 rtx pat = PATTERN (insn);
9731 int i;
9732
efc2922d 9733 if (GET_CODE (pat) == PARALLEL)
bbd21807 9734 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
9735 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == UNSPEC
9736 && XINT (XVECEXP (PATTERN (insn), 0, i), 1) == 7)
9737 return 1;
bda6fa4d 9738 }
bbd21807 9739 return 0;
9740}
bda6fa4d 9741
bbd21807 9742rtx
970e222f 9743create_TOC_reference (symbol)
bbd21807 9744 rtx symbol;
9745{
ec6cb94a 9746 return gen_rtx_PLUS (Pmode,
9747 gen_rtx_REG (Pmode, TOC_REGISTER),
9748 gen_rtx_CONST (Pmode,
9749 gen_rtx_MINUS (Pmode, symbol,
107be538 9750 gen_rtx_SYMBOL_REF (Pmode, toc_label_name))));
bbd21807 9751}
bda6fa4d 9752
bbd21807 9753#if TARGET_AIX
9754/* __throw will restore its own return address to be the same as the
9755 return address of the function that the throw is being made to.
9756 This is unfortunate, because we want to check the original
9757 return address to see if we need to restore the TOC.
9758 So we have to squirrel it away here.
9759 This is used only in compiling __throw and __rethrow.
3f0190d6 9760
bbd21807 9761 Most of this code should be removed by CSE. */
9762static rtx insn_after_throw;
3f0190d6 9763
970e222f 9764/* This does the saving... */
bbd21807 9765void
9766rs6000_aix_emit_builtin_unwind_init ()
9767{
9768 rtx mem;
9769 rtx stack_top = gen_reg_rtx (Pmode);
9770 rtx opcode_addr = gen_reg_rtx (Pmode);
9771
9772 insn_after_throw = gen_reg_rtx (SImode);
9773
9774 mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
9775 emit_move_insn (stack_top, mem);
9776
9777 mem = gen_rtx_MEM (Pmode,
9778 gen_rtx_PLUS (Pmode, stack_top,
9779 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
9780 emit_move_insn (opcode_addr, mem);
9781 emit_move_insn (insn_after_throw, gen_rtx_MEM (SImode, opcode_addr));
3f0190d6 9782}
9783
970e222f 9784/* Emit insns to _restore_ the TOC register, at runtime (specifically
9785 in _eh.o). Only used on AIX.
bbd21807 9786
9787 The idea is that on AIX, function calls look like this:
9788 bl somefunction-trampoline
9789 lwz r2,20(sp)
9790
970e222f 9791 and later,
bbd21807 9792 somefunction-trampoline:
9793 stw r2,20(sp)
9794 ... load function address in the count register ...
9795 bctr
9796 or like this, if the linker determines that this is not a cross-module call
9797 and so the TOC need not be restored:
9798 bl somefunction
9799 nop
9800 or like this, if the compiler could determine that this is not a
9801 cross-module call:
9802 bl somefunction
9803 now, the tricky bit here is that register 2 is saved and restored
9804 by the _linker_, so we can't readily generate debugging information
9805 for it. So we need to go back up the call chain looking at the
9806 insns at return addresses to see which calls saved the TOC register
9807 and so see where it gets restored from.
9808
9809 Oh, and all this gets done in RTL inside the eh_epilogue pattern,
9810 just before the actual epilogue.
9811
9812 On the bright side, this incurs no space or time overhead unless an
9813 exception is thrown, except for the extra code in libgcc.a.
9814
9815 The parameter STACKSIZE is a register containing (at runtime)
9816 the amount to be popped off the stack in addition to the stack frame
9817 of this routine (which will be __throw or __rethrow, and so is
9818 guaranteed to have a stack frame). */
970e222f 9819
bbd21807 9820void
9821rs6000_emit_eh_toc_restore (stacksize)
9822 rtx stacksize;
9823{
9824 rtx top_of_stack;
9825 rtx bottom_of_stack = gen_reg_rtx (Pmode);
9826 rtx tocompare = gen_reg_rtx (SImode);
9827 rtx opcode = gen_reg_rtx (SImode);
9828 rtx opcode_addr = gen_reg_rtx (Pmode);
9829 rtx mem;
9830 rtx loop_start = gen_label_rtx ();
9831 rtx no_toc_restore_needed = gen_label_rtx ();
9832 rtx loop_exit = gen_label_rtx ();
9833
9834 mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
ab6ab77e 9835 set_mem_alias_set (mem, rs6000_sr_alias_set);
bbd21807 9836 emit_move_insn (bottom_of_stack, mem);
9837
9838 top_of_stack = expand_binop (Pmode, add_optab,
9839 bottom_of_stack, stacksize,
9840 NULL_RTX, 1, OPTAB_WIDEN);
9841
2d232d05 9842 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
9843 : 0xE8410028, SImode));
bbd21807 9844
9845 if (insn_after_throw == NULL_RTX)
970e222f 9846 abort ();
bbd21807 9847 emit_move_insn (opcode, insn_after_throw);
9848
d946ea19 9849 emit_note (NULL, NOTE_INSN_LOOP_BEG);
bbd21807 9850 emit_label (loop_start);
9851
9852 do_compare_rtx_and_jump (opcode, tocompare, NE, 1,
5c0586b9 9853 SImode, NULL_RTX, NULL_RTX,
bbd21807 9854 no_toc_restore_needed);
9855
9856 mem = gen_rtx_MEM (Pmode,
9857 gen_rtx_PLUS (Pmode, bottom_of_stack,
9858 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
9859 emit_move_insn (gen_rtx_REG (Pmode, 2), mem);
9860
9861 emit_label (no_toc_restore_needed);
9862 do_compare_rtx_and_jump (top_of_stack, bottom_of_stack, EQ, 1,
5c0586b9 9863 Pmode, NULL_RTX, NULL_RTX,
bbd21807 9864 loop_exit);
9865
9866 mem = gen_rtx_MEM (Pmode, bottom_of_stack);
ab6ab77e 9867 set_mem_alias_set (mem, rs6000_sr_alias_set);
bbd21807 9868 emit_move_insn (bottom_of_stack, mem);
9869
9870 mem = gen_rtx_MEM (Pmode,
9871 gen_rtx_PLUS (Pmode, bottom_of_stack,
9872 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
9873 emit_move_insn (opcode_addr, mem);
9874 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
9875
d946ea19 9876 emit_note (NULL, NOTE_INSN_LOOP_CONT);
bbd21807 9877 emit_jump (loop_start);
d946ea19 9878 emit_note (NULL, NOTE_INSN_LOOP_END);
bbd21807 9879 emit_label (loop_exit);
9880}
9881#endif /* TARGET_AIX */
bda6fa4d 9882\f
ab6ab77e 9883/* This ties together stack memory (MEM with an alias set of
9884 rs6000_sr_alias_set) and the change to the stack pointer. */
9885
bbd21807 9886static void
9887rs6000_emit_stack_tie ()
9888{
ab6ab77e 9889 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
9890
9891 set_mem_alias_set (mem, rs6000_sr_alias_set);
bbd21807 9892 emit_insn (gen_stack_tie (mem));
9893}
bda6fa4d 9894
bbd21807 9895/* Emit the correct code for allocating stack space, as insns.
9896 If COPY_R12, make sure a copy of the old frame is left in r12.
9897 The generated code may use hard register 0 as a temporary. */
9898
9899static void
9900rs6000_emit_allocate_stack (size, copy_r12)
9901 HOST_WIDE_INT size;
bda6fa4d 9902 int copy_r12;
9903{
bbd21807 9904 rtx insn;
9905 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
9906 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
9907 rtx todec = GEN_INT (-size);
8f8ac140 9908
9909 if (current_function_limit_stack)
9910 {
9911 if (REG_P (stack_limit_rtx)
9912 && REGNO (stack_limit_rtx) > 1
9913 && REGNO (stack_limit_rtx) <= 31)
9914 {
bbd21807 9915 emit_insn (Pmode == SImode
9916 ? gen_addsi3 (tmp_reg,
9917 stack_limit_rtx,
9918 GEN_INT (size))
9919 : gen_adddi3 (tmp_reg,
9920 stack_limit_rtx,
9921 GEN_INT (size)));
9922
9923 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
9924 const0_rtx));
8f8ac140 9925 }
9926 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
bbd21807 9927 && TARGET_32BIT
e7ce8542 9928 && DEFAULT_ABI == ABI_V4)
8f8ac140 9929 {
bbd21807 9930 rtx toload = gen_rtx_CONST (VOIDmode,
9931 gen_rtx_PLUS (Pmode,
9932 stack_limit_rtx,
9933 GEN_INT (size)));
9934
9935 emit_insn (gen_elf_high (tmp_reg, toload));
9936 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
9937 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
9938 const0_rtx));
8f8ac140 9939 }
9940 else
9941 warning ("stack limit expression is not supported");
9942 }
9943
bbd21807 9944 if (copy_r12 || ! TARGET_UPDATE)
9945 emit_move_insn (gen_rtx_REG (Pmode, 12), stack_reg);
9946
bda6fa4d 9947 if (TARGET_UPDATE)
9948 {
bbd21807 9949 if (size > 32767)
bda6fa4d 9950 {
bbd21807 9951 /* Need a note here so that try_split doesn't get confused. */
9952 if (get_last_insn() == NULL_RTX)
9953 emit_note (0, NOTE_INSN_DELETED);
9954 insn = emit_move_insn (tmp_reg, todec);
9955 try_split (PATTERN (insn), insn, 0);
9956 todec = tmp_reg;
bda6fa4d 9957 }
bbd21807 9958
9959 if (Pmode == SImode)
9960 insn = emit_insn (gen_movsi_update (stack_reg, stack_reg,
9961 todec, stack_reg));
9962 else
9963 insn = emit_insn (gen_movdi_update (stack_reg, stack_reg,
9964 todec, stack_reg));
bda6fa4d 9965 }
9966 else
9967 {
bbd21807 9968 if (Pmode == SImode)
9969 insn = emit_insn (gen_addsi3 (stack_reg, stack_reg, todec));
bda6fa4d 9970 else
bbd21807 9971 insn = emit_insn (gen_adddi3 (stack_reg, stack_reg, todec));
9972 emit_move_insn (gen_rtx_MEM (Pmode, stack_reg),
9973 gen_rtx_REG (Pmode, 12));
9974 }
9975
9976 RTX_FRAME_RELATED_P (insn) = 1;
9977 REG_NOTES (insn) =
9978 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
9979 gen_rtx_SET (VOIDmode, stack_reg,
9980 gen_rtx_PLUS (Pmode, stack_reg,
9981 GEN_INT (-size))),
9982 REG_NOTES (insn));
9983}
9984
43b7e951 9985/* Add a RTX_FRAME_RELATED note so that dwarf2out_frame_debug_expr
9986 knows that:
9987
9988 (mem (plus (blah) (regXX)))
9989
9990 is really:
9991
9992 (mem (plus (blah) (const VALUE_OF_REGXX))). */
9993
9994static void
9995altivec_frame_fixup (insn, reg, val)
9996 rtx insn, reg;
9997 HOST_WIDE_INT val;
9998{
9999 rtx real;
10000
10001 real = copy_rtx (PATTERN (insn));
10002
10003 real = replace_rtx (real, reg, GEN_INT (val));
10004
10005 RTX_FRAME_RELATED_P (insn) = 1;
10006 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
10007 real,
10008 REG_NOTES (insn));
10009}
10010
970e222f 10011/* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
10012 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
10013 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
10014 deduce these equivalences by itself so it wasn't necessary to hold
10015 its hand so much. */
bbd21807 10016
10017static void
10018rs6000_frame_related (insn, reg, val, reg2, rreg)
10019 rtx insn;
10020 rtx reg;
10021 HOST_WIDE_INT val;
10022 rtx reg2;
10023 rtx rreg;
10024{
10025 rtx real, temp;
10026
fa21d128 10027 /* copy_rtx will not make unique copies of registers, so we need to
10028 ensure we don't have unwanted sharing here. */
10029 if (reg == reg2)
10030 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
10031
10032 if (reg == rreg)
10033 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
10034
bbd21807 10035 real = copy_rtx (PATTERN (insn));
10036
012f60b0 10037 if (reg2 != NULL_RTX)
10038 real = replace_rtx (real, reg2, rreg);
10039
bbd21807 10040 real = replace_rtx (real, reg,
10041 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
10042 STACK_POINTER_REGNUM),
10043 GEN_INT (val)));
10044
10045 /* We expect that 'real' is either a SET or a PARALLEL containing
10046 SETs (and possibly other stuff). In a PARALLEL, all the SETs
10047 are important so they all have to be marked RTX_FRAME_RELATED_P. */
10048
10049 if (GET_CODE (real) == SET)
10050 {
10051 rtx set = real;
10052
10053 temp = simplify_rtx (SET_SRC (set));
10054 if (temp)
10055 SET_SRC (set) = temp;
10056 temp = simplify_rtx (SET_DEST (set));
10057 if (temp)
10058 SET_DEST (set) = temp;
10059 if (GET_CODE (SET_DEST (set)) == MEM)
bda6fa4d 10060 {
bbd21807 10061 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
10062 if (temp)
10063 XEXP (SET_DEST (set), 0) = temp;
bda6fa4d 10064 }
bda6fa4d 10065 }
bbd21807 10066 else if (GET_CODE (real) == PARALLEL)
10067 {
10068 int i;
10069 for (i = 0; i < XVECLEN (real, 0); i++)
10070 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
10071 {
10072 rtx set = XVECEXP (real, 0, i);
10073
10074 temp = simplify_rtx (SET_SRC (set));
10075 if (temp)
10076 SET_SRC (set) = temp;
10077 temp = simplify_rtx (SET_DEST (set));
10078 if (temp)
10079 SET_DEST (set) = temp;
10080 if (GET_CODE (SET_DEST (set)) == MEM)
10081 {
10082 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
10083 if (temp)
10084 XEXP (SET_DEST (set), 0) = temp;
10085 }
10086 RTX_FRAME_RELATED_P (set) = 1;
10087 }
10088 }
10089 else
970e222f 10090 abort ();
bbd21807 10091
bbd21807 10092 RTX_FRAME_RELATED_P (insn) = 1;
10093 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
10094 real,
10095 REG_NOTES (insn));
bda6fa4d 10096}
10097
bb78803e 10098/* Returns an insn that has a vrsave set operation with the
10099 appropriate CLOBBERs. */
10100
10101static rtx
43b7e951 10102generate_set_vrsave (reg, info, epiloguep)
bb78803e 10103 rtx reg;
10104 rs6000_stack_t *info;
43b7e951 10105 int epiloguep;
bb78803e 10106{
10107 int nclobs, i;
10108 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
3affb0ca 10109 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
bb78803e 10110
3affb0ca 10111 clobs[0]
10112 = gen_rtx_SET (VOIDmode,
10113 vrsave,
10114 gen_rtx_UNSPEC_VOLATILE (SImode,
10115 gen_rtvec (2, reg, vrsave),
10116 30));
bb78803e 10117
10118 nclobs = 1;
10119
43b7e951 10120 /* We need to clobber the registers in the mask so the scheduler
10121 does not move sets to VRSAVE before sets of AltiVec registers.
10122
10123 However, if the function receives nonlocal gotos, reload will set
10124 all call saved registers live. We will end up with:
10125
10126 (set (reg 999) (mem))
10127 (parallel [ (set (reg vrsave) (unspec blah))
10128 (clobber (reg 999))])
10129
10130 The clobber will cause the store into reg 999 to be dead, and
10131 flow will attempt to delete an epilogue insn. In this case, we
10132 need an unspec use/set of the register. */
bb78803e 10133
10134 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
10135 if (info->vrsave_mask != 0 && ALTIVEC_REG_BIT (i) != 0)
43b7e951 10136 {
10137 if (!epiloguep || call_used_regs [i])
10138 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
10139 gen_rtx_REG (V4SImode, i));
10140 else
10141 {
10142 rtx reg = gen_rtx_REG (V4SImode, i);
43b7e951 10143
10144 clobs[nclobs++]
3affb0ca 10145 = gen_rtx_SET (VOIDmode,
10146 reg,
10147 gen_rtx_UNSPEC (V4SImode,
10148 gen_rtvec (1, reg), 27));
43b7e951 10149 }
10150 }
bb78803e 10151
10152 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
10153
10154 for (i = 0; i < nclobs; ++i)
10155 XVECEXP (insn, 0, i) = clobs[i];
10156
10157 return insn;
10158}
10159
012f60b0 10160/* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
10161 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
10162
10163static void
10164emit_frame_save (frame_reg, frame_ptr, mode, regno, offset, total_size)
10165 rtx frame_reg;
10166 rtx frame_ptr;
10167 enum machine_mode mode;
10168 unsigned int regno;
10169 int offset;
10170 int total_size;
10171{
10172 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
10173 rtx replacea, replaceb;
10174
10175 int_rtx = GEN_INT (offset);
10176
10177 /* Some cases that need register indexed addressing. */
10178 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
f19493d5 10179 || (TARGET_SPE_ABI
10180 && SPE_VECTOR_MODE (mode)
10181 && !SPE_CONST_OFFSET_OK (offset)))
012f60b0 10182 {
10183 /* Whomever calls us must make sure r11 is available in the
10184 flow path of instructions in the prologue. */
10185 offset_rtx = gen_rtx_REG (Pmode, 11);
10186 emit_move_insn (offset_rtx, int_rtx);
10187
10188 replacea = offset_rtx;
10189 replaceb = int_rtx;
10190 }
10191 else
10192 {
10193 offset_rtx = int_rtx;
10194 replacea = NULL_RTX;
10195 replaceb = NULL_RTX;
10196 }
10197
10198 reg = gen_rtx_REG (mode, regno);
10199 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
10200 mem = gen_rtx_MEM (mode, addr);
10201 set_mem_alias_set (mem, rs6000_sr_alias_set);
10202
10203 insn = emit_move_insn (mem, reg);
10204
10205 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
10206}
10207
f19493d5 10208/* Emit an offset memory reference suitable for a frame store, while
10209 converting to a valid addressing mode. */
10210
10211static rtx
10212gen_frame_mem_offset (mode, reg, offset)
10213 enum machine_mode mode;
10214 rtx reg;
10215 int offset;
10216{
10217 rtx int_rtx, offset_rtx;
10218
10219 int_rtx = GEN_INT (offset);
10220
10221 if (TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
10222 {
10223 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
10224 emit_move_insn (offset_rtx, int_rtx);
10225 }
10226 else
10227 offset_rtx = int_rtx;
10228
10229 return gen_rtx_MEM (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
10230}
10231
bbd21807 10232/* Emit function prologue as insns. */
10233
d1bd513e 10234void
4ce33b7f 10235rs6000_emit_prologue ()
d1bd513e 10236{
a3bbc303 10237 rs6000_stack_t *info = rs6000_stack_info ();
bbd21807 10238 enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
10239 int reg_size = TARGET_POWERPC64 ? 8 : 4;
10240 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
10241 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
10242 rtx frame_reg_rtx = sp_reg_rtx;
10243 rtx cr_save_rtx = NULL;
10244 rtx insn;
10245 int saving_FPRs_inline;
10246 int using_store_multiple;
10247 HOST_WIDE_INT sp_offset = 0;
10248
f19493d5 10249 if (TARGET_SPE_ABI)
10250 {
10251 reg_mode = V2SImode;
10252 reg_size = 8;
10253 }
10254
bbd21807 10255 using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
f19493d5 10256 && !TARGET_SPE_ABI
bbd21807 10257 && info->first_gp_reg_save < 31);
10258 saving_FPRs_inline = (info->first_fp_reg_save == 64
10259 || FP_SAVE_INLINE (info->first_fp_reg_save));
10260
10261 /* For V.4, update stack before we do any saving and set back pointer. */
e7ce8542 10262 if (info->push_p && DEFAULT_ABI == ABI_V4)
bbd21807 10263 {
10264 if (info->total_size < 32767)
10265 sp_offset = info->total_size;
10266 else
10267 frame_reg_rtx = frame_ptr_rtx;
10268 rs6000_emit_allocate_stack (info->total_size,
10269 (frame_reg_rtx != sp_reg_rtx
10270 && (info->cr_save_p
10271 || info->lr_save_p
10272 || info->first_fp_reg_save < 64
10273 || info->first_gp_reg_save < 32
10274 )));
10275 if (frame_reg_rtx != sp_reg_rtx)
10276 rs6000_emit_stack_tie ();
10277 }
10278
43b7e951 10279 /* Save AltiVec registers if needed. */
10280 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
10281 {
10282 int i;
10283
10284 /* There should be a non inline version of this, for when we
10285 are saving lots of vector registers. */
10286 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
10287 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
10288 {
10289 rtx areg, savereg, mem;
10290 int offset;
10291
10292 offset = info->altivec_save_offset + sp_offset
10293 + 16 * (i - info->first_altivec_reg_save);
10294
10295 savereg = gen_rtx_REG (V4SImode, i);
10296
10297 areg = gen_rtx_REG (Pmode, 0);
10298 emit_move_insn (areg, GEN_INT (offset));
10299
10300 /* AltiVec addressing mode is [reg+reg]. */
10301 mem = gen_rtx_MEM (V4SImode,
10302 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
10303
10304 set_mem_alias_set (mem, rs6000_sr_alias_set);
10305
10306 insn = emit_move_insn (mem, savereg);
10307
10308 altivec_frame_fixup (insn, areg, offset);
10309 }
10310 }
10311
10312 /* VRSAVE is a bit vector representing which AltiVec registers
10313 are used. The OS uses this to determine which vector
10314 registers to save on a context switch. We need to save
10315 VRSAVE on the stack frame, add whatever AltiVec registers we
10316 used in this function, and do the corresponding magic in the
10317 epilogue. */
10318
10319 if (TARGET_ALTIVEC && info->vrsave_mask != 0)
10320 {
3affb0ca 10321 rtx reg, mem, vrsave;
43b7e951 10322 int offset;
10323
10324 /* Get VRSAVE onto a GPR. */
10325 reg = gen_rtx_REG (SImode, 12);
3affb0ca 10326 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
894a5e3b 10327 if (TARGET_MACHO)
10328 emit_insn (gen_get_vrsave_internal (reg));
10329 else
10330 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
43b7e951 10331
10332 /* Save VRSAVE. */
10333 offset = info->vrsave_save_offset + sp_offset;
10334 mem
10335 = gen_rtx_MEM (SImode,
10336 gen_rtx_PLUS (Pmode, frame_reg_rtx, GEN_INT (offset)));
10337 set_mem_alias_set (mem, rs6000_sr_alias_set);
10338 insn = emit_move_insn (mem, reg);
10339
10340 /* Include the registers in the mask. */
10341 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
10342
10343 insn = emit_insn (generate_set_vrsave (reg, info, 0));
10344 }
10345
bbd21807 10346 /* If we use the link register, get it into r0. */
10347 if (info->lr_save_p)
8f474918 10348 emit_move_insn (gen_rtx_REG (Pmode, 0),
bbd21807 10349 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10350
10351 /* If we need to save CR, put it into r12. */
10352 if (info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
10353 {
10354 cr_save_rtx = gen_rtx_REG (SImode, 12);
10355 emit_insn (gen_movesi_from_cr (cr_save_rtx));
10356 }
10357
970e222f 10358 /* Do any required saving of fpr's. If only one or two to save, do
10359 it ourselves. Otherwise, call function. */
bbd21807 10360 if (saving_FPRs_inline)
10361 {
10362 int i;
10363 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10364 if ((regs_ever_live[info->first_fp_reg_save+i]
10365 && ! call_used_regs[info->first_fp_reg_save+i]))
012f60b0 10366 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, DFmode,
10367 info->first_fp_reg_save + i,
10368 info->fp_save_offset + sp_offset + 8 * i,
10369 info->total_size);
bbd21807 10370 }
10371 else if (info->first_fp_reg_save != 64)
10372 {
10373 int i;
10374 char rname[30];
44acf429 10375 const char *alloc_rname;
bbd21807 10376 rtvec p;
10377 p = rtvec_alloc (2 + 64 - info->first_fp_reg_save);
10378
10379 RTVEC_ELT (p, 0) = gen_rtx_CLOBBER (VOIDmode,
10380 gen_rtx_REG (Pmode,
10381 LINK_REGISTER_REGNUM));
10382 sprintf (rname, "%s%d%s", SAVE_FP_PREFIX,
10383 info->first_fp_reg_save - 32, SAVE_FP_SUFFIX);
ec6cb94a 10384 alloc_rname = ggc_strdup (rname);
bbd21807 10385 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
10386 gen_rtx_SYMBOL_REF (Pmode,
10387 alloc_rname));
10388 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10389 {
10390 rtx addr, reg, mem;
10391 reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
10392 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10393 GEN_INT (info->fp_save_offset
10394 + sp_offset + 8*i));
10395 mem = gen_rtx_MEM (DFmode, addr);
ab6ab77e 10396 set_mem_alias_set (mem, rs6000_sr_alias_set);
bbd21807 10397
10398 RTVEC_ELT (p, i + 2) = gen_rtx_SET (VOIDmode, mem, reg);
10399 }
10400 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
10401 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10402 NULL_RTX, NULL_RTX);
10403 }
6b02f2a5 10404
bbd21807 10405 /* Save GPRs. This is done as a PARALLEL if we are using
10406 the store-multiple instructions. */
10407 if (using_store_multiple)
6b02f2a5 10408 {
e08baea1 10409 rtvec p;
bbd21807 10410 int i;
10411 p = rtvec_alloc (32 - info->first_gp_reg_save);
bbd21807 10412 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
10413 {
10414 rtx addr, reg, mem;
10415 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
10416 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10417 GEN_INT (info->gp_save_offset
10418 + sp_offset
10419 + reg_size * i));
10420 mem = gen_rtx_MEM (reg_mode, addr);
ab6ab77e 10421 set_mem_alias_set (mem, rs6000_sr_alias_set);
bbd21807 10422
10423 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
10424 }
10425 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
10426 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10427 NULL_RTX, NULL_RTX);
6b02f2a5 10428 }
10429 else
10430 {
bbd21807 10431 int i;
10432 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
10433 if ((regs_ever_live[info->first_gp_reg_save+i]
10434 && ! call_used_regs[info->first_gp_reg_save+i])
479d644a 10435 || (i+info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
e7ce8542 10436 && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10437 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
f19493d5 10438 {
10439 rtx addr, reg, mem;
10440 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
10441
10442 if (TARGET_SPE_ABI)
10443 {
10444 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
10445 rtx b;
10446
10447 if (!SPE_CONST_OFFSET_OK (offset))
10448 {
10449 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
10450 emit_move_insn (b, GEN_INT (offset));
10451 }
10452 else
10453 b = GEN_INT (offset);
10454
10455 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
10456 mem = gen_rtx_MEM (V2SImode, addr);
10457 set_mem_alias_set (mem, rs6000_sr_alias_set);
10458 insn = emit_move_insn (mem, reg);
10459
10460 if (GET_CODE (b) == CONST_INT)
10461 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10462 NULL_RTX, NULL_RTX);
10463 else
10464 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10465 b, GEN_INT (offset));
10466 }
10467 else
10468 {
10469 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10470 GEN_INT (info->gp_save_offset
10471 + sp_offset
10472 + reg_size * i));
10473 mem = gen_rtx_MEM (reg_mode, addr);
10474 set_mem_alias_set (mem, rs6000_sr_alias_set);
10475
10476 insn = emit_move_insn (mem, reg);
10477 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10478 NULL_RTX, NULL_RTX);
10479 }
10480 }
bbd21807 10481 }
10482
4ce33b7f 10483 /* ??? There's no need to emit actual instructions here, but it's the
10484 easiest way to get the frame unwind information emitted. */
10485 if (current_function_calls_eh_return)
10486 {
42aeaad8 10487 unsigned int i, regno;
10488
4ce33b7f 10489 for (i = 0; ; ++i)
10490 {
4ce33b7f 10491 regno = EH_RETURN_DATA_REGNO (i);
10492 if (regno == INVALID_REGNUM)
10493 break;
10494
012f60b0 10495 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
10496 info->ehrd_offset + sp_offset
10497 + reg_size * (int) i,
10498 info->total_size);
4ce33b7f 10499 }
10500 }
10501
bbd21807 10502 /* Save lr if we used it. */
10503 if (info->lr_save_p)
10504 {
10505 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10506 GEN_INT (info->lr_save_offset + sp_offset));
10507 rtx reg = gen_rtx_REG (Pmode, 0);
10508 rtx mem = gen_rtx_MEM (Pmode, addr);
10509 /* This should not be of rs6000_sr_alias_set, because of
10510 __builtin_return_address. */
10511
10512 insn = emit_move_insn (mem, reg);
10513 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10514 reg, gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10515 }
10516
10517 /* Save CR if we use any that must be preserved. */
10518 if (info->cr_save_p)
10519 {
10520 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10521 GEN_INT (info->cr_save_offset + sp_offset));
10522 rtx mem = gen_rtx_MEM (SImode, addr);
ab6ab77e 10523
10524 set_mem_alias_set (mem, rs6000_sr_alias_set);
bbd21807 10525
10526 /* If r12 was used to hold the original sp, copy cr into r0 now
10527 that it's free. */
10528 if (REGNO (frame_reg_rtx) == 12)
10529 {
10530 cr_save_rtx = gen_rtx_REG (SImode, 0);
10531 emit_insn (gen_movesi_from_cr (cr_save_rtx));
10532 }
10533 insn = emit_move_insn (mem, cr_save_rtx);
10534
10535 /* Now, there's no way that dwarf2out_frame_debug_expr is going
10536 to understand '(unspec:SI [(reg:CC 68) ...] 19)'. But that's
10537 OK. All we have to do is specify that _one_ condition code
10538 register is saved in this stack slot. The thrower's epilogue
f5c9ea10 10539 will then restore all the call-saved registers.
10540 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
bbd21807 10541 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
f5c9ea10 10542 cr_save_rtx, gen_rtx_REG (SImode, CR2_REGNO));
bbd21807 10543 }
10544
10545 /* Update stack and set back pointer unless this is V.4,
10546 for which it was done previously. */
e7ce8542 10547 if (info->push_p && DEFAULT_ABI != ABI_V4)
bbd21807 10548 rs6000_emit_allocate_stack (info->total_size, FALSE);
10549
10550 /* Set frame pointer, if needed. */
10551 if (frame_pointer_needed)
10552 {
f19493d5 10553 insn = emit_move_insn (gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM),
bbd21807 10554 sp_reg_rtx);
10555 RTX_FRAME_RELATED_P (insn) = 1;
6b02f2a5 10556 }
d1bd513e 10557
479d644a 10558 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
bbd21807 10559 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
e7ce8542 10560 || (DEFAULT_ABI == ABI_V4 && flag_pic == 1
479d644a 10561 && regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM]))
bbd21807 10562 {
10563 /* If emit_load_toc_table will use the link register, we need to save
10564 it. We use R11 for this purpose because emit_load_toc_table
10565 can use register 0. This allows us to use a plain 'blr' to return
10566 from the procedure more often. */
aee5207b 10567 int save_LR_around_toc_setup = (TARGET_ELF && flag_pic != 0
10568 && ! info->lr_save_p
10569 && EXIT_BLOCK_PTR->pred != NULL);
bbd21807 10570 if (save_LR_around_toc_setup)
10571 emit_move_insn (gen_rtx_REG (Pmode, 11),
10572 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10573
10574 rs6000_emit_load_toc_table (TRUE);
10575
10576 if (save_LR_around_toc_setup)
10577 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
10578 gen_rtx_REG (Pmode, 11));
10579 }
80d725d7 10580
cf7d5bc7 10581#if TARGET_MACHO
80d725d7 10582 if (DEFAULT_ABI == ABI_DARWIN
10583 && flag_pic && current_function_uses_pic_offset_table)
10584 {
10585 rtx dest = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
46e442c7 10586 char *picbase = machopic_function_base_name ();
10587 rtx src = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (picbase, -1));
80d725d7 10588
46e442c7 10589 rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (dest, src)));
80d725d7 10590
10591 rs6000_maybe_dead (
479d644a 10592 emit_move_insn (gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM),
80d725d7 10593 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)));
10594 }
cf7d5bc7 10595#endif
bbd21807 10596}
10597
bbd21807 10598/* Write function prologue. */
970e222f 10599
17d9b0c3 10600static void
10601rs6000_output_function_prologue (file, size)
bbd21807 10602 FILE *file;
17d9b0c3 10603 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
bbd21807 10604{
10605 rs6000_stack_t *info = rs6000_stack_info ();
10606
a3bbc303 10607 if (TARGET_DEBUG_STACK)
10608 debug_stack_info (info);
d1bd513e 10609
970e222f 10610 /* Write .extern for any function we will call to save and restore
10611 fp values. */
10612 if (info->first_fp_reg_save < 64
10613 && !FP_SAVE_INLINE (info->first_fp_reg_save))
5a81dade 10614 fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
a3bbc303 10615 SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX,
970e222f 10616 RESTORE_FP_PREFIX, info->first_fp_reg_save - 32,
10617 RESTORE_FP_SUFFIX);
d1bd513e 10618
f789c138 10619 /* Write .extern for AIX common mode routines, if needed. */
10620 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
10621 {
75bebd93 10622 fputs ("\t.extern __mulh\n", file);
10623 fputs ("\t.extern __mull\n", file);
10624 fputs ("\t.extern __divss\n", file);
10625 fputs ("\t.extern __divus\n", file);
10626 fputs ("\t.extern __quoss\n", file);
10627 fputs ("\t.extern __quous\n", file);
f789c138 10628 common_mode_defined = 1;
10629 }
d1bd513e 10630
bbd21807 10631 if (! HAVE_prologue)
344f7625 10632 {
bbd21807 10633 start_sequence ();
02c2c577 10634
970e222f 10635 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
10636 the "toplevel" insn chain. */
bbd21807 10637 emit_note (0, NOTE_INSN_DELETED);
10638 rs6000_emit_prologue ();
10639 emit_note (0, NOTE_INSN_DELETED);
9f781781 10640
10641 /* Expand INSN_ADDRESSES so final() doesn't crash. */
10642 {
10643 rtx insn;
10644 unsigned addr = 0;
10645 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
10646 {
10647 INSN_ADDRESSES_NEW (insn, addr);
10648 addr += 4;
10649 }
10650 }
02c2c577 10651
bbd21807 10652 if (TARGET_DEBUG_STACK)
970e222f 10653 debug_rtx_list (get_insns (), 100);
10654 final (get_insns (), file, FALSE, FALSE);
bbd21807 10655 end_sequence ();
344f7625 10656 }
10657
bbd21807 10658 rs6000_pic_labelno++;
10659}
10660
10661/* Emit function epilogue as insns.
d1bd513e 10662
bbd21807 10663 At present, dwarf2out_frame_debug_expr doesn't understand
10664 register restores, so we don't bother setting RTX_FRAME_RELATED_P
10665 anywhere in the epilogue. Most of the insns below would in any case
10666 need special notes to explain where r11 is in relation to the stack. */
d1bd513e 10667
bbd21807 10668void
4ce33b7f 10669rs6000_emit_epilogue (sibcall)
bbd21807 10670 int sibcall;
10671{
10672 rs6000_stack_t *info;
10673 int restoring_FPRs_inline;
10674 int using_load_multiple;
10675 int using_mfcr_multiple;
10676 int use_backchain_to_restore_sp;
10677 int sp_offset = 0;
10678 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
10679 rtx frame_reg_rtx = sp_reg_rtx;
10680 enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
10681 int reg_size = TARGET_POWERPC64 ? 8 : 4;
10682 int i;
10683
f19493d5 10684 if (TARGET_SPE_ABI)
10685 {
10686 reg_mode = V2SImode;
10687 reg_size = 8;
10688 }
10689
bbd21807 10690 info = rs6000_stack_info ();
10691 using_load_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
f19493d5 10692 && !TARGET_SPE_ABI
bbd21807 10693 && info->first_gp_reg_save < 31);
10694 restoring_FPRs_inline = (sibcall
4ce33b7f 10695 || current_function_calls_eh_return
bbd21807 10696 || info->first_fp_reg_save == 64
10697 || FP_SAVE_INLINE (info->first_fp_reg_save));
10698 use_backchain_to_restore_sp = (frame_pointer_needed
10699 || current_function_calls_alloca
10700 || info->total_size > 32767);
10701 using_mfcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
10702 || rs6000_cpu == PROCESSOR_PPC603
10703 || rs6000_cpu == PROCESSOR_PPC750
10704 || optimize_size);
10705
10706 /* If we have a frame pointer, a call to alloca, or a large stack
10707 frame, restore the old stack pointer using the backchain. Otherwise,
10708 we know what size to update it with. */
10709 if (use_backchain_to_restore_sp)
87c3d372 10710 {
bbd21807 10711 /* Under V.4, don't reset the stack pointer until after we're done
10712 loading the saved registers. */
e7ce8542 10713 if (DEFAULT_ABI == ABI_V4)
bbd21807 10714 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
a3bbc303 10715
bbd21807 10716 emit_move_insn (frame_reg_rtx,
10717 gen_rtx_MEM (Pmode, sp_reg_rtx));
10718
87c3d372 10719 }
bbd21807 10720 else if (info->push_p)
c7cb5c53 10721 {
e7ce8542 10722 if (DEFAULT_ABI == ABI_V4)
bbd21807 10723 sp_offset = info->total_size;
10724 else
10725 {
10726 emit_insn (TARGET_32BIT
10727 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
10728 GEN_INT (info->total_size))
10729 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
10730 GEN_INT (info->total_size)));
10731 }
c7cb5c53 10732 }
bbd21807 10733
43b7e951 10734 /* Restore AltiVec registers if needed. */
10735 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
10736 {
10737 int i;
10738
10739 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
10740 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
10741 {
10742 rtx addr, areg, mem;
10743
10744 areg = gen_rtx_REG (Pmode, 0);
10745 emit_move_insn
10746 (areg, GEN_INT (info->altivec_save_offset
10747 + sp_offset
10748 + 16 * (i - info->first_altivec_reg_save)));
10749
10750 /* AltiVec addressing mode is [reg+reg]. */
10751 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
10752 mem = gen_rtx_MEM (V4SImode, addr);
10753 set_mem_alias_set (mem, rs6000_sr_alias_set);
10754
10755 emit_move_insn (gen_rtx_REG (V4SImode, i), mem);
10756 }
10757 }
10758
10759 /* Restore VRSAVE if needed. */
10760 if (TARGET_ALTIVEC_ABI && info->vrsave_mask != 0)
10761 {
10762 rtx addr, mem, reg;
10763
10764 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10765 GEN_INT (info->vrsave_save_offset + sp_offset));
10766 mem = gen_rtx_MEM (SImode, addr);
10767 set_mem_alias_set (mem, rs6000_sr_alias_set);
10768 reg = gen_rtx_REG (SImode, 12);
10769 emit_move_insn (reg, mem);
10770
10771 emit_insn (generate_set_vrsave (reg, info, 1));
10772 }
10773
bbd21807 10774 /* Get the old lr if we saved it. */
10775 if (info->lr_save_p)
6b02f2a5 10776 {
f19493d5 10777 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
10778 info->lr_save_offset + sp_offset);
ab6ab77e 10779
10780 set_mem_alias_set (mem, rs6000_sr_alias_set);
6b02f2a5 10781
bbd21807 10782 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
6b02f2a5 10783 }
bbd21807 10784
10785 /* Get the old cr if we saved it. */
10786 if (info->cr_save_p)
10787 {
10788 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10789 GEN_INT (info->cr_save_offset + sp_offset));
10790 rtx mem = gen_rtx_MEM (SImode, addr);
ab6ab77e 10791
10792 set_mem_alias_set (mem, rs6000_sr_alias_set);
6b02f2a5 10793
bbd21807 10794 emit_move_insn (gen_rtx_REG (SImode, 12), mem);
10795 }
10796
10797 /* Set LR here to try to overlap restores below. */
a3bbc303 10798 if (info->lr_save_p)
bbd21807 10799 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
10800 gen_rtx_REG (Pmode, 0));
10801
4ce33b7f 10802 /* Load exception handler data registers, if needed. */
10803 if (current_function_calls_eh_return)
10804 {
42aeaad8 10805 unsigned int i, regno;
10806
4ce33b7f 10807 for (i = 0; ; ++i)
10808 {
f19493d5 10809 rtx mem;
4ce33b7f 10810
10811 regno = EH_RETURN_DATA_REGNO (i);
10812 if (regno == INVALID_REGNUM)
10813 break;
10814
f19493d5 10815 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
10816 info->ehrd_offset + sp_offset
10817 + reg_size * (int) i);
ab6ab77e 10818 set_mem_alias_set (mem, rs6000_sr_alias_set);
4ce33b7f 10819
10820 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
10821 }
10822 }
bbd21807 10823
10824 /* Restore GPRs. This is done as a PARALLEL if we are using
10825 the load-multiple instructions. */
10826 if (using_load_multiple)
344f7625 10827 {
bbd21807 10828 rtvec p;
10829 p = rtvec_alloc (32 - info->first_gp_reg_save);
10830 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
344f7625 10831 {
bbd21807 10832 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10833 GEN_INT (info->gp_save_offset
10834 + sp_offset
10835 + reg_size * i));
10836 rtx mem = gen_rtx_MEM (reg_mode, addr);
ab6ab77e 10837
10838 set_mem_alias_set (mem, rs6000_sr_alias_set);
bbd21807 10839
10840 RTVEC_ELT (p, i) =
10841 gen_rtx_SET (VOIDmode,
10842 gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
10843 mem);
344f7625 10844 }
bbd21807 10845 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
344f7625 10846 }
bbd21807 10847 else
10848 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
10849 if ((regs_ever_live[info->first_gp_reg_save+i]
10850 && ! call_used_regs[info->first_gp_reg_save+i])
479d644a 10851 || (i+info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
e7ce8542 10852 && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10853 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
bbd21807 10854 {
10855 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10856 GEN_INT (info->gp_save_offset
10857 + sp_offset
10858 + reg_size * i));
10859 rtx mem = gen_rtx_MEM (reg_mode, addr);
ab6ab77e 10860
f19493d5 10861 /* Restore 64-bit quantities for SPE. */
10862 if (TARGET_SPE_ABI)
10863 {
10864 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
10865 rtx b;
10866
10867 if (!SPE_CONST_OFFSET_OK (offset))
10868 {
10869 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
10870 emit_move_insn (b, GEN_INT (offset));
10871 }
10872 else
10873 b = GEN_INT (offset);
10874
10875 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
10876 mem = gen_rtx_MEM (V2SImode, addr);
10877 }
10878
ab6ab77e 10879 set_mem_alias_set (mem, rs6000_sr_alias_set);
bbd21807 10880
10881 emit_move_insn (gen_rtx_REG (reg_mode,
f19493d5 10882 info->first_gp_reg_save + i), mem);
bbd21807 10883 }
d1bd513e 10884
bbd21807 10885 /* Restore fpr's if we need to do it without calling a function. */
10886 if (restoring_FPRs_inline)
10887 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10888 if ((regs_ever_live[info->first_fp_reg_save+i]
10889 && ! call_used_regs[info->first_fp_reg_save+i]))
10890 {
10891 rtx addr, mem;
10892 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10893 GEN_INT (info->fp_save_offset
10894 + sp_offset
970e222f 10895 + 8 * i));
bbd21807 10896 mem = gen_rtx_MEM (DFmode, addr);
ab6ab77e 10897 set_mem_alias_set (mem, rs6000_sr_alias_set);
bbd21807 10898
10899 emit_move_insn (gen_rtx_REG (DFmode,
10900 info->first_fp_reg_save + i),
10901 mem);
10902 }
38794c37 10903
bbd21807 10904 /* If we saved cr, restore it here. Just those that were used. */
10905 if (info->cr_save_p)
344f7625 10906 {
bbd21807 10907 rtx r12_rtx = gen_rtx_REG (SImode, 12);
90e1e7af 10908 int count = 0;
bbd21807 10909
10910 if (using_mfcr_multiple)
344f7625 10911 {
bbd21807 10912 for (i = 0; i < 8; i++)
10913 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
90e1e7af 10914 count++;
bbd21807 10915 if (count == 0)
90e1e7af 10916 abort ();
10917 }
10918
10919 if (using_mfcr_multiple && count > 1)
10920 {
10921 rtvec p;
10922 int ndx;
bbd21807 10923
90e1e7af 10924 p = rtvec_alloc (count);
bbd21807 10925
90e1e7af 10926 ndx = 0;
bbd21807 10927 for (i = 0; i < 8; i++)
10928 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
10929 {
10930 rtvec r = rtvec_alloc (2);
10931 RTVEC_ELT (r, 0) = r12_rtx;
10932 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
90e1e7af 10933 RTVEC_ELT (p, ndx) =
bbd21807 10934 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
10935 gen_rtx_UNSPEC (CCmode, r, 20));
90e1e7af 10936 ndx++;
bbd21807 10937 }
10938 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
90e1e7af 10939 if (ndx != count)
10940 abort ();
344f7625 10941 }
10942 else
bbd21807 10943 for (i = 0; i < 8; i++)
10944 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
344f7625 10945 {
bbd21807 10946 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
10947 CR0_REGNO+i),
10948 r12_rtx));
344f7625 10949 }
344f7625 10950 }
10951
bbd21807 10952 /* If this is V.4, unwind the stack pointer after all of the loads
10953 have been done. We need to emit a block here so that sched
10954 doesn't decide to move the sp change before the register restores
10955 (which may not have any obvious dependency on the stack). This
10956 doesn't hurt performance, because there is no scheduling that can
10957 be done after this point. */
e7ce8542 10958 if (DEFAULT_ABI == ABI_V4)
6b02f2a5 10959 {
bbd21807 10960 if (frame_reg_rtx != sp_reg_rtx)
10961 rs6000_emit_stack_tie ();
6b02f2a5 10962
bbd21807 10963 if (use_backchain_to_restore_sp)
6b02f2a5 10964 {
bbd21807 10965 emit_move_insn (sp_reg_rtx, frame_reg_rtx);
6b02f2a5 10966 }
bbd21807 10967 else if (sp_offset != 0)
d6bc6110 10968 {
bbd21807 10969 emit_insn (Pmode == SImode
10970 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
10971 GEN_INT (sp_offset))
10972 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
10973 GEN_INT (sp_offset)));
d6bc6110 10974 }
bbd21807 10975 }
6b02f2a5 10976
4ce33b7f 10977 if (current_function_calls_eh_return)
10978 {
10979 rtx sa = EH_RETURN_STACKADJ_RTX;
10980 emit_insn (Pmode == SImode
10981 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, sa)
10982 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx, sa));
10983 }
10984
bbd21807 10985 if (!sibcall)
10986 {
10987 rtvec p;
10988 if (! restoring_FPRs_inline)
10989 p = rtvec_alloc (3 + 64 - info->first_fp_reg_save);
10990 else
10991 p = rtvec_alloc (2);
6b02f2a5 10992
90e1e7af 10993 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
10994 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
bbd21807 10995 gen_rtx_REG (Pmode,
10996 LINK_REGISTER_REGNUM));
bbd21807 10997
10998 /* If we have to restore more than two FP registers, branch to the
10999 restore function. It will return to our caller. */
11000 if (! restoring_FPRs_inline)
11001 {
11002 int i;
11003 char rname[30];
44acf429 11004 const char *alloc_rname;
344f7625 11005
bbd21807 11006 sprintf (rname, "%s%d%s", RESTORE_FP_PREFIX,
11007 info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
ec6cb94a 11008 alloc_rname = ggc_strdup (rname);
bbd21807 11009 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode,
11010 gen_rtx_SYMBOL_REF (Pmode,
11011 alloc_rname));
6b02f2a5 11012
bbd21807 11013 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
11014 {
11015 rtx addr, mem;
11016 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
11017 GEN_INT (info->fp_save_offset + 8*i));
11018 mem = gen_rtx_MEM (DFmode, addr);
ab6ab77e 11019 set_mem_alias_set (mem, rs6000_sr_alias_set);
bbd21807 11020
11021 RTVEC_ELT (p, i+3) =
11022 gen_rtx_SET (VOIDmode,
11023 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
11024 mem);
6b02f2a5 11025 }
11026 }
bbd21807 11027
11028 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
8f84ead8 11029 }
d1bd513e 11030}
11031
11032/* Write function epilogue. */
11033
17d9b0c3 11034static void
11035rs6000_output_function_epilogue (file, size)
d1bd513e 11036 FILE *file;
17d9b0c3 11037 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
d1bd513e 11038{
a3bbc303 11039 rs6000_stack_t *info = rs6000_stack_info ();
d1bd513e 11040
bbd21807 11041 if (! HAVE_epilogue)
d1bd513e 11042 {
bbd21807 11043 rtx insn = get_last_insn ();
11044 /* If the last insn was a BARRIER, we don't have to write anything except
11045 the trace table. */
11046 if (GET_CODE (insn) == NOTE)
11047 insn = prev_nonnote_insn (insn);
11048 if (insn == 0 || GET_CODE (insn) != BARRIER)
a3bbc303 11049 {
bbd21807 11050 /* This is slightly ugly, but at least we don't have two
11051 copies of the epilogue-emitting code. */
11052 start_sequence ();
11053
11054 /* A NOTE_INSN_DELETED is supposed to be at the start
11055 and end of the "toplevel" insn chain. */
11056 emit_note (0, NOTE_INSN_DELETED);
11057 rs6000_emit_epilogue (FALSE);
11058 emit_note (0, NOTE_INSN_DELETED);
11059
9f781781 11060 /* Expand INSN_ADDRESSES so final() doesn't crash. */
11061 {
11062 rtx insn;
11063 unsigned addr = 0;
11064 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
11065 {
11066 INSN_ADDRESSES_NEW (insn, addr);
11067 addr += 4;
11068 }
11069 }
11070
bbd21807 11071 if (TARGET_DEBUG_STACK)
970e222f 11072 debug_rtx_list (get_insns (), 100);
11073 final (get_insns (), file, FALSE, FALSE);
bbd21807 11074 end_sequence ();
a3bbc303 11075 }
d1bd513e 11076 }
bdf74c8a 11077
c5767608 11078 /* Output a traceback table here. See /usr/include/sys/debug.h for info
fd65c809 11079 on its format.
11080
11081 We don't output a traceback table if -finhibit-size-directive was
11082 used. The documentation for -finhibit-size-directive reads
11083 ``don't output a @code{.size} assembler directive, or anything
11084 else that would cause trouble if the function is split in the
11085 middle, and the two halves are placed at locations far apart in
11086 memory.'' The traceback table has this property, since it
11087 includes the offset from the start of the function to the
5a81dade 11088 traceback table itself.
11089
11090 System V.4 Powerpc's (and the embedded ABI derived from it) use a
6b02f2a5 11091 different traceback table. */
58a8d617 11092 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
11093 && rs6000_traceback != traceback_none)
c5767608 11094 {
3d033361 11095 const char *fname = NULL;
d19bd1f0 11096 const char *language_string = lang_hooks.name;
c0efea40 11097 int fixed_parms = 0, float_parms = 0, parm_info = 0;
fd65c809 11098 int i;
58a8d617 11099 int optional_tbtab;
11100
11101 if (rs6000_traceback == traceback_full)
11102 optional_tbtab = 1;
11103 else if (rs6000_traceback == traceback_part)
11104 optional_tbtab = 0;
11105 else
11106 optional_tbtab = !optimize_size && !TARGET_ELF;
fd65c809 11107
3d033361 11108 if (optional_tbtab)
11109 {
11110 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
11111 while (*fname == '.') /* V.4 encodes . in the name */
11112 fname++;
11113
11114 /* Need label immediately before tbtab, so we can compute
11115 its offset from the function start. */
11116 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
11117 ASM_OUTPUT_LABEL (file, fname);
11118 }
fd65c809 11119
11120 /* The .tbtab pseudo-op can only be used for the first eight
11121 expressions, since it can't handle the possibly variable
11122 length fields that follow. However, if you omit the optional
11123 fields, the assembler outputs zeros for all optional fields
11124 anyways, giving each variable length field is minimum length
11125 (as defined in sys/debug.h). Thus we can not use the .tbtab
11126 pseudo-op at all. */
11127
11128 /* An all-zero word flags the start of the tbtab, for debuggers
11129 that have to find it by searching forward from the entry
11130 point or from the current pc. */
66455505 11131 fputs ("\t.long 0\n", file);
fd65c809 11132
11133 /* Tbtab format type. Use format type 0. */
66455505 11134 fputs ("\t.byte 0,", file);
fd65c809 11135
11136 /* Language type. Unfortunately, there doesn't seem to be any
11137 official way to get this info, so we use language_string. C
11138 is 0. C++ is 9. No number defined for Obj-C, so use the
b77ba239 11139 value for C for now. There is no official value for Java,
6a796f6b 11140 although IBM appears to be using 13. There is no official value
8ef587dc 11141 for Chill, so we've chosen 44 pseudo-randomly. */
fd65c809 11142 if (! strcmp (language_string, "GNU C")
30c5e279 11143 || ! strcmp (language_string, "GNU Objective-C"))
fd65c809 11144 i = 0;
11145 else if (! strcmp (language_string, "GNU F77"))
11146 i = 1;
11147 else if (! strcmp (language_string, "GNU Ada"))
11148 i = 3;
32727b9e 11149 else if (! strcmp (language_string, "GNU Pascal"))
fd65c809 11150 i = 2;
11151 else if (! strcmp (language_string, "GNU C++"))
11152 i = 9;
b77ba239 11153 else if (! strcmp (language_string, "GNU Java"))
11154 i = 13;
6a796f6b 11155 else if (! strcmp (language_string, "GNU CHILL"))
11156 i = 44;
fd65c809 11157 else
11158 abort ();
11159 fprintf (file, "%d,", i);
11160
11161 /* 8 single bit fields: global linkage (not set for C extern linkage,
11162 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
11163 from start of procedure stored in tbtab, internal function, function
11164 has controlled storage, function has no toc, function uses fp,
11165 function logs/aborts fp operations. */
11166 /* Assume that fp operations are used if any fp reg must be saved. */
c0efea40 11167 fprintf (file, "%d,",
11168 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
fd65c809 11169
11170 /* 6 bitfields: function is interrupt handler, name present in
11171 proc table, function calls alloca, on condition directives
11172 (controls stack walks, 3 bits), saves condition reg, saves
11173 link reg. */
11174 /* The `function calls alloca' bit seems to be set whenever reg 31 is
11175 set up as a frame pointer, even when there is no alloca call. */
11176 fprintf (file, "%d,",
c0efea40 11177 ((optional_tbtab << 6)
11178 | ((optional_tbtab & frame_pointer_needed) << 5)
11179 | (info->cr_save_p << 1)
11180 | (info->lr_save_p)));
fd65c809 11181
c0efea40 11182 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
fd65c809 11183 (6 bits). */
11184 fprintf (file, "%d,",
a3bbc303 11185 (info->push_p << 7) | (64 - info->first_fp_reg_save));
fd65c809 11186
11187 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
11188 fprintf (file, "%d,", (32 - first_reg_to_save ()));
11189
c0efea40 11190 if (optional_tbtab)
11191 {
11192 /* Compute the parameter info from the function decl argument
11193 list. */
11194 tree decl;
11195 int next_parm_info_bit = 31;
fd65c809 11196
c0efea40 11197 for (decl = DECL_ARGUMENTS (current_function_decl);
11198 decl; decl = TREE_CHAIN (decl))
11199 {
11200 rtx parameter = DECL_INCOMING_RTL (decl);
11201 enum machine_mode mode = GET_MODE (parameter);
fd65c809 11202
c0efea40 11203 if (GET_CODE (parameter) == REG)
11204 {
11205 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
11206 {
11207 int bits;
11208
11209 float_parms++;
11210
11211 if (mode == SFmode)
11212 bits = 0x2;
cf7d5bc7 11213 else if (mode == DFmode || mode == TFmode)
c0efea40 11214 bits = 0x3;
11215 else
11216 abort ();
11217
11218 /* If only one bit will fit, don't or in this entry. */
11219 if (next_parm_info_bit > 0)
11220 parm_info |= (bits << (next_parm_info_bit - 1));
11221 next_parm_info_bit -= 2;
11222 }
11223 else
11224 {
11225 fixed_parms += ((GET_MODE_SIZE (mode)
11226 + (UNITS_PER_WORD - 1))
11227 / UNITS_PER_WORD);
11228 next_parm_info_bit -= 1;
11229 }
11230 }
11231 }
11232 }
fd65c809 11233
11234 /* Number of fixed point parameters. */
11235 /* This is actually the number of words of fixed point parameters; thus
11236 an 8 byte struct counts as 2; and thus the maximum value is 8. */
11237 fprintf (file, "%d,", fixed_parms);
11238
11239 /* 2 bitfields: number of floating point parameters (7 bits), parameters
11240 all on stack. */
11241 /* This is actually the number of fp registers that hold parameters;
11242 and thus the maximum value is 13. */
11243 /* Set parameters on stack bit if parameters are not in their original
11244 registers, regardless of whether they are on the stack? Xlc
11245 seems to set the bit when not optimizing. */
11246 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
11247
c0efea40 11248 if (! optional_tbtab)
11249 return;
11250
fd65c809 11251 /* Optional fields follow. Some are variable length. */
11252
11253 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
11254 11 double float. */
11255 /* There is an entry for each parameter in a register, in the order that
11256 they occur in the parameter list. Any intervening arguments on the
11257 stack are ignored. If the list overflows a long (max possible length
11258 34 bits) then completely leave off all elements that don't fit. */
11259 /* Only emit this long if there was at least one parameter. */
11260 if (fixed_parms || float_parms)
11261 fprintf (file, "\t.long %d\n", parm_info);
11262
11263 /* Offset from start of code to tb table. */
66455505 11264 fputs ("\t.long ", file);
fd65c809 11265 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
018718de 11266#if TARGET_AIX
11267 RS6000_OUTPUT_BASENAME (file, fname);
11268#else
bbd21807 11269 assemble_name (file, fname);
018718de 11270#endif
66455505 11271 fputs ("-.", file);
018718de 11272#if TARGET_AIX
11273 RS6000_OUTPUT_BASENAME (file, fname);
11274#else
bbd21807 11275 assemble_name (file, fname);
018718de 11276#endif
66455505 11277 putc ('\n', file);
fd65c809 11278
11279 /* Interrupt handler mask. */
11280 /* Omit this long, since we never set the interrupt handler bit
11281 above. */
11282
11283 /* Number of CTL (controlled storage) anchors. */
11284 /* Omit this long, since the has_ctl bit is never set above. */
11285
11286 /* Displacement into stack of each CTL anchor. */
11287 /* Omit this list of longs, because there are no CTL anchors. */
11288
11289 /* Length of function name. */
3d033361 11290 if (*fname == '*')
11291 ++fname;
600e851b 11292 fprintf (file, "\t.short %d\n", (int) strlen (fname));
fd65c809 11293
11294 /* Function name. */
11295 assemble_string (fname, strlen (fname));
11296
11297 /* Register for alloca automatic storage; this is always reg 31.
11298 Only emit this if the alloca bit was set above. */
11299 if (frame_pointer_needed)
66455505 11300 fputs ("\t.byte 31\n", file);
6007cde0 11301
11302 fputs ("\t.align 2\n", file);
c5767608 11303 }
d1bd513e 11304}
1c9aa673 11305\f
970e222f 11306/* A C compound statement that outputs the assembler code for a thunk
11307 function, used to implement C++ virtual function calls with
11308 multiple inheritance. The thunk acts as a wrapper around a virtual
11309 function, adjusting the implicit object parameter before handing
11310 control off to the real function.
11311
11312 First, emit code to add the integer DELTA to the location that
11313 contains the incoming first argument. Assume that this argument
11314 contains a pointer, and is the one used to pass the `this' pointer
11315 in C++. This is the incoming argument *before* the function
11316 prologue, e.g. `%o0' on a sparc. The addition must preserve the
11317 values of all other incoming arguments.
1c9aa673 11318
11319 After the addition, emit code to jump to FUNCTION, which is a
970e222f 11320 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
11321 not touch the return address. Hence returning from FUNCTION will
11322 return to whoever called the current `thunk'.
1c9aa673 11323
970e222f 11324 The effect must be as if FUNCTION had been called directly with the
11325 adjusted first argument. This macro is responsible for emitting
11326 all of the code for a thunk function; output_function_prologue()
11327 and output_function_epilogue() are not invoked.
1c9aa673 11328
970e222f 11329 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
11330 been extracted from it.) It might possibly be useful on some
11331 targets, but probably not.
1c9aa673 11332
970e222f 11333 If you do not define this macro, the target-independent code in the
11334 C++ frontend will generate a less efficient heavyweight thunk that
11335 calls FUNCTION instead of jumping to it. The generic approach does
11336 not support varargs. */
1c9aa673 11337
eb344f43 11338static void
11339rs6000_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function)
1c9aa673 11340 FILE *file;
c0256c4b 11341 tree thunk_fndecl ATTRIBUTE_UNUSED;
e7f5e241 11342 HOST_WIDE_INT delta;
eb344f43 11343 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
1c9aa673 11344 tree function;
11345{
970e222f 11346 const char *this_reg =
11347 reg_names[ aggregate_value_p (TREE_TYPE (TREE_TYPE (function))) ? 4 : 3 ];
c0256c4b 11348 const char *prefix;
9a356c3c 11349 const char *fname;
c0256c4b 11350 const char *r0 = reg_names[0];
c0256c4b 11351 const char *toc = reg_names[2];
11352 const char *schain = reg_names[11];
11353 const char *r12 = reg_names[12];
1c9aa673 11354 char buf[512];
11355 static int labelno = 0;
11356
970e222f 11357 /* Small constants that can be done by one add instruction. */
1c9aa673 11358 if (delta >= -32768 && delta <= 32767)
11359 {
bafeaff6 11360 if (! TARGET_NEW_MNEMONICS)
e7f5e241 11361 fprintf (file, "\tcal %s,%d(%s)\n", this_reg, (int) delta, this_reg);
1c9aa673 11362 else
e7f5e241 11363 fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, (int) delta);
1c9aa673 11364 }
11365
94493f7d 11366 /* 64-bit constants. If "int" is 32 bits, we'll never hit this abort. */
11367 else if (TARGET_64BIT && (delta < -2147483647 - 1 || delta > 2147483647))
11368 abort ();
11369
970e222f 11370 /* Large constants that can be done by one addis instruction. */
94493f7d 11371 else if ((delta & 0xffff) == 0)
1c9aa673 11372 asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
e7f5e241 11373 (int) (delta >> 16));
1c9aa673 11374
11375 /* 32-bit constants that can be done by an add and addis instruction. */
94493f7d 11376 else
1c9aa673 11377 {
970e222f 11378 /* Break into two pieces, propagating the sign bit from the low
11379 word to the upper word. */
94493f7d 11380 int delta_low = ((delta & 0xffff) ^ 0x8000) - 0x8000;
11381 int delta_high = (delta - delta_low) >> 16;
1c9aa673 11382
11383 asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
11384 delta_high);
11385
bafeaff6 11386 if (! TARGET_NEW_MNEMONICS)
1c9aa673 11387 fprintf (file, "\tcal %s,%d(%s)\n", this_reg, delta_low, this_reg);
11388 else
11389 fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, delta_low);
11390 }
11391
1c9aa673 11392 /* Get the prefix in front of the names. */
11393 switch (DEFAULT_ABI)
11394 {
11395 default:
11396 abort ();
11397
11398 case ABI_AIX:
11399 prefix = ".";
11400 break;
11401
11402 case ABI_V4:
11403 case ABI_AIX_NODESC:
6ea17e53 11404 case ABI_DARWIN:
1c9aa673 11405 prefix = "";
11406 break;
1c9aa673 11407 }
11408
11409 /* If the function is compiled in this module, jump to it directly.
11410 Otherwise, load up its address and jump to it. */
11411
11412 fname = XSTR (XEXP (DECL_RTL (function), 0), 0);
c7d58dfa 11413
bbd21807 11414 if (current_file_function_operand (XEXP (DECL_RTL (function), 0), VOIDmode)
edd2f2ae 11415 && (! lookup_attribute ("longcall",
11416 TYPE_ATTRIBUTES (TREE_TYPE (function)))
11417 || lookup_attribute ("shortcall",
11418 TYPE_ATTRIBUTES (TREE_TYPE (function)))))
1c9aa673 11419 {
11420 fprintf (file, "\tb %s", prefix);
11421 assemble_name (file, fname);
bafeaff6 11422 if (DEFAULT_ABI == ABI_V4 && flag_pic) fputs ("@local", file);
1270d073 11423 putc ('\n', file);
1c9aa673 11424 }
11425
11426 else
11427 {
11428 switch (DEFAULT_ABI)
11429 {
11430 default:
1c9aa673 11431 abort ();
11432
11433 case ABI_AIX:
11434 /* Set up a TOC entry for the function. */
11435 ASM_GENERATE_INTERNAL_LABEL (buf, "Lthunk", labelno);
11436 toc_section ();
805e22b2 11437 (*targetm.asm_out.internal_label) (file, "Lthunk", labelno);
1c9aa673 11438 labelno++;
11439
3047993b 11440 if (TARGET_MINIMAL_TOC)
11441 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
11442 else
11443 {
11444 fputs ("\t.tc ", file);
11445 assemble_name (file, fname);
11446 fputs ("[TC],", file);
11447 }
11448 assemble_name (file, fname);
1c9aa673 11449 putc ('\n', file);
eb344f43 11450 function_section (current_function_decl);
0b9800e9 11451 if (TARGET_MINIMAL_TOC)
11452 asm_fprintf (file, (TARGET_32BIT)
11453 ? "\t{l|lwz} %s,%s(%s)\n" : "\tld %s,%s(%s)\n", r12,
11454 TARGET_ELF ? ".LCTOC0@toc" : ".LCTOC..1", toc);
2d87c8ca 11455 asm_fprintf (file, (TARGET_32BIT) ? "\t{l|lwz} %s," : "\tld %s,", r12);
1c9aa673 11456 assemble_name (file, buf);
0b9800e9 11457 if (TARGET_ELF && TARGET_MINIMAL_TOC)
11458 fputs ("-(.LCTOC1)", file);
11459 asm_fprintf (file, "(%s)\n", TARGET_MINIMAL_TOC ? r12 : toc);
1c9aa673 11460 asm_fprintf (file,
11461 (TARGET_32BIT) ? "\t{l|lwz} %s,0(%s)\n" : "\tld %s,0(%s)\n",
11462 r0, r12);
11463
11464 asm_fprintf (file,
11465 (TARGET_32BIT) ? "\t{l|lwz} %s,4(%s)\n" : "\tld %s,8(%s)\n",
11466 toc, r12);
11467
11468 asm_fprintf (file, "\tmtctr %s\n", r0);
11469 asm_fprintf (file,
11470 (TARGET_32BIT) ? "\t{l|lwz} %s,8(%s)\n" : "\tld %s,16(%s)\n",
11471 schain, r12);
11472
11473 asm_fprintf (file, "\tbctr\n");
11474 break;
11475
bbd21807 11476 case ABI_AIX_NODESC:
1c9aa673 11477 case ABI_V4:
bafeaff6 11478 fprintf (file, "\tb %s", prefix);
11479 assemble_name (file, fname);
11480 if (flag_pic) fputs ("@plt", file);
1270d073 11481 putc ('\n', file);
bafeaff6 11482 break;
80d725d7 11483
11484#if TARGET_MACHO
11485 case ABI_DARWIN:
11486 fprintf (file, "\tb %s", prefix);
11487 if (flag_pic && !machopic_name_defined_p (fname))
11488 assemble_name (file, machopic_stub_name (fname));
11489 else
11490 assemble_name (file, fname);
11491 putc ('\n', file);
11492 break;
11493#endif
bbd21807 11494 }
11495 }
11496}
bbd21807 11497\f
11498/* A quick summary of the various types of 'constant-pool tables'
11499 under PowerPC:
11500
11501 Target Flags Name One table per
11502 AIX (none) AIX TOC object file
11503 AIX -mfull-toc AIX TOC object file
11504 AIX -mminimal-toc AIX minimal TOC translation unit
11505 SVR4/EABI (none) SVR4 SDATA object file
11506 SVR4/EABI -fpic SVR4 pic object file
11507 SVR4/EABI -fPIC SVR4 PIC translation unit
11508 SVR4/EABI -mrelocatable EABI TOC function
11509 SVR4/EABI -maix AIX TOC object file
11510 SVR4/EABI -maix -mminimal-toc
11511 AIX minimal TOC translation unit
11512
11513 Name Reg. Set by entries contains:
11514 made by addrs? fp? sum?
11515
11516 AIX TOC 2 crt0 as Y option option
11517 AIX minimal TOC 30 prolog gcc Y Y option
11518 SVR4 SDATA 13 crt0 gcc N Y N
11519 SVR4 pic 30 prolog ld Y not yet N
11520 SVR4 PIC 30 prolog gcc Y option option
11521 EABI TOC 30 prolog gcc Y option option
11522
11523*/
11524
11525/* Hash table stuff for keeping track of TOC entries. */
11526
11527struct toc_hash_struct
11528{
11529 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
11530 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
11531 rtx key;
e2f08fad 11532 enum machine_mode key_mode;
bbd21807 11533 int labelno;
11534};
1c9aa673 11535
bbd21807 11536static htab_t toc_hash_table;
11537
11538/* Hash functions for the hash table. */
11539
11540static unsigned
11541rs6000_hash_constant (k)
11542 rtx k;
11543{
3393215f 11544 enum rtx_code code = GET_CODE (k);
11545 enum machine_mode mode = GET_MODE (k);
11546 unsigned result = (code << 3) ^ mode;
11547 const char *format;
11548 int flen, fidx;
bbd21807 11549
3393215f 11550 format = GET_RTX_FORMAT (code);
11551 flen = strlen (format);
11552 fidx = 0;
bbd21807 11553
3393215f 11554 switch (code)
11555 {
11556 case LABEL_REF:
11557 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
11558
11559 case CONST_DOUBLE:
11560 if (mode != VOIDmode)
11561 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
11562 flen = 2;
11563 break;
11564
11565 case CODE_LABEL:
11566 fidx = 3;
11567 break;
11568
11569 default:
11570 break;
11571 }
bbd21807 11572
11573 for (; fidx < flen; fidx++)
11574 switch (format[fidx])
11575 {
11576 case 's':
11577 {
11578 unsigned i, len;
11579 const char *str = XSTR (k, fidx);
11580 len = strlen (str);
11581 result = result * 613 + len;
11582 for (i = 0; i < len; i++)
11583 result = result * 613 + (unsigned) str[i];
1c9aa673 11584 break;
11585 }
bbd21807 11586 case 'u':
11587 case 'e':
11588 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
11589 break;
11590 case 'i':
11591 case 'n':
11592 result = result * 613 + (unsigned) XINT (k, fidx);
11593 break;
11594 case 'w':
11595 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
11596 result = result * 613 + (unsigned) XWINT (k, fidx);
11597 else
11598 {
11599 size_t i;
11600 for (i = 0; i < sizeof(HOST_WIDE_INT)/sizeof(unsigned); i++)
11601 result = result * 613 + (unsigned) (XWINT (k, fidx)
11602 >> CHAR_BIT * i);
11603 }
11604 break;
11605 default:
970e222f 11606 abort ();
bbd21807 11607 }
3393215f 11608
bbd21807 11609 return result;
11610}
11611
11612static unsigned
11613toc_hash_function (hash_entry)
11614 const void * hash_entry;
11615{
e2f08fad 11616 const struct toc_hash_struct *thc =
11617 (const struct toc_hash_struct *) hash_entry;
11618 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
bbd21807 11619}
11620
11621/* Compare H1 and H2 for equivalence. */
11622
11623static int
11624toc_hash_eq (h1, h2)
11625 const void * h1;
11626 const void * h2;
11627{
11628 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
11629 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
11630
e2f08fad 11631 if (((const struct toc_hash_struct *) h1)->key_mode
11632 != ((const struct toc_hash_struct *) h2)->key_mode)
11633 return 0;
11634
2ff23ed0 11635 return rtx_equal_p (r1, r2);
bbd21807 11636}
11637
11638/* Mark the hash table-entry HASH_ENTRY. */
11639
11640static int
11641toc_hash_mark_entry (hash_slot, unused)
a019e19d 11642 void ** hash_slot;
bbd21807 11643 void * unused ATTRIBUTE_UNUSED;
11644{
11645 const struct toc_hash_struct * hash_entry =
11646 *(const struct toc_hash_struct **) hash_slot;
11647 rtx r = hash_entry->key;
11648 ggc_set_mark (hash_entry);
970e222f 11649 /* For CODE_LABELS, we don't want to drag in the whole insn chain... */
bbd21807 11650 if (GET_CODE (r) == LABEL_REF)
11651 {
11652 ggc_set_mark (r);
11653 ggc_set_mark (XEXP (r, 0));
11654 }
11655 else
11656 ggc_mark_rtx (r);
11657 return 1;
11658}
11659
11660/* Mark all the elements of the TOC hash-table *HT. */
11661
11662static void
11663toc_hash_mark_table (vht)
11664 void *vht;
11665{
11666 htab_t *ht = vht;
11667
11668 htab_traverse (*ht, toc_hash_mark_entry, (void *)0);
1c9aa673 11669}
11670
360a0889 11671/* These are the names given by the C++ front-end to vtables, and
11672 vtable-like objects. Ideally, this logic should not be here;
11673 instead, there should be some programmatic way of inquiring as
11674 to whether or not an object is a vtable. */
11675
11676#define VTABLE_NAME_P(NAME) \
11677 (strncmp ("_vt.", name, strlen("_vt.")) == 0 \
11678 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
11679 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
11680 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
11681
11682void
11683rs6000_output_symbol_ref (file, x)
11684 FILE *file;
11685 rtx x;
11686{
11687 /* Currently C++ toc references to vtables can be emitted before it
11688 is decided whether the vtable is public or private. If this is
11689 the case, then the linker will eventually complain that there is
11690 a reference to an unknown section. Thus, for vtables only,
11691 we emit the TOC reference to reference the symbol and not the
11692 section. */
11693 const char *name = XSTR (x, 0);
018718de 11694
11695 if (VTABLE_NAME_P (name))
11696 {
11697 RS6000_OUTPUT_BASENAME (file, name);
11698 }
11699 else
11700 assemble_name (file, name);
360a0889 11701}
11702
970e222f 11703/* Output a TOC entry. We derive the entry name from what is being
11704 written. */
d1bd513e 11705
11706void
e2f08fad 11707output_toc (file, x, labelno, mode)
d1bd513e 11708 FILE *file;
11709 rtx x;
11710 int labelno;
e2f08fad 11711 enum machine_mode mode;
d1bd513e 11712{
11713 char buf[256];
9a356c3c 11714 const char *name = buf;
6e1d237a 11715 const char *real_name;
d1bd513e 11716 rtx base = x;
11717 int offset = 0;
11718
a3bbc303 11719 if (TARGET_NO_TOC)
11720 abort ();
11721
bbd21807 11722 /* When the linker won't eliminate them, don't output duplicate
11723 TOC entries (this happens on AIX if there is any kind of TOC,
d7c47c0e 11724 and on SVR4 under -fPIC or -mrelocatable). */
11725 if (TARGET_TOC)
bbd21807 11726 {
11727 struct toc_hash_struct *h;
11728 void * * found;
11729
11730 h = ggc_alloc (sizeof (*h));
11731 h->key = x;
e2f08fad 11732 h->key_mode = mode;
bbd21807 11733 h->labelno = labelno;
11734
11735 found = htab_find_slot (toc_hash_table, h, 1);
11736 if (*found == NULL)
11737 *found = h;
11738 else /* This is indeed a duplicate.
11739 Set this label equal to that label. */
11740 {
11741 fputs ("\t.set ", file);
11742 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
11743 fprintf (file, "%d,", labelno);
11744 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
11745 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
11746 found)->labelno));
11747 return;
11748 }
11749 }
11750
11751 /* If we're going to put a double constant in the TOC, make sure it's
11752 aligned properly when strict alignment is on. */
67b19be7 11753 if (GET_CODE (x) == CONST_DOUBLE
11754 && STRICT_ALIGNMENT
e2f08fad 11755 && GET_MODE_BITSIZE (mode) >= 64
67b19be7 11756 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
11757 ASM_OUTPUT_ALIGN (file, 3);
11758 }
11759
805e22b2 11760 (*targetm.asm_out.internal_label) (file, "LC", labelno);
d1bd513e 11761
91c8fd43 11762 /* Handle FP constants specially. Note that if we have a minimal
11763 TOC, things we put here aren't actually in the TOC, so we can allow
11764 FP constants. */
cf7d5bc7 11765 if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == TFmode)
11766 {
11767 REAL_VALUE_TYPE rv;
11768 long k[4];
11769
11770 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
11771 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
11772
11773 if (TARGET_64BIT)
11774 {
11775 if (TARGET_MINIMAL_TOC)
11776 fputs (DOUBLE_INT_ASM_OP, file);
11777 else
11778 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
11779 k[0] & 0xffffffff, k[1] & 0xffffffff,
11780 k[2] & 0xffffffff, k[3] & 0xffffffff);
11781 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
11782 k[0] & 0xffffffff, k[1] & 0xffffffff,
11783 k[2] & 0xffffffff, k[3] & 0xffffffff);
11784 return;
11785 }
11786 else
11787 {
11788 if (TARGET_MINIMAL_TOC)
11789 fputs ("\t.long ", file);
11790 else
11791 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
11792 k[0] & 0xffffffff, k[1] & 0xffffffff,
11793 k[2] & 0xffffffff, k[3] & 0xffffffff);
11794 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
11795 k[0] & 0xffffffff, k[1] & 0xffffffff,
11796 k[2] & 0xffffffff, k[3] & 0xffffffff);
11797 return;
11798 }
11799 }
11800 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
d1bd513e 11801 {
eb856d33 11802 REAL_VALUE_TYPE rv;
11803 long k[2];
aa1f527a 11804
eb856d33 11805 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
11806 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
23f6e091 11807
8ca6622c 11808 if (TARGET_64BIT)
11809 {
11810 if (TARGET_MINIMAL_TOC)
8eaf2dd1 11811 fputs (DOUBLE_INT_ASM_OP, file);
8ca6622c 11812 else
b6dc1ff7 11813 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
11814 k[0] & 0xffffffff, k[1] & 0xffffffff);
11815 fprintf (file, "0x%lx%08lx\n",
11816 k[0] & 0xffffffff, k[1] & 0xffffffff);
8ca6622c 11817 return;
11818 }
8c93d319 11819 else
8ca6622c 11820 {
11821 if (TARGET_MINIMAL_TOC)
8eaf2dd1 11822 fputs ("\t.long ", file);
8ca6622c 11823 else
b6dc1ff7 11824 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
11825 k[0] & 0xffffffff, k[1] & 0xffffffff);
11826 fprintf (file, "0x%lx,0x%lx\n",
11827 k[0] & 0xffffffff, k[1] & 0xffffffff);
8ca6622c 11828 return;
11829 }
d1bd513e 11830 }
e2f08fad 11831 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
d1bd513e 11832 {
eb856d33 11833 REAL_VALUE_TYPE rv;
11834 long l;
d1bd513e 11835
eb856d33 11836 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
11837 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
11838
23f6e091 11839 if (TARGET_64BIT)
11840 {
11841 if (TARGET_MINIMAL_TOC)
8eaf2dd1 11842 fputs (DOUBLE_INT_ASM_OP, file);
23f6e091 11843 else
b6dc1ff7 11844 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
11845 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
23f6e091 11846 return;
11847 }
eb856d33 11848 else
23f6e091 11849 {
11850 if (TARGET_MINIMAL_TOC)
8eaf2dd1 11851 fputs ("\t.long ", file);
23f6e091 11852 else
b6dc1ff7 11853 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
11854 fprintf (file, "0x%lx\n", l & 0xffffffff);
23f6e091 11855 return;
11856 }
eb856d33 11857 }
b0c92e30 11858 else if (GET_MODE (x) == VOIDmode
e2f08fad 11859 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
eb856d33 11860 {
30c5e279 11861 unsigned HOST_WIDE_INT low;
eb856d33 11862 HOST_WIDE_INT high;
11863
11864 if (GET_CODE (x) == CONST_DOUBLE)
11865 {
11866 low = CONST_DOUBLE_LOW (x);
11867 high = CONST_DOUBLE_HIGH (x);
11868 }
11869 else
11870#if HOST_BITS_PER_WIDE_INT == 32
11871 {
11872 low = INTVAL (x);
dde53c28 11873 high = (low & 0x80000000) ? ~0 : 0;
eb856d33 11874 }
11875#else
11876 {
dde53c28 11877 low = INTVAL (x) & 0xffffffff;
eb856d33 11878 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
11879 }
11880#endif
d1bd513e 11881
e2f08fad 11882 /* TOC entries are always Pmode-sized, but since this
11883 is a bigendian machine then if we're putting smaller
11884 integer constants in the TOC we have to pad them.
11885 (This is still a win over putting the constants in
11886 a separate constant pool, because then we'd have
a7f32c2d 11887 to have both a TOC entry _and_ the actual constant.)
11888
11889 For a 32-bit target, CONST_INT values are loaded and shifted
11890 entirely within `low' and can be stored in one TOC entry. */
11891
11892 if (TARGET_64BIT && POINTER_SIZE < GET_MODE_BITSIZE (mode))
e2f08fad 11893 abort ();/* It would be easy to make this work, but it doesn't now. */
a7f32c2d 11894
11895 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
170be75e 11896 {
11897#if HOST_BITS_PER_WIDE_INT == 32
11898 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
11899 POINTER_SIZE, &low, &high, 0);
11900#else
11901 low |= high << 32;
11902 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
11903 high = (HOST_WIDE_INT) low >> 32;
11904 low &= 0xffffffff;
11905#endif
11906 }
e2f08fad 11907
8ca6622c 11908 if (TARGET_64BIT)
11909 {
11910 if (TARGET_MINIMAL_TOC)
8eaf2dd1 11911 fputs (DOUBLE_INT_ASM_OP, file);
8ca6622c 11912 else
b6dc1ff7 11913 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
11914 (long) high & 0xffffffff, (long) low & 0xffffffff);
11915 fprintf (file, "0x%lx%08lx\n",
11916 (long) high & 0xffffffff, (long) low & 0xffffffff);
8ca6622c 11917 return;
11918 }
8c93d319 11919 else
8ca6622c 11920 {
a7f32c2d 11921 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
11922 {
11923 if (TARGET_MINIMAL_TOC)
8eaf2dd1 11924 fputs ("\t.long ", file);
a7f32c2d 11925 else
8eaf2dd1 11926 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
b6dc1ff7 11927 (long) high & 0xffffffff, (long) low & 0xffffffff);
11928 fprintf (file, "0x%lx,0x%lx\n",
11929 (long) high & 0xffffffff, (long) low & 0xffffffff);
a7f32c2d 11930 }
8ca6622c 11931 else
a7f32c2d 11932 {
11933 if (TARGET_MINIMAL_TOC)
8eaf2dd1 11934 fputs ("\t.long ", file);
a7f32c2d 11935 else
b6dc1ff7 11936 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
11937 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
a7f32c2d 11938 }
8ca6622c 11939 return;
11940 }
d1bd513e 11941 }
11942
11943 if (GET_CODE (x) == CONST)
11944 {
8eaf2dd1 11945 if (GET_CODE (XEXP (x, 0)) != PLUS)
11946 abort ();
11947
d1bd513e 11948 base = XEXP (XEXP (x, 0), 0);
11949 offset = INTVAL (XEXP (XEXP (x, 0), 1));
11950 }
11951
11952 if (GET_CODE (base) == SYMBOL_REF)
11953 name = XSTR (base, 0);
11954 else if (GET_CODE (base) == LABEL_REF)
11955 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (base, 0)));
11956 else if (GET_CODE (base) == CODE_LABEL)
11957 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
11958 else
11959 abort ();
11960
7b4a38a6 11961 real_name = (*targetm.strip_name_encoding) (name);
8c93d319 11962 if (TARGET_MINIMAL_TOC)
8eaf2dd1 11963 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
8c93d319 11964 else
11965 {
6b02f2a5 11966 fprintf (file, "\t.tc %s", real_name);
d1bd513e 11967
8c93d319 11968 if (offset < 0)
11969 fprintf (file, ".N%d", - offset);
11970 else if (offset)
11971 fprintf (file, ".P%d", offset);
d1bd513e 11972
66455505 11973 fputs ("[TC],", file);
8c93d319 11974 }
c18a09db 11975
11976 /* Currently C++ toc references to vtables can be emitted before it
11977 is decided whether the vtable is public or private. If this is
11978 the case, then the linker will eventually complain that there is
11979 a TOC reference to an unknown section. Thus, for vtables only,
11980 we emit the TOC reference to reference the symbol and not the
11981 section. */
360a0889 11982 if (VTABLE_NAME_P (name))
c18a09db 11983 {
018718de 11984 RS6000_OUTPUT_BASENAME (file, name);
c18a09db 11985 if (offset < 0)
11986 fprintf (file, "%d", offset);
11987 else if (offset > 0)
11988 fprintf (file, "+%d", offset);
11989 }
11990 else
11991 output_addr_const (file, x);
66455505 11992 putc ('\n', file);
d1bd513e 11993}
11994\f
11995/* Output an assembler pseudo-op to write an ASCII string of N characters
11996 starting at P to FILE.
11997
11998 On the RS/6000, we have to do this using the .byte operation and
11999 write out special characters outside the quoted string.
12000 Also, the assembler is broken; very long strings are truncated,
970e222f 12001 so we must artificially break them up early. */
d1bd513e 12002
12003void
12004output_ascii (file, p, n)
12005 FILE *file;
c0256c4b 12006 const char *p;
d1bd513e 12007 int n;
12008{
12009 char c;
12010 int i, count_string;
c0256c4b 12011 const char *for_string = "\t.byte \"";
12012 const char *for_decimal = "\t.byte ";
12013 const char *to_close = NULL;
d1bd513e 12014
12015 count_string = 0;
12016 for (i = 0; i < n; i++)
12017 {
12018 c = *p++;
12019 if (c >= ' ' && c < 0177)
12020 {
12021 if (for_string)
12022 fputs (for_string, file);
12023 putc (c, file);
12024
12025 /* Write two quotes to get one. */
12026 if (c == '"')
12027 {
12028 putc (c, file);
12029 ++count_string;
12030 }
12031
12032 for_string = NULL;
12033 for_decimal = "\"\n\t.byte ";
12034 to_close = "\"\n";
12035 ++count_string;
12036
12037 if (count_string >= 512)
12038 {
12039 fputs (to_close, file);
12040
12041 for_string = "\t.byte \"";
12042 for_decimal = "\t.byte ";
12043 to_close = NULL;
12044 count_string = 0;
12045 }
12046 }
12047 else
12048 {
12049 if (for_decimal)
12050 fputs (for_decimal, file);
12051 fprintf (file, "%d", c);
12052
12053 for_string = "\n\t.byte \"";
12054 for_decimal = ", ";
12055 to_close = "\n";
12056 count_string = 0;
12057 }
12058 }
12059
12060 /* Now close the string if we have written one. Then end the line. */
12061 if (to_close)
bbd21807 12062 fputs (to_close, file);
d1bd513e 12063}
12064\f
12065/* Generate a unique section name for FILENAME for a section type
12066 represented by SECTION_DESC. Output goes into BUF.
12067
12068 SECTION_DESC can be any string, as long as it is different for each
12069 possible section type.
12070
12071 We name the section in the same manner as xlc. The name begins with an
12072 underscore followed by the filename (after stripping any leading directory
0a1d858e 12073 names) with the last period replaced by the string SECTION_DESC. If
12074 FILENAME does not contain a period, SECTION_DESC is appended to the end of
12075 the name. */
d1bd513e 12076
12077void
12078rs6000_gen_section_name (buf, filename, section_desc)
12079 char **buf;
bbd21807 12080 const char *filename;
12081 const char *section_desc;
d1bd513e 12082{
bbd21807 12083 const char *q, *after_last_slash, *last_period = 0;
d1bd513e 12084 char *p;
12085 int len;
d1bd513e 12086
12087 after_last_slash = filename;
12088 for (q = filename; *q; q++)
0a1d858e 12089 {
12090 if (*q == '/')
12091 after_last_slash = q + 1;
12092 else if (*q == '.')
12093 last_period = q;
12094 }
d1bd513e 12095
0a1d858e 12096 len = strlen (after_last_slash) + strlen (section_desc) + 2;
92192583 12097 *buf = (char *) xmalloc (len);
d1bd513e 12098
12099 p = *buf;
12100 *p++ = '_';
12101
12102 for (q = after_last_slash; *q; q++)
12103 {
0a1d858e 12104 if (q == last_period)
d1bd513e 12105 {
12106 strcpy (p, section_desc);
12107 p += strlen (section_desc);
d1bd513e 12108 }
12109
cc404a47 12110 else if (ISALNUM (*q))
d1bd513e 12111 *p++ = *q;
12112 }
12113
0a1d858e 12114 if (last_period == 0)
d1bd513e 12115 strcpy (p, section_desc);
12116 else
12117 *p = '\0';
12118}
c725ca16 12119\f
970e222f 12120/* Emit profile function. */
104d9861 12121
104d9861 12122void
12123output_profile_hook (labelno)
58a8d617 12124 int labelno ATTRIBUTE_UNUSED;
104d9861 12125{
075e4952 12126 if (DEFAULT_ABI == ABI_AIX)
12127 {
58a8d617 12128#ifdef NO_PROFILE_COUNTERS
12129 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0);
12130#else
075e4952 12131 char buf[30];
1482a25d 12132 const char *label_name;
075e4952 12133 rtx fun;
104d9861 12134
075e4952 12135 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
7b4a38a6 12136 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
075e4952 12137 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
104d9861 12138
075e4952 12139 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1,
12140 fun, Pmode);
58a8d617 12141#endif
075e4952 12142 }
80d725d7 12143 else if (DEFAULT_ABI == ABI_DARWIN)
12144 {
aee5207b 12145 const char *mcount_name = RS6000_MCOUNT;
80d725d7 12146 int caller_addr_regno = LINK_REGISTER_REGNUM;
12147
12148 /* Be conservative and always set this, at least for now. */
12149 current_function_uses_pic_offset_table = 1;
12150
12151#if TARGET_MACHO
12152 /* For PIC code, set up a stub and collect the caller's address
12153 from r0, which is where the prologue puts it. */
12154 if (flag_pic)
12155 {
12156 mcount_name = machopic_stub_name (mcount_name);
12157 if (current_function_uses_pic_offset_table)
12158 caller_addr_regno = 0;
12159 }
12160#endif
12161 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
12162 0, VOIDmode, 1,
12163 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
12164 }
104d9861 12165}
12166
970e222f 12167/* Write function profiler code. */
c725ca16 12168
12169void
12170output_function_profiler (file, labelno)
12171 FILE *file;
12172 int labelno;
12173{
8f84ead8 12174 char buf[100];
e67e7d6f 12175 int save_lr = 8;
c725ca16 12176
8f84ead8 12177 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
bda6fa4d 12178 switch (DEFAULT_ABI)
8f84ead8 12179 {
bda6fa4d 12180 default:
12181 abort ();
12182
12183 case ABI_V4:
e67e7d6f 12184 save_lr = 4;
12185 /* Fall through. */
12186
bda6fa4d 12187 case ABI_AIX_NODESC:
e67e7d6f 12188 if (!TARGET_32BIT)
12189 {
12190 warning ("no profiling of 64-bit code for this ABI");
12191 return;
12192 }
bda6fa4d 12193 fprintf (file, "\tmflr %s\n", reg_names[0]);
12194 if (flag_pic == 1)
12195 {
13c06a53 12196 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
e67e7d6f 12197 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12198 reg_names[0], save_lr, reg_names[1]);
1c9aa673 12199 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
13c06a53 12200 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
bda6fa4d 12201 assemble_name (file, buf);
1c9aa673 12202 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
bda6fa4d 12203 }
bbd21807 12204 else if (flag_pic > 1)
bda6fa4d 12205 {
e67e7d6f 12206 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12207 reg_names[0], save_lr, reg_names[1]);
bbd21807 12208 /* Now, we need to get the address of the label. */
12209 fputs ("\tbl 1f\n\t.long ", file);
0dc80f60 12210 assemble_name (file, buf);
bbd21807 12211 fputs ("-.\n1:", file);
12212 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
12213 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
12214 reg_names[0], reg_names[11]);
12215 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
12216 reg_names[0], reg_names[0], reg_names[11]);
bda6fa4d 12217 }
bda6fa4d 12218 else
12219 {
1c9aa673 12220 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
bda6fa4d 12221 assemble_name (file, buf);
13c06a53 12222 fputs ("@ha\n", file);
e67e7d6f 12223 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12224 reg_names[0], save_lr, reg_names[1]);
8cda90b9 12225 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
bda6fa4d 12226 assemble_name (file, buf);
1c9aa673 12227 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
bda6fa4d 12228 }
12229
e67e7d6f 12230 if (current_function_needs_context && DEFAULT_ABI == ABI_AIX_NODESC)
12231 {
12232 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12233 reg_names[STATIC_CHAIN_REGNUM],
12234 12, reg_names[1]);
12235 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
12236 asm_fprintf (file, "\t{l|lwz} %s,%d(%s)\n",
12237 reg_names[STATIC_CHAIN_REGNUM],
12238 12, reg_names[1]);
12239 }
12240 else
12241 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
12242 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
bda6fa4d 12243 break;
12244
12245 case ABI_AIX:
80d725d7 12246 case ABI_DARWIN:
970e222f 12247 /* Don't do anything, done in output_profile_hook (). */
bda6fa4d 12248 break;
12249 }
c725ca16 12250}
c3dea6d3 12251
12252/* Adjust the cost of a scheduling dependency. Return the new cost of
12253 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
12254
747af5e7 12255static int
d6c0d720 12256rs6000_adjust_cost (insn, link, dep_insn, cost)
c3dea6d3 12257 rtx insn;
12258 rtx link;
600e851b 12259 rtx dep_insn ATTRIBUTE_UNUSED;
c3dea6d3 12260 int cost;
12261{
12262 if (! recog_memoized (insn))
12263 return 0;
12264
12265 if (REG_NOTE_KIND (link) != 0)
12266 return 0;
12267
12268 if (REG_NOTE_KIND (link) == 0)
12269 {
979b4d09 12270 /* Data dependency; DEP_INSN writes a register that INSN reads
12271 some cycles later. */
12272 switch (get_attr_type (insn))
12273 {
12274 case TYPE_JMPREG:
72943b59 12275 /* Tell the first scheduling pass about the latency between
979b4d09 12276 a mtctr and bctr (and mtlr and br/blr). The first
12277 scheduling pass will not know about this latency since
12278 the mtctr instruction, which has the latency associated
12279 to it, will be generated by reload. */
72943b59 12280 return TARGET_POWER ? 5 : 4;
979b4d09 12281 case TYPE_BRANCH:
12282 /* Leave some extra cycles between a compare and its
12283 dependent branch, to inhibit expensive mispredicts. */
72943b59 12284 if ((rs6000_cpu_attr == CPU_PPC603
12285 || rs6000_cpu_attr == CPU_PPC604
12286 || rs6000_cpu_attr == CPU_PPC604E
12287 || rs6000_cpu_attr == CPU_PPC620
12288 || rs6000_cpu_attr == CPU_PPC630
12289 || rs6000_cpu_attr == CPU_PPC750
12290 || rs6000_cpu_attr == CPU_PPC7400
12291 || rs6000_cpu_attr == CPU_PPC7450
12292 || rs6000_cpu_attr == CPU_POWER4)
979b4d09 12293 && recog_memoized (dep_insn)
12294 && (INSN_CODE (dep_insn) >= 0)
12295 && (get_attr_type (dep_insn) == TYPE_COMPARE
12296 || get_attr_type (dep_insn) == TYPE_DELAYED_COMPARE
12297 || get_attr_type (dep_insn) == TYPE_FPCOMPARE
12298 || get_attr_type (dep_insn) == TYPE_CR_LOGICAL))
12299 return cost + 2;
12300 default:
12301 break;
12302 }
c3dea6d3 12303 /* Fall out to return default cost. */
12304 }
12305
12306 return cost;
12307}
6b02f2a5 12308
970e222f 12309/* A C statement (sans semicolon) to update the integer scheduling
12310 priority INSN_PRIORITY (INSN). Reduce the priority to execute the
12311 INSN earlier, increase the priority to execute INSN later. Do not
12312 define this macro if you do not need to adjust the scheduling
12313 priorities of insns. */
932cf0bd 12314
747af5e7 12315static int
932cf0bd 12316rs6000_adjust_priority (insn, priority)
c0256c4b 12317 rtx insn ATTRIBUTE_UNUSED;
932cf0bd 12318 int priority;
12319{
970e222f 12320 /* On machines (like the 750) which have asymmetric integer units,
12321 where one integer unit can do multiply and divides and the other
12322 can't, reduce the priority of multiply/divide so it is scheduled
12323 before other integer operations. */
932cf0bd 12324
12325#if 0
9204e736 12326 if (! INSN_P (insn))
932cf0bd 12327 return priority;
12328
12329 if (GET_CODE (PATTERN (insn)) == USE)
12330 return priority;
12331
12332 switch (rs6000_cpu_attr) {
12333 case CPU_PPC750:
12334 switch (get_attr_type (insn))
12335 {
12336 default:
12337 break;
12338
12339 case TYPE_IMUL:
12340 case TYPE_IDIV:
91452706 12341 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
12342 priority, priority);
932cf0bd 12343 if (priority >= 0 && priority < 0x01000000)
12344 priority >>= 3;
12345 break;
12346 }
12347 }
12348#endif
12349
12350 return priority;
12351}
12352
970e222f 12353/* Return how many instructions the machine can issue per cycle. */
12354
747af5e7 12355static int
12356rs6000_issue_rate ()
6b02f2a5 12357{
12358 switch (rs6000_cpu_attr) {
91452706 12359 case CPU_RIOS1: /* ? */
12360 case CPU_RS64A:
12361 case CPU_PPC601: /* ? */
979b4d09 12362 case CPU_PPC7450:
91452706 12363 return 3;
6b02f2a5 12364 case CPU_PPC603:
932cf0bd 12365 case CPU_PPC750:
979b4d09 12366 case CPU_PPC7400:
932cf0bd 12367 return 2;
91452706 12368 case CPU_RIOS2:
6b02f2a5 12369 case CPU_PPC604:
7e065dae 12370 case CPU_PPC604E:
6b02f2a5 12371 case CPU_PPC620:
91452706 12372 case CPU_PPC630:
72943b59 12373 case CPU_POWER4:
6b02f2a5 12374 return 4;
12375 default:
12376 return 1;
12377 }
12378}
12379
6b02f2a5 12380\f
6b02f2a5 12381/* Length in units of the trampoline for entering a nested function. */
12382
12383int
12384rs6000_trampoline_size ()
12385{
12386 int ret = 0;
12387
12388 switch (DEFAULT_ABI)
12389 {
12390 default:
12391 abort ();
12392
12393 case ABI_AIX:
671422a6 12394 ret = (TARGET_32BIT) ? 12 : 24;
6b02f2a5 12395 break;
12396
9b505f64 12397 case ABI_DARWIN:
6b02f2a5 12398 case ABI_V4:
12399 case ABI_AIX_NODESC:
aecbd9f8 12400 ret = (TARGET_32BIT) ? 40 : 48;
6b02f2a5 12401 break;
6b02f2a5 12402 }
12403
12404 return ret;
12405}
12406
12407/* Emit RTL insns to initialize the variable parts of a trampoline.
12408 FNADDR is an RTX for the address of the function's pure code.
12409 CXT is an RTX for the static chain value for the function. */
12410
12411void
12412rs6000_initialize_trampoline (addr, fnaddr, cxt)
12413 rtx addr;
12414 rtx fnaddr;
12415 rtx cxt;
12416{
df72cce1 12417 enum machine_mode pmode = Pmode;
7ddfeb8f 12418 int regsize = (TARGET_32BIT) ? 4 : 8;
12419 rtx ctx_reg = force_reg (pmode, cxt);
6b02f2a5 12420
12421 switch (DEFAULT_ABI)
12422 {
12423 default:
12424 abort ();
12425
7ddfeb8f 12426/* Macros to shorten the code expansions below. */
3469a3e2 12427#define MEM_DEREF(addr) gen_rtx_MEM (pmode, memory_address (pmode, addr))
7014838c 12428#define MEM_PLUS(addr,offset) \
12429 gen_rtx_MEM (pmode, memory_address (pmode, plus_constant (addr, offset)))
377433d4 12430
6b02f2a5 12431 /* Under AIX, just build the 3 word function descriptor */
12432 case ABI_AIX:
7ddfeb8f 12433 {
12434 rtx fn_reg = gen_reg_rtx (pmode);
12435 rtx toc_reg = gen_reg_rtx (pmode);
12436 emit_move_insn (fn_reg, MEM_DEREF (fnaddr));
0982eb4e 12437 emit_move_insn (toc_reg, MEM_PLUS (fnaddr, regsize));
7ddfeb8f 12438 emit_move_insn (MEM_DEREF (addr), fn_reg);
12439 emit_move_insn (MEM_PLUS (addr, regsize), toc_reg);
12440 emit_move_insn (MEM_PLUS (addr, 2*regsize), ctx_reg);
12441 }
6b02f2a5 12442 break;
12443
9b505f64 12444 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
12445 case ABI_DARWIN:
6b02f2a5 12446 case ABI_V4:
12447 case ABI_AIX_NODESC:
3469a3e2 12448 emit_library_call (gen_rtx_SYMBOL_REF (SImode, "__trampoline_setup"),
f9fff8e4 12449 FALSE, VOIDmode, 4,
12450 addr, pmode,
12451 GEN_INT (rs6000_trampoline_size ()), SImode,
12452 fnaddr, pmode,
12453 ctx_reg, pmode);
6b02f2a5 12454 break;
6b02f2a5 12455 }
12456
12457 return;
12458}
7a2fc9d6 12459
12460\f
e3c541f0 12461/* Table of valid machine attributes. */
970e222f 12462
e3c541f0 12463const struct attribute_spec rs6000_attribute_table[] =
7a2fc9d6 12464{
e3c541f0 12465 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
edd2f2ae 12466 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
12467 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
12468 { NULL, 0, 0, false, false, false, NULL }
e3c541f0 12469};
7a2fc9d6 12470
edd2f2ae 12471/* Handle a "longcall" or "shortcall" attribute; arguments as in
12472 struct attribute_spec.handler. */
970e222f 12473
e3c541f0 12474static tree
12475rs6000_handle_longcall_attribute (node, name, args, flags, no_add_attrs)
12476 tree *node;
12477 tree name;
12478 tree args ATTRIBUTE_UNUSED;
12479 int flags ATTRIBUTE_UNUSED;
12480 bool *no_add_attrs;
12481{
12482 if (TREE_CODE (*node) != FUNCTION_TYPE
12483 && TREE_CODE (*node) != FIELD_DECL
12484 && TREE_CODE (*node) != TYPE_DECL)
12485 {
12486 warning ("`%s' attribute only applies to functions",
12487 IDENTIFIER_POINTER (name));
12488 *no_add_attrs = true;
12489 }
fed06885 12490
e3c541f0 12491 return NULL_TREE;
7a2fc9d6 12492}
12493
edd2f2ae 12494/* Set longcall attributes on all functions declared when
12495 rs6000_default_long_calls is true. */
12496static void
12497rs6000_set_default_type_attributes (type)
12498 tree type;
12499{
12500 if (rs6000_default_long_calls
12501 && (TREE_CODE (type) == FUNCTION_TYPE
12502 || TREE_CODE (type) == METHOD_TYPE))
12503 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
12504 NULL_TREE,
12505 TYPE_ATTRIBUTES (type));
12506}
12507
91452706 12508/* Return a reference suitable for calling a function with the
12509 longcall attribute. */
970e222f 12510
fed06885 12511struct rtx_def *
12512rs6000_longcall_ref (call_ref)
12513 rtx call_ref;
12514{
c0256c4b 12515 const char *call_name;
fed06885 12516 tree node;
12517
12518 if (GET_CODE (call_ref) != SYMBOL_REF)
12519 return call_ref;
12520
12521 /* System V adds '.' to the internal name, so skip them. */
12522 call_name = XSTR (call_ref, 0);
12523 if (*call_name == '.')
12524 {
12525 while (*call_name == '.')
12526 call_name++;
12527
12528 node = get_identifier (call_name);
3469a3e2 12529 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
fed06885 12530 }
12531
12532 return force_reg (Pmode, call_ref);
12533}
12534
7a2fc9d6 12535\f
bbfbe351 12536#ifdef USING_ELFOS_H
12537
7a2fc9d6 12538/* A C statement or statements to switch to the appropriate section
12539 for output of RTX in mode MODE. You can assume that RTX is some
12540 kind of constant in RTL. The argument MODE is redundant except in
12541 the case of a `const_int' rtx. Select the section by calling
12542 `text_section' or one of the alternatives for other sections.
12543
12544 Do not define this macro if you put all constants in the read-only
12545 data section. */
12546
bbfbe351 12547static void
12548rs6000_elf_select_rtx_section (mode, x, align)
e2f08fad 12549 enum machine_mode mode;
7a2fc9d6 12550 rtx x;
bbfbe351 12551 unsigned HOST_WIDE_INT align;
7a2fc9d6 12552{
e2f08fad 12553 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
7a2fc9d6 12554 toc_section ();
7a2fc9d6 12555 else
bbfbe351 12556 default_elf_select_rtx_section (mode, x, align);
7a2fc9d6 12557}
12558
12559/* A C statement or statements to switch to the appropriate
12560 section for output of DECL. DECL is either a `VAR_DECL' node
12561 or a constant of some sort. RELOC indicates whether forming
12562 the initial value of DECL requires link-time relocations. */
12563
52470889 12564static void
12565rs6000_elf_select_section (decl, reloc, align)
7a2fc9d6 12566 tree decl;
12567 int reloc;
62afdbc8 12568 unsigned HOST_WIDE_INT align;
7a2fc9d6 12569{
62afdbc8 12570 default_elf_select_section_1 (decl, reloc, align,
12571 flag_pic || DEFAULT_ABI == ABI_AIX);
7349e86e 12572}
12573
12574/* A C statement to build up a unique section name, expressed as a
12575 STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
12576 RELOC indicates whether the initial value of EXP requires
12577 link-time relocations. If you do not define this macro, GCC will use
12578 the symbol name prefixed by `.' as the section name. Note - this
35a3065a 12579 macro can now be called for uninitialized data items as well as
457275b6 12580 initialized data and functions. */
7349e86e 12581
52470889 12582static void
12583rs6000_elf_unique_section (decl, reloc)
7349e86e 12584 tree decl;
12585 int reloc;
12586{
62afdbc8 12587 default_unique_section_1 (decl, reloc,
12588 flag_pic || DEFAULT_ABI == ABI_AIX);
7a2fc9d6 12589}
d72e2a6e 12590
12591\f
d72e2a6e 12592/* If we are referencing a function that is static or is known to be
12593 in this file, make the SYMBOL_REF special. We can use this to indicate
12594 that we can branch to this function without emitting a no-op after the
bbd21807 12595 call. For real AIX calling sequences, we also replace the
d72e2a6e 12596 function name with the real name (1 or 2 leading .'s), rather than
12597 the function descriptor name. This saves a lot of overriding code
8cda90b9 12598 to read the prefixes. */
d72e2a6e 12599
7811991d 12600static void
12601rs6000_elf_encode_section_info (decl, first)
d72e2a6e 12602 tree decl;
41eb471c 12603 int first;
d72e2a6e 12604{
41eb471c 12605 if (!first)
12606 return;
12607
d72e2a6e 12608 if (TREE_CODE (decl) == FUNCTION_DECL)
12609 {
12610 rtx sym_ref = XEXP (DECL_RTL (decl), 0);
a164e2a9 12611 if ((*targetm.binds_local_p) (decl))
d72e2a6e 12612 SYMBOL_REF_FLAG (sym_ref) = 1;
12613
bbd21807 12614 if (DEFAULT_ABI == ABI_AIX)
d72e2a6e 12615 {
8b832a9a 12616 size_t len1 = (DEFAULT_ABI == ABI_AIX) ? 1 : 2;
12617 size_t len2 = strlen (XSTR (sym_ref, 0));
44acf429 12618 char *str = alloca (len1 + len2 + 1);
8b832a9a 12619 str[0] = '.';
12620 str[1] = '.';
12621 memcpy (str + len1, XSTR (sym_ref, 0), len2 + 1);
12622
44acf429 12623 XSTR (sym_ref, 0) = ggc_alloc_string (str, len1 + len2);
d72e2a6e 12624 }
12625 }
12626 else if (rs6000_sdata != SDATA_NONE
e7ce8542 12627 && DEFAULT_ABI == ABI_V4
d72e2a6e 12628 && TREE_CODE (decl) == VAR_DECL)
12629 {
12630 int size = int_size_in_bytes (TREE_TYPE (decl));
12631 tree section_name = DECL_SECTION_NAME (decl);
c0256c4b 12632 const char *name = (char *)0;
d72e2a6e 12633 int len = 0;
12634
12635 if (section_name)
12636 {
12637 if (TREE_CODE (section_name) == STRING_CST)
12638 {
12639 name = TREE_STRING_POINTER (section_name);
12640 len = TREE_STRING_LENGTH (section_name);
12641 }
12642 else
12643 abort ();
12644 }
12645
12646 if ((size > 0 && size <= g_switch_value)
12647 || (name
837b446a 12648 && ((len == sizeof (".sdata") - 1
91452706 12649 && strcmp (name, ".sdata") == 0)
837b446a 12650 || (len == sizeof (".sdata2") - 1
91452706 12651 && strcmp (name, ".sdata2") == 0)
837b446a 12652 || (len == sizeof (".sbss") - 1
91452706 12653 && strcmp (name, ".sbss") == 0)
837b446a 12654 || (len == sizeof (".sbss2") - 1
91452706 12655 && strcmp (name, ".sbss2") == 0)
837b446a 12656 || (len == sizeof (".PPC.EMB.sdata0") - 1
91452706 12657 && strcmp (name, ".PPC.EMB.sdata0") == 0)
837b446a 12658 || (len == sizeof (".PPC.EMB.sbss0") - 1
91452706 12659 && strcmp (name, ".PPC.EMB.sbss0") == 0))))
d72e2a6e 12660 {
12661 rtx sym_ref = XEXP (DECL_RTL (decl), 0);
8b832a9a 12662 size_t len = strlen (XSTR (sym_ref, 0));
e6b3f164 12663 char *str = alloca (len + 2);
8b832a9a 12664
8b832a9a 12665 str[0] = '@';
12666 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
e6b3f164 12667 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
d72e2a6e 12668 }
12669 }
12670}
12671
7b4a38a6 12672static const char *
12673rs6000_elf_strip_name_encoding (str)
12674 const char *str;
12675{
12676 while (*str == '*' || *str == '@')
12677 str++;
12678 return str;
12679}
12680
62afdbc8 12681static bool
12682rs6000_elf_in_small_data_p (decl)
12683 tree decl;
12684{
12685 if (rs6000_sdata == SDATA_NONE)
12686 return false;
12687
12688 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
12689 {
12690 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
12691 if (strcmp (section, ".sdata") == 0
12692 || strcmp (section, ".sdata2") == 0
12693 || strcmp (section, ".sbss") == 0)
12694 return true;
12695 }
12696 else
12697 {
12698 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
12699
12700 if (size > 0
12701 && size <= g_switch_value
12702 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
12703 return true;
12704 }
12705
12706 return false;
12707}
12708
327811ee 12709#endif /* USING_ELFOS_H */
36daf5a5 12710
7ee7da40 12711\f
36daf5a5 12712/* Return a REG that occurs in ADDR with coefficient 1.
b3423339 12713 ADDR can be effectively incremented by incrementing REG.
12714
12715 r0 is special and we must not select it as an address
12716 register by this routine since our caller will try to
12717 increment the returned register via an "la" instruction. */
36daf5a5 12718
12719struct rtx_def *
12720find_addr_reg (addr)
12721 rtx addr;
12722{
12723 while (GET_CODE (addr) == PLUS)
12724 {
b3423339 12725 if (GET_CODE (XEXP (addr, 0)) == REG
12726 && REGNO (XEXP (addr, 0)) != 0)
36daf5a5 12727 addr = XEXP (addr, 0);
b3423339 12728 else if (GET_CODE (XEXP (addr, 1)) == REG
12729 && REGNO (XEXP (addr, 1)) != 0)
36daf5a5 12730 addr = XEXP (addr, 1);
12731 else if (CONSTANT_P (XEXP (addr, 0)))
12732 addr = XEXP (addr, 1);
12733 else if (CONSTANT_P (XEXP (addr, 1)))
12734 addr = XEXP (addr, 0);
12735 else
12736 abort ();
12737 }
b3423339 12738 if (GET_CODE (addr) == REG && REGNO (addr) != 0)
36daf5a5 12739 return addr;
12740 abort ();
12741}
12742
7ee7da40 12743void
12744rs6000_fatal_bad_address (op)
12745 rtx op;
12746{
12747 fatal_insn ("bad address", op);
12748}
b36db59b 12749
12750/* Called to register all of our global variables with the garbage
12751 collector. */
12752
12753static void
12754rs6000_add_gc_roots ()
12755{
bbd21807 12756 toc_hash_table = htab_create (1021, toc_hash_function, toc_hash_eq, NULL);
12757 ggc_add_root (&toc_hash_table, 1, sizeof (toc_hash_table),
12758 toc_hash_mark_table);
80d725d7 12759}
12760
12761#if TARGET_MACHO
12762
12763#if 0
12764/* Returns 1 if OP is either a symbol reference or a sum of a symbol
12765 reference and a constant. */
12766
12767int
12768symbolic_operand (op)
773e893a 12769 rtx op;
80d725d7 12770{
12771 switch (GET_CODE (op))
12772 {
12773 case SYMBOL_REF:
12774 case LABEL_REF:
12775 return 1;
12776 case CONST:
12777 op = XEXP (op, 0);
12778 return (GET_CODE (op) == SYMBOL_REF ||
12779 (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
12780 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
12781 && GET_CODE (XEXP (op, 1)) == CONST_INT);
12782 default:
12783 return 0;
12784 }
b36db59b 12785}
80d725d7 12786#endif
12787
12788#ifdef RS6000_LONG_BRANCH
12789
12790static tree stub_list = 0;
12791
12792/* ADD_COMPILER_STUB adds the compiler generated stub for handling
12793 procedure calls to the linked list. */
12794
12795void
12796add_compiler_stub (label_name, function_name, line_number)
12797 tree label_name;
12798 tree function_name;
12799 int line_number;
12800{
12801 tree stub = build_tree_list (function_name, label_name);
12802 TREE_TYPE (stub) = build_int_2 (line_number, 0);
12803 TREE_CHAIN (stub) = stub_list;
12804 stub_list = stub;
12805}
12806
12807#define STUB_LABEL_NAME(STUB) TREE_VALUE (STUB)
12808#define STUB_FUNCTION_NAME(STUB) TREE_PURPOSE (STUB)
12809#define STUB_LINE_NUMBER(STUB) TREE_INT_CST_LOW (TREE_TYPE (STUB))
12810
970e222f 12811/* OUTPUT_COMPILER_STUB outputs the compiler generated stub for
12812 handling procedure calls from the linked list and initializes the
12813 linked list. */
80d725d7 12814
970e222f 12815void
12816output_compiler_stub ()
80d725d7 12817{
12818 char tmp_buf[256];
12819 char label_buf[256];
e08baea1 12820 tree stub;
80d725d7 12821
12822 if (!flag_pic)
12823 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
12824 {
12825 fprintf (asm_out_file,
12826 "%s:\n", IDENTIFIER_POINTER(STUB_LABEL_NAME(stub)));
12827
12828#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
12829 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
12830 fprintf (asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER(stub));
12831#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
12832
12833 if (IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))[0] == '*')
12834 strcpy (label_buf,
12835 IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))+1);
12836 else
12837 {
12838 label_buf[0] = '_';
12839 strcpy (label_buf+1,
12840 IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub)));
12841 }
12842
12843 strcpy (tmp_buf, "lis r12,hi16(");
12844 strcat (tmp_buf, label_buf);
12845 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
12846 strcat (tmp_buf, label_buf);
12847 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
12848 output_asm_insn (tmp_buf, 0);
12849
12850#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
12851 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
12852 fprintf(asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER (stub));
12853#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
12854 }
12855
12856 stub_list = 0;
12857}
12858
12859/* NO_PREVIOUS_DEF checks in the link list whether the function name is
12860 already there or not. */
12861
970e222f 12862int
12863no_previous_def (function_name)
80d725d7 12864 tree function_name;
12865{
12866 tree stub;
12867 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
12868 if (function_name == STUB_FUNCTION_NAME (stub))
12869 return 0;
12870 return 1;
12871}
12872
12873/* GET_PREV_LABEL gets the label name from the previous definition of
12874 the function. */
12875
970e222f 12876tree
12877get_prev_label (function_name)
80d725d7 12878 tree function_name;
12879{
12880 tree stub;
12881 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
12882 if (function_name == STUB_FUNCTION_NAME (stub))
12883 return STUB_LABEL_NAME (stub);
12884 return 0;
12885}
12886
12887/* INSN is either a function call or a millicode call. It may have an
12888 unconditional jump in its delay slot.
12889
12890 CALL_DEST is the routine we are calling. */
12891
12892char *
12893output_call (insn, call_dest, operand_number)
12894 rtx insn;
12895 rtx call_dest;
12896 int operand_number;
12897{
12898 static char buf[256];
12899 if (GET_CODE (call_dest) == SYMBOL_REF && TARGET_LONG_BRANCH && !flag_pic)
12900 {
12901 tree labelname;
12902 tree funname = get_identifier (XSTR (call_dest, 0));
12903
12904 if (no_previous_def (funname))
12905 {
e08baea1 12906 int line_number = 0;
80d725d7 12907 rtx label_rtx = gen_label_rtx ();
12908 char *label_buf, temp_buf[256];
12909 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
12910 CODE_LABEL_NUMBER (label_rtx));
12911 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
12912 labelname = get_identifier (label_buf);
12913 for (; insn && GET_CODE (insn) != NOTE; insn = PREV_INSN (insn));
12914 if (insn)
12915 line_number = NOTE_LINE_NUMBER (insn);
12916 add_compiler_stub (labelname, funname, line_number);
12917 }
12918 else
12919 labelname = get_prev_label (funname);
12920
12921 sprintf (buf, "jbsr %%z%d,%.246s",
12922 operand_number, IDENTIFIER_POINTER (labelname));
12923 return buf;
12924 }
12925 else
12926 {
12927 sprintf (buf, "bl %%z%d", operand_number);
12928 return buf;
12929 }
12930}
12931
12932#endif /* RS6000_LONG_BRANCH */
12933
12934#define GEN_LOCAL_LABEL_FOR_SYMBOL(BUF,SYMBOL,LENGTH,N) \
12935 do { \
0d95286f 12936 const char *const symbol_ = (SYMBOL); \
80d725d7 12937 char *buffer_ = (BUF); \
12938 if (symbol_[0] == '"') \
12939 { \
12940 sprintf(buffer_, "\"L%d$%s", (N), symbol_+1); \
12941 } \
12942 else if (name_needs_quotes(symbol_)) \
12943 { \
12944 sprintf(buffer_, "\"L%d$%s\"", (N), symbol_); \
12945 } \
12946 else \
12947 { \
12948 sprintf(buffer_, "L%d$%s", (N), symbol_); \
12949 } \
12950 } while (0)
12951
12952
12953/* Generate PIC and indirect symbol stubs. */
12954
12955void
12956machopic_output_stub (file, symb, stub)
12957 FILE *file;
12958 const char *symb, *stub;
12959{
12960 unsigned int length;
970e222f 12961 char *symbol_name, *lazy_ptr_name;
12962 char *local_label_0;
80d725d7 12963 static int label = 0;
12964
8dfaa51b 12965 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
7b4a38a6 12966 symb = (*targetm.strip_name_encoding) (symb);
8dfaa51b 12967
80d725d7 12968 label += 1;
12969
80d725d7 12970 length = strlen (symb);
12971 symbol_name = alloca (length + 32);
12972 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
12973
12974 lazy_ptr_name = alloca (length + 32);
12975 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
12976
12977 local_label_0 = alloca (length + 32);
12978 GEN_LOCAL_LABEL_FOR_SYMBOL (local_label_0, symb, length, 0);
12979
80d725d7 12980 if (flag_pic == 2)
12981 machopic_picsymbol_stub_section ();
12982 else
12983 machopic_symbol_stub_section ();
12984
12985 fprintf (file, "%s:\n", stub);
12986 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
12987
12988 if (flag_pic == 2)
12989 {
12990 fprintf (file, "\tmflr r0\n");
12991 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
12992 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
12993 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
12994 lazy_ptr_name, local_label_0);
12995 fprintf (file, "\tmtlr r0\n");
12996 fprintf (file, "\tlwz r12,lo16(%s-%s)(r11)\n",
12997 lazy_ptr_name, local_label_0);
12998 fprintf (file, "\tmtctr r12\n");
12999 fprintf (file, "\taddi r11,r11,lo16(%s-%s)\n",
13000 lazy_ptr_name, local_label_0);
13001 fprintf (file, "\tbctr\n");
13002 }
13003 else
13004 fprintf (file, "non-pure not supported\n");
13005
13006 machopic_lazy_symbol_ptr_section ();
13007 fprintf (file, "%s:\n", lazy_ptr_name);
13008 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
13009 fprintf (file, "\t.long dyld_stub_binding_helper\n");
13010}
13011
13012/* Legitimize PIC addresses. If the address is already
13013 position-independent, we return ORIG. Newly generated
13014 position-independent addresses go into a reg. This is REG if non
13015 zero, otherwise we allocate register(s) as necessary. */
13016
ad3ed368 13017#define SMALL_INT(X) ((unsigned) (INTVAL(X) + 0x8000) < 0x10000)
80d725d7 13018
13019rtx
13020rs6000_machopic_legitimize_pic_address (orig, mode, reg)
13021 rtx orig;
13022 enum machine_mode mode;
13023 rtx reg;
13024{
13025 rtx base, offset;
13026
13027 if (reg == NULL && ! reload_in_progress && ! reload_completed)
13028 reg = gen_reg_rtx (Pmode);
13029
13030 if (GET_CODE (orig) == CONST)
13031 {
13032 if (GET_CODE (XEXP (orig, 0)) == PLUS
13033 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
13034 return orig;
13035
13036 if (GET_CODE (XEXP (orig, 0)) == PLUS)
13037 {
970e222f 13038 base =
13039 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
13040 Pmode, reg);
13041 offset =
13042 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
13043 Pmode, reg);
80d725d7 13044 }
13045 else
13046 abort ();
13047
13048 if (GET_CODE (offset) == CONST_INT)
13049 {
13050 if (SMALL_INT (offset))
b244d4c7 13051 return plus_constant (base, INTVAL (offset));
80d725d7 13052 else if (! reload_in_progress && ! reload_completed)
13053 offset = force_reg (Pmode, offset);
13054 else
ad3ed368 13055 {
13056 rtx mem = force_const_mem (Pmode, orig);
13057 return machopic_legitimize_pic_address (mem, Pmode, reg);
13058 }
80d725d7 13059 }
13060 return gen_rtx (PLUS, Pmode, base, offset);
13061 }
13062
13063 /* Fall back on generic machopic code. */
13064 return machopic_legitimize_pic_address (orig, mode, reg);
13065}
13066
13067/* This is just a placeholder to make linking work without having to
13068 add this to the generic Darwin EXTRA_SECTIONS. If -mcall-aix is
13069 ever needed for Darwin (not too likely!) this would have to get a
13070 real definition. */
13071
13072void
13073toc_section ()
13074{
13075}
13076
13077#endif /* TARGET_MACHO */
2cb4ac60 13078
13079#if TARGET_ELF
13080static unsigned int
13081rs6000_elf_section_type_flags (decl, name, reloc)
13082 tree decl;
13083 const char *name;
13084 int reloc;
13085{
d3e1259a 13086 unsigned int flags
13087 = default_section_type_flags_1 (decl, name, reloc,
13088 flag_pic || DEFAULT_ABI == ABI_AIX);
2cb4ac60 13089
f5d9353e 13090 if (TARGET_RELOCATABLE)
13091 flags |= SECTION_WRITE;
2cb4ac60 13092
16544f20 13093 return flags;
2cb4ac60 13094}
b77e8561 13095
13096/* Record an element in the table of global constructors. SYMBOL is
13097 a SYMBOL_REF of the function to be called; PRIORITY is a number
13098 between 0 and MAX_INIT_PRIORITY.
13099
13100 This differs from default_named_section_asm_out_constructor in
13101 that we have special handling for -mrelocatable. */
13102
13103static void
13104rs6000_elf_asm_out_constructor (symbol, priority)
13105 rtx symbol;
13106 int priority;
13107{
13108 const char *section = ".ctors";
13109 char buf[16];
13110
13111 if (priority != DEFAULT_INIT_PRIORITY)
13112 {
13113 sprintf (buf, ".ctors.%.5u",
13114 /* Invert the numbering so the linker puts us in the proper
13115 order; constructors are run from right to left, and the
13116 linker sorts in increasing order. */
13117 MAX_INIT_PRIORITY - priority);
13118 section = buf;
13119 }
13120
29a0ebee 13121 named_section_flags (section, SECTION_WRITE);
13122 assemble_align (POINTER_SIZE);
b77e8561 13123
13124 if (TARGET_RELOCATABLE)
13125 {
13126 fputs ("\t.long (", asm_out_file);
13127 output_addr_const (asm_out_file, symbol);
13128 fputs (")@fixup\n", asm_out_file);
13129 }
13130 else
09d688ff 13131 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
b77e8561 13132}
13133
13134static void
13135rs6000_elf_asm_out_destructor (symbol, priority)
13136 rtx symbol;
13137 int priority;
13138{
13139 const char *section = ".dtors";
13140 char buf[16];
13141
13142 if (priority != DEFAULT_INIT_PRIORITY)
13143 {
13144 sprintf (buf, ".dtors.%.5u",
13145 /* Invert the numbering so the linker puts us in the proper
13146 order; constructors are run from right to left, and the
13147 linker sorts in increasing order. */
13148 MAX_INIT_PRIORITY - priority);
13149 section = buf;
13150 }
13151
29a0ebee 13152 named_section_flags (section, SECTION_WRITE);
13153 assemble_align (POINTER_SIZE);
b77e8561 13154
13155 if (TARGET_RELOCATABLE)
13156 {
13157 fputs ("\t.long (", asm_out_file);
13158 output_addr_const (asm_out_file, symbol);
13159 fputs (")@fixup\n", asm_out_file);
13160 }
13161 else
09d688ff 13162 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
b77e8561 13163}
2cb4ac60 13164#endif
13165
17fb2af4 13166#if TARGET_XCOFF
2cb4ac60 13167static void
f9648009 13168rs6000_xcoff_asm_globalize_label (stream, name)
13169 FILE *stream;
13170 const char *name;
13171{
13172 fputs (GLOBAL_ASM_OP, stream);
13173 RS6000_OUTPUT_BASENAME (stream, name);
13174 putc ('\n', stream);
13175}
13176
13177static void
13178rs6000_xcoff_asm_named_section (name, flags)
2cb4ac60 13179 const char *name;
62afdbc8 13180 unsigned int flags;
2cb4ac60 13181{
62afdbc8 13182 int smclass;
13183 static const char * const suffix[3] = { "PR", "RO", "RW" };
13184
13185 if (flags & SECTION_CODE)
13186 smclass = 0;
13187 else if (flags & SECTION_WRITE)
13188 smclass = 2;
13189 else
13190 smclass = 1;
13191
6f2cc60f 13192 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
62afdbc8 13193 (flags & SECTION_CODE) ? "." : "",
6f2cc60f 13194 name, suffix[smclass], flags & SECTION_ENTSIZE);
2cb4ac60 13195}
52470889 13196
13197static void
62afdbc8 13198rs6000_xcoff_select_section (decl, reloc, align)
13199 tree decl;
52470889 13200 int reloc;
13201 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
13202{
d3e1259a 13203 if (decl_readonly_section_1 (decl, reloc, 1))
52470889 13204 {
62afdbc8 13205 if (TREE_PUBLIC (decl))
52470889 13206 read_only_data_section ();
13207 else
13208 read_only_private_data_section ();
13209 }
13210 else
13211 {
62afdbc8 13212 if (TREE_PUBLIC (decl))
52470889 13213 data_section ();
13214 else
13215 private_data_section ();
13216 }
13217}
13218
13219static void
13220rs6000_xcoff_unique_section (decl, reloc)
13221 tree decl;
7b4a38a6 13222 int reloc ATTRIBUTE_UNUSED;
52470889 13223{
13224 const char *name;
52470889 13225
6f2cc60f 13226 /* Use select_section for private and uninitialized data. */
13227 if (!TREE_PUBLIC (decl)
13228 || DECL_COMMON (decl)
62afdbc8 13229 || DECL_INITIAL (decl) == NULL_TREE
13230 || DECL_INITIAL (decl) == error_mark_node
13231 || (flag_zero_initialized_in_bss
13232 && initializer_zerop (DECL_INITIAL (decl))))
13233 return;
13234
13235 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
13236 name = (*targetm.strip_name_encoding) (name);
13237 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
52470889 13238}
bbfbe351 13239
7811991d 13240/* Select section for constant in constant pool.
13241
13242 On RS/6000, all constants are in the private read-only data area.
13243 However, if this is being placed in the TOC it must be output as a
13244 toc entry. */
13245
bbfbe351 13246static void
13247rs6000_xcoff_select_rtx_section (mode, x, align)
13248 enum machine_mode mode;
13249 rtx x;
13250 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
13251{
13252 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
13253 toc_section ();
13254 else
13255 read_only_private_data_section ();
13256}
7b4a38a6 13257
13258/* Remove any trailing [DS] or the like from the symbol name. */
13259
13260static const char *
13261rs6000_xcoff_strip_name_encoding (name)
13262 const char *name;
13263{
13264 size_t len;
13265 if (*name == '*')
13266 name++;
13267 len = strlen (name);
13268 if (name[len - 1] == ']')
13269 return ggc_alloc_string (name, len - 4);
13270 else
13271 return name;
13272}
13273
d3e1259a 13274/* Section attributes. AIX is always PIC. */
13275
13276static unsigned int
13277rs6000_xcoff_section_type_flags (decl, name, reloc)
13278 tree decl;
13279 const char *name;
13280 int reloc;
13281{
6f2cc60f 13282 unsigned int align;
13283 unsigned int flags = default_section_type_flags_1 (decl, name, reloc, 1);
13284
13285 /* Align to at least UNIT size. */
13286 if (flags & SECTION_CODE)
13287 align = MIN_UNITS_PER_WORD;
13288 else
13289 /* Increase alignment of large objects if not already stricter. */
13290 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
13291 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
13292 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
13293
13294 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
d3e1259a 13295}
13296
17fb2af4 13297#endif /* TARGET_XCOFF */
7811991d 13298
62afdbc8 13299/* Note that this is also used for PPC64 Linux. */
7811991d 13300
13301static void
13302rs6000_xcoff_encode_section_info (decl, first)
13303 tree decl;
13304 int first ATTRIBUTE_UNUSED;
13305{
13306 if (TREE_CODE (decl) == FUNCTION_DECL
a164e2a9 13307 && (*targetm.binds_local_p) (decl))
7811991d 13308 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
13309}
62afdbc8 13310
13311/* Cross-module name binding. For AIX and PPC64 Linux, which always are
13312 PIC, use private copy of flag_pic. */
13313
4e06ed1d 13314static bool
62afdbc8 13315rs6000_binds_local_p (decl)
13316 tree decl;
13317{
d3e1259a 13318 return default_binds_local_p_1 (decl, flag_pic || rs6000_flag_pic);
62afdbc8 13319}
4880d8d5 13320
13321/* A C expression returning the cost of moving data from a register of class
13322 CLASS1 to one of CLASS2. */
13323
13324int
13325rs6000_register_move_cost (mode, from, to)
13326 enum machine_mode mode;
13327 enum reg_class from, to;
13328{
13329 /* Moves from/to GENERAL_REGS. */
13330 if (reg_classes_intersect_p (to, GENERAL_REGS)
13331 || reg_classes_intersect_p (from, GENERAL_REGS))
13332 {
13333 if (! reg_classes_intersect_p (to, GENERAL_REGS))
13334 from = to;
13335
13336 if (from == FLOAT_REGS || from == ALTIVEC_REGS)
13337 return (rs6000_memory_move_cost (mode, from, 0)
13338 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
13339
13340/* It's more expensive to move CR_REGS than CR0_REGS because of the shift...*/
13341 else if (from == CR_REGS)
13342 return 4;
13343
13344 else
13345/* A move will cost one instruction per GPR moved. */
13346 return 2 * HARD_REGNO_NREGS (0, mode);
13347 }
13348
13349/* Moving between two similar registers is just one instruction. */
13350 else if (reg_classes_intersect_p (to, from))
13351 return mode == TFmode ? 4 : 2;
13352
13353/* Everything else has to go through GENERAL_REGS. */
13354 else
13355 return (rs6000_register_move_cost (mode, GENERAL_REGS, to)
13356 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
13357}
13358
13359/* A C expressions returning the cost of moving data of MODE from a register to
13360 or from memory. */
13361
13362int
13363rs6000_memory_move_cost (mode, class, in)
13364 enum machine_mode mode;
13365 enum reg_class class;
13366 int in ATTRIBUTE_UNUSED;
13367{
13368 if (reg_classes_intersect_p (class, GENERAL_REGS))
13369 return 4 * HARD_REGNO_NREGS (0, mode);
13370 else if (reg_classes_intersect_p (class, FLOAT_REGS))
13371 return 4 * HARD_REGNO_NREGS (32, mode);
13372 else if (reg_classes_intersect_p (class, ALTIVEC_REGS))
13373 return 4 * HARD_REGNO_NREGS (FIRST_ALTIVEC_REGNO, mode);
13374 else
13375 return 4 + rs6000_register_move_cost (mode, class, GENERAL_REGS);
13376}
13377