Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/mips/mips.c @ 63:b7f97abdc517 gcc-4.6-20100522
update gcc from gcc-4.5.0 to gcc-4.6
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 24 May 2010 12:47:05 +0900 |
parents | 77e2b8dfacca |
children | f6334be47118 |
comparison
equal
deleted
inserted
replaced
56:3c8a44c06a95 | 63:b7f97abdc517 |
---|---|
1 /* Subroutines used for MIPS code generation. | 1 /* Subroutines used for MIPS code generation. |
2 Copyright (C) 1989, 1990, 1991, 1993, 1994, 1995, 1996, 1997, 1998, | 2 Copyright (C) 1989, 1990, 1991, 1993, 1994, 1995, 1996, 1997, 1998, |
3 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 | 3 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 |
4 Free Software Foundation, Inc. | 4 Free Software Foundation, Inc. |
5 Contributed by A. Lichnewsky, lich@inria.inria.fr. | 5 Contributed by A. Lichnewsky, lich@inria.inria.fr. |
6 Changes by Michael Meissner, meissner@osf.org. | 6 Changes by Michael Meissner, meissner@osf.org. |
7 64-bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and | 7 64-bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and |
8 Brendan Eich, brendan@microunity.com. | 8 Brendan Eich, brendan@microunity.com. |
29 #include "tm.h" | 29 #include "tm.h" |
30 #include <signal.h> | 30 #include <signal.h> |
31 #include "rtl.h" | 31 #include "rtl.h" |
32 #include "regs.h" | 32 #include "regs.h" |
33 #include "hard-reg-set.h" | 33 #include "hard-reg-set.h" |
34 #include "real.h" | |
35 #include "insn-config.h" | 34 #include "insn-config.h" |
36 #include "conditions.h" | 35 #include "conditions.h" |
37 #include "insn-attr.h" | 36 #include "insn-attr.h" |
38 #include "recog.h" | 37 #include "recog.h" |
39 #include "toplev.h" | 38 #include "toplev.h" |
5447 TREE_CHAIN (f_foff) = f_res; | 5446 TREE_CHAIN (f_foff) = f_res; |
5448 | 5447 |
5449 layout_type (record); | 5448 layout_type (record); |
5450 return record; | 5449 return record; |
5451 } | 5450 } |
5452 else if (TARGET_IRIX && TARGET_IRIX6) | 5451 else if (TARGET_IRIX6) |
5453 /* On IRIX 6, this type is 'char *'. */ | 5452 /* On IRIX 6, this type is 'char *'. */ |
5454 return build_pointer_type (char_type_node); | 5453 return build_pointer_type (char_type_node); |
5455 else | 5454 else |
5456 /* Otherwise, we use 'void *'. */ | 5455 /* Otherwise, we use 'void *'. */ |
5457 return ptr_type_node; | 5456 return ptr_type_node; |
7862 fputs ("\t.extern\t", file); | 7861 fputs ("\t.extern\t", file); |
7863 assemble_name (file, name); | 7862 assemble_name (file, name); |
7864 fprintf (file, ", " HOST_WIDE_INT_PRINT_DEC "\n", | 7863 fprintf (file, ", " HOST_WIDE_INT_PRINT_DEC "\n", |
7865 int_size_in_bytes (TREE_TYPE (decl))); | 7864 int_size_in_bytes (TREE_TYPE (decl))); |
7866 } | 7865 } |
7867 else if (TARGET_IRIX | |
7868 && mips_abi == ABI_32 | |
7869 && TREE_CODE (decl) == FUNCTION_DECL) | |
7870 { | |
7871 /* In IRIX 5 or IRIX 6 for the O32 ABI, we must output a | |
7872 `.global name .text' directive for every used but | |
7873 undefined function. If we don't, the linker may perform | |
7874 an optimization (skipping over the insns that set $gp) | |
7875 when it is unsafe. */ | |
7876 fputs ("\t.globl ", file); | |
7877 assemble_name (file, name); | |
7878 fputs (" .text\n", file); | |
7879 } | |
7880 } | 7866 } |
7881 } | 7867 } |
7882 | 7868 |
7883 /* Implement ASM_OUTPUT_SOURCE_FILENAME. */ | 7869 /* Implement ASM_OUTPUT_SOURCE_FILENAME. */ |
7884 | 7870 |
8164 default_file_start (); | 8150 default_file_start (); |
8165 | 8151 |
8166 /* Generate a special section to describe the ABI switches used to | 8152 /* Generate a special section to describe the ABI switches used to |
8167 produce the resultant binary. This is unnecessary on IRIX and | 8153 produce the resultant binary. This is unnecessary on IRIX and |
8168 causes unwanted warnings from the native linker. */ | 8154 causes unwanted warnings from the native linker. */ |
8169 if (!TARGET_IRIX) | 8155 if (!TARGET_IRIX6) |
8170 { | 8156 { |
8171 /* Record the ABI itself. Modern versions of binutils encode | 8157 /* Record the ABI itself. Modern versions of binutils encode |
8172 this information in the ELF header flags, but GDB needs the | 8158 this information in the ELF header flags, but GDB needs the |
8173 information in order to correctly debug binaries produced by | 8159 information in order to correctly debug binaries produced by |
8174 older binutils. See the function mips_gdbarch_init in | 8160 older binutils. See the function mips_gdbarch_init in |
8183 if (mips_abi == ABI_EABI || mips_abi == ABI_O64) | 8169 if (mips_abi == ABI_EABI || mips_abi == ABI_O64) |
8184 fprintf (asm_out_file, "\t.section .gcc_compiled_long%d\n" | 8170 fprintf (asm_out_file, "\t.section .gcc_compiled_long%d\n" |
8185 "\t.previous\n", TARGET_LONG64 ? 64 : 32); | 8171 "\t.previous\n", TARGET_LONG64 ? 64 : 32); |
8186 | 8172 |
8187 #ifdef HAVE_AS_GNU_ATTRIBUTE | 8173 #ifdef HAVE_AS_GNU_ATTRIBUTE |
8188 fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n", | 8174 { |
8189 (TARGET_HARD_FLOAT_ABI | 8175 int attr; |
8190 ? (TARGET_DOUBLE_FLOAT | 8176 |
8191 ? ((!TARGET_64BIT && TARGET_FLOAT64) ? 4 : 1) : 2) : 3)); | 8177 /* No floating-point operations, -mno-float. */ |
8178 if (TARGET_NO_FLOAT) | |
8179 attr = 0; | |
8180 /* Soft-float code, -msoft-float. */ | |
8181 else if (!TARGET_HARD_FLOAT_ABI) | |
8182 attr = 3; | |
8183 /* Single-float code, -msingle-float. */ | |
8184 else if (!TARGET_DOUBLE_FLOAT) | |
8185 attr = 2; | |
8186 /* 64-bit FP registers on a 32-bit target, -mips32r2 -mfp64. */ | |
8187 else if (!TARGET_64BIT && TARGET_FLOAT64) | |
8188 attr = 4; | |
8189 /* Regular FP code, FP regs same size as GP regs, -mdouble-float. */ | |
8190 else | |
8191 attr = 1; | |
8192 | |
8193 fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n", attr); | |
8194 } | |
8192 #endif | 8195 #endif |
8193 } | 8196 } |
8194 | 8197 |
8195 /* If TARGET_ABICALLS, tell GAS to generate -KPIC code. */ | 8198 /* If TARGET_ABICALLS, tell GAS to generate -KPIC code. */ |
8196 if (TARGET_ABICALLS) | 8199 if (TARGET_ABICALLS) |
9809 assemble_start_function. This is needed so that the name used here | 9812 assemble_start_function. This is needed so that the name used here |
9810 exactly matches the name used in ASM_DECLARE_FUNCTION_NAME. */ | 9813 exactly matches the name used in ASM_DECLARE_FUNCTION_NAME. */ |
9811 fnname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); | 9814 fnname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); |
9812 mips_start_function_definition (fnname, TARGET_MIPS16); | 9815 mips_start_function_definition (fnname, TARGET_MIPS16); |
9813 | 9816 |
9814 /* Stop mips_file_end from treating this function as external. */ | |
9815 if (TARGET_IRIX && mips_abi == ABI_32) | |
9816 TREE_ASM_WRITTEN (DECL_NAME (cfun->decl)) = 1; | |
9817 | |
9818 /* Output MIPS-specific frame information. */ | 9817 /* Output MIPS-specific frame information. */ |
9819 if (!flag_inhibit_size_directive) | 9818 if (!flag_inhibit_size_directive) |
9820 { | 9819 { |
9821 const struct mips_frame_info *frame; | 9820 const struct mips_frame_info *frame; |
9822 | 9821 |
10716 | 10715 |
10717 We therefore disallow all mode changes involving FPRs. */ | 10716 We therefore disallow all mode changes involving FPRs. */ |
10718 return reg_classes_intersect_p (FP_REGS, rclass); | 10717 return reg_classes_intersect_p (FP_REGS, rclass); |
10719 } | 10718 } |
10720 | 10719 |
10720 /* Implement target hook small_register_classes_for_mode_p. */ | |
10721 | |
10722 static bool | |
10723 mips_small_register_classes_for_mode_p (enum machine_mode mode | |
10724 ATTRIBUTE_UNUSED) | |
10725 { | |
10726 return TARGET_MIPS16; | |
10727 } | |
10728 | |
10721 /* Return true if moves in mode MODE can use the FPU's mov.fmt instruction. */ | 10729 /* Return true if moves in mode MODE can use the FPU's mov.fmt instruction. */ |
10722 | 10730 |
10723 static bool | 10731 static bool |
10724 mips_mode_ok_for_mov_fmt_p (enum machine_mode mode) | 10732 mips_mode_ok_for_mov_fmt_p (enum machine_mode mode) |
10725 { | 10733 { |
11806 { | 11814 { |
11807 output_asm_insn (s, operands); | 11815 output_asm_insn (s, operands); |
11808 s = "bnez\t%2,1f\n\tbreak\t7\n1:"; | 11816 s = "bnez\t%2,1f\n\tbreak\t7\n1:"; |
11809 } | 11817 } |
11810 else if (GENERATE_DIVIDE_TRAPS) | 11818 else if (GENERATE_DIVIDE_TRAPS) |
11811 { | 11819 { |
11812 output_asm_insn (s, operands); | 11820 /* Avoid long replay penalty on load miss by putting the trap before |
11813 s = "teq\t%2,%.,7"; | 11821 the divide. */ |
11814 } | 11822 if (TUNE_74K) |
11823 output_asm_insn ("teq\t%2,%.,7", operands); | |
11824 else | |
11825 { | |
11826 output_asm_insn (s, operands); | |
11827 s = "teq\t%2,%.,7"; | |
11828 } | |
11829 } | |
11815 else | 11830 else |
11816 { | 11831 { |
11817 output_asm_insn ("%(bne\t%2,%.,1f", operands); | 11832 output_asm_insn ("%(bne\t%2,%.,1f", operands); |
11818 output_asm_insn (s, operands); | 11833 output_asm_insn (s, operands); |
11819 s = "break\t7%)\n1:"; | 11834 s = "break\t7%)\n1:"; |
14005 | 14020 |
14006 free_dominance_info (CDI_DOMINATORS); | 14021 free_dominance_info (CDI_DOMINATORS); |
14007 } | 14022 } |
14008 | 14023 |
14009 /* If INSN is a call, return the underlying CALL expr. Return NULL_RTX | 14024 /* If INSN is a call, return the underlying CALL expr. Return NULL_RTX |
14010 otherwise. */ | 14025 otherwise. If INSN has two call rtx, then store the second one in |
14026 SECOND_CALL. */ | |
14011 | 14027 |
14012 static rtx | 14028 static rtx |
14013 mips_call_expr_from_insn (rtx insn) | 14029 mips_call_expr_from_insn (rtx insn, rtx *second_call) |
14014 { | 14030 { |
14015 rtx x; | 14031 rtx x; |
14032 rtx x2; | |
14016 | 14033 |
14017 if (!CALL_P (insn)) | 14034 if (!CALL_P (insn)) |
14018 return NULL_RTX; | 14035 return NULL_RTX; |
14019 | 14036 |
14020 x = PATTERN (insn); | 14037 x = PATTERN (insn); |
14021 if (GET_CODE (x) == PARALLEL) | 14038 if (GET_CODE (x) == PARALLEL) |
14022 x = XVECEXP (x, 0, 0); | 14039 { |
14040 /* Calls returning complex values have two CALL rtx. Look for the second | |
14041 one here, and return it via the SECOND_CALL arg. */ | |
14042 x2 = XVECEXP (x, 0, 1); | |
14043 if (GET_CODE (x2) == SET) | |
14044 x2 = XEXP (x2, 1); | |
14045 if (GET_CODE (x2) == CALL) | |
14046 *second_call = x2; | |
14047 | |
14048 x = XVECEXP (x, 0, 0); | |
14049 } | |
14023 if (GET_CODE (x) == SET) | 14050 if (GET_CODE (x) == SET) |
14024 x = XEXP (x, 1); | 14051 x = XEXP (x, 1); |
14025 | |
14026 gcc_assert (GET_CODE (x) == CALL); | 14052 gcc_assert (GET_CODE (x) == CALL); |
14053 | |
14027 return x; | 14054 return x; |
14028 } | 14055 } |
14029 | 14056 |
14030 /* REG is set in DEF. See if the definition is one of the ways we load a | 14057 /* REG is set in DEF. See if the definition is one of the ways we load a |
14031 register with a symbol address for a mips_use_pic_fn_addr_reg_p call. If | 14058 register with a symbol address for a mips_use_pic_fn_addr_reg_p call. If |
14153 rtx insn; | 14180 rtx insn; |
14154 | 14181 |
14155 FOR_EACH_BB (bb) | 14182 FOR_EACH_BB (bb) |
14156 FOR_BB_INSNS (bb, insn) | 14183 FOR_BB_INSNS (bb, insn) |
14157 { | 14184 { |
14158 rtx call, reg, symbol; | 14185 rtx call, reg, symbol, second_call; |
14159 | 14186 |
14160 call = mips_call_expr_from_insn (insn); | 14187 second_call = 0; |
14188 call = mips_call_expr_from_insn (insn, &second_call); | |
14161 if (!call) | 14189 if (!call) |
14162 continue; | 14190 continue; |
14163 gcc_assert (MEM_P (XEXP (call, 0))); | 14191 gcc_assert (MEM_P (XEXP (call, 0))); |
14164 reg = XEXP (XEXP (call, 0), 0); | 14192 reg = XEXP (XEXP (call, 0), 0); |
14165 if (!REG_P (reg)) | 14193 if (!REG_P (reg)) |
14166 continue; | 14194 continue; |
14167 | 14195 |
14168 symbol = mips_find_pic_call_symbol (insn, reg); | 14196 symbol = mips_find_pic_call_symbol (insn, reg); |
14169 if (symbol) | 14197 if (symbol) |
14170 mips_annotate_pic_call_expr (call, symbol); | 14198 { |
14199 mips_annotate_pic_call_expr (call, symbol); | |
14200 if (second_call) | |
14201 mips_annotate_pic_call_expr (second_call, symbol); | |
14202 } | |
14171 } | 14203 } |
14172 } | 14204 } |
14173 | 14205 |
14174 /* A temporary variable used by for_each_rtx callbacks, etc. */ | 14206 /* A temporary variable used by for_each_rtx callbacks, etc. */ |
14175 static rtx mips_sim_insn; | 14207 static rtx mips_sim_insn; |
15387 | 15419 |
15388 #ifdef SUBTARGET_OVERRIDE_OPTIONS | 15420 #ifdef SUBTARGET_OVERRIDE_OPTIONS |
15389 SUBTARGET_OVERRIDE_OPTIONS; | 15421 SUBTARGET_OVERRIDE_OPTIONS; |
15390 #endif | 15422 #endif |
15391 | 15423 |
15424 /* -mno-float overrides -mhard-float and -msoft-float. */ | |
15425 if (TARGET_NO_FLOAT) | |
15426 { | |
15427 target_flags |= MASK_SOFT_FLOAT_ABI; | |
15428 target_flags_explicit |= MASK_SOFT_FLOAT_ABI; | |
15429 } | |
15430 | |
15392 /* Set the small data limit. */ | 15431 /* Set the small data limit. */ |
15393 mips_small_data_threshold = (g_switch_set | 15432 mips_small_data_threshold = (g_switch_set |
15394 ? g_switch_value | 15433 ? g_switch_value |
15395 : MIPS_DEFAULT_GVALUE); | 15434 : MIPS_DEFAULT_GVALUE); |
15396 | 15435 |
16268 #undef TARGET_SCHED_DFA_POST_ADVANCE_CYCLE | 16307 #undef TARGET_SCHED_DFA_POST_ADVANCE_CYCLE |
16269 #define TARGET_SCHED_DFA_POST_ADVANCE_CYCLE mips_dfa_post_advance_cycle | 16308 #define TARGET_SCHED_DFA_POST_ADVANCE_CYCLE mips_dfa_post_advance_cycle |
16270 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD | 16309 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD |
16271 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \ | 16310 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \ |
16272 mips_multipass_dfa_lookahead | 16311 mips_multipass_dfa_lookahead |
16312 #undef TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P | |
16313 #define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P \ | |
16314 mips_small_register_classes_for_mode_p | |
16273 | 16315 |
16274 #undef TARGET_DEFAULT_TARGET_FLAGS | 16316 #undef TARGET_DEFAULT_TARGET_FLAGS |
16275 #define TARGET_DEFAULT_TARGET_FLAGS \ | 16317 #define TARGET_DEFAULT_TARGET_FLAGS \ |
16276 (TARGET_DEFAULT \ | 16318 (TARGET_DEFAULT \ |
16277 | TARGET_CPU_DEFAULT \ | 16319 | TARGET_CPU_DEFAULT \ |