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
>

Reply via email to