Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/h8300/h8300.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 |
---|---|
36 #include "flags.h" | 36 #include "flags.h" |
37 #include "recog.h" | 37 #include "recog.h" |
38 #include "expr.h" | 38 #include "expr.h" |
39 #include "function.h" | 39 #include "function.h" |
40 #include "optabs.h" | 40 #include "optabs.h" |
41 #include "toplev.h" | 41 #include "diagnostic-core.h" |
42 #include "c-pragma.h" | 42 #include "c-family/c-pragma.h" /* ??? */ |
43 #include "tm_p.h" | 43 #include "tm_p.h" |
44 #include "ggc.h" | 44 #include "ggc.h" |
45 #include "target.h" | 45 #include "target.h" |
46 #include "target-def.h" | 46 #include "target-def.h" |
47 #include "df.h" | |
47 | 48 |
48 /* Classifies a h8300_src_operand or h8300_dst_operand. | 49 /* Classifies a h8300_src_operand or h8300_dst_operand. |
49 | 50 |
50 H8OP_IMMEDIATE | 51 H8OP_IMMEDIATE |
51 A constant operand of some sort. | 52 A constant operand of some sort. |
300 H8_300, | 301 H8_300, |
301 H8_300H, | 302 H8_300H, |
302 H8_S | 303 H8_S |
303 }; | 304 }; |
304 | 305 |
306 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ | |
307 | |
308 static const struct default_options h8300_option_optimization_table[] = | |
309 { | |
310 /* Basic block reordering is only beneficial on targets with cache | |
311 and/or variable-cycle branches where (cycle count taken != | |
312 cycle count not taken). */ | |
313 { OPT_LEVELS_ALL, OPT_freorder_blocks, NULL, 0 }, | |
314 { OPT_LEVELS_NONE, 0, NULL, 0 } | |
315 }; | |
316 | |
305 /* Initialize various cpu specific globals at start up. */ | 317 /* Initialize various cpu specific globals at start up. */ |
306 | 318 |
307 void | 319 static void |
308 h8300_init_once (void) | 320 h8300_option_override (void) |
309 { | 321 { |
310 static const char *const h8_push_ops[2] = { "push" , "push.l" }; | 322 static const char *const h8_push_ops[2] = { "push" , "push.l" }; |
311 static const char *const h8_pop_ops[2] = { "pop" , "pop.l" }; | 323 static const char *const h8_pop_ops[2] = { "pop" , "pop.l" }; |
312 static const char *const h8_mov_ops[2] = { "mov.w", "mov.l" }; | 324 static const char *const h8_mov_ops[2] = { "mov.w", "mov.l" }; |
313 | 325 |
400 /* We use movmd sequences for some moves since it can be quicker | 412 /* We use movmd sequences for some moves since it can be quicker |
401 than calling memcpy(). The sequences will need to save and | 413 than calling memcpy(). The sequences will need to save and |
402 restore er6 though, so bump up the cost. */ | 414 restore er6 though, so bump up the cost. */ |
403 h8300_move_ratio = 6; | 415 h8300_move_ratio = 6; |
404 } | 416 } |
417 | |
418 /* This target defaults to strict volatile bitfields. */ | |
419 if (flag_strict_volatile_bitfields < 0) | |
420 flag_strict_volatile_bitfields = 1; | |
405 } | 421 } |
406 | 422 |
407 /* Implement REG_CLASS_FROM_LETTER. | 423 /* Implement REG_CLASS_FROM_LETTER. |
408 | 424 |
409 Some patterns need to use er6 as a scratch register. This is | 425 Some patterns need to use er6 as a scratch register. This is |
621 else if (!TARGET_NORMAL_MODE) | 637 else if (!TARGET_NORMAL_MODE) |
622 x = gen_push_h8300hs_advanced (reg); | 638 x = gen_push_h8300hs_advanced (reg); |
623 else | 639 else |
624 x = gen_push_h8300hs_normal (reg); | 640 x = gen_push_h8300hs_normal (reg); |
625 x = F (emit_insn (x), true); | 641 x = F (emit_insn (x), true); |
626 REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, 0); | 642 add_reg_note (x, REG_INC, stack_pointer_rtx); |
627 } | 643 } |
628 | 644 |
629 /* Emit an insn to pop register RN. */ | 645 /* Emit an insn to pop register RN. */ |
630 | 646 |
631 static void | 647 static void |
639 else if (!TARGET_NORMAL_MODE) | 655 else if (!TARGET_NORMAL_MODE) |
640 x = gen_pop_h8300hs_advanced (reg); | 656 x = gen_pop_h8300hs_advanced (reg); |
641 else | 657 else |
642 x = gen_pop_h8300hs_normal (reg); | 658 x = gen_pop_h8300hs_normal (reg); |
643 x = emit_insn (x); | 659 x = emit_insn (x); |
644 REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, 0); | 660 add_reg_note (x, REG_INC, stack_pointer_rtx); |
645 } | 661 } |
646 | 662 |
647 /* Emit an instruction to push or pop NREGS consecutive registers | 663 /* Emit an instruction to push or pop NREGS consecutive registers |
648 starting at register REGNO. POP_P selects a pop rather than a | 664 starting at register REGNO. POP_P selects a pop rather than a |
649 push and RETURN_P is true if the instruction should return. | 665 push and RETURN_P is true if the instruction should return. |
1077 } | 1093 } |
1078 | 1094 |
1079 /* If the next function argument with MODE and TYPE is to be passed in | 1095 /* If the next function argument with MODE and TYPE is to be passed in |
1080 a register, return a reg RTX for the hard register in which to pass | 1096 a register, return a reg RTX for the hard register in which to pass |
1081 the argument. CUM represents the state after the last argument. | 1097 the argument. CUM represents the state after the last argument. |
1082 If the argument is to be pushed, NULL_RTX is returned. */ | 1098 If the argument is to be pushed, NULL_RTX is returned. |
1083 | 1099 |
1084 rtx | 1100 On the H8/300 all normal args are pushed, unless -mquickcall in which |
1085 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, | 1101 case the first 3 arguments are passed in registers. */ |
1086 tree type, int named) | 1102 |
1103 static rtx | |
1104 h8300_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, | |
1105 const_tree type, bool named) | |
1087 { | 1106 { |
1088 static const char *const hand_list[] = { | 1107 static const char *const hand_list[] = { |
1089 "__main", | 1108 "__main", |
1090 "__cmpsi2", | 1109 "__cmpsi2", |
1091 "__divhi3", | 1110 "__divhi3", |
1145 result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD); | 1164 result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD); |
1146 } | 1165 } |
1147 | 1166 |
1148 return result; | 1167 return result; |
1149 } | 1168 } |
1169 | |
1170 /* Update the data in CUM to advance over an argument | |
1171 of mode MODE and data type TYPE. | |
1172 (TYPE is null for libcalls where that information may not be available.) */ | |
1173 | |
1174 static void | |
1175 h8300_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, | |
1176 const_tree type, bool named ATTRIBUTE_UNUSED) | |
1177 { | |
1178 cum->nbytes += (mode != BLKmode | |
1179 ? (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD | |
1180 : (int_size_in_bytes (type) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD); | |
1181 } | |
1182 | |
1150 | 1183 |
1151 /* Compute the cost of an and insn. */ | 1184 /* Compute the cost of an and insn. */ |
1152 | 1185 |
1153 static int | 1186 static int |
1154 h8300_and_costs (rtx x) | 1187 h8300_and_costs (rtx x) |
1883 h8300_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) | 1916 h8300_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) |
1884 { | 1917 { |
1885 return (to == STACK_POINTER_REGNUM ? ! frame_pointer_needed : true); | 1918 return (to == STACK_POINTER_REGNUM ? ! frame_pointer_needed : true); |
1886 } | 1919 } |
1887 | 1920 |
1921 /* Conditionally modify register usage based on target flags. */ | |
1922 | |
1923 static void | |
1924 h8300_conditional_register_usage (void) | |
1925 { | |
1926 if (!TARGET_MAC) | |
1927 fixed_regs[MAC_REG] = call_used_regs[MAC_REG] = 1; | |
1928 } | |
1929 | |
1888 /* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET). | 1930 /* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET). |
1889 Define the offset between two registers, one to be eliminated, and | 1931 Define the offset between two registers, one to be eliminated, and |
1890 the other its replacement, at the start of a routine. */ | 1932 the other its replacement, at the start of a routine. */ |
1891 | 1933 |
1892 int | 1934 int |
3099 } | 3141 } |
3100 } | 3142 } |
3101 | 3143 |
3102 /* Compute which flag bits are valid after an addition insn. */ | 3144 /* Compute which flag bits are valid after an addition insn. */ |
3103 | 3145 |
3104 int | 3146 enum attr_cc |
3105 compute_plussi_cc (rtx *operands) | 3147 compute_plussi_cc (rtx *operands) |
3106 { | 3148 { |
3107 enum machine_mode mode = GET_MODE (operands[0]); | 3149 enum machine_mode mode = GET_MODE (operands[0]); |
3108 | 3150 |
3109 gcc_assert (mode == SImode); | 3151 gcc_assert (mode == SImode); |
3483 return length; | 3525 return length; |
3484 } | 3526 } |
3485 | 3527 |
3486 /* Compute which flag bits are valid after a logical insn. */ | 3528 /* Compute which flag bits are valid after a logical insn. */ |
3487 | 3529 |
3488 int | 3530 enum attr_cc |
3489 compute_logical_op_cc (enum machine_mode mode, rtx *operands) | 3531 compute_logical_op_cc (enum machine_mode mode, rtx *operands) |
3490 { | 3532 { |
3491 /* Figure out the logical op that we need to perform. */ | 3533 /* Figure out the logical op that we need to perform. */ |
3492 enum rtx_code code = GET_CODE (operands[3]); | 3534 enum rtx_code code = GET_CODE (operands[3]); |
3493 /* Pretend that every byte is affected if both operands are registers. */ | 3535 /* Pretend that every byte is affected if both operands are registers. */ |
3734 } | 3776 } |
3735 | 3777 |
3736 /* Emit code to do shifts. */ | 3778 /* Emit code to do shifts. */ |
3737 | 3779 |
3738 bool | 3780 bool |
3739 expand_a_shift (enum machine_mode mode, int code, rtx operands[]) | 3781 expand_a_shift (enum machine_mode mode, enum rtx_code code, rtx operands[]) |
3740 { | 3782 { |
3741 switch (h8sx_classify_shift (mode, code, operands[2])) | 3783 switch (h8sx_classify_shift (mode, code, operands[2])) |
3742 { | 3784 { |
3743 case H8SX_SHIFT_BINARY: | 3785 case H8SX_SHIFT_BINARY: |
3744 operands[1] = force_reg (mode, operands[1]); | 3786 operands[1] = force_reg (mode, operands[1]); |
3779 bits, 0 means CC isn't left in a usable state). */ | 3821 bits, 0 means CC isn't left in a usable state). */ |
3780 | 3822 |
3781 struct shift_insn | 3823 struct shift_insn |
3782 { | 3824 { |
3783 const char *const assembler; | 3825 const char *const assembler; |
3784 const int cc_valid; | 3826 const enum attr_cc cc_valid; |
3785 }; | 3827 }; |
3786 | 3828 |
3787 /* Assembler instruction shift table. | 3829 /* Assembler instruction shift table. |
3788 | 3830 |
3789 These tables are used to look up the basic shifts. | 3831 These tables are used to look up the basic shifts. |
3947 /* Insn for a two-bit shift. Valid when ALG is either SHIFT_INLINE | 3989 /* Insn for a two-bit shift. Valid when ALG is either SHIFT_INLINE |
3948 or SHIFT_SPECIAL, and REMAINDER is nonzero. */ | 3990 or SHIFT_SPECIAL, and REMAINDER is nonzero. */ |
3949 const char *shift2; | 3991 const char *shift2; |
3950 | 3992 |
3951 /* CC status for SHIFT_INLINE. */ | 3993 /* CC status for SHIFT_INLINE. */ |
3952 int cc_inline; | 3994 enum attr_cc cc_inline; |
3953 | 3995 |
3954 /* CC status for SHIFT_SPECIAL. */ | 3996 /* CC status for SHIFT_SPECIAL. */ |
3955 int cc_special; | 3997 enum attr_cc cc_special; |
3956 }; | 3998 }; |
3957 | 3999 |
3958 static void get_shift_alg (enum shift_type, | 4000 static void get_shift_alg (enum shift_type, |
3959 enum shift_mode, unsigned int, | 4001 enum shift_mode, unsigned int, |
3960 struct shift_info *); | 4002 struct shift_info *); |
4780 } | 4822 } |
4781 } | 4823 } |
4782 | 4824 |
4783 /* Compute which flag bits are valid after a shift insn. */ | 4825 /* Compute which flag bits are valid after a shift insn. */ |
4784 | 4826 |
4785 int | 4827 enum attr_cc |
4786 compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands) | 4828 compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands) |
4787 { | 4829 { |
4788 rtx shift = operands[3]; | 4830 rtx shift = operands[3]; |
4789 enum machine_mode mode = GET_MODE (shift); | 4831 enum machine_mode mode = GET_MODE (shift); |
4790 enum rtx_code code = GET_CODE (shift); | 4832 enum rtx_code code = GET_CODE (shift); |
5897 #define TARGET_INIT_LIBFUNCS h8300_init_libfuncs | 5939 #define TARGET_INIT_LIBFUNCS h8300_init_libfuncs |
5898 | 5940 |
5899 #undef TARGET_RETURN_IN_MEMORY | 5941 #undef TARGET_RETURN_IN_MEMORY |
5900 #define TARGET_RETURN_IN_MEMORY h8300_return_in_memory | 5942 #define TARGET_RETURN_IN_MEMORY h8300_return_in_memory |
5901 | 5943 |
5944 #undef TARGET_FUNCTION_ARG | |
5945 #define TARGET_FUNCTION_ARG h8300_function_arg | |
5946 | |
5947 #undef TARGET_FUNCTION_ARG_ADVANCE | |
5948 #define TARGET_FUNCTION_ARG_ADVANCE h8300_function_arg_advance | |
5949 | |
5902 #undef TARGET_MACHINE_DEPENDENT_REORG | 5950 #undef TARGET_MACHINE_DEPENDENT_REORG |
5903 #define TARGET_MACHINE_DEPENDENT_REORG h8300_reorg | 5951 #define TARGET_MACHINE_DEPENDENT_REORG h8300_reorg |
5904 | 5952 |
5905 #undef TARGET_HARD_REGNO_SCRATCH_OK | 5953 #undef TARGET_HARD_REGNO_SCRATCH_OK |
5906 #define TARGET_HARD_REGNO_SCRATCH_OK h8300_hard_regno_scratch_ok | 5954 #define TARGET_HARD_REGNO_SCRATCH_OK h8300_hard_regno_scratch_ok |
5912 #define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT | 5960 #define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT |
5913 | 5961 |
5914 #undef TARGET_CAN_ELIMINATE | 5962 #undef TARGET_CAN_ELIMINATE |
5915 #define TARGET_CAN_ELIMINATE h8300_can_eliminate | 5963 #define TARGET_CAN_ELIMINATE h8300_can_eliminate |
5916 | 5964 |
5965 #undef TARGET_CONDITIONAL_REGISTER_USAGE | |
5966 #define TARGET_CONDITIONAL_REGISTER_USAGE h8300_conditional_register_usage | |
5967 | |
5917 #undef TARGET_TRAMPOLINE_INIT | 5968 #undef TARGET_TRAMPOLINE_INIT |
5918 #define TARGET_TRAMPOLINE_INIT h8300_trampoline_init | 5969 #define TARGET_TRAMPOLINE_INIT h8300_trampoline_init |
5919 | 5970 |
5971 #undef TARGET_OPTION_OVERRIDE | |
5972 #define TARGET_OPTION_OVERRIDE h8300_option_override | |
5973 | |
5974 #undef TARGET_OPTION_OPTIMIZATION_TABLE | |
5975 #define TARGET_OPTION_OPTIMIZATION_TABLE h8300_option_optimization_table | |
5976 | |
5977 #undef TARGET_EXCEPT_UNWIND_INFO | |
5978 #define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info | |
5979 | |
5920 struct gcc_target targetm = TARGET_INITIALIZER; | 5980 struct gcc_target targetm = TARGET_INITIALIZER; |