Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/m32r/m32r.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
comparison
equal
deleted
inserted
replaced
131:84e7813d76e9 | 145:1830386684a0 |
---|---|
1 /* Subroutines used for code generation on the Renesas M32R cpu. | 1 /* Subroutines used for code generation on the Renesas M32R cpu. |
2 Copyright (C) 1996-2018 Free Software Foundation, Inc. | 2 Copyright (C) 1996-2020 Free Software Foundation, Inc. |
3 | 3 |
4 This file is part of GCC. | 4 This file is part of GCC. |
5 | 5 |
6 GCC is free software; you can redistribute it and/or modify it | 6 GCC is free software; you can redistribute it and/or modify it |
7 under the terms of the GNU General Public License as published | 7 under the terms of the GNU General Public License as published |
84 static bool m32r_in_small_data_p (const_tree); | 84 static bool m32r_in_small_data_p (const_tree); |
85 static bool m32r_return_in_memory (const_tree, const_tree); | 85 static bool m32r_return_in_memory (const_tree, const_tree); |
86 static rtx m32r_function_value (const_tree, const_tree, bool); | 86 static rtx m32r_function_value (const_tree, const_tree, bool); |
87 static rtx m32r_libcall_value (machine_mode, const_rtx); | 87 static rtx m32r_libcall_value (machine_mode, const_rtx); |
88 static bool m32r_function_value_regno_p (const unsigned int); | 88 static bool m32r_function_value_regno_p (const unsigned int); |
89 static void m32r_setup_incoming_varargs (cumulative_args_t, machine_mode, | 89 static void m32r_setup_incoming_varargs (cumulative_args_t, |
90 tree, int *, int); | 90 const function_arg_info &, |
91 int *, int); | |
91 static void init_idents (void); | 92 static void init_idents (void); |
92 static bool m32r_rtx_costs (rtx, machine_mode, int, int, int *, bool speed); | 93 static bool m32r_rtx_costs (rtx, machine_mode, int, int, int *, bool speed); |
93 static int m32r_memory_move_cost (machine_mode, reg_class_t, bool); | 94 static int m32r_memory_move_cost (machine_mode, reg_class_t, bool); |
94 static bool m32r_pass_by_reference (cumulative_args_t, machine_mode, | 95 static bool m32r_pass_by_reference (cumulative_args_t, |
95 const_tree, bool); | 96 const function_arg_info &arg); |
96 static int m32r_arg_partial_bytes (cumulative_args_t, machine_mode, | 97 static int m32r_arg_partial_bytes (cumulative_args_t, |
97 tree, bool); | 98 const function_arg_info &); |
98 static rtx m32r_function_arg (cumulative_args_t, machine_mode, | 99 static rtx m32r_function_arg (cumulative_args_t, const function_arg_info &); |
99 const_tree, bool); | 100 static void m32r_function_arg_advance (cumulative_args_t, |
100 static void m32r_function_arg_advance (cumulative_args_t, machine_mode, | 101 const function_arg_info &); |
101 const_tree, bool); | |
102 static bool m32r_can_eliminate (const int, const int); | 102 static bool m32r_can_eliminate (const int, const int); |
103 static void m32r_conditional_register_usage (void); | 103 static void m32r_conditional_register_usage (void); |
104 static void m32r_trampoline_init (rtx, tree, rtx); | 104 static void m32r_trampoline_init (rtx, tree, rtx); |
105 static bool m32r_legitimate_constant_p (machine_mode, rtx); | 105 static bool m32r_legitimate_constant_p (machine_mode, rtx); |
106 static bool m32r_attribute_identifier (const_tree); | 106 static bool m32r_attribute_identifier (const_tree); |
678 memreg_operand (rtx op, machine_mode mode ATTRIBUTE_UNUSED) | 678 memreg_operand (rtx op, machine_mode mode ATTRIBUTE_UNUSED) |
679 { | 679 { |
680 return MEM_P (op) && REG_P (XEXP (op, 0)); | 680 return MEM_P (op) && REG_P (XEXP (op, 0)); |
681 } | 681 } |
682 | 682 |
683 /* Return nonzero if TYPE must be passed by indirect reference. */ | 683 /* Return nonzero if ARG must be passed by indirect reference. */ |
684 | 684 |
685 static bool | 685 static bool |
686 m32r_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED, | 686 m32r_pass_by_reference (cumulative_args_t, const function_arg_info &arg) |
687 machine_mode mode, const_tree type, | 687 { |
688 bool named ATTRIBUTE_UNUSED) | 688 int size = arg.type_size_in_bytes (); |
689 { | |
690 int size; | |
691 | |
692 if (type) | |
693 size = int_size_in_bytes (type); | |
694 else | |
695 size = GET_MODE_SIZE (mode); | |
696 | |
697 return (size < 0 || size > 8); | 689 return (size < 0 || size > 8); |
698 } | 690 } |
699 | 691 |
700 /* Comparisons. */ | 692 /* Comparisons. */ |
701 | 693 |
1162 return val; | 1154 return val; |
1163 } | 1155 } |
1164 | 1156 |
1165 | 1157 |
1166 static int | 1158 static int |
1167 m32r_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode, | 1159 m32r_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg) |
1168 tree type, bool named ATTRIBUTE_UNUSED) | |
1169 { | 1160 { |
1170 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); | 1161 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); |
1171 | 1162 |
1172 int words; | 1163 int words; |
1173 unsigned int size = | 1164 unsigned int size = |
1174 (((mode == BLKmode && type) | 1165 (arg.promoted_size_in_bytes () + UNITS_PER_WORD - 1) / UNITS_PER_WORD; |
1175 ? (unsigned int) int_size_in_bytes (type) | |
1176 : GET_MODE_SIZE (mode)) + UNITS_PER_WORD - 1) | |
1177 / UNITS_PER_WORD; | |
1178 | 1166 |
1179 if (*cum >= M32R_MAX_PARM_REGS) | 1167 if (*cum >= M32R_MAX_PARM_REGS) |
1180 words = 0; | 1168 words = 0; |
1181 else if (*cum + size > M32R_MAX_PARM_REGS) | 1169 else if (*cum + size > M32R_MAX_PARM_REGS) |
1182 words = (*cum + size) - M32R_MAX_PARM_REGS; | 1170 words = (*cum + size) - M32R_MAX_PARM_REGS; |
1210 | 1198 |
1211 /* Determine where to put an argument to a function. | 1199 /* Determine where to put an argument to a function. |
1212 Value is zero to push the argument on the stack, | 1200 Value is zero to push the argument on the stack, |
1213 or a hard register in which to store the argument. | 1201 or a hard register in which to store the argument. |
1214 | 1202 |
1215 MODE is the argument's machine mode. | |
1216 TYPE is the data type of the argument (as a tree). | |
1217 This is null for libcalls where that information may | |
1218 not be available. | |
1219 CUM is a variable of type CUMULATIVE_ARGS which gives info about | 1203 CUM is a variable of type CUMULATIVE_ARGS which gives info about |
1220 the preceding args and about the function being called. | 1204 the preceding args and about the function being called. |
1221 NAMED is nonzero if this argument is a named parameter | 1205 ARG is a description of the argument. */ |
1222 (otherwise it is an extra parameter matching an ellipsis). */ | |
1223 /* On the M32R the first M32R_MAX_PARM_REGS args are normally in registers | 1206 /* On the M32R the first M32R_MAX_PARM_REGS args are normally in registers |
1224 and the rest are pushed. */ | 1207 and the rest are pushed. */ |
1225 | 1208 |
1226 static rtx | 1209 static rtx |
1227 m32r_function_arg (cumulative_args_t cum_v, machine_mode mode, | 1210 m32r_function_arg (cumulative_args_t cum_v, const function_arg_info &arg) |
1228 const_tree type ATTRIBUTE_UNUSED, | |
1229 bool named ATTRIBUTE_UNUSED) | |
1230 { | 1211 { |
1231 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); | 1212 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); |
1232 | 1213 |
1233 return (PASS_IN_REG_P (*cum, mode, type) | 1214 return (PASS_IN_REG_P (*cum, arg.mode, arg.type) |
1234 ? gen_rtx_REG (mode, ROUND_ADVANCE_CUM (*cum, mode, type)) | 1215 ? gen_rtx_REG (arg.mode, |
1216 ROUND_ADVANCE_CUM (*cum, arg.mode, arg.type)) | |
1235 : NULL_RTX); | 1217 : NULL_RTX); |
1236 } | 1218 } |
1237 | 1219 |
1238 /* Update the data in CUM to advance over an argument | 1220 /* Update the data in CUM to advance over argument ARG. */ |
1239 of mode MODE and data type TYPE. | |
1240 (TYPE is null for libcalls where that information may not be available.) */ | |
1241 | 1221 |
1242 static void | 1222 static void |
1243 m32r_function_arg_advance (cumulative_args_t cum_v, machine_mode mode, | 1223 m32r_function_arg_advance (cumulative_args_t cum_v, |
1244 const_tree type, bool named ATTRIBUTE_UNUSED) | 1224 const function_arg_info &arg) |
1245 { | 1225 { |
1246 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); | 1226 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); |
1247 | 1227 |
1248 *cum = (ROUND_ADVANCE_CUM (*cum, mode, type) | 1228 *cum = (ROUND_ADVANCE_CUM (*cum, arg.mode, arg.type) |
1249 + ROUND_ADVANCE_ARG (mode, type)); | 1229 + ROUND_ADVANCE_ARG (arg.mode, arg.type)); |
1250 } | 1230 } |
1251 | 1231 |
1252 /* Worker function for TARGET_RETURN_IN_MEMORY. */ | 1232 /* Worker function for TARGET_RETURN_IN_MEMORY. */ |
1253 | 1233 |
1254 static bool | 1234 static bool |
1255 m32r_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) | 1235 m32r_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) |
1256 { | 1236 { |
1257 cumulative_args_t dummy = pack_cumulative_args (NULL); | 1237 cumulative_args_t dummy = pack_cumulative_args (NULL); |
1258 | 1238 function_arg_info arg (const_cast<tree> (type), /*named=*/false); |
1259 return m32r_pass_by_reference (dummy, TYPE_MODE (type), type, false); | 1239 return m32r_pass_by_reference (dummy, arg); |
1260 } | 1240 } |
1261 | 1241 |
1262 /* Worker function for TARGET_FUNCTION_VALUE. */ | 1242 /* Worker function for TARGET_FUNCTION_VALUE. */ |
1263 | 1243 |
1264 static rtx | 1244 static rtx |
1290 | 1270 |
1291 /* Do any needed setup for a variadic function. For the M32R, we must | 1271 /* Do any needed setup for a variadic function. For the M32R, we must |
1292 create a register parameter block, and then copy any anonymous arguments | 1272 create a register parameter block, and then copy any anonymous arguments |
1293 in registers to memory. | 1273 in registers to memory. |
1294 | 1274 |
1295 CUM has not been updated for the last named argument which has type TYPE | 1275 CUM has not been updated for the last named argument (which is given |
1296 and mode MODE, and we rely on this fact. */ | 1276 by ARG), and we rely on this fact. */ |
1297 | 1277 |
1298 static void | 1278 static void |
1299 m32r_setup_incoming_varargs (cumulative_args_t cum, machine_mode mode, | 1279 m32r_setup_incoming_varargs (cumulative_args_t cum, |
1300 tree type, int *pretend_size, int no_rtl) | 1280 const function_arg_info &arg, |
1281 int *pretend_size, int no_rtl) | |
1301 { | 1282 { |
1302 int first_anon_arg; | 1283 int first_anon_arg; |
1303 | 1284 |
1304 if (no_rtl) | 1285 if (no_rtl) |
1305 return; | 1286 return; |
1306 | 1287 |
1307 /* All BLKmode values are passed by reference. */ | 1288 /* All BLKmode values are passed by reference. */ |
1308 gcc_assert (mode != BLKmode); | 1289 gcc_assert (arg.mode != BLKmode); |
1309 | 1290 |
1310 first_anon_arg = (ROUND_ADVANCE_CUM (*get_cumulative_args (cum), mode, type) | 1291 first_anon_arg = (ROUND_ADVANCE_CUM (*get_cumulative_args (cum), |
1311 + ROUND_ADVANCE_ARG (mode, type)); | 1292 arg.mode, arg.type) |
1293 + ROUND_ADVANCE_ARG (arg.mode, arg.type)); | |
1312 | 1294 |
1313 if (first_anon_arg < M32R_MAX_PARM_REGS) | 1295 if (first_anon_arg < M32R_MAX_PARM_REGS) |
1314 { | 1296 { |
1315 /* Note that first_reg_offset < M32R_MAX_PARM_REGS. */ | 1297 /* Note that first_reg_offset < M32R_MAX_PARM_REGS. */ |
1316 int first_reg_offset = first_anon_arg; | 1298 int first_reg_offset = first_anon_arg; |
1542 /* Tell prologue and epilogue if register REGNO should be saved / restored. | 1524 /* Tell prologue and epilogue if register REGNO should be saved / restored. |
1543 The return address and frame pointer are treated separately. | 1525 The return address and frame pointer are treated separately. |
1544 Don't consider them here. */ | 1526 Don't consider them here. */ |
1545 #define MUST_SAVE_REGISTER(regno, interrupt_p) \ | 1527 #define MUST_SAVE_REGISTER(regno, interrupt_p) \ |
1546 ((regno) != RETURN_ADDR_REGNUM && (regno) != FRAME_POINTER_REGNUM \ | 1528 ((regno) != RETURN_ADDR_REGNUM && (regno) != FRAME_POINTER_REGNUM \ |
1547 && (df_regs_ever_live_p (regno) && (!call_really_used_regs[regno] || interrupt_p))) | 1529 && (df_regs_ever_live_p (regno) && (!call_used_regs[regno] || interrupt_p))) |
1548 | 1530 |
1549 #define MUST_SAVE_FRAME_POINTER (df_regs_ever_live_p (FRAME_POINTER_REGNUM)) | 1531 #define MUST_SAVE_FRAME_POINTER (df_regs_ever_live_p (FRAME_POINTER_REGNUM)) |
1550 #define MUST_SAVE_RETURN_ADDR (df_regs_ever_live_p (RETURN_ADDR_REGNUM) || crtl->profile) | 1532 #define MUST_SAVE_RETURN_ADDR (df_regs_ever_live_p (RETURN_ADDR_REGNUM) || crtl->profile) |
1551 | 1533 |
1552 #define SHORT_INSN_SIZE 2 /* Size of small instructions. */ | 1534 #define SHORT_INSN_SIZE 2 /* Size of small instructions. */ |
2596 | 2578 |
2597 /* It is known that output_block_move() will update src_reg to point | 2579 /* It is known that output_block_move() will update src_reg to point |
2598 to the word after the end of the source block, and dst_reg to point | 2580 to the word after the end of the source block, and dst_reg to point |
2599 to the last word of the destination block, provided that the block | 2581 to the last word of the destination block, provided that the block |
2600 is MAX_MOVE_BYTES long. */ | 2582 is MAX_MOVE_BYTES long. */ |
2601 emit_insn (gen_movmemsi_internal (dst_reg, src_reg, at_a_time, | 2583 emit_insn (gen_cpymemsi_internal (dst_reg, src_reg, at_a_time, |
2602 new_dst_reg, new_src_reg)); | 2584 new_dst_reg, new_src_reg)); |
2603 emit_move_insn (dst_reg, new_dst_reg); | 2585 emit_move_insn (dst_reg, new_dst_reg); |
2604 emit_move_insn (src_reg, new_src_reg); | 2586 emit_move_insn (src_reg, new_src_reg); |
2605 emit_insn (gen_addsi3 (dst_reg, dst_reg, GEN_INT (4))); | 2587 emit_insn (gen_addsi3 (dst_reg, dst_reg, GEN_INT (4))); |
2606 | 2588 |
2610 emit_jump_insn (gen_cbranchsi4 (test, src_reg, final_src, label)); | 2592 emit_jump_insn (gen_cbranchsi4 (test, src_reg, final_src, label)); |
2611 } | 2593 } |
2612 } | 2594 } |
2613 | 2595 |
2614 if (leftover) | 2596 if (leftover) |
2615 emit_insn (gen_movmemsi_internal (dst_reg, src_reg, GEN_INT (leftover), | 2597 emit_insn (gen_cpymemsi_internal (dst_reg, src_reg, GEN_INT (leftover), |
2616 gen_reg_rtx (SImode), | 2598 gen_reg_rtx (SImode), |
2617 gen_reg_rtx (SImode))); | 2599 gen_reg_rtx (SImode))); |
2618 return 1; | 2600 return 1; |
2619 } | 2601 } |
2620 | 2602 |
2943 | 2925 |
2944 static void | 2926 static void |
2945 m32r_conditional_register_usage (void) | 2927 m32r_conditional_register_usage (void) |
2946 { | 2928 { |
2947 if (flag_pic) | 2929 if (flag_pic) |
2948 { | 2930 fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; |
2949 fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; | |
2950 call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; | |
2951 } | |
2952 } | 2931 } |
2953 | 2932 |
2954 /* Implement TARGET_LEGITIMATE_CONSTANT_P | 2933 /* Implement TARGET_LEGITIMATE_CONSTANT_P |
2955 | 2934 |
2956 We don't allow (plus symbol large-constant) as the relocations can't | 2935 We don't allow (plus symbol large-constant) as the relocations can't |