Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/mmix/mmix.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 |
---|---|
28 #include "regs.h" | 28 #include "regs.h" |
29 #include "hard-reg-set.h" | 29 #include "hard-reg-set.h" |
30 #include "hashtab.h" | 30 #include "hashtab.h" |
31 #include "insn-config.h" | 31 #include "insn-config.h" |
32 #include "output.h" | 32 #include "output.h" |
33 #include "basic-block.h" | |
33 #include "flags.h" | 34 #include "flags.h" |
34 #include "tree.h" | 35 #include "tree.h" |
35 #include "function.h" | 36 #include "function.h" |
36 #include "expr.h" | 37 #include "expr.h" |
37 #include "toplev.h" | 38 #include "diagnostic-core.h" |
38 #include "recog.h" | 39 #include "recog.h" |
39 #include "ggc.h" | 40 #include "ggc.h" |
40 #include "dwarf2.h" | 41 #include "dwarf2.h" |
41 #include "debug.h" | 42 #include "debug.h" |
42 #include "tm_p.h" | 43 #include "tm_p.h" |
43 #include "integrate.h" | 44 #include "integrate.h" |
44 #include "target.h" | 45 #include "target.h" |
45 #include "target-def.h" | 46 #include "target-def.h" |
47 #include "df.h" | |
46 | 48 |
47 /* First some local helper definitions. */ | 49 /* First some local helper definitions. */ |
48 #define MMIX_FIRST_GLOBAL_REGNUM 32 | 50 #define MMIX_FIRST_GLOBAL_REGNUM 32 |
49 | 51 |
50 /* We'd need a current_function_has_landing_pad. It's marked as such when | 52 /* We'd need a current_function_has_landing_pad. It's marked as such when |
109 /* Declarations of locals. */ | 111 /* Declarations of locals. */ |
110 | 112 |
111 /* Intermediate for insn output. */ | 113 /* Intermediate for insn output. */ |
112 static int mmix_output_destination_register; | 114 static int mmix_output_destination_register; |
113 | 115 |
116 static void mmix_option_override (void); | |
117 static void mmix_asm_output_source_filename (FILE *, const char *); | |
114 static void mmix_output_shiftvalue_op_from_str | 118 static void mmix_output_shiftvalue_op_from_str |
115 (FILE *, const char *, HOST_WIDEST_INT); | 119 (FILE *, const char *, HOST_WIDEST_INT); |
116 static void mmix_output_shifted_value (FILE *, HOST_WIDEST_INT); | 120 static void mmix_output_shifted_value (FILE *, HOST_WIDEST_INT); |
117 static void mmix_output_condition (FILE *, rtx, int); | 121 static void mmix_output_condition (FILE *, rtx, int); |
118 static HOST_WIDEST_INT mmix_intval (rtx); | 122 static HOST_WIDEST_INT mmix_intval (rtx); |
136 static bool mmix_rtx_costs (rtx, int, int, int *, bool); | 140 static bool mmix_rtx_costs (rtx, int, int, int *, bool); |
137 static rtx mmix_struct_value_rtx (tree, int); | 141 static rtx mmix_struct_value_rtx (tree, int); |
138 static enum machine_mode mmix_promote_function_mode (const_tree, | 142 static enum machine_mode mmix_promote_function_mode (const_tree, |
139 enum machine_mode, | 143 enum machine_mode, |
140 int *, const_tree, int); | 144 int *, const_tree, int); |
145 static void mmix_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, | |
146 const_tree, bool); | |
147 static rtx mmix_function_arg_1 (const CUMULATIVE_ARGS *, enum machine_mode, | |
148 const_tree, bool, bool); | |
149 static rtx mmix_function_incoming_arg (CUMULATIVE_ARGS *, enum machine_mode, | |
150 const_tree, bool); | |
151 static rtx mmix_function_arg (CUMULATIVE_ARGS *, enum machine_mode, | |
152 const_tree, bool); | |
141 static rtx mmix_function_value (const_tree, const_tree, bool); | 153 static rtx mmix_function_value (const_tree, const_tree, bool); |
142 static rtx mmix_libcall_value (enum machine_mode, const_rtx); | 154 static rtx mmix_libcall_value (enum machine_mode, const_rtx); |
143 static bool mmix_function_value_regno_p (const unsigned int); | 155 static bool mmix_function_value_regno_p (const unsigned int); |
144 static bool mmix_pass_by_reference (CUMULATIVE_ARGS *, | 156 static bool mmix_pass_by_reference (CUMULATIVE_ARGS *, |
145 enum machine_mode, const_tree, bool); | 157 enum machine_mode, const_tree, bool); |
146 static bool mmix_frame_pointer_required (void); | 158 static bool mmix_frame_pointer_required (void); |
147 static void mmix_asm_trampoline_template (FILE *); | 159 static void mmix_asm_trampoline_template (FILE *); |
148 static void mmix_trampoline_init (rtx, tree, rtx); | 160 static void mmix_trampoline_init (rtx, tree, rtx); |
161 static void mmix_conditional_register_usage (void); | |
162 | |
163 /* TARGET_OPTION_OPTIMIZATION_TABLE. */ | |
164 | |
165 static const struct default_options mmix_option_optimization_table[] = | |
166 { | |
167 { OPT_LEVELS_1_PLUS, OPT_fregmove, NULL, 1 }, | |
168 { OPT_LEVELS_2_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, | |
169 { OPT_LEVELS_NONE, 0, NULL, 0 } | |
170 }; | |
149 | 171 |
150 /* Target structure macros. Listed by node. See `Using and Porting GCC' | 172 /* Target structure macros. Listed by node. See `Using and Porting GCC' |
151 for a general description. */ | 173 for a general description. */ |
152 | 174 |
153 /* Node: Function Entry */ | 175 /* Node: Function Entry */ |
185 #define TARGET_ASM_FILE_START mmix_file_start | 207 #define TARGET_ASM_FILE_START mmix_file_start |
186 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE | 208 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE |
187 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true | 209 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true |
188 #undef TARGET_ASM_FILE_END | 210 #undef TARGET_ASM_FILE_END |
189 #define TARGET_ASM_FILE_END mmix_file_end | 211 #define TARGET_ASM_FILE_END mmix_file_end |
212 #undef TARGET_ASM_OUTPUT_SOURCE_FILENAME | |
213 #define TARGET_ASM_OUTPUT_SOURCE_FILENAME mmix_asm_output_source_filename | |
214 | |
215 #undef TARGET_CONDITIONAL_REGISTER_USAGE | |
216 #define TARGET_CONDITIONAL_REGISTER_USAGE mmix_conditional_register_usage | |
190 | 217 |
191 #undef TARGET_RTX_COSTS | 218 #undef TARGET_RTX_COSTS |
192 #define TARGET_RTX_COSTS mmix_rtx_costs | 219 #define TARGET_RTX_COSTS mmix_rtx_costs |
193 #undef TARGET_ADDRESS_COST | 220 #undef TARGET_ADDRESS_COST |
194 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0 | 221 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0 |
204 #undef TARGET_LIBCALL_VALUE | 231 #undef TARGET_LIBCALL_VALUE |
205 #define TARGET_LIBCALL_VALUE mmix_libcall_value | 232 #define TARGET_LIBCALL_VALUE mmix_libcall_value |
206 #undef TARGET_FUNCTION_VALUE_REGNO_P | 233 #undef TARGET_FUNCTION_VALUE_REGNO_P |
207 #define TARGET_FUNCTION_VALUE_REGNO_P mmix_function_value_regno_p | 234 #define TARGET_FUNCTION_VALUE_REGNO_P mmix_function_value_regno_p |
208 | 235 |
236 #undef TARGET_FUNCTION_ARG | |
237 #define TARGET_FUNCTION_ARG mmix_function_arg | |
238 #undef TARGET_FUNCTION_INCOMING_ARG | |
239 #define TARGET_FUNCTION_INCOMING_ARG mmix_function_incoming_arg | |
240 #undef TARGET_FUNCTION_ARG_ADVANCE | |
241 #define TARGET_FUNCTION_ARG_ADVANCE mmix_function_arg_advance | |
209 #undef TARGET_STRUCT_VALUE_RTX | 242 #undef TARGET_STRUCT_VALUE_RTX |
210 #define TARGET_STRUCT_VALUE_RTX mmix_struct_value_rtx | 243 #define TARGET_STRUCT_VALUE_RTX mmix_struct_value_rtx |
211 #undef TARGET_SETUP_INCOMING_VARARGS | 244 #undef TARGET_SETUP_INCOMING_VARARGS |
212 #define TARGET_SETUP_INCOMING_VARARGS mmix_setup_incoming_varargs | 245 #define TARGET_SETUP_INCOMING_VARARGS mmix_setup_incoming_varargs |
213 #undef TARGET_PASS_BY_REFERENCE | 246 #undef TARGET_PASS_BY_REFERENCE |
226 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE | 259 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE |
227 #define TARGET_ASM_TRAMPOLINE_TEMPLATE mmix_asm_trampoline_template | 260 #define TARGET_ASM_TRAMPOLINE_TEMPLATE mmix_asm_trampoline_template |
228 #undef TARGET_TRAMPOLINE_INIT | 261 #undef TARGET_TRAMPOLINE_INIT |
229 #define TARGET_TRAMPOLINE_INIT mmix_trampoline_init | 262 #define TARGET_TRAMPOLINE_INIT mmix_trampoline_init |
230 | 263 |
264 #undef TARGET_OPTION_OVERRIDE | |
265 #define TARGET_OPTION_OVERRIDE mmix_option_override | |
266 #undef TARGET_OPTION_OPTIMIZATION_TABLE | |
267 #define TARGET_OPTION_OPTIMIZATION_TABLE mmix_option_optimization_table | |
268 | |
231 struct gcc_target targetm = TARGET_INITIALIZER; | 269 struct gcc_target targetm = TARGET_INITIALIZER; |
232 | 270 |
233 /* Functions that are expansions for target macros. | 271 /* Functions that are expansions for target macros. |
234 See Target Macros in `Using and Porting GCC'. */ | 272 See Target Macros in `Using and Porting GCC'. */ |
235 | 273 |
236 /* OVERRIDE_OPTIONS. */ | 274 /* TARGET_OPTION_OVERRIDE. */ |
237 | 275 |
238 void | 276 static void |
239 mmix_override_options (void) | 277 mmix_option_override (void) |
240 { | 278 { |
241 /* Should we err or should we warn? Hmm. At least we must neutralize | 279 /* Should we err or should we warn? Hmm. At least we must neutralize |
242 it. For example the wrong kind of case-tables will be generated with | 280 it. For example the wrong kind of case-tables will be generated with |
243 PIC; we use absolute address items for mmixal compatibility. FIXME: | 281 PIC; we use absolute address items for mmixal compatibility. FIXME: |
244 They could be relative if we just elide them to after all pertinent | 282 They could be relative if we just elide them to after all pertinent |
261 /* Set the per-function data. */ | 299 /* Set the per-function data. */ |
262 | 300 |
263 static struct machine_function * | 301 static struct machine_function * |
264 mmix_init_machine_status (void) | 302 mmix_init_machine_status (void) |
265 { | 303 { |
266 return GGC_CNEW (struct machine_function); | 304 return ggc_alloc_cleared_machine_function (); |
267 } | 305 } |
268 | 306 |
269 /* DATA_ALIGNMENT. | 307 /* DATA_ALIGNMENT. |
270 We have trouble getting the address of stuff that is located at other | 308 We have trouble getting the address of stuff that is located at other |
271 than 32-bit alignments (GETA requirements), so try to give everything | 309 than 32-bit alignments (GETA requirements), so try to give everything |
291 return basic_align; | 329 return basic_align; |
292 } | 330 } |
293 | 331 |
294 /* LOCAL_ALIGNMENT. */ | 332 /* LOCAL_ALIGNMENT. */ |
295 | 333 |
296 int | 334 unsigned |
297 mmix_local_alignment (tree type ATTRIBUTE_UNUSED, int basic_align) | 335 mmix_local_alignment (tree type ATTRIBUTE_UNUSED, unsigned basic_align) |
298 { | 336 { |
299 if (basic_align < 32) | 337 if (basic_align < 32) |
300 return 32; | 338 return 32; |
301 | 339 |
302 return basic_align; | 340 return basic_align; |
303 } | 341 } |
304 | 342 |
305 /* CONDITIONAL_REGISTER_USAGE. */ | 343 /* TARGET_CONDITIONAL_REGISTER_USAGE. */ |
306 | 344 |
307 void | 345 static void |
308 mmix_conditional_register_usage (void) | 346 mmix_conditional_register_usage (void) |
309 { | 347 { |
310 int i; | 348 int i; |
311 | 349 |
312 if (TARGET_ABI_GNU) | 350 if (TARGET_ABI_GNU) |
343 | 381 |
344 /* INCOMING_REGNO and OUTGOING_REGNO worker function. | 382 /* INCOMING_REGNO and OUTGOING_REGNO worker function. |
345 Those two macros must only be applied to function argument | 383 Those two macros must only be applied to function argument |
346 registers. FIXME: for their current use in gcc, it'd be better | 384 registers. FIXME: for their current use in gcc, it'd be better |
347 with an explicit specific additional FUNCTION_INCOMING_ARG_REGNO_P | 385 with an explicit specific additional FUNCTION_INCOMING_ARG_REGNO_P |
348 a'la FUNCTION_ARG / FUNCTION_INCOMING_ARG instead of forcing the | 386 a'la TARGET_FUNCTION_ARG / TARGET_FUNCTION_INCOMING_ARG instead of |
349 target to commit to a fixed mapping and for any unspecified | 387 forcing the target to commit to a fixed mapping and for any |
350 register use. */ | 388 unspecified register use. */ |
351 | 389 |
352 int | 390 int |
353 mmix_opposite_regno (int regno, int incoming) | 391 mmix_opposite_regno (int regno, int incoming) |
354 { | 392 { |
355 if (!mmix_function_arg_regno_p (regno, incoming)) | 393 if (!mmix_function_arg_regno_p (regno, incoming)) |
596 + (MMIX_CFUN_HAS_LANDING_PAD | 634 + (MMIX_CFUN_HAS_LANDING_PAD |
597 ? 16 : (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS ? 8 : 0)) | 635 ? 16 : (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS ? 8 : 0)) |
598 + (fromreg == MMIX_ARG_POINTER_REGNUM ? 0 : 8); | 636 + (fromreg == MMIX_ARG_POINTER_REGNUM ? 0 : 8); |
599 } | 637 } |
600 | 638 |
601 /* Return an rtx for a function argument to go in a register, and 0 for | 639 static void |
602 one that must go on stack. */ | 640 mmix_function_arg_advance (CUMULATIVE_ARGS *argsp, enum machine_mode mode, |
603 | 641 const_tree type, bool named ATTRIBUTE_UNUSED) |
604 rtx | 642 { |
605 mmix_function_arg (const CUMULATIVE_ARGS *argsp, | 643 int arg_size = MMIX_FUNCTION_ARG_SIZE (mode, type); |
606 enum machine_mode mode, | 644 |
607 tree type, | 645 argsp->regs = ((targetm.calls.must_pass_in_stack (mode, type) |
608 int named ATTRIBUTE_UNUSED, | 646 || (arg_size > 8 |
609 int incoming) | 647 && !TARGET_LIBFUNC |
648 && !argsp->lib)) | |
649 ? (MMIX_MAX_ARGS_IN_REGS) + 1 | |
650 : argsp->regs + (7 + arg_size) / 8); | |
651 } | |
652 | |
653 /* Helper function for mmix_function_arg and mmix_function_incoming_arg. */ | |
654 | |
655 static rtx | |
656 mmix_function_arg_1 (const CUMULATIVE_ARGS *argsp, | |
657 enum machine_mode mode, | |
658 const_tree type, | |
659 bool named ATTRIBUTE_UNUSED, | |
660 bool incoming) | |
610 { | 661 { |
611 /* Last-argument marker. */ | 662 /* Last-argument marker. */ |
612 if (type == void_type_node) | 663 if (type == void_type_node) |
613 return (argsp->regs < MMIX_MAX_ARGS_IN_REGS) | 664 return (argsp->regs < MMIX_MAX_ARGS_IN_REGS) |
614 ? gen_rtx_REG (mode, | 665 ? gen_rtx_REG (mode, |
626 (incoming | 677 (incoming |
627 ? MMIX_FIRST_INCOMING_ARG_REGNUM | 678 ? MMIX_FIRST_INCOMING_ARG_REGNUM |
628 : MMIX_FIRST_ARG_REGNUM) | 679 : MMIX_FIRST_ARG_REGNUM) |
629 + argsp->regs) | 680 + argsp->regs) |
630 : NULL_RTX; | 681 : NULL_RTX; |
682 } | |
683 | |
684 /* Return an rtx for a function argument to go in a register, and 0 for | |
685 one that must go on stack. */ | |
686 | |
687 static rtx | |
688 mmix_function_arg (CUMULATIVE_ARGS *argsp, | |
689 enum machine_mode mode, | |
690 const_tree type, | |
691 bool named) | |
692 { | |
693 return mmix_function_arg_1 (argsp, mode, type, named, false); | |
694 } | |
695 | |
696 static rtx | |
697 mmix_function_incoming_arg (CUMULATIVE_ARGS *argsp, | |
698 enum machine_mode mode, | |
699 const_tree type, | |
700 bool named) | |
701 { | |
702 return mmix_function_arg_1 (argsp, mode, type, named, true); | |
631 } | 703 } |
632 | 704 |
633 /* Returns nonzero for everything that goes by reference, 0 for | 705 /* Returns nonzero for everything that goes by reference, 0 for |
634 everything that goes by value. */ | 706 everything that goes by value. */ |
635 | 707 |
1241 { | 1313 { |
1242 /* Make sure each file ends with the data section. */ | 1314 /* Make sure each file ends with the data section. */ |
1243 switch_to_section (data_section); | 1315 switch_to_section (data_section); |
1244 } | 1316 } |
1245 | 1317 |
1246 /* ASM_OUTPUT_SOURCE_FILENAME. */ | 1318 /* TARGET_ASM_OUTPUT_SOURCE_FILENAME. */ |
1247 | 1319 |
1248 void | 1320 static void |
1249 mmix_asm_output_source_filename (FILE *stream, const char *name) | 1321 mmix_asm_output_source_filename (FILE *stream, const char *name) |
1250 { | 1322 { |
1251 fprintf (stream, "# 1 "); | 1323 fprintf (stream, "# 1 "); |
1252 OUTPUT_QUOTED_STRING (stream, name); | 1324 OUTPUT_QUOTED_STRING (stream, name); |
1253 fprintf (stream, "\n"); | 1325 fprintf (stream, "\n"); |
1831 fprintf (stream, "\tLOC @+(%d-@)&%d\n", 1 << power, (1 << power) - 1); | 1903 fprintf (stream, "\tLOC @+(%d-@)&%d\n", 1 << power, (1 << power) - 1); |
1832 } | 1904 } |
1833 | 1905 |
1834 /* DBX_REGISTER_NUMBER. */ | 1906 /* DBX_REGISTER_NUMBER. */ |
1835 | 1907 |
1836 int | 1908 unsigned |
1837 mmix_dbx_register_number (int regno) | 1909 mmix_dbx_register_number (unsigned regno) |
1838 { | 1910 { |
1839 /* Adjust the register number to the one it will be output as, dammit. | 1911 /* Adjust the register number to the one it will be output as, dammit. |
1840 It'd be nice if we could check the assumption that we're filling a | 1912 It'd be nice if we could check the assumption that we're filling a |
1841 gap, but every register between the last saved register and parameter | 1913 gap, but every register between the last saved register and parameter |
1842 registers might be a valid parameter register. */ | 1914 registers might be a valid parameter register. */ |
2040 insn = emit_move_insn (gen_rtx_MEM (DImode, | 2112 insn = emit_move_insn (gen_rtx_MEM (DImode, |
2041 plus_constant (stack_pointer_rtx, | 2113 plus_constant (stack_pointer_rtx, |
2042 offset)), | 2114 offset)), |
2043 tmpreg); | 2115 tmpreg); |
2044 RTX_FRAME_RELATED_P (insn) = 1; | 2116 RTX_FRAME_RELATED_P (insn) = 1; |
2045 REG_NOTES (insn) | 2117 add_reg_note (insn, REG_FRAME_RELATED_EXPR, |
2046 = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, | 2118 gen_rtx_SET (VOIDmode, |
2047 gen_rtx_SET (VOIDmode, | 2119 gen_rtx_MEM (DImode, |
2048 gen_rtx_MEM (DImode, | 2120 plus_constant (stack_pointer_rtx, |
2049 plus_constant (stack_pointer_rtx, | 2121 offset)), |
2050 offset)), | 2122 retreg)); |
2051 retreg), | |
2052 REG_NOTES (insn)); | |
2053 | 2123 |
2054 offset -= 8; | 2124 offset -= 8; |
2055 } | 2125 } |
2056 else if (MMIX_CFUN_HAS_LANDING_PAD) | 2126 else if (MMIX_CFUN_HAS_LANDING_PAD) |
2057 offset -= 8; | 2127 offset -= 8; |
2675 retval *= 2; | 2745 retval *= 2; |
2676 retval |= CONST_DOUBLE_LOW (x) & 1; | 2746 retval |= CONST_DOUBLE_LOW (x) & 1; |
2677 | 2747 |
2678 retval |= | 2748 retval |= |
2679 (unsigned HOST_WIDEST_INT) CONST_DOUBLE_HIGH (x) | 2749 (unsigned HOST_WIDEST_INT) CONST_DOUBLE_HIGH (x) |
2680 << (HOST_BITS_PER_LONG); | 2750 << (HOST_BITS_PER_LONG)/2 << (HOST_BITS_PER_LONG)/2; |
2681 } | 2751 } |
2682 else | 2752 else |
2683 retval = CONST_DOUBLE_HIGH (x); | 2753 retval = CONST_DOUBLE_HIGH (x); |
2684 | 2754 |
2685 return retval; | 2755 return retval; |