comparison gcc/config/arc/arc.c @ 67:f6334be47118

update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
date Tue, 22 Mar 2011 17:18:12 +0900
parents b7f97abdc517
children 04ced10e8804
comparison
equal deleted inserted replaced
65:65488c3d617d 67:f6334be47118
1 /* Subroutines used for code generation on the Argonaut ARC cpu. 1 /* Subroutines used for code generation on the Argonaut ARC cpu.
2 Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2 Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. 3 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
4 4
5 This file is part of GCC. 5 This file is part of GCC.
6 6
7 GCC is free software; you can redistribute it and/or modify 7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 8 it under the terms of the GNU General Public License as published by
34 #include "insn-attr.h" 34 #include "insn-attr.h"
35 #include "flags.h" 35 #include "flags.h"
36 #include "function.h" 36 #include "function.h"
37 #include "expr.h" 37 #include "expr.h"
38 #include "recog.h" 38 #include "recog.h"
39 #include "toplev.h" 39 #include "diagnostic-core.h"
40 #include "df.h" 40 #include "df.h"
41 #include "tm_p.h" 41 #include "tm_p.h"
42 #include "target.h" 42 #include "target.h"
43 #include "target-def.h" 43 #include "target-def.h"
44 44
91 static int arc_address_cost (rtx, bool); 91 static int arc_address_cost (rtx, bool);
92 static void arc_external_libcall (rtx); 92 static void arc_external_libcall (rtx);
93 static bool arc_return_in_memory (const_tree, const_tree); 93 static bool arc_return_in_memory (const_tree, const_tree);
94 static bool arc_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, 94 static bool arc_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
95 const_tree, bool); 95 const_tree, bool);
96 static rtx arc_function_arg (CUMULATIVE_ARGS *, enum machine_mode,
97 const_tree, bool);
98 static void arc_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
99 const_tree, bool);
100 static unsigned int arc_function_arg_boundary (enum machine_mode, const_tree);
96 static void arc_trampoline_init (rtx, tree, rtx); 101 static void arc_trampoline_init (rtx, tree, rtx);
102 static void arc_option_override (void);
103 static void arc_conditional_register_usage (void);
97 104
98 105
99 /* ARC specific attributs. */ 106 /* ARC specific attributs. */
100 107
101 static const struct attribute_spec arc_attribute_table[] = 108 static const struct attribute_spec arc_attribute_table[] =
127 #define TARGET_ASM_EXTERNAL_LIBCALL arc_external_libcall 134 #define TARGET_ASM_EXTERNAL_LIBCALL arc_external_libcall
128 135
129 #undef TARGET_HANDLE_OPTION 136 #undef TARGET_HANDLE_OPTION
130 #define TARGET_HANDLE_OPTION arc_handle_option 137 #define TARGET_HANDLE_OPTION arc_handle_option
131 138
139 #undef TARGET_OPTION_OVERRIDE
140 #define TARGET_OPTION_OVERRIDE arc_option_override
141
132 #undef TARGET_RTX_COSTS 142 #undef TARGET_RTX_COSTS
133 #define TARGET_RTX_COSTS arc_rtx_costs 143 #define TARGET_RTX_COSTS arc_rtx_costs
134 #undef TARGET_ADDRESS_COST 144 #undef TARGET_ADDRESS_COST
135 #define TARGET_ADDRESS_COST arc_address_cost 145 #define TARGET_ADDRESS_COST arc_address_cost
136 146
141 151
142 #undef TARGET_RETURN_IN_MEMORY 152 #undef TARGET_RETURN_IN_MEMORY
143 #define TARGET_RETURN_IN_MEMORY arc_return_in_memory 153 #define TARGET_RETURN_IN_MEMORY arc_return_in_memory
144 #undef TARGET_PASS_BY_REFERENCE 154 #undef TARGET_PASS_BY_REFERENCE
145 #define TARGET_PASS_BY_REFERENCE arc_pass_by_reference 155 #define TARGET_PASS_BY_REFERENCE arc_pass_by_reference
156 #undef TARGET_FUNCTION_ARG
157 #define TARGET_FUNCTION_ARG arc_function_arg
158 #undef TARGET_FUNCTION_ARG_ADVANCE
159 #define TARGET_FUNCTION_ARG_ADVANCE arc_function_arg_advance
160 #undef TARGET_FUNCTION_ARG_BOUNDARY
161 #define TARGET_FUNCTION_ARG_BOUNDARY arc_function_arg_boundary
146 #undef TARGET_CALLEE_COPIES 162 #undef TARGET_CALLEE_COPIES
147 #define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true 163 #define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true
148 164
149 #undef TARGET_SETUP_INCOMING_VARARGS 165 #undef TARGET_SETUP_INCOMING_VARARGS
150 #define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs 166 #define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs
152 #undef TARGET_EXPAND_BUILTIN_VA_START 168 #undef TARGET_EXPAND_BUILTIN_VA_START
153 #define TARGET_EXPAND_BUILTIN_VA_START arc_va_start 169 #define TARGET_EXPAND_BUILTIN_VA_START arc_va_start
154 170
155 #undef TARGET_TRAMPOLINE_INIT 171 #undef TARGET_TRAMPOLINE_INIT
156 #define TARGET_TRAMPOLINE_INIT arc_trampoline_init 172 #define TARGET_TRAMPOLINE_INIT arc_trampoline_init
173
174 #undef TARGET_CONDITIONAL_REGISTER_USAGE
175 #define TARGET_CONDITIONAL_REGISTER_USAGE arc_conditional_register_usage
157 176
158 struct gcc_target targetm = TARGET_INITIALIZER; 177 struct gcc_target targetm = TARGET_INITIALIZER;
159 178
160 /* Implement TARGET_HANDLE_OPTION. */ 179 /* Implement TARGET_HANDLE_OPTION. */
161 180
170 default: 189 default:
171 return true; 190 return true;
172 } 191 }
173 } 192 }
174 193
175 /* Called by OVERRIDE_OPTIONS to initialize various things. */ 194 /* Implement TARGET_OPTION_OVERRIDE.
176 195 These need to be done at start up. It's convenient to do them here. */
177 void 196
178 arc_init (void) 197 static void
198 arc_option_override (void)
179 { 199 {
180 char *tmp; 200 char *tmp;
181 201
182 /* Set the pseudo-ops for the various standard sections. */ 202 /* Set the pseudo-ops for the various standard sections. */
183 arc_text_section = tmp = XNEWVEC (char, strlen (arc_text_string) + sizeof (ARC_SECTION_FORMAT) + 1); 203 arc_text_section = tmp = XNEWVEC (char, strlen (arc_text_string) + sizeof (ARC_SECTION_FORMAT) + 1);
2346 size = GET_MODE_SIZE (mode); 2366 size = GET_MODE_SIZE (mode);
2347 2367
2348 return size > 8; 2368 return size > 8;
2349 } 2369 }
2350 2370
2371 /* Round SIZE up to a word boundary. */
2372 #define ROUND_ADVANCE(SIZE) \
2373 (((SIZE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
2374
2375 /* Round arg MODE/TYPE up to the next word boundary. */
2376 #define ROUND_ADVANCE_ARG(MODE, TYPE) \
2377 ((MODE) == BLKmode \
2378 ? ROUND_ADVANCE (int_size_in_bytes (TYPE)) \
2379 : ROUND_ADVANCE (GET_MODE_SIZE (MODE)))
2380
2381 /* Round CUM up to the necessary point for argument MODE/TYPE. */
2382 #define ROUND_ADVANCE_CUM(CUM, MODE, TYPE) \
2383 ((((MODE) == BLKmode ? TYPE_ALIGN (TYPE) : GET_MODE_BITSIZE (MODE)) \
2384 > BITS_PER_WORD) \
2385 ? (((CUM) + 1) & ~1) \
2386 : (CUM))
2387
2388 /* Return boolean indicating arg of type TYPE and mode MODE will be passed in
2389 a reg. This includes arguments that have to be passed by reference as the
2390 pointer to them is passed in a reg if one is available (and that is what
2391 we're given). */
2392 #define PASS_IN_REG_P(CUM, MODE, TYPE) \
2393 ((CUM) < MAX_ARC_PARM_REGS \
2394 && ((ROUND_ADVANCE_CUM ((CUM), (MODE), (TYPE)) \
2395 + ROUND_ADVANCE_ARG ((MODE), (TYPE)) \
2396 <= MAX_ARC_PARM_REGS)))
2397
2398 /* Determine where to put an argument to a function.
2399 Value is zero to push the argument on the stack,
2400 or a hard register in which to store the argument.
2401
2402 MODE is the argument's machine mode.
2403 TYPE is the data type of the argument (as a tree).
2404 This is null for libcalls where that information may
2405 not be available.
2406 CUM is a variable of type CUMULATIVE_ARGS which gives info about
2407 the preceding args and about the function being called.
2408 NAMED is nonzero if this argument is a named parameter
2409 (otherwise it is an extra parameter matching an ellipsis). */
2410 /* On the ARC the first MAX_ARC_PARM_REGS args are normally in registers
2411 and the rest are pushed. */
2412
2413 static rtx
2414 arc_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
2415 const_tree type, bool named ATTRIBUTE_UNUSED)
2416 {
2417 return (PASS_IN_REG_P (*cum, mode, type)
2418 ? gen_rtx_REG (mode, ROUND_ADVANCE_CUM (*cum, mode, type))
2419 : NULL_RTX);
2420 }
2421
2422 /* Worker function for TARGET_FUNCTION_ARG_ADVANCE. */
2423
2424 static void
2425 arc_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
2426 const_tree type, bool named ATTRIBUTE_UNUSED)
2427 {
2428 *cum = (ROUND_ADVANCE_CUM (*cum, mode, type)
2429 + ROUND_ADVANCE_ARG (mode, type));
2430 }
2431
2432 /* Worker function for TARGET_FUNCTION_ARG_BOUNDARY. */
2433
2434 static unsigned int
2435 arc_function_arg_boundary (enum machine_mode mode, const_tree type)
2436 {
2437 return (type != NULL_TREE
2438 ? TYPE_ALIGN (type)
2439 : (GET_MODE_BITSIZE (mode) <= PARM_BOUNDARY
2440 ? PARM_BOUNDARY
2441 : 2 * PARM_BOUNDARY));
2442 }
2443
2351 /* Trampolines. */ 2444 /* Trampolines. */
2352 /* ??? This doesn't work yet because GCC will use as the address of a nested 2445 /* ??? This doesn't work yet because GCC will use as the address of a nested
2353 function the address of the trampoline. We need to use that address 2446 function the address of the trampoline. We need to use that address
2354 right shifted by 2. It looks like we'll need PSImode after all. :-( 2447 right shifted by 2. It looks like we'll need PSImode after all. :-(
2355 2448
2381 mem = adjust_address (m_tramp, SImode, 12); 2474 mem = adjust_address (m_tramp, SImode, 12);
2382 emit_move_insn (mem, fnaddr); 2475 emit_move_insn (mem, fnaddr);
2383 2476
2384 emit_insn (gen_flush_icache (m_tramp)); 2477 emit_insn (gen_flush_icache (m_tramp));
2385 } 2478 }
2479
2480 /* Worker function for TARGET_CONDITIONAL_REGISTER_USAGE. */
2481
2482 static void
2483 arc_conditional_register_usage (void)
2484 {
2485 if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
2486 {
2487 fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
2488 call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
2489 }
2490 }
2491