Just a quick heads-up to avoid duplication of work: we have a series queued up for later this week (right now, SPEC2017 is still running for QA purposes) that adds if-conversion support and converts that into Zicond operations. It doesn't have much overlap (except handling the "zicond" flag), as we don't use builtins but a new canonical pattern.
Philipp. On Thu, 9 Feb 2023 at 12:06, <shiyul...@iscas.ac.cn> wrote: > > 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 >