Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/riscv/riscv.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
1 /* Subroutines used for code generation for RISC-V. | 1 /* Subroutines used for code generation for RISC-V. |
2 Copyright (C) 2011-2017 Free Software Foundation, Inc. | 2 Copyright (C) 2011-2018 Free Software Foundation, Inc. |
3 Contributed by Andrew Waterman (andrew@sifive.com). | 3 Contributed by Andrew Waterman (andrew@sifive.com). |
4 Based on MIPS target for GNU compiler. | 4 Based on MIPS target for GNU compiler. |
5 | 5 |
6 This file is part of GCC. | 6 This file is part of GCC. |
7 | 7 |
16 GNU General Public License for more details. | 16 GNU General Public License for more details. |
17 | 17 |
18 You should have received a copy of the GNU General Public License | 18 You should have received a copy of the GNU General Public License |
19 along with GCC; see the file COPYING3. If not see | 19 along with GCC; see the file COPYING3. If not see |
20 <http://www.gnu.org/licenses/>. */ | 20 <http://www.gnu.org/licenses/>. */ |
21 | |
22 #define IN_TARGET_CODE 1 | |
21 | 23 |
22 #include "config.h" | 24 #include "config.h" |
23 #include "system.h" | 25 #include "system.h" |
24 #include "coretypes.h" | 26 #include "coretypes.h" |
25 #include "tm.h" | 27 #include "tm.h" |
49 #include "optabs.h" | 51 #include "optabs.h" |
50 #include "bitmap.h" | 52 #include "bitmap.h" |
51 #include "df.h" | 53 #include "df.h" |
52 #include "diagnostic.h" | 54 #include "diagnostic.h" |
53 #include "builtins.h" | 55 #include "builtins.h" |
56 #include "predict.h" | |
54 | 57 |
55 /* True if X is an UNSPEC wrapper around a SYMBOL_REF or LABEL_REF. */ | 58 /* True if X is an UNSPEC wrapper around a SYMBOL_REF or LABEL_REF. */ |
56 #define UNSPEC_ADDRESS_P(X) \ | 59 #define UNSPEC_ADDRESS_P(X) \ |
57 (GET_CODE (X) == UNSPEC \ | 60 (GET_CODE (X) == UNSPEC \ |
58 && XINT (X, 1) >= UNSPEC_ADDRESS_FIRST \ | 61 && XINT (X, 1) >= UNSPEC_ADDRESS_FIRST \ |
117 | 120 |
118 /* The offset of arg_pointer_rtx from the bottom of the frame. */ | 121 /* The offset of arg_pointer_rtx from the bottom of the frame. */ |
119 HOST_WIDE_INT arg_pointer_offset; | 122 HOST_WIDE_INT arg_pointer_offset; |
120 }; | 123 }; |
121 | 124 |
125 enum riscv_privilege_levels { | |
126 UNKNOWN_MODE, USER_MODE, SUPERVISOR_MODE, MACHINE_MODE | |
127 }; | |
128 | |
122 struct GTY(()) machine_function { | 129 struct GTY(()) machine_function { |
123 /* The number of extra stack bytes taken up by register varargs. | 130 /* The number of extra stack bytes taken up by register varargs. |
124 This area is allocated by the callee at the very top of the frame. */ | 131 This area is allocated by the callee at the very top of the frame. */ |
125 int varargs_size; | 132 int varargs_size; |
126 | 133 |
127 /* Memoized return value of leaf_function_p. <0 if false, >0 if true. */ | 134 /* True if current function is a naked function. */ |
128 int is_leaf; | 135 bool naked_p; |
136 | |
137 /* True if current function is an interrupt function. */ | |
138 bool interrupt_handler_p; | |
139 /* For an interrupt handler, indicates the privilege level. */ | |
140 enum riscv_privilege_levels interrupt_mode; | |
141 | |
142 /* True if attributes on current function have been checked. */ | |
143 bool attributes_checked_p; | |
129 | 144 |
130 /* The current frame information, calculated by riscv_compute_frame_info. */ | 145 /* The current frame information, calculated by riscv_compute_frame_info. */ |
131 struct riscv_frame_info frame; | 146 struct riscv_frame_info frame; |
132 }; | 147 }; |
133 | 148 |
215 }; | 230 }; |
216 | 231 |
217 /* Global variables for machine-dependent things. */ | 232 /* Global variables for machine-dependent things. */ |
218 | 233 |
219 /* Whether unaligned accesses execute very slowly. */ | 234 /* Whether unaligned accesses execute very slowly. */ |
220 static bool riscv_slow_unaligned_access_p; | 235 bool riscv_slow_unaligned_access_p; |
236 | |
237 /* Stack alignment to assume/maintain. */ | |
238 unsigned riscv_stack_boundary; | |
221 | 239 |
222 /* Which tuning parameters to use. */ | 240 /* Which tuning parameters to use. */ |
223 static const struct riscv_tune_info *tune_info; | 241 static const struct riscv_tune_info *tune_info; |
224 | 242 |
225 /* Index R is the smallest register class that contains register R. */ | 243 /* Index R is the smallest register class that contains register R. */ |
267 1, /* branch_cost */ | 285 1, /* branch_cost */ |
268 2, /* memory_cost */ | 286 2, /* memory_cost */ |
269 false, /* slow_unaligned_access */ | 287 false, /* slow_unaligned_access */ |
270 }; | 288 }; |
271 | 289 |
290 static tree riscv_handle_fndecl_attribute (tree *, tree, tree, int, bool *); | |
291 static tree riscv_handle_type_attribute (tree *, tree, tree, int, bool *); | |
292 | |
293 /* Defining target-specific uses of __attribute__. */ | |
294 static const struct attribute_spec riscv_attribute_table[] = | |
295 { | |
296 /* Syntax: { name, min_len, max_len, decl_required, type_required, | |
297 function_type_required, affects_type_identity, handler, | |
298 exclude } */ | |
299 | |
300 /* The attribute telling no prologue/epilogue. */ | |
301 { "naked", 0, 0, true, false, false, false, | |
302 riscv_handle_fndecl_attribute, NULL }, | |
303 /* This attribute generates prologue/epilogue for interrupt handlers. */ | |
304 { "interrupt", 0, 1, false, true, true, false, | |
305 riscv_handle_type_attribute, NULL }, | |
306 | |
307 /* The last attribute spec is set to be NULL. */ | |
308 { NULL, 0, 0, false, false, false, false, NULL, NULL } | |
309 }; | |
310 | |
272 /* A table describing all the processors GCC knows about. */ | 311 /* A table describing all the processors GCC knows about. */ |
273 static const struct riscv_cpu_info riscv_cpu_info_table[] = { | 312 static const struct riscv_cpu_info riscv_cpu_info_table[] = { |
274 { "rocket", &rocket_tune_info }, | 313 { "rocket", &rocket_tune_info }, |
275 { "size", &optimize_size_tune_info }, | 314 { "size", &optimize_size_tune_info }, |
276 }; | 315 }; |
761 { | 800 { |
762 struct riscv_address_info addr; | 801 struct riscv_address_info addr; |
763 int n = 1; | 802 int n = 1; |
764 | 803 |
765 if (!riscv_classify_address (&addr, x, mode, false)) | 804 if (!riscv_classify_address (&addr, x, mode, false)) |
766 return 0; | 805 { |
806 /* This could be a pattern from the pic.md file. In which case we want | |
807 this address to always have a cost of 3 to make it as expensive as the | |
808 most expensive symbol. This prevents constant propagation from | |
809 preferring symbols over register plus offset. */ | |
810 return 3; | |
811 } | |
767 | 812 |
768 /* BLKmode is used for single unaligned loads and stores and should | 813 /* BLKmode is used for single unaligned loads and stores and should |
769 not count as a multiword mode. */ | 814 not count as a multiword mode. */ |
770 if (mode != BLKmode && might_split_p) | 815 if (mode != BLKmode && might_split_p) |
771 n += (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD; | 816 n += (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD; |
1056 ssize_t bytes = snprintf (buf, sizeof (buf), ".LA%u", seqno); | 1101 ssize_t bytes = snprintf (buf, sizeof (buf), ".LA%u", seqno); |
1057 gcc_assert ((size_t) bytes < sizeof (buf)); | 1102 gcc_assert ((size_t) bytes < sizeof (buf)); |
1058 | 1103 |
1059 label = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); | 1104 label = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); |
1060 SYMBOL_REF_FLAGS (label) |= SYMBOL_FLAG_LOCAL; | 1105 SYMBOL_REF_FLAGS (label) |= SYMBOL_FLAG_LOCAL; |
1106 /* ??? Ugly hack to make weak symbols work. May need to change the | |
1107 RTL for the auipc and/or low patterns to get a better fix for | |
1108 this. */ | |
1109 if (! nonzero_address_p (addr)) | |
1110 SYMBOL_REF_WEAK (label) = 1; | |
1061 | 1111 |
1062 if (temp == NULL) | 1112 if (temp == NULL) |
1063 temp = gen_reg_rtx (Pmode); | 1113 temp = gen_reg_rtx (Pmode); |
1064 | 1114 |
1065 if (Pmode == DImode) | 1115 if (Pmode == DImode) |
1330 riscv_legitimize_const_move (mode, dest, src); | 1380 riscv_legitimize_const_move (mode, dest, src); |
1331 set_unique_reg_note (get_last_insn (), REG_EQUAL, copy_rtx (src)); | 1381 set_unique_reg_note (get_last_insn (), REG_EQUAL, copy_rtx (src)); |
1332 return true; | 1382 return true; |
1333 } | 1383 } |
1334 | 1384 |
1385 /* RISC-V GCC may generate non-legitimate address due to we provide some | |
1386 pattern for optimize access PIC local symbol and it's make GCC generate | |
1387 unrecognizable instruction during optmizing. */ | |
1388 | |
1389 if (MEM_P (dest) && !riscv_legitimate_address_p (mode, XEXP (dest, 0), | |
1390 reload_completed)) | |
1391 { | |
1392 XEXP (dest, 0) = riscv_force_address (XEXP (dest, 0), mode); | |
1393 } | |
1394 | |
1395 if (MEM_P (src) && !riscv_legitimate_address_p (mode, XEXP (src, 0), | |
1396 reload_completed)) | |
1397 { | |
1398 XEXP (src, 0) = riscv_force_address (XEXP (src, 0), mode); | |
1399 } | |
1400 | |
1335 return false; | 1401 return false; |
1336 } | 1402 } |
1337 | 1403 |
1338 /* Return true if there is an instruction that implements CODE and accepts | 1404 /* Return true if there is an instruction that implements CODE and accepts |
1339 X as an immediate operand. */ | 1405 X as an immediate operand. */ |
1409 /* We need to use a shift left and a shift right. */ | 1475 /* We need to use a shift left and a shift right. */ |
1410 return COSTS_N_INSNS (2); | 1476 return COSTS_N_INSNS (2); |
1411 } | 1477 } |
1412 | 1478 |
1413 /* Implement TARGET_RTX_COSTS. */ | 1479 /* Implement TARGET_RTX_COSTS. */ |
1480 | |
1481 #define SINGLE_SHIFT_COST 1 | |
1414 | 1482 |
1415 static bool | 1483 static bool |
1416 riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UNUSED, | 1484 riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UNUSED, |
1417 int *total, bool speed) | 1485 int *total, bool speed) |
1418 { | 1486 { |
1470 case XOR: | 1538 case XOR: |
1471 /* Double-word operations use two single-word operations. */ | 1539 /* Double-word operations use two single-word operations. */ |
1472 *total = riscv_binary_cost (x, 1, 2); | 1540 *total = riscv_binary_cost (x, 1, 2); |
1473 return false; | 1541 return false; |
1474 | 1542 |
1543 case ZERO_EXTRACT: | |
1544 /* This is an SImode shift. */ | |
1545 if (outer_code == SET && (INTVAL (XEXP (x, 2)) > 0) | |
1546 && (INTVAL (XEXP (x, 1)) + INTVAL (XEXP (x, 2)) == 32)) | |
1547 { | |
1548 *total = COSTS_N_INSNS (SINGLE_SHIFT_COST); | |
1549 return true; | |
1550 } | |
1551 return false; | |
1552 | |
1475 case ASHIFT: | 1553 case ASHIFT: |
1476 case ASHIFTRT: | 1554 case ASHIFTRT: |
1477 case LSHIFTRT: | 1555 case LSHIFTRT: |
1478 *total = riscv_binary_cost (x, 1, CONSTANT_P (XEXP (x, 1)) ? 4 : 9); | 1556 *total = riscv_binary_cost (x, SINGLE_SHIFT_COST, |
1557 CONSTANT_P (XEXP (x, 1)) ? 4 : 9); | |
1479 return false; | 1558 return false; |
1480 | 1559 |
1481 case ABS: | 1560 case ABS: |
1482 *total = COSTS_N_INSNS (float_mode_p ? 1 : 3); | 1561 *total = COSTS_N_INSNS (float_mode_p ? 1 : 3); |
1483 return false; | 1562 return false; |
1485 case LO_SUM: | 1564 case LO_SUM: |
1486 *total = set_src_cost (XEXP (x, 0), mode, speed); | 1565 *total = set_src_cost (XEXP (x, 0), mode, speed); |
1487 return true; | 1566 return true; |
1488 | 1567 |
1489 case LT: | 1568 case LT: |
1569 /* This is an SImode shift. */ | |
1570 if (outer_code == SET && GET_MODE (x) == DImode | |
1571 && GET_MODE (XEXP (x, 0)) == SImode) | |
1572 { | |
1573 *total = COSTS_N_INSNS (SINGLE_SHIFT_COST); | |
1574 return true; | |
1575 } | |
1576 /* Fall through. */ | |
1490 case LTU: | 1577 case LTU: |
1491 case LE: | 1578 case LE: |
1492 case LEU: | 1579 case LEU: |
1493 case GT: | 1580 case GT: |
1494 case GTU: | 1581 case GTU: |
1556 return false; | 1643 return false; |
1557 | 1644 |
1558 case MULT: | 1645 case MULT: |
1559 if (float_mode_p) | 1646 if (float_mode_p) |
1560 *total = tune_info->fp_mul[mode == DFmode]; | 1647 *total = tune_info->fp_mul[mode == DFmode]; |
1648 else if (!TARGET_MUL) | |
1649 /* Estimate the cost of a library call. */ | |
1650 *total = COSTS_N_INSNS (speed ? 32 : 6); | |
1561 else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD) | 1651 else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD) |
1562 *total = 3 * tune_info->int_mul[0] + COSTS_N_INSNS (2); | 1652 *total = 3 * tune_info->int_mul[0] + COSTS_N_INSNS (2); |
1563 else if (!speed) | 1653 else if (!speed) |
1564 *total = COSTS_N_INSNS (1); | 1654 *total = COSTS_N_INSNS (1); |
1565 else | 1655 else |
1576 } | 1666 } |
1577 /* Fall through. */ | 1667 /* Fall through. */ |
1578 | 1668 |
1579 case UDIV: | 1669 case UDIV: |
1580 case UMOD: | 1670 case UMOD: |
1581 if (speed) | 1671 if (!TARGET_DIV) |
1672 /* Estimate the cost of a library call. */ | |
1673 *total = COSTS_N_INSNS (speed ? 32 : 6); | |
1674 else if (speed) | |
1582 *total = tune_info->int_div[mode == DImode]; | 1675 *total = tune_info->int_div[mode == DImode]; |
1583 else | 1676 else |
1584 *total = COSTS_N_INSNS (1); | 1677 *total = COSTS_N_INSNS (1); |
1585 return false; | 1678 return false; |
1586 | 1679 |
1680 case ZERO_EXTEND: | |
1681 /* This is an SImode shift. */ | |
1682 if (GET_CODE (XEXP (x, 0)) == LSHIFTRT) | |
1683 { | |
1684 *total = COSTS_N_INSNS (SINGLE_SHIFT_COST); | |
1685 return true; | |
1686 } | |
1687 /* Fall through. */ | |
1587 case SIGN_EXTEND: | 1688 case SIGN_EXTEND: |
1588 case ZERO_EXTEND: | |
1589 *total = riscv_extend_cost (XEXP (x, 0), GET_CODE (x) == ZERO_EXTEND); | 1689 *total = riscv_extend_cost (XEXP (x, 0), GET_CODE (x) == ZERO_EXTEND); |
1590 return false; | 1690 return false; |
1591 | 1691 |
1592 case FLOAT: | 1692 case FLOAT: |
1593 case UNSIGNED_FLOAT: | 1693 case UNSIGNED_FLOAT: |
1781 if (src_code == MEM) | 1881 if (src_code == MEM) |
1782 return dbl_p ? "fld\t%0,%1" : "flw\t%0,%1"; | 1882 return dbl_p ? "fld\t%0,%1" : "flw\t%0,%1"; |
1783 } | 1883 } |
1784 gcc_unreachable (); | 1884 gcc_unreachable (); |
1785 } | 1885 } |
1886 | |
1887 const char * | |
1888 riscv_output_return () | |
1889 { | |
1890 if (cfun->machine->naked_p) | |
1891 return ""; | |
1892 | |
1893 return "ret"; | |
1894 } | |
1895 | |
1786 | 1896 |
1787 /* Return true if CMP1 is a suitable second operand for integer ordering | 1897 /* Return true if CMP1 is a suitable second operand for integer ordering |
1788 test CODE. See also the *sCC patterns in riscv.md. */ | 1898 test CODE. See also the *sCC patterns in riscv.md. */ |
1789 | 1899 |
1790 static bool | 1900 static bool |
1917 riscv_extend_comparands (rtx_code code, rtx *op0, rtx *op1) | 2027 riscv_extend_comparands (rtx_code code, rtx *op0, rtx *op1) |
1918 { | 2028 { |
1919 /* Comparisons consider all XLEN bits, so extend sub-XLEN values. */ | 2029 /* Comparisons consider all XLEN bits, so extend sub-XLEN values. */ |
1920 if (GET_MODE_SIZE (word_mode) > GET_MODE_SIZE (GET_MODE (*op0))) | 2030 if (GET_MODE_SIZE (word_mode) > GET_MODE_SIZE (GET_MODE (*op0))) |
1921 { | 2031 { |
1922 /* It is more profitable to zero-extend QImode values. */ | 2032 /* It is more profitable to zero-extend QImode values. But not if the |
1923 if (unsigned_condition (code) == code && GET_MODE (*op0) == QImode) | 2033 first operand has already been sign-extended, and the second one is |
2034 is a constant or has already been sign-extended also. */ | |
2035 if (unsigned_condition (code) == code | |
2036 && (GET_MODE (*op0) == QImode | |
2037 && ! (GET_CODE (*op0) == SUBREG | |
2038 && SUBREG_PROMOTED_VAR_P (*op0) | |
2039 && SUBREG_PROMOTED_SIGNED_P (*op0) | |
2040 && (CONST_INT_P (*op1) | |
2041 || (GET_CODE (*op1) == SUBREG | |
2042 && SUBREG_PROMOTED_VAR_P (*op1) | |
2043 && SUBREG_PROMOTED_SIGNED_P (*op1)))))) | |
1924 { | 2044 { |
1925 *op0 = gen_rtx_ZERO_EXTEND (word_mode, *op0); | 2045 *op0 = gen_rtx_ZERO_EXTEND (word_mode, *op0); |
1926 if (CONST_INT_P (*op1)) | 2046 if (CONST_INT_P (*op1)) |
1927 *op1 = GEN_INT ((uint8_t) INTVAL (*op1)); | 2047 *op1 = GEN_INT ((uint8_t) INTVAL (*op1)); |
1928 else | 2048 else |
2117 emit_jump_insn (gen_condjump (condition, label)); | 2237 emit_jump_insn (gen_condjump (condition, label)); |
2118 } | 2238 } |
2119 | 2239 |
2120 /* Implement TARGET_FUNCTION_ARG_BOUNDARY. Every parameter gets at | 2240 /* Implement TARGET_FUNCTION_ARG_BOUNDARY. Every parameter gets at |
2121 least PARM_BOUNDARY bits of alignment, but will be given anything up | 2241 least PARM_BOUNDARY bits of alignment, but will be given anything up |
2122 to STACK_BOUNDARY bits if the type requires it. */ | 2242 to PREFERRED_STACK_BOUNDARY bits if the type requires it. */ |
2123 | 2243 |
2124 static unsigned int | 2244 static unsigned int |
2125 riscv_function_arg_boundary (machine_mode mode, const_tree type) | 2245 riscv_function_arg_boundary (machine_mode mode, const_tree type) |
2126 { | 2246 { |
2127 unsigned int alignment; | 2247 unsigned int alignment; |
2130 if (type && !AGGREGATE_TYPE_P (type)) | 2250 if (type && !AGGREGATE_TYPE_P (type)) |
2131 alignment = TYPE_ALIGN (TYPE_MAIN_VARIANT (type)); | 2251 alignment = TYPE_ALIGN (TYPE_MAIN_VARIANT (type)); |
2132 else | 2252 else |
2133 alignment = type ? TYPE_ALIGN (type) : GET_MODE_ALIGNMENT (mode); | 2253 alignment = type ? TYPE_ALIGN (type) : GET_MODE_ALIGNMENT (mode); |
2134 | 2254 |
2135 return MIN (STACK_BOUNDARY, MAX (PARM_BOUNDARY, alignment)); | 2255 return MIN (PREFERRED_STACK_BOUNDARY, MAX (PARM_BOUNDARY, alignment)); |
2136 } | 2256 } |
2137 | 2257 |
2138 /* If MODE represents an argument that can be passed or returned in | 2258 /* If MODE represents an argument that can be passed or returned in |
2139 floating-point registers, return the number of registers, else 0. */ | 2259 floating-point registers, return the number of registers, else 0. */ |
2140 | 2260 |
2601 } | 2721 } |
2602 if (REG_PARM_STACK_SPACE (cfun->decl) == 0) | 2722 if (REG_PARM_STACK_SPACE (cfun->decl) == 0) |
2603 cfun->machine->varargs_size = gp_saved * UNITS_PER_WORD; | 2723 cfun->machine->varargs_size = gp_saved * UNITS_PER_WORD; |
2604 } | 2724 } |
2605 | 2725 |
2726 /* Handle an attribute requiring a FUNCTION_DECL; | |
2727 arguments as in struct attribute_spec.handler. */ | |
2728 static tree | |
2729 riscv_handle_fndecl_attribute (tree *node, tree name, | |
2730 tree args ATTRIBUTE_UNUSED, | |
2731 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs) | |
2732 { | |
2733 if (TREE_CODE (*node) != FUNCTION_DECL) | |
2734 { | |
2735 warning (OPT_Wattributes, "%qE attribute only applies to functions", | |
2736 name); | |
2737 *no_add_attrs = true; | |
2738 } | |
2739 | |
2740 return NULL_TREE; | |
2741 } | |
2742 | |
2743 /* Verify type based attributes. NODE is the what the attribute is being | |
2744 applied to. NAME is the attribute name. ARGS are the attribute args. | |
2745 FLAGS gives info about the context. NO_ADD_ATTRS should be set to true if | |
2746 the attribute should be ignored. */ | |
2747 | |
2748 static tree | |
2749 riscv_handle_type_attribute (tree *node ATTRIBUTE_UNUSED, tree name, tree args, | |
2750 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs) | |
2751 { | |
2752 /* Check for an argument. */ | |
2753 if (is_attribute_p ("interrupt", name)) | |
2754 { | |
2755 if (args) | |
2756 { | |
2757 tree cst = TREE_VALUE (args); | |
2758 const char *string; | |
2759 | |
2760 if (TREE_CODE (cst) != STRING_CST) | |
2761 { | |
2762 warning (OPT_Wattributes, | |
2763 "%qE attribute requires a string argument", | |
2764 name); | |
2765 *no_add_attrs = true; | |
2766 return NULL_TREE; | |
2767 } | |
2768 | |
2769 string = TREE_STRING_POINTER (cst); | |
2770 if (strcmp (string, "user") && strcmp (string, "supervisor") | |
2771 && strcmp (string, "machine")) | |
2772 { | |
2773 warning (OPT_Wattributes, | |
2774 "argument to %qE attribute is not \"user\", \"supervisor\", or \"machine\"", | |
2775 name); | |
2776 *no_add_attrs = true; | |
2777 } | |
2778 } | |
2779 } | |
2780 | |
2781 return NULL_TREE; | |
2782 } | |
2783 | |
2784 /* Return true if function TYPE is an interrupt function. */ | |
2785 static bool | |
2786 riscv_interrupt_type_p (tree type) | |
2787 { | |
2788 return lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type)) != NULL; | |
2789 } | |
2790 | |
2791 /* Return true if FUNC is a naked function. */ | |
2792 static bool | |
2793 riscv_naked_function_p (tree func) | |
2794 { | |
2795 tree func_decl = func; | |
2796 if (func == NULL_TREE) | |
2797 func_decl = current_function_decl; | |
2798 return NULL_TREE != lookup_attribute ("naked", DECL_ATTRIBUTES (func_decl)); | |
2799 } | |
2800 | |
2801 /* Implement TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS. */ | |
2802 static bool | |
2803 riscv_allocate_stack_slots_for_args () | |
2804 { | |
2805 /* Naked functions should not allocate stack slots for arguments. */ | |
2806 return !riscv_naked_function_p (current_function_decl); | |
2807 } | |
2808 | |
2809 /* Implement TARGET_WARN_FUNC_RETURN. */ | |
2810 static bool | |
2811 riscv_warn_func_return (tree decl) | |
2812 { | |
2813 /* Naked functions are implemented entirely in assembly, including the | |
2814 return sequence, so suppress warnings about this. */ | |
2815 return !riscv_naked_function_p (decl); | |
2816 } | |
2817 | |
2606 /* Implement TARGET_EXPAND_BUILTIN_VA_START. */ | 2818 /* Implement TARGET_EXPAND_BUILTIN_VA_START. */ |
2607 | 2819 |
2608 static void | 2820 static void |
2609 riscv_va_start (tree valist, rtx nextarg) | 2821 riscv_va_start (tree valist, rtx nextarg) |
2610 { | 2822 { |
2622 rtx reg = RISCV_PROLOGUE_TEMP (Pmode); | 2834 rtx reg = RISCV_PROLOGUE_TEMP (Pmode); |
2623 riscv_emit_move (reg, addr); | 2835 riscv_emit_move (reg, addr); |
2624 return reg; | 2836 return reg; |
2625 } | 2837 } |
2626 return addr; | 2838 return addr; |
2839 } | |
2840 | |
2841 /* Emit straight-line code to move LENGTH bytes from SRC to DEST. | |
2842 Assume that the areas do not overlap. */ | |
2843 | |
2844 static void | |
2845 riscv_block_move_straight (rtx dest, rtx src, HOST_WIDE_INT length) | |
2846 { | |
2847 HOST_WIDE_INT offset, delta; | |
2848 unsigned HOST_WIDE_INT bits; | |
2849 int i; | |
2850 enum machine_mode mode; | |
2851 rtx *regs; | |
2852 | |
2853 bits = MAX (BITS_PER_UNIT, | |
2854 MIN (BITS_PER_WORD, MIN (MEM_ALIGN (src), MEM_ALIGN (dest)))); | |
2855 | |
2856 mode = mode_for_size (bits, MODE_INT, 0).require (); | |
2857 delta = bits / BITS_PER_UNIT; | |
2858 | |
2859 /* Allocate a buffer for the temporary registers. */ | |
2860 regs = XALLOCAVEC (rtx, length / delta); | |
2861 | |
2862 /* Load as many BITS-sized chunks as possible. Use a normal load if | |
2863 the source has enough alignment, otherwise use left/right pairs. */ | |
2864 for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++) | |
2865 { | |
2866 regs[i] = gen_reg_rtx (mode); | |
2867 riscv_emit_move (regs[i], adjust_address (src, mode, offset)); | |
2868 } | |
2869 | |
2870 /* Copy the chunks to the destination. */ | |
2871 for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++) | |
2872 riscv_emit_move (adjust_address (dest, mode, offset), regs[i]); | |
2873 | |
2874 /* Mop up any left-over bytes. */ | |
2875 if (offset < length) | |
2876 { | |
2877 src = adjust_address (src, BLKmode, offset); | |
2878 dest = adjust_address (dest, BLKmode, offset); | |
2879 move_by_pieces (dest, src, length - offset, | |
2880 MIN (MEM_ALIGN (src), MEM_ALIGN (dest)), 0); | |
2881 } | |
2882 } | |
2883 | |
2884 /* Helper function for doing a loop-based block operation on memory | |
2885 reference MEM. Each iteration of the loop will operate on LENGTH | |
2886 bytes of MEM. | |
2887 | |
2888 Create a new base register for use within the loop and point it to | |
2889 the start of MEM. Create a new memory reference that uses this | |
2890 register. Store them in *LOOP_REG and *LOOP_MEM respectively. */ | |
2891 | |
2892 static void | |
2893 riscv_adjust_block_mem (rtx mem, HOST_WIDE_INT length, | |
2894 rtx *loop_reg, rtx *loop_mem) | |
2895 { | |
2896 *loop_reg = copy_addr_to_reg (XEXP (mem, 0)); | |
2897 | |
2898 /* Although the new mem does not refer to a known location, | |
2899 it does keep up to LENGTH bytes of alignment. */ | |
2900 *loop_mem = change_address (mem, BLKmode, *loop_reg); | |
2901 set_mem_align (*loop_mem, MIN (MEM_ALIGN (mem), length * BITS_PER_UNIT)); | |
2902 } | |
2903 | |
2904 /* Move LENGTH bytes from SRC to DEST using a loop that moves BYTES_PER_ITER | |
2905 bytes at a time. LENGTH must be at least BYTES_PER_ITER. Assume that | |
2906 the memory regions do not overlap. */ | |
2907 | |
2908 static void | |
2909 riscv_block_move_loop (rtx dest, rtx src, HOST_WIDE_INT length, | |
2910 HOST_WIDE_INT bytes_per_iter) | |
2911 { | |
2912 rtx label, src_reg, dest_reg, final_src, test; | |
2913 HOST_WIDE_INT leftover; | |
2914 | |
2915 leftover = length % bytes_per_iter; | |
2916 length -= leftover; | |
2917 | |
2918 /* Create registers and memory references for use within the loop. */ | |
2919 riscv_adjust_block_mem (src, bytes_per_iter, &src_reg, &src); | |
2920 riscv_adjust_block_mem (dest, bytes_per_iter, &dest_reg, &dest); | |
2921 | |
2922 /* Calculate the value that SRC_REG should have after the last iteration | |
2923 of the loop. */ | |
2924 final_src = expand_simple_binop (Pmode, PLUS, src_reg, GEN_INT (length), | |
2925 0, 0, OPTAB_WIDEN); | |
2926 | |
2927 /* Emit the start of the loop. */ | |
2928 label = gen_label_rtx (); | |
2929 emit_label (label); | |
2930 | |
2931 /* Emit the loop body. */ | |
2932 riscv_block_move_straight (dest, src, bytes_per_iter); | |
2933 | |
2934 /* Move on to the next block. */ | |
2935 riscv_emit_move (src_reg, plus_constant (Pmode, src_reg, bytes_per_iter)); | |
2936 riscv_emit_move (dest_reg, plus_constant (Pmode, dest_reg, bytes_per_iter)); | |
2937 | |
2938 /* Emit the loop condition. */ | |
2939 test = gen_rtx_NE (VOIDmode, src_reg, final_src); | |
2940 if (Pmode == DImode) | |
2941 emit_jump_insn (gen_cbranchdi4 (test, src_reg, final_src, label)); | |
2942 else | |
2943 emit_jump_insn (gen_cbranchsi4 (test, src_reg, final_src, label)); | |
2944 | |
2945 /* Mop up any left-over bytes. */ | |
2946 if (leftover) | |
2947 riscv_block_move_straight (dest, src, leftover); | |
2948 else | |
2949 emit_insn(gen_nop ()); | |
2950 } | |
2951 | |
2952 /* Expand a movmemsi instruction, which copies LENGTH bytes from | |
2953 memory reference SRC to memory reference DEST. */ | |
2954 | |
2955 bool | |
2956 riscv_expand_block_move (rtx dest, rtx src, rtx length) | |
2957 { | |
2958 if (CONST_INT_P (length)) | |
2959 { | |
2960 HOST_WIDE_INT factor, align; | |
2961 | |
2962 align = MIN (MIN (MEM_ALIGN (src), MEM_ALIGN (dest)), BITS_PER_WORD); | |
2963 factor = BITS_PER_WORD / align; | |
2964 | |
2965 if (optimize_function_for_size_p (cfun) | |
2966 && INTVAL (length) * factor * UNITS_PER_WORD > MOVE_RATIO (false)) | |
2967 return false; | |
2968 | |
2969 if (INTVAL (length) <= RISCV_MAX_MOVE_BYTES_STRAIGHT / factor) | |
2970 { | |
2971 riscv_block_move_straight (dest, src, INTVAL (length)); | |
2972 return true; | |
2973 } | |
2974 else if (optimize && align >= BITS_PER_WORD) | |
2975 { | |
2976 unsigned min_iter_words | |
2977 = RISCV_MAX_MOVE_BYTES_PER_LOOP_ITER / UNITS_PER_WORD; | |
2978 unsigned iter_words = min_iter_words; | |
2979 HOST_WIDE_INT bytes = INTVAL (length), words = bytes / UNITS_PER_WORD; | |
2980 | |
2981 /* Lengthen the loop body if it shortens the tail. */ | |
2982 for (unsigned i = min_iter_words; i < min_iter_words * 2 - 1; i++) | |
2983 { | |
2984 unsigned cur_cost = iter_words + words % iter_words; | |
2985 unsigned new_cost = i + words % i; | |
2986 if (new_cost <= cur_cost) | |
2987 iter_words = i; | |
2988 } | |
2989 | |
2990 riscv_block_move_loop (dest, src, bytes, iter_words * UNITS_PER_WORD); | |
2991 return true; | |
2992 } | |
2993 } | |
2994 return false; | |
2627 } | 2995 } |
2628 | 2996 |
2629 /* Print symbolic operand OP, which is part of a HIGH or LO_SUM | 2997 /* Print symbolic operand OP, which is part of a HIGH or LO_SUM |
2630 in context CONTEXT. HI_RELOC indicates a high-part reloc. */ | 2998 in context CONTEXT. HI_RELOC indicates a high-part reloc. */ |
2631 | 2999 |
2715 any outermost HIGH. | 3083 any outermost HIGH. |
2716 'R' Print the low-part relocation associated with OP. | 3084 'R' Print the low-part relocation associated with OP. |
2717 'C' Print the integer branch condition for comparison OP. | 3085 'C' Print the integer branch condition for comparison OP. |
2718 'A' Print the atomic operation suffix for memory model OP. | 3086 'A' Print the atomic operation suffix for memory model OP. |
2719 'F' Print a FENCE if the memory model requires a release. | 3087 'F' Print a FENCE if the memory model requires a release. |
2720 'z' Print x0 if OP is zero, otherwise print OP normally. */ | 3088 'z' Print x0 if OP is zero, otherwise print OP normally. |
3089 'i' Print i if the operand is not a register. */ | |
2721 | 3090 |
2722 static void | 3091 static void |
2723 riscv_print_operand (FILE *file, rtx op, int letter) | 3092 riscv_print_operand (FILE *file, rtx op, int letter) |
2724 { | 3093 { |
2725 machine_mode mode = GET_MODE (op); | 3094 machine_mode mode = GET_MODE (op); |
2748 break; | 3117 break; |
2749 | 3118 |
2750 case 'F': | 3119 case 'F': |
2751 if (riscv_memmodel_needs_release_fence ((enum memmodel) INTVAL (op))) | 3120 if (riscv_memmodel_needs_release_fence ((enum memmodel) INTVAL (op))) |
2752 fputs ("fence iorw,ow; ", file); | 3121 fputs ("fence iorw,ow; ", file); |
3122 break; | |
3123 | |
3124 case 'i': | |
3125 if (code != REG) | |
3126 fputs ("i", file); | |
2753 break; | 3127 break; |
2754 | 3128 |
2755 default: | 3129 default: |
2756 switch (code) | 3130 switch (code) |
2757 { | 3131 { |
2833 } | 3207 } |
2834 | 3208 |
2835 return riscv_size_ok_for_small_data_p (int_size_in_bytes (TREE_TYPE (x))); | 3209 return riscv_size_ok_for_small_data_p (int_size_in_bytes (TREE_TYPE (x))); |
2836 } | 3210 } |
2837 | 3211 |
3212 /* Switch to the appropriate section for output of DECL. */ | |
3213 | |
3214 static section * | |
3215 riscv_select_section (tree decl, int reloc, | |
3216 unsigned HOST_WIDE_INT align) | |
3217 { | |
3218 switch (categorize_decl_for_section (decl, reloc)) | |
3219 { | |
3220 case SECCAT_SRODATA: | |
3221 return get_named_section (decl, ".srodata", reloc); | |
3222 | |
3223 default: | |
3224 return default_elf_select_section (decl, reloc, align); | |
3225 } | |
3226 } | |
3227 | |
2838 /* Return a section for X, handling small data. */ | 3228 /* Return a section for X, handling small data. */ |
2839 | 3229 |
2840 static section * | 3230 static section * |
2841 riscv_elf_select_rtx_section (machine_mode mode, rtx x, | 3231 riscv_elf_select_rtx_section (machine_mode mode, rtx x, |
2842 unsigned HOST_WIDE_INT align) | 3232 unsigned HOST_WIDE_INT align) |
2902 return true; | 3292 return true; |
2903 | 3293 |
2904 if (regno == RETURN_ADDR_REGNUM && crtl->calls_eh_return) | 3294 if (regno == RETURN_ADDR_REGNUM && crtl->calls_eh_return) |
2905 return true; | 3295 return true; |
2906 | 3296 |
3297 /* If this is an interrupt handler, then must save extra registers. */ | |
3298 if (cfun->machine->interrupt_handler_p) | |
3299 { | |
3300 /* zero register is always zero. */ | |
3301 if (regno == GP_REG_FIRST) | |
3302 return false; | |
3303 | |
3304 /* The function will return the stack pointer to its original value. */ | |
3305 if (regno == STACK_POINTER_REGNUM) | |
3306 return false; | |
3307 | |
3308 /* By convention, we assume that gp and tp are safe. */ | |
3309 if (regno == GP_REGNUM || regno == THREAD_POINTER_REGNUM) | |
3310 return false; | |
3311 | |
3312 /* We must save every register used in this function. If this is not a | |
3313 leaf function, then we must save all temporary registers. */ | |
3314 if (df_regs_ever_live_p (regno) | |
3315 || (!crtl->is_leaf && call_used_regs[regno])) | |
3316 return true; | |
3317 } | |
3318 | |
2907 return false; | 3319 return false; |
2908 } | 3320 } |
2909 | 3321 |
2910 /* Determine whether to call GPR save/restore routines. */ | 3322 /* Determine whether to call GPR save/restore routines. */ |
2911 static bool | 3323 static bool |
2912 riscv_use_save_libcall (const struct riscv_frame_info *frame) | 3324 riscv_use_save_libcall (const struct riscv_frame_info *frame) |
2913 { | 3325 { |
2914 if (!TARGET_SAVE_RESTORE || crtl->calls_eh_return || frame_pointer_needed) | 3326 if (!TARGET_SAVE_RESTORE || crtl->calls_eh_return || frame_pointer_needed |
3327 || cfun->machine->interrupt_handler_p) | |
2915 return false; | 3328 return false; |
2916 | 3329 |
2917 return frame->save_libcall_adjustment != 0; | 3330 return frame->save_libcall_adjustment != 0; |
2918 } | 3331 } |
2919 | 3332 |
2968 | 3381 |
2969 Dynamic stack allocations such as alloca insert data at point P. | 3382 Dynamic stack allocations such as alloca insert data at point P. |
2970 They decrease stack_pointer_rtx but leave frame_pointer_rtx and | 3383 They decrease stack_pointer_rtx but leave frame_pointer_rtx and |
2971 hard_frame_pointer_rtx unchanged. */ | 3384 hard_frame_pointer_rtx unchanged. */ |
2972 | 3385 |
3386 static HOST_WIDE_INT riscv_first_stack_step (struct riscv_frame_info *frame); | |
3387 | |
2973 static void | 3388 static void |
2974 riscv_compute_frame_info (void) | 3389 riscv_compute_frame_info (void) |
2975 { | 3390 { |
2976 struct riscv_frame_info *frame; | 3391 struct riscv_frame_info *frame; |
2977 HOST_WIDE_INT offset; | 3392 HOST_WIDE_INT offset; |
3393 bool interrupt_save_t1 = false; | |
2978 unsigned int regno, i, num_x_saved = 0, num_f_saved = 0; | 3394 unsigned int regno, i, num_x_saved = 0, num_f_saved = 0; |
2979 | 3395 |
2980 frame = &cfun->machine->frame; | 3396 frame = &cfun->machine->frame; |
3397 | |
3398 /* In an interrupt function, if we have a large frame, then we need to | |
3399 save/restore t1. We check for this before clearing the frame struct. */ | |
3400 if (cfun->machine->interrupt_handler_p) | |
3401 { | |
3402 HOST_WIDE_INT step1 = riscv_first_stack_step (frame); | |
3403 if (! SMALL_OPERAND (frame->total_size - step1)) | |
3404 interrupt_save_t1 = true; | |
3405 } | |
3406 | |
2981 memset (frame, 0, sizeof (*frame)); | 3407 memset (frame, 0, sizeof (*frame)); |
2982 | 3408 |
2983 /* Find out which GPRs we need to save. */ | 3409 if (!cfun->machine->naked_p) |
2984 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++) | 3410 { |
2985 if (riscv_save_reg_p (regno)) | 3411 /* Find out which GPRs we need to save. */ |
2986 frame->mask |= 1 << (regno - GP_REG_FIRST), num_x_saved++; | 3412 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++) |
2987 | 3413 if (riscv_save_reg_p (regno) |
2988 /* If this function calls eh_return, we must also save and restore the | 3414 || (interrupt_save_t1 && (regno == T1_REGNUM))) |
2989 EH data registers. */ | 3415 frame->mask |= 1 << (regno - GP_REG_FIRST), num_x_saved++; |
2990 if (crtl->calls_eh_return) | 3416 |
2991 for (i = 0; (regno = EH_RETURN_DATA_REGNO (i)) != INVALID_REGNUM; i++) | 3417 /* If this function calls eh_return, we must also save and restore the |
2992 frame->mask |= 1 << (regno - GP_REG_FIRST), num_x_saved++; | 3418 EH data registers. */ |
2993 | 3419 if (crtl->calls_eh_return) |
2994 /* Find out which FPRs we need to save. This loop must iterate over | 3420 for (i = 0; (regno = EH_RETURN_DATA_REGNO (i)) != INVALID_REGNUM; i++) |
2995 the same space as its companion in riscv_for_each_saved_reg. */ | 3421 frame->mask |= 1 << (regno - GP_REG_FIRST), num_x_saved++; |
2996 if (TARGET_HARD_FLOAT) | 3422 |
2997 for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++) | 3423 /* Find out which FPRs we need to save. This loop must iterate over |
2998 if (riscv_save_reg_p (regno)) | 3424 the same space as its companion in riscv_for_each_saved_reg. */ |
2999 frame->fmask |= 1 << (regno - FP_REG_FIRST), num_f_saved++; | 3425 if (TARGET_HARD_FLOAT) |
3426 for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++) | |
3427 if (riscv_save_reg_p (regno)) | |
3428 frame->fmask |= 1 << (regno - FP_REG_FIRST), num_f_saved++; | |
3429 } | |
3000 | 3430 |
3001 /* At the bottom of the frame are any outgoing stack arguments. */ | 3431 /* At the bottom of the frame are any outgoing stack arguments. */ |
3002 offset = crtl->outgoing_args_size; | 3432 offset = RISCV_STACK_ALIGN (crtl->outgoing_args_size); |
3003 /* Next are local stack variables. */ | 3433 /* Next are local stack variables. */ |
3004 offset += RISCV_STACK_ALIGN (get_frame_size ()); | 3434 offset += RISCV_STACK_ALIGN (get_frame_size ()); |
3005 /* The virtual frame pointer points above the local variables. */ | 3435 /* The virtual frame pointer points above the local variables. */ |
3006 frame->frame_pointer_offset = offset; | 3436 frame->frame_pointer_offset = offset; |
3007 /* Next are the callee-saved FPRs. */ | 3437 /* Next are the callee-saved FPRs. */ |
3014 unsigned x_save_size = RISCV_STACK_ALIGN (num_x_saved * UNITS_PER_WORD); | 3444 unsigned x_save_size = RISCV_STACK_ALIGN (num_x_saved * UNITS_PER_WORD); |
3015 unsigned num_save_restore = 1 + riscv_save_libcall_count (frame->mask); | 3445 unsigned num_save_restore = 1 + riscv_save_libcall_count (frame->mask); |
3016 | 3446 |
3017 /* Only use save/restore routines if they don't alter the stack size. */ | 3447 /* Only use save/restore routines if they don't alter the stack size. */ |
3018 if (RISCV_STACK_ALIGN (num_save_restore * UNITS_PER_WORD) == x_save_size) | 3448 if (RISCV_STACK_ALIGN (num_save_restore * UNITS_PER_WORD) == x_save_size) |
3019 frame->save_libcall_adjustment = x_save_size; | 3449 { |
3450 /* Libcall saves/restores 3 registers at once, so we need to | |
3451 allocate 12 bytes for callee-saved register. */ | |
3452 if (TARGET_RVE) | |
3453 x_save_size = 3 * UNITS_PER_WORD; | |
3454 | |
3455 frame->save_libcall_adjustment = x_save_size; | |
3456 } | |
3020 | 3457 |
3021 offset += x_save_size; | 3458 offset += x_save_size; |
3022 } | 3459 } |
3023 frame->gp_sp_offset = offset - UNITS_PER_WORD; | 3460 frame->gp_sp_offset = offset - UNITS_PER_WORD; |
3024 /* The hard frame pointer points above the callee-saved GPRs. */ | 3461 /* The hard frame pointer points above the callee-saved GPRs. */ |
3025 frame->hard_frame_pointer_offset = offset; | 3462 frame->hard_frame_pointer_offset = offset; |
3026 /* Above the hard frame pointer is the callee-allocated varags save area. */ | 3463 /* Above the hard frame pointer is the callee-allocated varags save area. */ |
3027 offset += RISCV_STACK_ALIGN (cfun->machine->varargs_size); | 3464 offset += RISCV_STACK_ALIGN (cfun->machine->varargs_size); |
3028 frame->arg_pointer_offset = offset; | |
3029 /* Next is the callee-allocated area for pretend stack arguments. */ | 3465 /* Next is the callee-allocated area for pretend stack arguments. */ |
3030 offset += crtl->args.pretend_args_size; | 3466 offset += RISCV_STACK_ALIGN (crtl->args.pretend_args_size); |
3467 /* Arg pointer must be below pretend args, but must be above alignment | |
3468 padding. */ | |
3469 frame->arg_pointer_offset = offset - crtl->args.pretend_args_size; | |
3031 frame->total_size = offset; | 3470 frame->total_size = offset; |
3032 /* Next points the incoming stack pointer and any incoming arguments. */ | 3471 /* Next points the incoming stack pointer and any incoming arguments. */ |
3033 | 3472 |
3034 /* Only use save/restore routines when the GPRs are atop the frame. */ | 3473 /* Only use save/restore routines when the GPRs are atop the frame. */ |
3035 if (frame->hard_frame_pointer_offset != frame->total_size) | 3474 if (frame->hard_frame_pointer_offset != frame->total_size) |
3121 /* Call FN for each register that is saved by the current function. | 3560 /* Call FN for each register that is saved by the current function. |
3122 SP_OFFSET is the offset of the current stack pointer from the start | 3561 SP_OFFSET is the offset of the current stack pointer from the start |
3123 of the frame. */ | 3562 of the frame. */ |
3124 | 3563 |
3125 static void | 3564 static void |
3126 riscv_for_each_saved_reg (HOST_WIDE_INT sp_offset, riscv_save_restore_fn fn) | 3565 riscv_for_each_saved_reg (HOST_WIDE_INT sp_offset, riscv_save_restore_fn fn, |
3566 bool epilogue, bool maybe_eh_return) | |
3127 { | 3567 { |
3128 HOST_WIDE_INT offset; | 3568 HOST_WIDE_INT offset; |
3129 | 3569 |
3130 /* Save the link register and s-registers. */ | 3570 /* Save the link register and s-registers. */ |
3131 offset = cfun->machine->frame.gp_sp_offset - sp_offset; | 3571 offset = cfun->machine->frame.gp_sp_offset - sp_offset; |
3132 for (int regno = GP_REG_FIRST; regno <= GP_REG_LAST-1; regno++) | 3572 for (unsigned int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++) |
3133 if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST)) | 3573 if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST)) |
3134 { | 3574 { |
3135 riscv_save_restore_reg (word_mode, regno, offset, fn); | 3575 bool handle_reg = TRUE; |
3576 | |
3577 /* If this is a normal return in a function that calls the eh_return | |
3578 builtin, then do not restore the eh return data registers as that | |
3579 would clobber the return value. But we do still need to save them | |
3580 in the prologue, and restore them for an exception return, so we | |
3581 need special handling here. */ | |
3582 if (epilogue && !maybe_eh_return && crtl->calls_eh_return) | |
3583 { | |
3584 unsigned int i, regnum; | |
3585 | |
3586 for (i = 0; (regnum = EH_RETURN_DATA_REGNO (i)) != INVALID_REGNUM; | |
3587 i++) | |
3588 if (regno == regnum) | |
3589 { | |
3590 handle_reg = FALSE; | |
3591 break; | |
3592 } | |
3593 } | |
3594 | |
3595 if (handle_reg) | |
3596 riscv_save_restore_reg (word_mode, regno, offset, fn); | |
3136 offset -= UNITS_PER_WORD; | 3597 offset -= UNITS_PER_WORD; |
3137 } | 3598 } |
3138 | 3599 |
3139 /* This loop must iterate over the same space as its companion in | 3600 /* This loop must iterate over the same space as its companion in |
3140 riscv_compute_frame_info. */ | 3601 riscv_compute_frame_info. */ |
3141 offset = cfun->machine->frame.fp_sp_offset - sp_offset; | 3602 offset = cfun->machine->frame.fp_sp_offset - sp_offset; |
3142 for (int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++) | 3603 for (unsigned int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++) |
3143 if (BITSET_P (cfun->machine->frame.fmask, regno - FP_REG_FIRST)) | 3604 if (BITSET_P (cfun->machine->frame.fmask, regno - FP_REG_FIRST)) |
3144 { | 3605 { |
3145 machine_mode mode = TARGET_DOUBLE_FLOAT ? DFmode : SFmode; | 3606 machine_mode mode = TARGET_DOUBLE_FLOAT ? DFmode : SFmode; |
3146 | 3607 |
3147 riscv_save_restore_reg (mode, regno, offset, fn); | 3608 riscv_save_restore_reg (mode, regno, offset, fn); |
3185 return s; | 3646 return s; |
3186 } | 3647 } |
3187 | 3648 |
3188 /* For stack frames that can't be allocated with a single ADDI instruction, | 3649 /* For stack frames that can't be allocated with a single ADDI instruction, |
3189 compute the best value to initially allocate. It must at a minimum | 3650 compute the best value to initially allocate. It must at a minimum |
3190 allocate enough space to spill the callee-saved registers. */ | 3651 allocate enough space to spill the callee-saved registers. If TARGET_RVC, |
3652 try to pick a value that will allow compression of the register saves | |
3653 without adding extra instructions. */ | |
3191 | 3654 |
3192 static HOST_WIDE_INT | 3655 static HOST_WIDE_INT |
3193 riscv_first_stack_step (struct riscv_frame_info *frame) | 3656 riscv_first_stack_step (struct riscv_frame_info *frame) |
3194 { | 3657 { |
3195 HOST_WIDE_INT min_first_step = frame->total_size - frame->fp_sp_offset; | |
3196 HOST_WIDE_INT max_first_step = IMM_REACH / 2 - STACK_BOUNDARY / 8; | |
3197 | |
3198 if (SMALL_OPERAND (frame->total_size)) | 3658 if (SMALL_OPERAND (frame->total_size)) |
3199 return frame->total_size; | 3659 return frame->total_size; |
3200 | 3660 |
3661 HOST_WIDE_INT min_first_step = | |
3662 RISCV_STACK_ALIGN (frame->total_size - frame->fp_sp_offset); | |
3663 HOST_WIDE_INT max_first_step = IMM_REACH / 2 - PREFERRED_STACK_BOUNDARY / 8; | |
3664 HOST_WIDE_INT min_second_step = frame->total_size - max_first_step; | |
3665 gcc_assert (min_first_step <= max_first_step); | |
3666 | |
3201 /* As an optimization, use the least-significant bits of the total frame | 3667 /* As an optimization, use the least-significant bits of the total frame |
3202 size, so that the second adjustment step is just LUI + ADD. */ | 3668 size, so that the second adjustment step is just LUI + ADD. */ |
3203 if (!SMALL_OPERAND (frame->total_size - max_first_step) | 3669 if (!SMALL_OPERAND (min_second_step) |
3204 && frame->total_size % IMM_REACH < IMM_REACH / 2 | 3670 && frame->total_size % IMM_REACH < IMM_REACH / 2 |
3205 && frame->total_size % IMM_REACH >= min_first_step) | 3671 && frame->total_size % IMM_REACH >= min_first_step) |
3206 return frame->total_size % IMM_REACH; | 3672 return frame->total_size % IMM_REACH; |
3207 | 3673 |
3208 gcc_assert (min_first_step <= max_first_step); | 3674 if (TARGET_RVC) |
3675 { | |
3676 /* If we need two subtracts, and one is small enough to allow compressed | |
3677 loads and stores, then put that one first. */ | |
3678 if (IN_RANGE (min_second_step, 0, | |
3679 (TARGET_64BIT ? SDSP_REACH : SWSP_REACH))) | |
3680 return MAX (min_second_step, min_first_step); | |
3681 | |
3682 /* If we need LUI + ADDI + ADD for the second adjustment step, then start | |
3683 with the minimum first step, so that we can get compressed loads and | |
3684 stores. */ | |
3685 else if (!SMALL_OPERAND (min_second_step)) | |
3686 return min_first_step; | |
3687 } | |
3688 | |
3209 return max_first_step; | 3689 return max_first_step; |
3210 } | 3690 } |
3211 | 3691 |
3212 static rtx | 3692 static rtx |
3213 riscv_adjust_libcall_cfi_prologue () | 3693 riscv_adjust_libcall_cfi_prologue () |
3215 rtx dwarf = NULL_RTX; | 3695 rtx dwarf = NULL_RTX; |
3216 rtx adjust_sp_rtx, reg, mem, insn; | 3696 rtx adjust_sp_rtx, reg, mem, insn; |
3217 int saved_size = cfun->machine->frame.save_libcall_adjustment; | 3697 int saved_size = cfun->machine->frame.save_libcall_adjustment; |
3218 int offset; | 3698 int offset; |
3219 | 3699 |
3220 for (int regno = GP_REG_FIRST; regno <= GP_REG_LAST-1; regno++) | 3700 for (int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++) |
3221 if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST)) | 3701 if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST)) |
3222 { | 3702 { |
3223 /* The save order is ra, s0, s1, s2 to s11. */ | 3703 /* The save order is ra, s0, s1, s2 to s11. */ |
3224 if (regno == RETURN_ADDR_REGNUM) | 3704 if (regno == RETURN_ADDR_REGNUM) |
3225 offset = saved_size - UNITS_PER_WORD; | 3705 offset = saved_size - UNITS_PER_WORD; |
3267 rtx insn; | 3747 rtx insn; |
3268 | 3748 |
3269 if (flag_stack_usage_info) | 3749 if (flag_stack_usage_info) |
3270 current_function_static_stack_size = size; | 3750 current_function_static_stack_size = size; |
3271 | 3751 |
3752 if (cfun->machine->naked_p) | |
3753 return; | |
3754 | |
3272 /* When optimizing for size, call a subroutine to save the registers. */ | 3755 /* When optimizing for size, call a subroutine to save the registers. */ |
3273 if (riscv_use_save_libcall (frame)) | 3756 if (riscv_use_save_libcall (frame)) |
3274 { | 3757 { |
3275 rtx dwarf = NULL_RTX; | 3758 rtx dwarf = NULL_RTX; |
3276 dwarf = riscv_adjust_libcall_cfi_prologue (); | 3759 dwarf = riscv_adjust_libcall_cfi_prologue (); |
3291 insn = gen_add3_insn (stack_pointer_rtx, | 3774 insn = gen_add3_insn (stack_pointer_rtx, |
3292 stack_pointer_rtx, | 3775 stack_pointer_rtx, |
3293 GEN_INT (-step1)); | 3776 GEN_INT (-step1)); |
3294 RTX_FRAME_RELATED_P (emit_insn (insn)) = 1; | 3777 RTX_FRAME_RELATED_P (emit_insn (insn)) = 1; |
3295 size -= step1; | 3778 size -= step1; |
3296 riscv_for_each_saved_reg (size, riscv_save_reg); | 3779 riscv_for_each_saved_reg (size, riscv_save_reg, false, false); |
3297 } | 3780 } |
3298 | 3781 |
3299 frame->mask = mask; /* Undo the above fib. */ | 3782 frame->mask = mask; /* Undo the above fib. */ |
3300 | 3783 |
3301 /* Set up the frame pointer, if we're using one. */ | 3784 /* Set up the frame pointer, if we're using one. */ |
3343 adjust_sp_rtx = gen_add3_insn (stack_pointer_rtx, | 3826 adjust_sp_rtx = gen_add3_insn (stack_pointer_rtx, |
3344 stack_pointer_rtx, GEN_INT (saved_size)); | 3827 stack_pointer_rtx, GEN_INT (saved_size)); |
3345 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, adjust_sp_rtx, | 3828 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, adjust_sp_rtx, |
3346 dwarf); | 3829 dwarf); |
3347 | 3830 |
3348 for (int regno = GP_REG_FIRST; regno <= GP_REG_LAST-1; regno++) | 3831 for (int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++) |
3349 if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST)) | 3832 if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST)) |
3350 { | 3833 { |
3351 reg = gen_rtx_REG (SImode, regno); | 3834 reg = gen_rtx_REG (SImode, regno); |
3352 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf); | 3835 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf); |
3353 } | 3836 } |
3354 | 3837 |
3355 return dwarf; | 3838 return dwarf; |
3356 } | 3839 } |
3357 | 3840 |
3358 /* Expand an "epilogue" or "sibcall_epilogue" pattern; SIBCALL_P | 3841 /* Expand an "epilogue", "sibcall_epilogue", or "eh_return_internal" pattern; |
3359 says which. */ | 3842 style says which. */ |
3360 | 3843 |
3361 void | 3844 void |
3362 riscv_expand_epilogue (bool sibcall_p) | 3845 riscv_expand_epilogue (int style) |
3363 { | 3846 { |
3364 /* Split the frame into two. STEP1 is the amount of stack we should | 3847 /* Split the frame into two. STEP1 is the amount of stack we should |
3365 deallocate before restoring the registers. STEP2 is the amount we | 3848 deallocate before restoring the registers. STEP2 is the amount we |
3366 should deallocate afterwards. | 3849 should deallocate afterwards. |
3367 | 3850 |
3368 Start off by assuming that no registers need to be restored. */ | 3851 Start off by assuming that no registers need to be restored. */ |
3369 struct riscv_frame_info *frame = &cfun->machine->frame; | 3852 struct riscv_frame_info *frame = &cfun->machine->frame; |
3370 unsigned mask = frame->mask; | 3853 unsigned mask = frame->mask; |
3371 HOST_WIDE_INT step1 = frame->total_size; | 3854 HOST_WIDE_INT step1 = frame->total_size; |
3372 HOST_WIDE_INT step2 = 0; | 3855 HOST_WIDE_INT step2 = 0; |
3373 bool use_restore_libcall = !sibcall_p && riscv_use_save_libcall (frame); | 3856 bool use_restore_libcall = ((style == NORMAL_RETURN) |
3857 && riscv_use_save_libcall (frame)); | |
3374 rtx ra = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); | 3858 rtx ra = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); |
3375 rtx insn; | 3859 rtx insn; |
3376 | 3860 |
3377 /* We need to add memory barrier to prevent read from deallocated stack. */ | 3861 /* We need to add memory barrier to prevent read from deallocated stack. */ |
3378 bool need_barrier_p = (get_frame_size () | 3862 bool need_barrier_p = (get_frame_size () |
3379 + cfun->machine->frame.arg_pointer_offset) != 0; | 3863 + cfun->machine->frame.arg_pointer_offset) != 0; |
3380 | 3864 |
3381 if (!sibcall_p && riscv_can_use_return_insn ()) | 3865 if (cfun->machine->naked_p) |
3866 { | |
3867 gcc_assert (style == NORMAL_RETURN); | |
3868 | |
3869 emit_jump_insn (gen_return ()); | |
3870 | |
3871 return; | |
3872 } | |
3873 | |
3874 if ((style == NORMAL_RETURN) && riscv_can_use_return_insn ()) | |
3382 { | 3875 { |
3383 emit_jump_insn (gen_return ()); | 3876 emit_jump_insn (gen_return ()); |
3384 return; | 3877 return; |
3385 } | 3878 } |
3386 | 3879 |
3451 | 3944 |
3452 if (use_restore_libcall) | 3945 if (use_restore_libcall) |
3453 frame->mask = 0; /* Temporarily fib that we need not save GPRs. */ | 3946 frame->mask = 0; /* Temporarily fib that we need not save GPRs. */ |
3454 | 3947 |
3455 /* Restore the registers. */ | 3948 /* Restore the registers. */ |
3456 riscv_for_each_saved_reg (frame->total_size - step2, riscv_restore_reg); | 3949 riscv_for_each_saved_reg (frame->total_size - step2, riscv_restore_reg, |
3950 true, style == EXCEPTION_RETURN); | |
3457 | 3951 |
3458 if (use_restore_libcall) | 3952 if (use_restore_libcall) |
3459 { | 3953 { |
3460 frame->mask = mask; /* Undo the above fib. */ | 3954 frame->mask = mask; /* Undo the above fib. */ |
3461 gcc_assert (step2 >= frame->save_libcall_adjustment); | 3955 gcc_assert (step2 >= frame->save_libcall_adjustment); |
3490 emit_jump_insn (gen_gpr_restore_return (ra)); | 3984 emit_jump_insn (gen_gpr_restore_return (ra)); |
3491 return; | 3985 return; |
3492 } | 3986 } |
3493 | 3987 |
3494 /* Add in the __builtin_eh_return stack adjustment. */ | 3988 /* Add in the __builtin_eh_return stack adjustment. */ |
3495 if (crtl->calls_eh_return) | 3989 if ((style == EXCEPTION_RETURN) && crtl->calls_eh_return) |
3496 emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, | 3990 emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, |
3497 EH_RETURN_STACKADJ_RTX)); | 3991 EH_RETURN_STACKADJ_RTX)); |
3498 | 3992 |
3499 if (!sibcall_p) | 3993 /* Return from interrupt. */ |
3994 if (cfun->machine->interrupt_handler_p) | |
3995 { | |
3996 enum riscv_privilege_levels mode = cfun->machine->interrupt_mode; | |
3997 | |
3998 gcc_assert (mode != UNKNOWN_MODE); | |
3999 | |
4000 if (mode == MACHINE_MODE) | |
4001 emit_jump_insn (gen_riscv_mret ()); | |
4002 else if (mode == SUPERVISOR_MODE) | |
4003 emit_jump_insn (gen_riscv_sret ()); | |
4004 else | |
4005 emit_jump_insn (gen_riscv_uret ()); | |
4006 } | |
4007 else if (style != SIBCALL_RETURN) | |
3500 emit_jump_insn (gen_simple_return_internal (ra)); | 4008 emit_jump_insn (gen_simple_return_internal (ra)); |
4009 } | |
4010 | |
4011 /* Implement EPILOGUE_USES. */ | |
4012 | |
4013 bool | |
4014 riscv_epilogue_uses (unsigned int regno) | |
4015 { | |
4016 if (regno == RETURN_ADDR_REGNUM) | |
4017 return true; | |
4018 | |
4019 if (epilogue_completed && cfun->machine->interrupt_handler_p) | |
4020 { | |
4021 /* An interrupt function restores temp regs, so we must indicate that | |
4022 they are live at function end. */ | |
4023 if (df_regs_ever_live_p (regno) | |
4024 || (!crtl->is_leaf && call_used_regs[regno])) | |
4025 return true; | |
4026 } | |
4027 | |
4028 return false; | |
3501 } | 4029 } |
3502 | 4030 |
3503 /* Return nonzero if this function is known to have a null epilogue. | 4031 /* Return nonzero if this function is known to have a null epilogue. |
3504 This allows the optimizer to omit jumps to jumps if no stack | 4032 This allows the optimizer to omit jumps to jumps if no stack |
3505 was created. */ | 4033 was created. */ |
3506 | 4034 |
3507 bool | 4035 bool |
3508 riscv_can_use_return_insn (void) | 4036 riscv_can_use_return_insn (void) |
3509 { | 4037 { |
3510 return reload_completed && cfun->machine->frame.total_size == 0; | 4038 return (reload_completed && cfun->machine->frame.total_size == 0 |
4039 && ! cfun->machine->interrupt_handler_p); | |
3511 } | 4040 } |
3512 | 4041 |
3513 /* Implement TARGET_SECONDARY_MEMORY_NEEDED. | 4042 /* Implement TARGET_SECONDARY_MEMORY_NEEDED. |
3514 | 4043 |
3515 When floating-point registers are wider than integer ones, moves between | 4044 When floating-point registers are wider than integer ones, moves between |
3634 { | 4163 { |
3635 default_file_start (); | 4164 default_file_start (); |
3636 | 4165 |
3637 /* Instruct GAS to generate position-[in]dependent code. */ | 4166 /* Instruct GAS to generate position-[in]dependent code. */ |
3638 fprintf (asm_out_file, "\t.option %spic\n", (flag_pic ? "" : "no")); | 4167 fprintf (asm_out_file, "\t.option %spic\n", (flag_pic ? "" : "no")); |
4168 | |
4169 /* If the user specifies "-mno-relax" on the command line then disable linker | |
4170 relaxation in the assembler. */ | |
4171 if (! riscv_mrelax) | |
4172 fprintf (asm_out_file, "\t.option norelax\n"); | |
3639 } | 4173 } |
3640 | 4174 |
3641 /* Implement TARGET_ASM_OUTPUT_MI_THUNK. Generate rtl rather than asm text | 4175 /* Implement TARGET_ASM_OUTPUT_MI_THUNK. Generate rtl rather than asm text |
3642 in order to avoid duplicating too much logic from elsewhere. */ | 4176 in order to avoid duplicating too much logic from elsewhere. */ |
3643 | 4177 |
3754 RISCV_TUNE_STRING_DEFAULT); | 4288 RISCV_TUNE_STRING_DEFAULT); |
3755 tune_info = optimize_size ? &optimize_size_tune_info : cpu->tune_info; | 4289 tune_info = optimize_size ? &optimize_size_tune_info : cpu->tune_info; |
3756 | 4290 |
3757 /* Use -mtune's setting for slow_unaligned_access, even when optimizing | 4291 /* Use -mtune's setting for slow_unaligned_access, even when optimizing |
3758 for size. For architectures that trap and emulate unaligned accesses, | 4292 for size. For architectures that trap and emulate unaligned accesses, |
3759 the performance cost is too great, even for -Os. */ | 4293 the performance cost is too great, even for -Os. Similarly, if |
4294 -m[no-]strict-align is left unspecified, heed -mtune's advice. */ | |
3760 riscv_slow_unaligned_access_p = (cpu->tune_info->slow_unaligned_access | 4295 riscv_slow_unaligned_access_p = (cpu->tune_info->slow_unaligned_access |
3761 || TARGET_STRICT_ALIGN); | 4296 || TARGET_STRICT_ALIGN); |
4297 if ((target_flags_explicit & MASK_STRICT_ALIGN) == 0 | |
4298 && cpu->tune_info->slow_unaligned_access) | |
4299 target_flags |= MASK_STRICT_ALIGN; | |
3762 | 4300 |
3763 /* If the user hasn't specified a branch cost, use the processor's | 4301 /* If the user hasn't specified a branch cost, use the processor's |
3764 default. */ | 4302 default. */ |
3765 if (riscv_branch_cost == 0) | 4303 if (riscv_branch_cost == 0) |
3766 riscv_branch_cost = tune_info->branch_cost; | 4304 riscv_branch_cost = tune_info->branch_cost; |
3780 /* Require that the ISA supports the requested floating-point ABI. */ | 4318 /* Require that the ISA supports the requested floating-point ABI. */ |
3781 if (UNITS_PER_FP_ARG > (TARGET_HARD_FLOAT ? UNITS_PER_FP_REG : 0)) | 4319 if (UNITS_PER_FP_ARG > (TARGET_HARD_FLOAT ? UNITS_PER_FP_REG : 0)) |
3782 error ("requested ABI requires -march to subsume the %qc extension", | 4320 error ("requested ABI requires -march to subsume the %qc extension", |
3783 UNITS_PER_FP_ARG > 8 ? 'Q' : (UNITS_PER_FP_ARG > 4 ? 'D' : 'F')); | 4321 UNITS_PER_FP_ARG > 8 ? 'Q' : (UNITS_PER_FP_ARG > 4 ? 'D' : 'F')); |
3784 | 4322 |
4323 if (TARGET_RVE && riscv_abi != ABI_ILP32E) | |
4324 error ("rv32e requires ilp32e ABI"); | |
4325 | |
3785 /* We do not yet support ILP32 on RV64. */ | 4326 /* We do not yet support ILP32 on RV64. */ |
3786 if (BITS_PER_WORD != POINTER_SIZE) | 4327 if (BITS_PER_WORD != POINTER_SIZE) |
3787 error ("ABI requires -march=rv%d", POINTER_SIZE); | 4328 error ("ABI requires -march=rv%d", POINTER_SIZE); |
4329 | |
4330 /* Validate -mpreferred-stack-boundary= value. */ | |
4331 riscv_stack_boundary = ABI_STACK_BOUNDARY; | |
4332 if (riscv_preferred_stack_boundary_arg) | |
4333 { | |
4334 int min = ctz_hwi (STACK_BOUNDARY / 8); | |
4335 int max = 8; | |
4336 | |
4337 if (!IN_RANGE (riscv_preferred_stack_boundary_arg, min, max)) | |
4338 error ("-mpreferred-stack-boundary=%d must be between %d and %d", | |
4339 riscv_preferred_stack_boundary_arg, min, max); | |
4340 | |
4341 riscv_stack_boundary = 8 << riscv_preferred_stack_boundary_arg; | |
4342 } | |
3788 } | 4343 } |
3789 | 4344 |
3790 /* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */ | 4345 /* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */ |
3791 | 4346 |
3792 static void | 4347 static void |
3793 riscv_conditional_register_usage (void) | 4348 riscv_conditional_register_usage (void) |
3794 { | 4349 { |
4350 /* We have only x0~x15 on RV32E. */ | |
4351 if (TARGET_RVE) | |
4352 { | |
4353 for (int r = 16; r <= 31; r++) | |
4354 fixed_regs[r] = 1; | |
4355 } | |
4356 | |
4357 if (riscv_abi == ABI_ILP32E) | |
4358 { | |
4359 for (int r = 16; r <= 31; r++) | |
4360 call_used_regs[r] = 1; | |
4361 } | |
4362 | |
3795 if (!TARGET_HARD_FLOAT) | 4363 if (!TARGET_HARD_FLOAT) |
3796 { | 4364 { |
3797 for (int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++) | 4365 for (int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++) |
3798 fixed_regs[regno] = call_used_regs[regno] = 1; | 4366 fixed_regs[regno] = call_used_regs[regno] = 1; |
4367 } | |
4368 | |
4369 /* In the soft-float ABI, there are no callee-saved FP registers. */ | |
4370 if (UNITS_PER_FP_ARG == 0) | |
4371 { | |
4372 for (int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++) | |
4373 call_used_regs[regno] = 1; | |
3799 } | 4374 } |
3800 } | 4375 } |
3801 | 4376 |
3802 /* Return a register priority for hard reg REGNO. */ | 4377 /* Return a register priority for hard reg REGNO. */ |
3803 | 4378 |
3945 /* Flush the code part of the trampoline. */ | 4520 /* Flush the code part of the trampoline. */ |
3946 emit_insn (gen_add3_insn (end_addr, addr, GEN_INT (TRAMPOLINE_SIZE))); | 4521 emit_insn (gen_add3_insn (end_addr, addr, GEN_INT (TRAMPOLINE_SIZE))); |
3947 emit_insn (gen_clear_cache (addr, end_addr)); | 4522 emit_insn (gen_clear_cache (addr, end_addr)); |
3948 } | 4523 } |
3949 | 4524 |
3950 /* Return leaf_function_p () and memoize the result. */ | |
3951 | |
3952 static bool | |
3953 riscv_leaf_function_p (void) | |
3954 { | |
3955 if (cfun->machine->is_leaf == 0) | |
3956 cfun->machine->is_leaf = leaf_function_p () ? 1 : -1; | |
3957 | |
3958 return cfun->machine->is_leaf > 0; | |
3959 } | |
3960 | |
3961 /* Implement TARGET_FUNCTION_OK_FOR_SIBCALL. */ | 4525 /* Implement TARGET_FUNCTION_OK_FOR_SIBCALL. */ |
3962 | 4526 |
3963 static bool | 4527 static bool |
3964 riscv_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED, | 4528 riscv_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED, |
3965 tree exp ATTRIBUTE_UNUSED) | 4529 tree exp ATTRIBUTE_UNUSED) |
3966 { | 4530 { |
3967 /* When optimzing for size, don't use sibcalls in non-leaf routines */ | 4531 /* Don't use sibcalls when use save-restore routine. */ |
3968 if (TARGET_SAVE_RESTORE) | 4532 if (TARGET_SAVE_RESTORE) |
3969 return riscv_leaf_function_p (); | 4533 return false; |
4534 | |
4535 /* Don't use sibcall for naked functions. */ | |
4536 if (cfun->machine->naked_p) | |
4537 return false; | |
4538 | |
4539 /* Don't use sibcall for interrupt functions. */ | |
4540 if (cfun->machine->interrupt_handler_p) | |
4541 return false; | |
3970 | 4542 |
3971 return true; | 4543 return true; |
4544 } | |
4545 | |
4546 /* Get the intterupt type, return UNKNOWN_MODE if it's not | |
4547 interrupt function. */ | |
4548 static enum riscv_privilege_levels | |
4549 riscv_get_interrupt_type (tree decl) | |
4550 { | |
4551 gcc_assert (decl != NULL_TREE); | |
4552 | |
4553 if ((TREE_CODE(decl) != FUNCTION_DECL) | |
4554 || (!riscv_interrupt_type_p (TREE_TYPE (decl)))) | |
4555 return UNKNOWN_MODE; | |
4556 | |
4557 tree attr_args | |
4558 = TREE_VALUE (lookup_attribute ("interrupt", | |
4559 TYPE_ATTRIBUTES (TREE_TYPE (decl)))); | |
4560 | |
4561 if (attr_args && TREE_CODE (TREE_VALUE (attr_args)) != VOID_TYPE) | |
4562 { | |
4563 const char *string = TREE_STRING_POINTER (TREE_VALUE (attr_args)); | |
4564 | |
4565 if (!strcmp (string, "user")) | |
4566 return USER_MODE; | |
4567 else if (!strcmp (string, "supervisor")) | |
4568 return SUPERVISOR_MODE; | |
4569 else /* Must be "machine". */ | |
4570 return MACHINE_MODE; | |
4571 } | |
4572 else | |
4573 /* Interrupt attributes are machine mode by default. */ | |
4574 return MACHINE_MODE; | |
4575 } | |
4576 | |
4577 /* Implement `TARGET_SET_CURRENT_FUNCTION'. */ | |
4578 /* Sanity cheching for above function attributes. */ | |
4579 static void | |
4580 riscv_set_current_function (tree decl) | |
4581 { | |
4582 if (decl == NULL_TREE | |
4583 || current_function_decl == NULL_TREE | |
4584 || current_function_decl == error_mark_node | |
4585 || ! cfun->machine | |
4586 || cfun->machine->attributes_checked_p) | |
4587 return; | |
4588 | |
4589 cfun->machine->naked_p = riscv_naked_function_p (decl); | |
4590 cfun->machine->interrupt_handler_p | |
4591 = riscv_interrupt_type_p (TREE_TYPE (decl)); | |
4592 | |
4593 if (cfun->machine->naked_p && cfun->machine->interrupt_handler_p) | |
4594 error ("function attributes %qs and %qs are mutually exclusive", | |
4595 "interrupt", "naked"); | |
4596 | |
4597 if (cfun->machine->interrupt_handler_p) | |
4598 { | |
4599 tree ret = TREE_TYPE (TREE_TYPE (decl)); | |
4600 tree args = TYPE_ARG_TYPES (TREE_TYPE (decl)); | |
4601 | |
4602 if (TREE_CODE (ret) != VOID_TYPE) | |
4603 error ("%qs function cannot return a value", "interrupt"); | |
4604 | |
4605 if (args && TREE_CODE (TREE_VALUE (args)) != VOID_TYPE) | |
4606 error ("%qs function cannot have arguments", "interrupt"); | |
4607 | |
4608 cfun->machine->interrupt_mode = riscv_get_interrupt_type (decl); | |
4609 | |
4610 gcc_assert (cfun->machine->interrupt_mode != UNKNOWN_MODE); | |
4611 } | |
4612 | |
4613 /* Don't print the above diagnostics more than once. */ | |
4614 cfun->machine->attributes_checked_p = 1; | |
4615 } | |
4616 | |
4617 /* Implement TARGET_MERGE_DECL_ATTRIBUTES. */ | |
4618 static tree | |
4619 riscv_merge_decl_attributes (tree olddecl, tree newdecl) | |
4620 { | |
4621 tree combined_attrs; | |
4622 | |
4623 enum riscv_privilege_levels old_interrupt_type | |
4624 = riscv_get_interrupt_type (olddecl); | |
4625 enum riscv_privilege_levels new_interrupt_type | |
4626 = riscv_get_interrupt_type (newdecl); | |
4627 | |
4628 /* Check old and new has same interrupt type. */ | |
4629 if ((old_interrupt_type != UNKNOWN_MODE) | |
4630 && (new_interrupt_type != UNKNOWN_MODE) | |
4631 && (old_interrupt_type != new_interrupt_type)) | |
4632 error ("%qs function cannot have different intterupt type.", "interrupt"); | |
4633 | |
4634 /* Create combined attributes. */ | |
4635 combined_attrs = merge_attributes (DECL_ATTRIBUTES (olddecl), | |
4636 DECL_ATTRIBUTES (newdecl)); | |
4637 | |
4638 return combined_attrs; | |
3972 } | 4639 } |
3973 | 4640 |
3974 /* Implement TARGET_CANNOT_COPY_INSN_P. */ | 4641 /* Implement TARGET_CANNOT_COPY_INSN_P. */ |
3975 | 4642 |
3976 static bool | 4643 static bool |
4023 #undef TARGET_SCHED_ISSUE_RATE | 4690 #undef TARGET_SCHED_ISSUE_RATE |
4024 #define TARGET_SCHED_ISSUE_RATE riscv_issue_rate | 4691 #define TARGET_SCHED_ISSUE_RATE riscv_issue_rate |
4025 | 4692 |
4026 #undef TARGET_FUNCTION_OK_FOR_SIBCALL | 4693 #undef TARGET_FUNCTION_OK_FOR_SIBCALL |
4027 #define TARGET_FUNCTION_OK_FOR_SIBCALL riscv_function_ok_for_sibcall | 4694 #define TARGET_FUNCTION_OK_FOR_SIBCALL riscv_function_ok_for_sibcall |
4695 | |
4696 #undef TARGET_SET_CURRENT_FUNCTION | |
4697 #define TARGET_SET_CURRENT_FUNCTION riscv_set_current_function | |
4028 | 4698 |
4029 #undef TARGET_REGISTER_MOVE_COST | 4699 #undef TARGET_REGISTER_MOVE_COST |
4030 #define TARGET_REGISTER_MOVE_COST riscv_register_move_cost | 4700 #define TARGET_REGISTER_MOVE_COST riscv_register_move_cost |
4031 #undef TARGET_MEMORY_MOVE_COST | 4701 #undef TARGET_MEMORY_MOVE_COST |
4032 #define TARGET_MEMORY_MOVE_COST riscv_memory_move_cost | 4702 #define TARGET_MEMORY_MOVE_COST riscv_memory_move_cost |
4059 #undef TARGET_PRINT_OPERAND_ADDRESS | 4729 #undef TARGET_PRINT_OPERAND_ADDRESS |
4060 #define TARGET_PRINT_OPERAND_ADDRESS riscv_print_operand_address | 4730 #define TARGET_PRINT_OPERAND_ADDRESS riscv_print_operand_address |
4061 | 4731 |
4062 #undef TARGET_SETUP_INCOMING_VARARGS | 4732 #undef TARGET_SETUP_INCOMING_VARARGS |
4063 #define TARGET_SETUP_INCOMING_VARARGS riscv_setup_incoming_varargs | 4733 #define TARGET_SETUP_INCOMING_VARARGS riscv_setup_incoming_varargs |
4734 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS | |
4735 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS riscv_allocate_stack_slots_for_args | |
4064 #undef TARGET_STRICT_ARGUMENT_NAMING | 4736 #undef TARGET_STRICT_ARGUMENT_NAMING |
4065 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true | 4737 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true |
4066 #undef TARGET_MUST_PASS_IN_STACK | 4738 #undef TARGET_MUST_PASS_IN_STACK |
4067 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size | 4739 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size |
4068 #undef TARGET_PASS_BY_REFERENCE | 4740 #undef TARGET_PASS_BY_REFERENCE |
4107 #define TARGET_TRAMPOLINE_INIT riscv_trampoline_init | 4779 #define TARGET_TRAMPOLINE_INIT riscv_trampoline_init |
4108 | 4780 |
4109 #undef TARGET_IN_SMALL_DATA_P | 4781 #undef TARGET_IN_SMALL_DATA_P |
4110 #define TARGET_IN_SMALL_DATA_P riscv_in_small_data_p | 4782 #define TARGET_IN_SMALL_DATA_P riscv_in_small_data_p |
4111 | 4783 |
4784 #undef TARGET_HAVE_SRODATA_SECTION | |
4785 #define TARGET_HAVE_SRODATA_SECTION true | |
4786 | |
4787 #undef TARGET_ASM_SELECT_SECTION | |
4788 #define TARGET_ASM_SELECT_SECTION riscv_select_section | |
4789 | |
4112 #undef TARGET_ASM_SELECT_RTX_SECTION | 4790 #undef TARGET_ASM_SELECT_RTX_SECTION |
4113 #define TARGET_ASM_SELECT_RTX_SECTION riscv_elf_select_rtx_section | 4791 #define TARGET_ASM_SELECT_RTX_SECTION riscv_elf_select_rtx_section |
4114 | 4792 |
4115 #undef TARGET_MIN_ANCHOR_OFFSET | 4793 #undef TARGET_MIN_ANCHOR_OFFSET |
4116 #define TARGET_MIN_ANCHOR_OFFSET (-IMM_REACH/2) | 4794 #define TARGET_MIN_ANCHOR_OFFSET (-IMM_REACH/2) |
4154 #define TARGET_CAN_CHANGE_MODE_CLASS riscv_can_change_mode_class | 4832 #define TARGET_CAN_CHANGE_MODE_CLASS riscv_can_change_mode_class |
4155 | 4833 |
4156 #undef TARGET_CONSTANT_ALIGNMENT | 4834 #undef TARGET_CONSTANT_ALIGNMENT |
4157 #define TARGET_CONSTANT_ALIGNMENT riscv_constant_alignment | 4835 #define TARGET_CONSTANT_ALIGNMENT riscv_constant_alignment |
4158 | 4836 |
4837 #undef TARGET_MERGE_DECL_ATTRIBUTES | |
4838 #define TARGET_MERGE_DECL_ATTRIBUTES riscv_merge_decl_attributes | |
4839 | |
4840 #undef TARGET_ATTRIBUTE_TABLE | |
4841 #define TARGET_ATTRIBUTE_TABLE riscv_attribute_table | |
4842 | |
4843 #undef TARGET_WARN_FUNC_RETURN | |
4844 #define TARGET_WARN_FUNC_RETURN riscv_warn_func_return | |
4845 | |
4846 /* The low bit is ignored by jump instructions so is safe to use. */ | |
4847 #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS | |
4848 #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 1 | |
4849 | |
4159 struct gcc_target targetm = TARGET_INITIALIZER; | 4850 struct gcc_target targetm = TARGET_INITIALIZER; |
4160 | 4851 |
4161 #include "gt-riscv.h" | 4852 #include "gt-riscv.h" |