On 2/9/23 04: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.

+(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"
Why use UNSPEC here? The semantics of these instructions can be fully expressed in RTL. Using an UNSPEC just prevents optimization and will ultimately require adding more patterns to utilize these instructions automatically.

Based on the work we've been doing here at Ventana, I would strongly suggest moving to a conditional zero idiom like

(set (dest) (if_then_else (cond) (reg) (const_int 0)))

That has the advantage that many passes know how to form it rather than the form VRULL originally used which looked something like

(set (dest) (and (neg (cond) (reg)))


Jeff

Reply via email to