From 9f34cfe4473beb006bad8de6754dc5c93f87d03c Mon Sep 17 00:00:00 2001 From: Tsukasa OI Date: Tue, 25 Oct 2022 06:49:58 +0000 Subject: [PATCH] UNRATIFIED RISC-V: Add 'ZiCond' extension [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' extension on GitHub: bfd/ChangeLog: * elfxx-riscv.c (riscv_supported_std_z_ext): Add 'ZiCond'. (riscv_multi_subset_supports): Support new instruction class. (riscv_multi_subset_supports_ext): Likewise. gas/ChangeLog: * testsuite/gas/riscv/zicond.s: New test for 'ZiCond'. * testsuite/gas/riscv/zicond.d: Likewise. * testsuite/gas/riscv/zicond-noarch.d: New test for architecture failure. * testsuite/gas/riscv/zicond-noarch.l: Likewise. include/ChangeLog: * opcode/riscv-opc.h (MATCH_CZERO_EQZ, MASK_CZERO_EQZ, MATCH_CZERO_NEZ, MASK_CZERO_NEZ): New. * opcode/riscv.h (enum riscv_insn_class): Add new instruction class INSN_CLASS_ZICOND. opcodes/ChangeLog: * riscv-opc.c (riscv_opcodes): Add new instructions from the 'ZiCond' extension. --- bfd/elfxx-riscv.c | 5 +++++ gas/testsuite/gas/riscv/zicond-noarch.d | 3 +++ gas/testsuite/gas/riscv/zicond-noarch.l | 3 +++ gas/testsuite/gas/riscv/zicond.d | 11 +++++++++++ gas/testsuite/gas/riscv/zicond.s | 3 +++ include/opcode/riscv-opc.h | 8 ++++++++ include/opcode/riscv.h | 1 + opcodes/riscv-opc.c | 4 ++++ 8 files changed, 38 insertions(+) create mode 100644 gas/testsuite/gas/riscv/zicond-noarch.d create mode 100644 gas/testsuite/gas/riscv/zicond-noarch.l create mode 100644 gas/testsuite/gas/riscv/zicond.d create mode 100644 gas/testsuite/gas/riscv/zicond.s diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index 19391d94e30..fbee34d90d3 100644 --- a/bfd/elfxx-riscv.c +++ b/bfd/elfxx-riscv.c @@ -1168,6 +1168,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] = {"zicbom", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zicbop", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zicboz", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zicond", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zicsr", ISA_SPEC_CLASS_20191213, 2, 0, 0 }, {"zicsr", ISA_SPEC_CLASS_20190608, 2, 0, 0 }, {"zifencei", ISA_SPEC_CLASS_20191213, 2, 0, 0 }, @@ -2258,6 +2259,8 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps, return riscv_subset_supports (rps, "zicbop"); case INSN_CLASS_ZICBOZ: return riscv_subset_supports (rps, "zicboz"); + case INSN_CLASS_ZICOND: + return riscv_subset_supports (rps, "zicond"); case INSN_CLASS_ZICSR: return riscv_subset_supports (rps, "zicsr"); case INSN_CLASS_ZIFENCEI: @@ -2407,6 +2410,8 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps, return "zicbop"; case INSN_CLASS_ZICBOZ: return "zicboz"; + case INSN_CLASS_ZICOND: + return "zicond"; case INSN_CLASS_ZICSR: return "zicsr"; case INSN_CLASS_ZIFENCEI: diff --git a/gas/testsuite/gas/riscv/zicond-noarch.d b/gas/testsuite/gas/riscv/zicond-noarch.d new file mode 100644 index 00000000000..f087315b4b1 --- /dev/null +++ b/gas/testsuite/gas/riscv/zicond-noarch.d @@ -0,0 +1,3 @@ +#as: -march=rv32i +#source: zicond.s +#error_output: zicond-noarch.l diff --git a/gas/testsuite/gas/riscv/zicond-noarch.l b/gas/testsuite/gas/riscv/zicond-noarch.l new file mode 100644 index 00000000000..c1aabf1b385 --- /dev/null +++ b/gas/testsuite/gas/riscv/zicond-noarch.l @@ -0,0 +1,3 @@ +.*: Assembler messages: +.*: Error: unrecognized opcode `czero\.eqz a0,a1,a2', extension `zicond' required +.*: Error: unrecognized opcode `czero\.nez a3,a4,a5', extension `zicond' required diff --git a/gas/testsuite/gas/riscv/zicond.d b/gas/testsuite/gas/riscv/zicond.d new file mode 100644 index 00000000000..1d61e0797b9 --- /dev/null +++ b/gas/testsuite/gas/riscv/zicond.d @@ -0,0 +1,11 @@ +#as: -march=rv32i_zicond +#source: zicond.s +#objdump: -d + +.*:[ ]+file format .* + +Disassembly of section .text: + +0+000 : +[ ]+[0-9a-f]+:[ ]+0ec5d533[ ]+czero\.eqz[ ]+a0,a1,a2 +[ ]+[0-9a-f]+:[ ]+0ef776b3[ ]+czero\.nez[ ]+a3,a4,a5 diff --git a/gas/testsuite/gas/riscv/zicond.s b/gas/testsuite/gas/riscv/zicond.s new file mode 100644 index 00000000000..dcf3d98ccd7 --- /dev/null +++ b/gas/testsuite/gas/riscv/zicond.s @@ -0,0 +1,3 @@ +target: + czero.eqz a0, a1, a2 + czero.nez a3, a4, a5 diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h index 85d35c1efc9..e8c35db775f 100644 --- a/include/opcode/riscv-opc.h +++ b/include/opcode/riscv-opc.h @@ -2113,6 +2113,11 @@ #define MASK_CBO_INVAL 0xfff07fff #define MATCH_CBO_ZERO 0x40200f #define MASK_CBO_ZERO 0xfff07fff +/* ZiCond instructions. */ +#define MATCH_CZERO_EQZ 0xe005033 +#define MASK_CZERO_EQZ 0xfe00707f +#define MATCH_CZERO_NEZ 0xe007033 +#define MASK_CZERO_NEZ 0xfe00707f /* Zawrs intructions. */ #define MATCH_WRS_NTO 0x00d00073 #define MASK_WRS_NTO 0xffffffff @@ -3115,6 +3120,9 @@ DECLARE_INSN(cbo_clean, MATCH_CBO_CLEAN, MASK_CBO_CLEAN); DECLARE_INSN(cbo_flush, MATCH_CBO_FLUSH, MASK_CBO_FLUSH); DECLARE_INSN(cbo_inval, MATCH_CBO_INVAL, MASK_CBO_INVAL); DECLARE_INSN(cbo_zero, MATCH_CBO_ZERO, MASK_CBO_ZERO); +/* ZiCond instructions. */ +DECLARE_INSN(czero_eqz, MATCH_CZERO_EQZ, MASK_CZERO_EQZ) +DECLARE_INSN(czero_nez, MATCH_CZERO_NEZ, MASK_CZERO_NEZ) /* Zawrs instructions. */ DECLARE_INSN(wrs_nto, MATCH_WRS_NTO, MASK_WRS_NTO) DECLARE_INSN(wrs_sto, MATCH_WRS_STO, MASK_WRS_STO) diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h index b4ae55249bb..a9df4946923 100644 --- a/include/opcode/riscv.h +++ b/include/opcode/riscv.h @@ -375,6 +375,7 @@ enum riscv_insn_class INSN_CLASS_Q, INSN_CLASS_F_AND_C, INSN_CLASS_D_AND_C, + INSN_CLASS_ZICOND, INSN_CLASS_ZICSR, INSN_CLASS_ZIFENCEI, INSN_CLASS_ZIHINTPAUSE, diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c index 6b65296a3f2..a62c74eb8fb 100644 --- a/opcodes/riscv-opc.c +++ b/opcodes/riscv-opc.c @@ -935,6 +935,10 @@ const struct riscv_opcode riscv_opcodes[] = {"cbo.inval", 0, INSN_CLASS_ZICBOM, "0(s)", MATCH_CBO_INVAL, MASK_CBO_INVAL, match_opcode, 0 }, {"cbo.zero", 0, INSN_CLASS_ZICBOZ, "0(s)", MATCH_CBO_ZERO, MASK_CBO_ZERO, match_opcode, 0 }, +/* ZiCond instructions. */ +{"czero.eqz", 0, INSN_CLASS_ZICOND, "d,s,t", MATCH_CZERO_EQZ, MASK_CZERO_EQZ, match_opcode, 0 }, +{"czero.nez", 0, INSN_CLASS_ZICOND, "d,s,t", MATCH_CZERO_NEZ, MASK_CZERO_NEZ, match_opcode, 0 }, + /* Zawrs instructions. */ {"wrs.nto", 0, INSN_CLASS_ZAWRS, "", MATCH_WRS_NTO, MASK_WRS_NTO, match_opcode, 0 }, {"wrs.sto", 0, INSN_CLASS_ZAWRS, "", MATCH_WRS_STO, MASK_WRS_STO, match_opcode, 0 },