From 595e49a4b7c6769ef23a2573148db72872c61935 Mon Sep 17 00:00:00 2001 From: Nelson Chu Date: Wed, 20 Nov 2024 16:30:39 +0800 Subject: [PATCH] RISC-V: Support SiFive extensions: xsfvqmaccdod, xsfvqmaccqoq and xsfvfnrclipxfqf Those SiFive extensions have been published on the web for a while, and we plan to implement intrinsics in GCC for those instructions soon. NOTE: The original patch was written by Nelson when he was still working at SiFive, and Kito rebased it to the trunk. Therefore, I kept the author as Nelson with his SiFive email. Document links: xsfvqmaccdod: https://www.sifive.com/document-file/sifive-int8-matrix-multiplication-extensions-specification xsfvqmaccqoq: https://www.sifive.com/document-file/sifive-int8-matrix-multiplication-extensions-specification xsfvfnrclipxfqf: https://www.sifive.com/document-file/fp32-to-int8-ranged-clip-instructions Co-authored-by: Kito Cheng --- bfd/elfxx-riscv.c | 14 +++++++++++ gas/NEWS | 5 ++-- gas/testsuite/gas/riscv/march-help.l | 3 +++ .../gas/riscv/march-imply-xsfvfnrclipxfqf.d | 6 +++++ .../gas/riscv/march-imply-xsfvqmaccdod.d | 6 +++++ .../gas/riscv/march-imply-xsfvqmaccqoq.d | 6 +++++ gas/testsuite/gas/riscv/sifive-insns.d | 10 ++++++++ gas/testsuite/gas/riscv/sifive-insns.s | 25 +++++++++++++++++++ include/opcode/riscv-opc.h | 22 ++++++++++++++++ include/opcode/riscv.h | 3 +++ opcodes/riscv-opc.c | 14 +++++++++++ 11 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 gas/testsuite/gas/riscv/march-imply-xsfvfnrclipxfqf.d create mode 100644 gas/testsuite/gas/riscv/march-imply-xsfvqmaccdod.d create mode 100644 gas/testsuite/gas/riscv/march-imply-xsfvqmaccqoq.d diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index 701c7242920..45da83e6926 100644 --- a/bfd/elfxx-riscv.c +++ b/bfd/elfxx-riscv.c @@ -1187,6 +1187,11 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] = {"a", "+zaamo,+zalrsc", check_implicit_always}, {"xsfvcp", "+zve32x", check_implicit_always}, + {"xsfvqmaccqoq", "+zve32x,+zvl256b", check_implicit_always}, + {"xsfvqmaccqoq", "+zvl256b", check_implicit_always}, + {"xsfvqmaccdod", "+zve32x,+zvl128b", check_implicit_always}, + {"xsfvfnrclipxfqf", "+zve32f", check_implicit_always}, + {"v", "+zve64d,+zvl128b", check_implicit_always}, {"zvfh", "+zvfhmin,+zfhmin", check_implicit_always}, {"zvfhmin", "+zve32f", check_implicit_always}, @@ -1493,6 +1498,9 @@ static struct riscv_supported_ext riscv_supported_vendor_x_ext[] = {"xventanacondops", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"xsfvcp", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"xsfcease", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"xsfvqmaccqoq", ISA_SPEC_CLASS_DRAFT, 1, 0, 0}, + {"xsfvqmaccdod", ISA_SPEC_CLASS_DRAFT, 1, 0, 0}, + {"xsfvfnrclipxfqf", ISA_SPEC_CLASS_DRAFT, 1, 0, 0}, {NULL, 0, 0, 0, 0} }; @@ -2776,6 +2784,12 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps, return riscv_subset_supports (rps, "xsfvcp"); case INSN_CLASS_XSFCEASE: return riscv_subset_supports (rps, "xsfcease"); + case INSN_CLASS_XSFVQMACCQOQ: + return riscv_subset_supports (rps, "xsfvqmaccqoq"); + case INSN_CLASS_XSFVQMACCDOD: + return riscv_subset_supports (rps, "xsfvqmaccdod"); + case INSN_CLASS_XSFVFNRCLIPXFQF: + return riscv_subset_supports (rps, "xsfvfnrclipxfqf"); default: rps->error_handler (_("internal: unreachable INSN_CLASS_*")); diff --git a/gas/NEWS b/gas/NEWS index 67ca298d11e..d4143da39c4 100644 --- a/gas/NEWS +++ b/gas/NEWS @@ -6,8 +6,9 @@ * On x86 emulation support (for secondary targets) was dropped. -* Add support for RISC-V Zcmp (cm.mva01s, cm.mvsa01), Smrnmi and CORE-V - (xcvbitmanip, xcvsimd) extensions with version 1.0. +* Add support for RISC-V Zcmp (cm.mva01s, cm.mvsa01), Smrnmi, CORE-V + (xcvbitmanip, xcvsimd) extensions with version 1.0 and more SiFive + extensions (xsfvqmaccdod, xsfvqmaccqoq and xsfvfnrclipxfqf). Changes in 2.43: diff --git a/gas/testsuite/gas/riscv/march-help.l b/gas/testsuite/gas/riscv/march-help.l index 4234b05598f..71cccb77102 100644 --- a/gas/testsuite/gas/riscv/march-help.l +++ b/gas/testsuite/gas/riscv/march-help.l @@ -157,3 +157,6 @@ All available -march extensions for RISC-V: xventanacondops 1.0 xsfvcp 1.0 xsfcease 1.0 + xsfvqmaccqoq 1.0 + xsfvqmaccdod 1.0 + xsfvfnrclipxfqf 1.0 diff --git a/gas/testsuite/gas/riscv/march-imply-xsfvfnrclipxfqf.d b/gas/testsuite/gas/riscv/march-imply-xsfvfnrclipxfqf.d new file mode 100644 index 00000000000..e77fee0298c --- /dev/null +++ b/gas/testsuite/gas/riscv/march-imply-xsfvfnrclipxfqf.d @@ -0,0 +1,6 @@ +#as: -march=rv32i_xsfvfnrclipxfqf -march-attr -misa-spec=20191213 +#readelf: -A +#source: empty.s +Attribute Section: riscv +File Attributes + Tag_RISCV_arch: "rv32i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvl32b1p0_xsfvfnrclipxfqf1p0" diff --git a/gas/testsuite/gas/riscv/march-imply-xsfvqmaccdod.d b/gas/testsuite/gas/riscv/march-imply-xsfvqmaccdod.d new file mode 100644 index 00000000000..47e91f89367 --- /dev/null +++ b/gas/testsuite/gas/riscv/march-imply-xsfvqmaccdod.d @@ -0,0 +1,6 @@ +#as: -march=rv32i_xsfvqmaccdod -march-attr -misa-spec=20191213 +#readelf: -A +#source: empty.s +Attribute Section: riscv +File Attributes + Tag_RISCV_arch: "rv32i2p1_zicsr2p0_zve32x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0_xsfvqmaccdod1p0" diff --git a/gas/testsuite/gas/riscv/march-imply-xsfvqmaccqoq.d b/gas/testsuite/gas/riscv/march-imply-xsfvqmaccqoq.d new file mode 100644 index 00000000000..784a8acd09d --- /dev/null +++ b/gas/testsuite/gas/riscv/march-imply-xsfvqmaccqoq.d @@ -0,0 +1,6 @@ +#as: -march=rv32i_xsfvqmaccqoq -march-attr -misa-spec=20191213 +#readelf: -A +#source: empty.s +Attribute Section: riscv +File Attributes + Tag_RISCV_arch: "rv32i2p1_zicsr2p0_zve32x1p0_zvl128b1p0_zvl256b1p0_zvl32b1p0_zvl64b1p0_xsfvqmaccqoq1p0" diff --git a/gas/testsuite/gas/riscv/sifive-insns.d b/gas/testsuite/gas/riscv/sifive-insns.d index 610f62588b3..d1917b47056 100644 --- a/gas/testsuite/gas/riscv/sifive-insns.d +++ b/gas/testsuite/gas/riscv/sifive-insns.d @@ -36,3 +36,13 @@ Disassembly of section .text: [ ]+[0-9a-f]+:[ ]+fc27b05b[ ]+sf.vc.v.ivw[ ]+0x3,v0,v2,15 [ ]+[0-9a-f]+:[ ]+fc25d05b[ ]+sf.vc.v.fvw[ ]+0x1,v0,v2,fa1 [ ]+[0-9a-f]+:[ ]+30500073[ ]+sf.cease +[ ]+[0-9a-f]+:[ ]+f2c4225b[ ]+sf.vqmaccu.4x8x4[ ]+v4,v8,v12 +[ ]+[0-9a-f]+:[ ]+f6c4225b[ ]+sf.vqmacc.4x8x4[ ]+v4,v8,v12 +[ ]+[0-9a-f]+:[ ]+fac4225b[ ]+sf.vqmaccus.4x8x4[ ]+v4,v8,v12 +[ ]+[0-9a-f]+:[ ]+fec4225b[ ]+sf.vqmaccsu.4x8x4[ ]+v4,v8,v12 +[ ]+[0-9a-f]+:[ ]+b2c4225b[ ]+sf.vqmaccu.2x8x2[ ]+v4,v8,v12 +[ ]+[0-9a-f]+:[ ]+b6c4225b[ ]+sf.vqmacc.2x8x2[ ]+v4,v8,v12 +[ ]+[0-9a-f]+:[ ]+bac4225b[ ]+sf.vqmaccus.2x8x2[ ]+v4,v8,v12 +[ ]+[0-9a-f]+:[ ]+bec4225b[ ]+sf.vqmaccsu.2x8x2[ ]+v4,v8,v12 +[ ]+[0-9a-f]+:[ ]+8a86525b[ ]+sf.vfnrclip.xu.f.qf[ ]+v4,v8,fa2 +[ ]+[0-9a-f]+:[ ]+8e86525b[ ]+sf.vfnrclip.x.f.qf[ ]+v4,v8,fa2 diff --git a/gas/testsuite/gas/riscv/sifive-insns.s b/gas/testsuite/gas/riscv/sifive-insns.s index cdf90c1b3ba..5005fb3b128 100644 --- a/gas/testsuite/gas/riscv/sifive-insns.s +++ b/gas/testsuite/gas/riscv/sifive-insns.s @@ -37,3 +37,28 @@ .option arch, +xsfcease1p0 sf.cease .option pop + + # xsfvqmaccqoq + .option push + .option arch, +xsfvqmaccqoq + sf.vqmaccu.4x8x4 v4, v8, v12 + sf.vqmacc.4x8x4 v4, v8, v12 + sf.vqmaccus.4x8x4 v4, v8, v12 + sf.vqmaccsu.4x8x4 v4, v8, v12 + .option pop + + # xsfvqmaccdod + .option push + .option arch, +xsfvqmaccdod + sf.vqmaccu.2x8x2 v4, v8, v12 + sf.vqmacc.2x8x2 v4, v8, v12 + sf.vqmaccus.2x8x2 v4, v8, v12 + sf.vqmaccsu.2x8x2 v4, v8, v12 + .option pop + + # xsfvfnrclipxfqf + .option push + .option arch, +xsfvfnrclipxfqf + sf.vfnrclip.xu.f.qf v4, v8, f12 + sf.vfnrclip.x.f.qf v4, v8, f12 + .option pop diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h index 8165686817b..253148b50be 100644 --- a/include/opcode/riscv-opc.h +++ b/include/opcode/riscv-opc.h @@ -3745,6 +3745,28 @@ /* Vendor-specific (SiFive) cease instruction. */ #define MATCH_SF_CEASE 0x30500073 #define MASK_SF_CEASE 0xffffffff +/* SiFive custom int8 matrix-multiply instruction. */ +#define MATCH_SFVQMACCU4X8X4 0xf200205b +#define MASK_SFVQMACCU4X8X4 0xfe00707f +#define MATCH_SFVQMACC4X8X4 0xf600205b +#define MASK_SFVQMACC4X8X4 0xfe00707f +#define MATCH_SFVQMACCUS4X8X4 0xfa00205b +#define MASK_SFVQMACCUS4X8X4 0xfe00707f +#define MATCH_SFVQMACCSU4X8X4 0xfe00205b +#define MASK_SFVQMACCSU4X8X4 0xfe00707f +#define MATCH_SFVQMACCU2X8X2 0xb200205b +#define MASK_SFVQMACCU2X8X2 0xfe00707f +#define MATCH_SFVQMACC2X8X2 0xb600205b +#define MASK_SFVQMACC2X8X2 0xfe00707f +#define MATCH_SFVQMACCUS2X8X2 0xba00205b +#define MASK_SFVQMACCUS2X8X2 0xfe00707f +#define MATCH_SFVQMACCSU2X8X2 0xbe00205b +#define MASK_SFVQMACCSU2X8X2 0xfe00707f +/* FP32-to-int8 Ranged Clip Instructions (Xsfvfnrclipxfqf). */ +#define MATCH_SFVFNRCLIPXUFQF 0x8a00505b +#define MASK_SFVFNRCLIPXUFQF 0xfe00707f +#define MATCH_SFVFNRCLIPXFQF 0x8e00505b +#define MASK_SFVFNRCLIPXFQF 0xfe00707f /* Unprivileged Counter/Timers CSR addresses. */ #define CSR_CYCLE 0xc00 #define CSR_TIME 0xc01 diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h index 5e5131e2d40..fedfdd24468 100644 --- a/include/opcode/riscv.h +++ b/include/opcode/riscv.h @@ -554,6 +554,9 @@ enum riscv_insn_class INSN_CLASS_XVENTANACONDOPS, INSN_CLASS_XSFVCP, INSN_CLASS_XSFCEASE, + INSN_CLASS_XSFVQMACCQOQ, + INSN_CLASS_XSFVQMACCDOD, + INSN_CLASS_XSFVFNRCLIPXFQF, }; /* This structure holds information for a particular instruction. */ diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c index 787beb7c029..200fe26d292 100644 --- a/opcodes/riscv-opc.c +++ b/opcodes/riscv-opc.c @@ -3449,6 +3449,20 @@ const struct riscv_opcode riscv_opcodes[] = /* Vendor-specific (SiFive) cease instruction. */ {"sf.cease", 0, INSN_CLASS_XSFCEASE, "", MATCH_SF_CEASE, MASK_SF_CEASE, match_opcode, 0 }, +/* SiFive custom int8 matrix-multiply instructions. */ +{"sf.vqmaccu.4x8x4", 0, INSN_CLASS_XSFVQMACCQOQ, "Vd,Vs,Vt", MATCH_SFVQMACCU4X8X4, MASK_SFVQMACCU4X8X4, match_opcode, 0}, +{"sf.vqmacc.4x8x4", 0, INSN_CLASS_XSFVQMACCQOQ, "Vd,Vs,Vt", MATCH_SFVQMACC4X8X4, MASK_SFVQMACC4X8X4, match_opcode, 0}, +{"sf.vqmaccus.4x8x4", 0, INSN_CLASS_XSFVQMACCQOQ, "Vd,Vs,Vt", MATCH_SFVQMACCUS4X8X4, MASK_SFVQMACCUS4X8X4, match_opcode, 0}, +{"sf.vqmaccsu.4x8x4", 0, INSN_CLASS_XSFVQMACCQOQ, "Vd,Vs,Vt", MATCH_SFVQMACCSU4X8X4, MASK_SFVQMACCSU4X8X4, match_opcode, 0}, +{"sf.vqmaccu.2x8x2", 0, INSN_CLASS_XSFVQMACCDOD, "Vd,Vs,Vt", MATCH_SFVQMACCU2X8X2, MASK_SFVQMACCU2X8X2, match_opcode, 0}, +{"sf.vqmacc.2x8x2", 0, INSN_CLASS_XSFVQMACCDOD, "Vd,Vs,Vt", MATCH_SFVQMACC2X8X2, MASK_SFVQMACC2X8X2, match_opcode, 0}, +{"sf.vqmaccus.2x8x2", 0, INSN_CLASS_XSFVQMACCDOD, "Vd,Vs,Vt", MATCH_SFVQMACCUS2X8X2, MASK_SFVQMACCUS2X8X2, match_opcode, 0}, +{"sf.vqmaccsu.2x8x2", 0, INSN_CLASS_XSFVQMACCDOD, "Vd,Vs,Vt", MATCH_SFVQMACCSU2X8X2, MASK_SFVQMACCSU2X8X2, match_opcode, 0}, + +/* SiFive FP32-to-int8 ranged clip instructions (Xsfvfnrclipxfqf). */ +{"sf.vfnrclip.xu.f.qf", 0, INSN_CLASS_XSFVFNRCLIPXFQF, "Vd,Vt,S", MATCH_SFVFNRCLIPXUFQF, MASK_SFVFNRCLIPXUFQF, match_opcode, 0}, +{"sf.vfnrclip.x.f.qf", 0, INSN_CLASS_XSFVFNRCLIPXFQF, "Vd,Vt,S", MATCH_SFVFNRCLIPXFQF, MASK_SFVFNRCLIPXFQF, match_opcode, 0}, + /* Terminate the list. */ {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0} };