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