Mercurial > hg > CbC > CbC_gcc
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 |