From fb72ef1b706a2dd0079a2bebd301f9503f5d2893 Mon Sep 17 00:00:00 2001 From: "max.ma" Date: Thu, 7 Jul 2022 00:30:21 -0700 Subject: [PATCH 06/11] merge b extension changes --- gcc/common/config/riscv/riscv-common.cc | 17 +++++++++-- gcc/config/riscv/riscv-builtins.cc | 10 +++++++ gcc/config/riscv/riscv-ftypes.def | 2 ++ gcc/config/riscv/riscv.cc | 34 +++++++++++++++++++++- gcc/config/riscv/riscv.h | 9 ++---- gcc/config/riscv/riscv.md | 38 +++++++++++++++++++++++++ gcc/config/riscv/riscv.opt | 2 ++ 7 files changed, 103 insertions(+), 9 deletions(-) diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index 1501242e296..967c28d0498 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -47,6 +47,10 @@ struct riscv_implied_info_t /* Implied ISA info, must end with NULL sentinel. */ static const riscv_implied_info_t riscv_implied_info[] = { + {"b", "zbb"}, + {"b", "zbs"}, + {"b", "zba"}, + {"b", "zbc"}, {"d", "f"}, {"f", "zicsr"}, {"d", "zicsr"}, @@ -149,6 +153,7 @@ static const struct riscv_ext_version riscv_ext_version_table[] = {"zifencei", ISA_SPEC_CLASS_20191213, 2, 0}, {"zifencei", ISA_SPEC_CLASS_20190608, 2, 0}, + {"b", ISA_SPEC_CLASS_NONE, 1, 0}, {"zba", ISA_SPEC_CLASS_NONE, 1, 0}, {"zbb", ISA_SPEC_CLASS_NONE, 1, 0}, {"zbc", ISA_SPEC_CLASS_NONE, 1, 0}, @@ -787,7 +792,14 @@ riscv_subset_list::parse_std_ext (const char *p) p = parsing_subset_version (subset, p, &major_version, &minor_version, /* std_ext_p= */ true, &explicit_version_p); - + if (std_ext == 'b') + { + add ("zba", major_version, minor_version, explicit_version_p, false); + add ("zbb", major_version, minor_version, explicit_version_p, false); + add ("zbc", major_version, minor_version, explicit_version_p, false); + add ("zbs", major_version, minor_version, explicit_version_p, false); + } + else add (subset, major_version, minor_version, explicit_version_p, false); } return p; @@ -1094,6 +1106,7 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] = {"zicsr", &gcc_options::x_riscv_zi_subext, MASK_ZICSR}, {"zifencei", &gcc_options::x_riscv_zi_subext, MASK_ZIFENCEI}, + {"b", &gcc_options::x_target_flags, MASK_BITMANIP}, {"zba", &gcc_options::x_riscv_zb_subext, MASK_ZBA}, {"zbb", &gcc_options::x_riscv_zb_subext, MASK_ZBB}, {"zbc", &gcc_options::x_riscv_zb_subext, MASK_ZBC}, @@ -1304,4 +1317,4 @@ static const struct default_options riscv_option_optimization_table[] = #undef TARGET_HANDLE_OPTION #define TARGET_HANDLE_OPTION riscv_handle_option -struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; \ No newline at end of file diff --git a/gcc/config/riscv/riscv-builtins.cc b/gcc/config/riscv/riscv-builtins.cc index 0658f8d3047..d50876a26f7 100644 --- a/gcc/config/riscv/riscv-builtins.cc +++ b/gcc/config/riscv/riscv-builtins.cc @@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see /* Macros to create an enumeration identifier for a function prototype. */ #define RISCV_FTYPE_NAME0(A) RISCV_##A##_FTYPE #define RISCV_FTYPE_NAME1(A, B) RISCV_##A##_FTYPE_##B +#define RISCV_FTYPE_NAME2(A, B, C) RISCV_##A##_FTYPE_##B##_##C /* Classifies the prototype of a built-in function. */ enum riscv_function_type { @@ -86,6 +87,8 @@ struct riscv_builtin_description { }; AVAIL (hard_float, TARGET_HARD_FLOAT) +AVAIL (zbb, TARGET_ZBB) +AVAIL (zbc, TARGET_ZBC) /* Construct a riscv_builtin_description from the given arguments. @@ -119,6 +122,7 @@ AVAIL (hard_float, TARGET_HARD_FLOAT) /* Argument types. */ #define RISCV_ATYPE_VOID void_type_node #define RISCV_ATYPE_USI unsigned_intSI_type_node +#define RISCV_ATYPE_SI intSI_type_node /* RISCV_FTYPE_ATYPESN takes N RISCV_FTYPES-like type codes and lists their associated RISCV_ATYPEs. */ @@ -126,8 +130,14 @@ AVAIL (hard_float, TARGET_HARD_FLOAT) RISCV_ATYPE_##A #define RISCV_FTYPE_ATYPES1(A, B) \ RISCV_ATYPE_##A, RISCV_ATYPE_##B +#define RISCV_FTYPE_ATYPES2(A, B, C) \ + RISCV_ATYPE_##A, RISCV_ATYPE_##B, RISCV_ATYPE_##C static const struct riscv_builtin_description riscv_builtins[] = { + DIRECT_BUILTIN (orc_b, RISCV_SI_FTYPE_SI, zbb), + DIRECT_BUILTIN (clmul, RISCV_SI_FTYPE_SI_SI, zbc), + DIRECT_BUILTIN (clmulh, RISCV_SI_FTYPE_SI_SI, zbc), + DIRECT_BUILTIN (clmulr, RISCV_SI_FTYPE_SI_SI, zbc), DIRECT_BUILTIN (frflags, RISCV_USI_FTYPE, hard_float), DIRECT_NO_TARGET_BUILTIN (fsflags, RISCV_VOID_FTYPE_USI, hard_float) }; diff --git a/gcc/config/riscv/riscv-ftypes.def b/gcc/config/riscv/riscv-ftypes.def index 2214c496f9b..edcfd44dacc 100644 --- a/gcc/config/riscv/riscv-ftypes.def +++ b/gcc/config/riscv/riscv-ftypes.def @@ -28,3 +28,5 @@ along with GCC; see the file COPYING3. If not see DEF_RISCV_FTYPE (0, (USI)) DEF_RISCV_FTYPE (1, (VOID, USI)) +DEF_RISCV_FTYPE (1, (SI, SI)) +DEF_RISCV_FTYPE (2, (SI, SI, SI)) \ No newline at end of file diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index ee756aab694..ec7030f6c2e 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -415,6 +415,15 @@ riscv_build_integer_1 (struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS], /* Simply BSETI. */ codes[0].code = UNKNOWN; codes[0].value = value; + + /* RISC-V sign-extends all 32bit values that life in a 32bit + register. To avoid paradoxes, we thus need to use the + sign-extended (negative) representation for the value, if we + want to build 0x80000000 in SImode. This will then expand + to an ADDI/LI instruction. */ + if (mode == SImode && value == 0x80000000) + codes[0].value = -2147483648; + return 1; } @@ -2014,8 +2023,22 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN (TARGET_64BIT && (mode == DImode))) && (GET_CODE (XEXP (x, 0)) == ASHIFT) && REG_P (XEXP (XEXP (x, 0), 0)) + && CONST_INT_P (XEXP (XEXP (x, 0), 0)) + && IN_RANGE (INTVAL (XEXP (XEXP (x, 0), 0)), 1, 3)) + { + *total = COSTS_N_INSNS (1); + return true; + } + /* Before strength-reduction, the shNadd can be expressed as the addition + of a multiplication with a power-of-two. If this case is not handled, + the strength-reduction in expmed.c will calculate an inflated cost. */ + if (TARGET_ZBA + && ((!TARGET_64BIT && (mode == SImode)) || + (TARGET_64BIT && (mode == DImode))) + && (GET_CODE (XEXP (x, 0)) == MULT) + && REG_P (XEXP (XEXP (x, 0), 0)) && CONST_INT_P (XEXP (XEXP (x, 0), 1)) - && IN_RANGE (INTVAL (XEXP (XEXP (x, 0), 1)), 1, 3)) + && IN_RANGE (pow2p_hwi (INTVAL (XEXP (XEXP (x, 0), 1))), 1, 3)) { *total = COSTS_N_INSNS (1); return true; @@ -2044,6 +2067,7 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN if (!CONST_INT_P (and_rhs)) break; + rtx ashift_lhs = XEXP (and_lhs, 0); rtx ashift_rhs = XEXP (and_lhs, 1); if (!CONST_INT_P (ashift_rhs) @@ -2131,6 +2155,14 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN *total = riscv_extend_cost (XEXP (x, 0), GET_CODE (x) == ZERO_EXTEND); return false; + case BSWAP: + if (TARGET_ZBB) + { + *total = COSTS_N_INSNS (1); + return true; + } + return false; + case FLOAT: case UNSIGNED_FLOAT: case FIX: diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 8a4d2cf7f85..045920b49cf 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -528,13 +528,10 @@ enum reg_class (((VALUE) | ((1UL<<31) - IMM_REACH)) == ((1UL<<31) - IMM_REACH) \ || ((VALUE) | ((1UL<<31) - IMM_REACH)) + IMM_REACH == 0) -/* If this is a single bit mask, then we can load it with bseti. But this - is not useful for any of the low 31 bits because we can use addi or lui - to load them. It is wrong for loading SImode 0x80000000 on rv64 because it - needs to be sign-extended. So we restrict this to the upper 32-bits - only. */ +/* If this is a single bit mask, then we can load it with bseti. Special + handling of SImode 0x80000000 on RV64 is done in riscv_build_integer_1. */ #define SINGLE_BIT_MASK_OPERAND(VALUE) \ - (pow2p_hwi (VALUE) && (ctz_hwi (VALUE) >= 32)) + (pow2p_hwi (VALUE)) /* Stack layout; function entry, exit and calling. */ diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index b3c5bce842a..e56979ca800 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -2767,6 +2767,44 @@ [(set_attr "length" "0")] ) +(define_insn "riscv_orc_b" + [(set (match_operand:SI 0 "register_operand" "=r") + (sign_extend:SI (match_operand:SI 1 "register_operand" "r")))] + "TARGET_ZBB" + "orc.b\t%0,%1,%2" + [(set_attr "type" "bitmanip")]) + +(define_insn "riscv_rev8" + [(set (match_operand:SI 0 "register_operand" "=r") + (sign_extend:SI (match_operand:SI 1 "register_operand" "r")))] + "TARGET_ZBB" + "rev8\t%0,%1,%2" + [(set_attr "type" "bitmanip")]) + +(define_insn "riscv_clmul" + [(set (match_operand:SI 0 "register_operand" "=r") + (sign_extend:SI (rotate:SI (match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "register_operand" "r"))))] + "TARGET_ZBC" + "clmul\t%0,%1,%2" + [(set_attr "type" "bitmanip")]) + +(define_insn "riscv_clmulh" + [(set (match_operand:SI 0 "register_operand" "=r") + (sign_extend:SI (rotate:SI (match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "register_operand" "r"))))] + "TARGET_ZBC" + "clmulh\t%0,%1,%2" + [(set_attr "type" "bitmanip")]) + +(define_insn "riscv_clmulr" + [(set (match_operand:SI 0 "register_operand" "=r") + (sign_extend:SI (rotate:SI (match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "register_operand" "r"))))] + "TARGET_ZBC" + "clmulr\t%0,%1,%2" + [(set_attr "type" "bitmanip")]) + ;; This fixes a failure with gcc.c-torture/execute/pr64242.c at -O2 for a ;; 32-bit target when using -mtune=sifive-7-series. The first sched pass ;; runs before register elimination, and we have a non-obvious dependency diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt index 492aad12324..fa6d61fc66a 100644 --- a/gcc/config/riscv/riscv.opt +++ b/gcc/config/riscv/riscv.opt @@ -136,6 +136,8 @@ Mask(64BIT) Mask(MUL) +Mask(BITMANIP) + Mask(ATOMIC) Mask(HARD_FLOAT) -- 2.25.1