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