[PATCH v4 2/3] RISC-V: Add 'Zmmul' extension
Tsukasa OI
research_trasio@irq.a4lg.com
Tue Aug 9 03:37:26 GMT 2022
This commit adds 'Zmmul' (multiply-only subset of 'M') extension and
changes so that multiply instructions a part of 'Zmmul'.
bfd/ChangeLog:
* elfxx-riscv.c (riscv_implicit_subsets): Add 'Zmmul' extension
implied by 'M'. (riscv_supported_std_z_ext) Add 'Zmmul'
extension. (riscv_multi_subset_supports): Add handling for
new instruction class.
gas/ChangeLog:
* testsuite/gas/riscv/attribute-09.d: Include implied 'Zmmul'
extension to expected output.
* testsuite/gas/riscv/option-arch-02.d: Include implied 'Zmmul'
extension to expected output.
* testsuite/gas/riscv/zmmul-32.d: New expected output.
* testsuite/gas/riscv/zmmul-64.d: Likewise.
include/ChangeLog:
* opcode/riscv.h (enum riscv_insn_class): Add new instruction
class INSN_CLASS_ZMMUL.
opcodes/ChangeLog:
* riscv-opc.c (riscv_opcodes): Change multiply instructions so
that a part of 'Zmmul' extension.
sim/ChangeLog:
* riscv/sim-main.c (execute_one): Add INSN_CLASS_ZMMUL
to run multiply instructions correctly.
* testsuite/riscv/m-ext.s: New test.
---
bfd/elfxx-riscv.c | 6 ++++++
gas/testsuite/gas/riscv/attribute-09.d | 2 +-
gas/testsuite/gas/riscv/option-arch-02.d | 2 +-
gas/testsuite/gas/riscv/zmmul-32.d | 14 +++++++++++++
gas/testsuite/gas/riscv/zmmul-64.d | 15 ++++++++++++++
include/opcode/riscv.h | 1 +
opcodes/riscv-opc.c | 26 ++++++++++++------------
sim/riscv/sim-main.c | 1 +
sim/testsuite/riscv/m-ext.s | 18 ++++++++++++++++
9 files changed, 70 insertions(+), 15 deletions(-)
create mode 100644 gas/testsuite/gas/riscv/zmmul-32.d
create mode 100644 gas/testsuite/gas/riscv/zmmul-64.d
create mode 100644 sim/testsuite/riscv/m-ext.s
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 0b2021f5cc7..b0b89158152 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1065,6 +1065,7 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] =
{"e", "i", check_implicit_always},
{"i", "zicsr", check_implicit_for_i},
{"i", "zifencei", check_implicit_for_i},
+ {"m", "zmmul", check_implicit_always},
{"g", "i", check_implicit_always},
{"g", "m", check_implicit_always},
{"g", "a", check_implicit_always},
@@ -1186,6 +1187,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] =
{"zifencei", ISA_SPEC_CLASS_20191213, 2, 0, 0 },
{"zifencei", ISA_SPEC_CLASS_20190608, 2, 0, 0 },
{"zihintpause", ISA_SPEC_CLASS_DRAFT, 2, 0, 0 },
+ {"zmmul", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zfh", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zfhmin", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zfinx", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
@@ -2313,6 +2315,8 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
return riscv_subset_supports (rps, "zihintpause");
case INSN_CLASS_M:
return riscv_subset_supports (rps, "m");
+ case INSN_CLASS_ZMMUL:
+ return riscv_subset_supports (rps, "zmmul");
case INSN_CLASS_A:
return riscv_subset_supports (rps, "a");
case INSN_CLASS_F:
@@ -2428,6 +2432,8 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
return "zihintpause";
case INSN_CLASS_M:
return "m";
+ case INSN_CLASS_ZMMUL:
+ return _ ("m' or `zmmul");
case INSN_CLASS_A:
return "a";
case INSN_CLASS_F:
diff --git a/gas/testsuite/gas/riscv/attribute-09.d b/gas/testsuite/gas/riscv/attribute-09.d
index fc87f82c554..c92dc970eea 100644
--- a/gas/testsuite/gas/riscv/attribute-09.d
+++ b/gas/testsuite/gas/riscv/attribute-09.d
@@ -3,4 +3,4 @@
#source: empty.s
Attribute Section: riscv
File Attributes
- Tag_RISCV_arch: "rv32i2p2_m2p0_zicsr2p0"
+ Tag_RISCV_arch: "rv32i2p2_m2p0_zicsr2p0_zmmul1p0"
diff --git a/gas/testsuite/gas/riscv/option-arch-02.d b/gas/testsuite/gas/riscv/option-arch-02.d
index 9ca013e507e..3c27419f9d3 100644
--- a/gas/testsuite/gas/riscv/option-arch-02.d
+++ b/gas/testsuite/gas/riscv/option-arch-02.d
@@ -4,5 +4,5 @@
Attribute Section: riscv
File Attributes
- Tag_RISCV_arch: "rv64i2p0_m3p0_f2p0_d3p0_c2p0_xvendor32x3p0"
+ Tag_RISCV_arch: "rv64i2p0_m3p0_f2p0_d3p0_c2p0_zmmul1p0_xvendor32x3p0"
#...
diff --git a/gas/testsuite/gas/riscv/zmmul-32.d b/gas/testsuite/gas/riscv/zmmul-32.d
new file mode 100644
index 00000000000..c9cf56ab33f
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zmmul-32.d
@@ -0,0 +1,14 @@
+#as: -march=rv32im -defsym zmmul=1
+#source: m-ext.s
+#objdump: -d
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ ]+[0-9a-f]+:[ ]+02c58533[ ]+mul[ ]+a0,a1,a2
+[ ]+[0-9a-f]+:[ ]+02c59533[ ]+mulh[ ]+a0,a1,a2
+[ ]+[0-9a-f]+:[ ]+02c5a533[ ]+mulhsu[ ]+a0,a1,a2
+[ ]+[0-9a-f]+:[ ]+02c5b533[ ]+mulhu[ ]+a0,a1,a2
diff --git a/gas/testsuite/gas/riscv/zmmul-64.d b/gas/testsuite/gas/riscv/zmmul-64.d
new file mode 100644
index 00000000000..67ef3604755
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zmmul-64.d
@@ -0,0 +1,15 @@
+#as: -march=rv64im -defsym zmmul=1 -defsym rv64=1
+#source: m-ext.s
+#objdump: -d
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ ]+[0-9a-f]+:[ ]+02c58533[ ]+mul[ ]+a0,a1,a2
+[ ]+[0-9a-f]+:[ ]+02c59533[ ]+mulh[ ]+a0,a1,a2
+[ ]+[0-9a-f]+:[ ]+02c5a533[ ]+mulhsu[ ]+a0,a1,a2
+[ ]+[0-9a-f]+:[ ]+02c5b533[ ]+mulhu[ ]+a0,a1,a2
+[ ]+[0-9a-f]+:[ ]+02c5853b[ ]+mulw[ ]+a0,a1,a2
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index b115e338a05..f1dabeaab8e 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -367,6 +367,7 @@ enum riscv_insn_class
INSN_CLASS_ZICSR,
INSN_CLASS_ZIFENCEI,
INSN_CLASS_ZIHINTPAUSE,
+ INSN_CLASS_ZMMUL,
INSN_CLASS_F_OR_ZFINX,
INSN_CLASS_D_OR_ZDINX,
INSN_CLASS_Q_OR_ZQINX,
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 2f9945aa930..79be78eb367 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -558,19 +558,19 @@ const struct riscv_opcode riscv_opcodes[] =
{"amominu.d.aqrl", 64, INSN_CLASS_A, "d,t,0(s)", MATCH_AMOMINU_D|MASK_AQRL, MASK_AMOMINU_D|MASK_AQRL, match_opcode, INSN_DREF|INSN_8_BYTE },
/* Multiply/Divide instruction subset. */
-{"mul", 0, INSN_CLASS_M, "d,s,t", MATCH_MUL, MASK_MUL, match_opcode, 0 },
-{"mulh", 0, INSN_CLASS_M, "d,s,t", MATCH_MULH, MASK_MULH, match_opcode, 0 },
-{"mulhu", 0, INSN_CLASS_M, "d,s,t", MATCH_MULHU, MASK_MULHU, match_opcode, 0 },
-{"mulhsu", 0, INSN_CLASS_M, "d,s,t", MATCH_MULHSU, MASK_MULHSU, match_opcode, 0 },
-{"div", 0, INSN_CLASS_M, "d,s,t", MATCH_DIV, MASK_DIV, match_opcode, 0 },
-{"divu", 0, INSN_CLASS_M, "d,s,t", MATCH_DIVU, MASK_DIVU, match_opcode, 0 },
-{"rem", 0, INSN_CLASS_M, "d,s,t", MATCH_REM, MASK_REM, match_opcode, 0 },
-{"remu", 0, INSN_CLASS_M, "d,s,t", MATCH_REMU, MASK_REMU, match_opcode, 0 },
-{"mulw", 64, INSN_CLASS_M, "d,s,t", MATCH_MULW, MASK_MULW, match_opcode, 0 },
-{"divw", 64, INSN_CLASS_M, "d,s,t", MATCH_DIVW, MASK_DIVW, match_opcode, 0 },
-{"divuw", 64, INSN_CLASS_M, "d,s,t", MATCH_DIVUW, MASK_DIVUW, match_opcode, 0 },
-{"remw", 64, INSN_CLASS_M, "d,s,t", MATCH_REMW, MASK_REMW, match_opcode, 0 },
-{"remuw", 64, INSN_CLASS_M, "d,s,t", MATCH_REMUW, MASK_REMUW, match_opcode, 0 },
+{"mul", 0, INSN_CLASS_ZMMUL, "d,s,t", MATCH_MUL, MASK_MUL, match_opcode, 0 },
+{"mulh", 0, INSN_CLASS_ZMMUL, "d,s,t", MATCH_MULH, MASK_MULH, match_opcode, 0 },
+{"mulhu", 0, INSN_CLASS_ZMMUL, "d,s,t", MATCH_MULHU, MASK_MULHU, match_opcode, 0 },
+{"mulhsu", 0, INSN_CLASS_ZMMUL, "d,s,t", MATCH_MULHSU, MASK_MULHSU, match_opcode, 0 },
+{"div", 0, INSN_CLASS_M, "d,s,t", MATCH_DIV, MASK_DIV, match_opcode, 0 },
+{"divu", 0, INSN_CLASS_M, "d,s,t", MATCH_DIVU, MASK_DIVU, match_opcode, 0 },
+{"rem", 0, INSN_CLASS_M, "d,s,t", MATCH_REM, MASK_REM, match_opcode, 0 },
+{"remu", 0, INSN_CLASS_M, "d,s,t", MATCH_REMU, MASK_REMU, match_opcode, 0 },
+{"mulw", 64, INSN_CLASS_ZMMUL, "d,s,t", MATCH_MULW, MASK_MULW, match_opcode, 0 },
+{"divw", 64, INSN_CLASS_M, "d,s,t", MATCH_DIVW, MASK_DIVW, match_opcode, 0 },
+{"divuw", 64, INSN_CLASS_M, "d,s,t", MATCH_DIVUW, MASK_DIVUW, match_opcode, 0 },
+{"remw", 64, INSN_CLASS_M, "d,s,t", MATCH_REMW, MASK_REMW, match_opcode, 0 },
+{"remuw", 64, INSN_CLASS_M, "d,s,t", MATCH_REMUW, MASK_REMUW, match_opcode, 0 },
/* Half-precision floating-point instruction subset. */
{"flh", 0, INSN_CLASS_ZFHMIN, "D,o(s)", MATCH_FLH, MASK_FLH, match_opcode, INSN_DREF|INSN_2_BYTE },
diff --git a/sim/riscv/sim-main.c b/sim/riscv/sim-main.c
index 62f475671c9..ea88103098a 100644
--- a/sim/riscv/sim-main.c
+++ b/sim/riscv/sim-main.c
@@ -936,6 +936,7 @@ execute_one (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
case INSN_CLASS_I:
return execute_i (cpu, iw, op);
case INSN_CLASS_M:
+ case INSN_CLASS_ZMMUL:
return execute_m (cpu, iw, op);
default:
TRACE_INSN (cpu, "UNHANDLED EXTENSION: %d", op->insn_class);
diff --git a/sim/testsuite/riscv/m-ext.s b/sim/testsuite/riscv/m-ext.s
new file mode 100644
index 00000000000..b85397a32a0
--- /dev/null
+++ b/sim/testsuite/riscv/m-ext.s
@@ -0,0 +1,18 @@
+# check that the RV32M instructions run without any fault.
+# mach: riscv
+
+.include "testutils.inc"
+
+ start
+
+ .option arch, +m
+ mul x0, x1, x2
+ mulh x0, x1, x2
+ mulhu x0, x1, x2
+ mulhsu x0, x1, x2
+ div x0, x1, x2
+ divu x0, x1, x2
+ rem x0, x1, x2
+ remu x0, x1, x2
+
+ pass
--
2.34.1
More information about the Binutils
mailing list