From: yulong <shiyul...@iscas.ac.cn> [DO NOT MERGE] Until 'ZiCond' extension is frozen/ratified and final version number is determined, this patch should not be merged upstream. This commit uses version 1.0 as in the documentation.
This commit adds support for the latest draft of RISC-V Integer Conditional (ZiCond) extension consisting of 2 new instructions. This is based on the early draft of ZiCond on GitHub: <https://github.com/riscv/riscv-zicondops/commit/394e243769390025893b1a855071f5fffc659f36> gcc/ChangeLog: * common/config/riscv/riscv-common.cc: Add zicond ext. * config/riscv/riscv-builtins.cc (RISCV_FTYPE_NAME2): New. (AVAIL): New. (RISCV_FTYPE_ATYPES2): New. * config/riscv/riscv-ftypes.def (2): New. * config/riscv/riscv-opts.h (MASK_ZICOND): New. (TARGET_ZICOND): New. * config/riscv/riscv.md (riscv_eqz_<mode>): Add new mode. (riscv_nez_<mode>): Add new mode. * config/riscv/riscv.opt: New. * config/riscv/riscv-zicond.def: New file. gcc/testsuite/ChangeLog: * gcc.target/riscv/zicond-1.c: New test. * gcc.target/riscv/zicond-2.c: New test. --- gcc/common/config/riscv/riscv-common.cc | 4 ++++ gcc/config/riscv/riscv-builtins.cc | 8 ++++++++ gcc/config/riscv/riscv-ftypes.def | 2 ++ gcc/config/riscv/riscv-opts.h | 3 +++ gcc/config/riscv/riscv-zicond.def | 5 +++++ gcc/config/riscv/riscv.md | 22 ++++++++++++++++++++++ gcc/config/riscv/riscv.opt | 3 +++ gcc/testsuite/gcc.target/riscv/zicond-1.c | 15 +++++++++++++++ gcc/testsuite/gcc.target/riscv/zicond-2.c | 15 +++++++++++++++ 9 files changed, 77 insertions(+) create mode 100644 gcc/config/riscv/riscv-zicond.def create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-2.c diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index 787674003cb..5a8b1278ac8 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -190,6 +190,8 @@ static const struct riscv_ext_version riscv_ext_version_table[] = {"zicbom",ISA_SPEC_CLASS_NONE, 1, 0}, {"zicbop",ISA_SPEC_CLASS_NONE, 1, 0}, + {"zicond",ISA_SPEC_CLASS_NONE, 1, 0}, + {"zk", ISA_SPEC_CLASS_NONE, 1, 0}, {"zkn", ISA_SPEC_CLASS_NONE, 1, 0}, {"zks", ISA_SPEC_CLASS_NONE, 1, 0}, @@ -1209,6 +1211,8 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] = {"zicbom", &gcc_options::x_riscv_zicmo_subext, MASK_ZICBOM}, {"zicbop", &gcc_options::x_riscv_zicmo_subext, MASK_ZICBOP}, + {"zicond", &gcc_options::x_riscv_zicond_subext, MASK_ZICOND}, + {"zve32x", &gcc_options::x_target_flags, MASK_VECTOR}, {"zve32f", &gcc_options::x_target_flags, MASK_VECTOR}, {"zve64x", &gcc_options::x_target_flags, MASK_VECTOR}, diff --git a/gcc/config/riscv/riscv-builtins.cc b/gcc/config/riscv/riscv-builtins.cc index 25ca407f9a9..66a8126b2b4 100644 --- a/gcc/config/riscv/riscv-builtins.cc +++ b/gcc/config/riscv/riscv-builtins.cc @@ -42,6 +42,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 { @@ -99,6 +100,10 @@ AVAIL (zero64, TARGET_ZICBOZ && TARGET_64BIT) AVAIL (prefetchi32, TARGET_ZICBOP && !TARGET_64BIT) AVAIL (prefetchi64, TARGET_ZICBOP && TARGET_64BIT) AVAIL (always, (!0)) +AVAIL (nez32, TARGET_ZICOND && !TARGET_64BIT) +AVAIL (nez64, TARGET_ZICOND && TARGET_64BIT) +AVAIL (eqz32, TARGET_ZICOND && !TARGET_64BIT) +AVAIL (eqz64, TARGET_ZICOND && TARGET_64BIT) /* Construct a riscv_builtin_description from the given arguments. @@ -142,9 +147,12 @@ AVAIL (always, (!0)) 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[] = { #include "riscv-cmo.def" + #include "riscv-zicond.def" 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 3a40c33e7c2..d305282d811 100644 --- a/gcc/config/riscv/riscv-ftypes.def +++ b/gcc/config/riscv/riscv-ftypes.def @@ -32,3 +32,5 @@ DEF_RISCV_FTYPE (1, (VOID, USI)) DEF_RISCV_FTYPE (1, (VOID, VOID_PTR)) DEF_RISCV_FTYPE (1, (SI, SI)) DEF_RISCV_FTYPE (1, (DI, DI)) +DEF_RISCV_FTYPE (2, (SI, SI, SI)) +DEF_RISCV_FTYPE (2, (DI, DI, DI)) diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h index ff398c0a2ae..0baf6553913 100644 --- a/gcc/config/riscv/riscv-opts.h +++ b/gcc/config/riscv/riscv-opts.h @@ -166,6 +166,9 @@ enum stack_protector_guard { #define TARGET_ZICBOM ((riscv_zicmo_subext & MASK_ZICBOM) != 0) #define TARGET_ZICBOP ((riscv_zicmo_subext & MASK_ZICBOP) != 0) +#define MASK_ZICOND (1 << 0) +#define TARGET_ZICOND ((riscv_zicond_subext & MASK_ZICOND) != 0) + #define MASK_ZFHMIN (1 << 0) #define MASK_ZFH (1 << 1) diff --git a/gcc/config/riscv/riscv-zicond.def b/gcc/config/riscv/riscv-zicond.def new file mode 100644 index 00000000000..ceacb825933 --- /dev/null +++ b/gcc/config/riscv/riscv-zicond.def @@ -0,0 +1,5 @@ +RISCV_BUILTIN (nez_si, "zicond_nez", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI, nez32), +RISCV_BUILTIN (nez_di, "zicond_nez", RISCV_BUILTIN_DIRECT, RISCV_DI_FTYPE_DI_DI, nez64), + +RISCV_BUILTIN (eqz_si, "zicond_eqz", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI, eqz32), +RISCV_BUILTIN (eqz_di, "zicond_eqz", RISCV_BUILTIN_DIRECT, RISCV_DI_FTYPE_DI_DI, eqz64), \ No newline at end of file diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index c8adc5af5d2..1b1979df0c9 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -98,6 +98,10 @@ UNSPECV_ZERO UNSPECV_PREI + ;;ZICOND instructions + UNSPECV_EQZ + UNSPECV_NEZ + ;; Zihintpause unspec UNSPECV_PAUSE ]) @@ -3085,6 +3089,24 @@ "prefetch.i\t%a0" ) +(define_insn "riscv_eqz_<mode>" + [(set (match_operand:X 0 "register_operand" "=r") + (unspec_volatile:X [(match_operand:X 1 "register_operand" " r") + (match_operand:X 2 "register_operand" " r")] + UNSPECV_EQZ))] + "TARGET_ZICOND" + "czero.eqz\t%0,%1,%2" +) + +(define_insn "riscv_nez_<mode>" + [(set (match_operand:X 0 "register_operand" "=r") + (unspec_volatile:X [(match_operand:X 1 "register_operand" " r") + (match_operand:X 2 "register_operand" " r")] + UNSPECV_NEZ))] + "TARGET_ZICOND" + "czero.nez\t%0,%1,%2" +) + (include "bitmanip.md") (include "sync.md") (include "peephole.md") diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt index e78c99382cd..a422b16a02f 100644 --- a/gcc/config/riscv/riscv.opt +++ b/gcc/config/riscv/riscv.opt @@ -224,6 +224,9 @@ int riscv_zvl_flags TargetVariable int riscv_zicmo_subext +TargetVariable +int riscv_zicond_subext + TargetVariable int riscv_zf_subext diff --git a/gcc/testsuite/gcc.target/riscv/zicond-1.c b/gcc/testsuite/gcc.target/riscv/zicond-1.c new file mode 100644 index 00000000000..395e53f870f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicond-1.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32i_zicond -mabi=ilp32" } */ + +void foo1() +{ + __builtin_riscv_zicond_nez(1,1); +} + +void foo2() +{ + __builtin_riscv_zicond_eqz(1,1); +} + +/* { dg-final { scan-assembler-times "czero.nez" 1 } } */ +/* { dg-final { scan-assembler-times "czero.eqz" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zicond-2.c b/gcc/testsuite/gcc.target/riscv/zicond-2.c new file mode 100644 index 00000000000..4ae01cb8bfa --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicond-2.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64i_zicond -mabi=lp64" } */ + +void foo1() +{ + __builtin_riscv_zicond_nez(1,1); +} + +void foo2() +{ + __builtin_riscv_zicond_eqz(1,1); +} + +/* { dg-final { scan-assembler-times "czero.nez" 1 } } */ +/* { dg-final { scan-assembler-times "czero.eqz" 1 } } */ -- 2.25.1