[Integration 3/6] RISC-V/sifive: Add sifive cache control instructions.

Nelson Chu nelson.chu@sifive.com
Tue Mar 30 09:36:54 GMT 2021


bfd/
    * elfxx-riscv.c (riscv_sifive_ext_strtab): Added to record the
    supported sifive extensions.
    (riscv_vendor_ext_strtab): Updated.
gas/
    * config/tc-riscv.c (enum SIFIVE_EXT): Added.
    (op_sifive_hash): Added sifive opcode hash table.
    (md_begin): Init op_sifive_hash.
    (extended_ext_version_table): Added default versions of sifive
    cache control instructions to v0.1.
    (riscv_extended_subset_supports): Handle INSN_CLASS_XSIFIVE_*.
    (riscv_find_extended_opcode_hash): Search instruction opcode
    from op_sifive_hash.
    * testsuite/gas/riscv/extended/extended.exp: Updated.
    * gas/testsuite/gas/riscv/extended/sifive-insns.d: New testcase.
    * testsuite/gas/riscv/extended/sifive-insns.s: Likewise.
include/
    * opcode/riscv-opc-extended.h: Added sifive encoding macros.
    * opcode/riscv.h (enum riscv_extended_insn_class):
    Added INSN_CLASS_XSIFIVE_*.
opcodes/
    * riscv-opc.c (riscv_sifive_opcodes): Added sifive cache control
    instructions.
    (riscv_extended_opcodes): Updated.
---
 bfd/elfxx-riscv.c                               |  7 +++++++
 gas/config/tc-riscv.c                           | 24 ++++++++++++++++++++++--
 gas/testsuite/gas/riscv/extended/extended.exp   |  1 +
 gas/testsuite/gas/riscv/extended/sifive-insns.d | 12 ++++++++++++
 gas/testsuite/gas/riscv/extended/sifive-insns.s |  4 ++++
 include/opcode/riscv-opc-extended.h             |  7 +++++++
 include/opcode/riscv.h                          |  9 +++++++++
 opcodes/riscv-opc.c                             | 13 +++++++++++++
 8 files changed, 75 insertions(+), 2 deletions(-)
 create mode 100644 gas/testsuite/gas/riscv/extended/sifive-insns.d
 create mode 100644 gas/testsuite/gas/riscv/extended/sifive-insns.s

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 1ce85e0..425d6df 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1625,8 +1625,15 @@ static const char * const riscv_std_draft_ext_strtab[] =
   NULL
 };
 
+static const char * const riscv_sifive_ext_strtab[] =
+{
+  "xsifivecdiscarddlone", "xsifivecflushdlone", "xsifivecflushilone",
+  NULL
+};
+
 static const char ** const riscv_vendor_ext_strtab[] =
 {
+  (const char **) riscv_sifive_ext_strtab,
   NULL
 };
 
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 01484f0..ab6bf0a 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -40,7 +40,8 @@
    extensions.  */
 enum
 {
-  EXTENDED_EXT_NUM = 0
+  SIFIVE_EXT = 0,
+  EXTENDED_EXT_NUM
 };
 
 /* Information about an instruction, including its format, operands
@@ -158,6 +159,10 @@ static const struct riscv_ext_version ext_version_table[] =
 /* Default versions for draft and vendor extensions.  */
 static const struct riscv_ext_version extended_ext_version_table[] =
 {
+  {"xsifivecdiscarddlone", ISA_SPEC_CLASS_DRAFT, 0, 1},
+  {"xsifivecflushdlone",   ISA_SPEC_CLASS_DRAFT, 0, 1},
+  {"xsifivecflushilone",   ISA_SPEC_CLASS_DRAFT, 0, 1},
+
   /* Terminate the list.  */
   {NULL, 0, 0, 0}
 };
@@ -330,6 +335,12 @@ riscv_extended_subset_supports (int insn_class)
 {
   switch (insn_class)
     {
+    case INSN_CLASS_XSIFIVE_CDISCARDDLONE:
+      return riscv_subset_supports ("xsifivecdiscarddlone");
+    case INSN_CLASS_XSIFIVE_CFLUSHDLONE:
+      return riscv_subset_supports ("xsifivecflushdlone");
+    case INSN_CLASS_XSIFIVE_CFLUSHILONE:
+      return riscv_subset_supports ("xsifivecflushilone");
     default:
       as_fatal ("internal: unknown INSN_CLASS (0x%x)", insn_class);
       return FALSE;
@@ -510,6 +521,9 @@ riscv_set_abi_by_arch (void)
 /* Handle of the OPCODE hash table.  */
 static htab_t op_hash = NULL;
 
+/* Handle of the sifive OPCODE hash table.  */
+static htab_t op_sifive_hash;
+
 /* Handle of the type of .insn hash table.  */
 static htab_t insn_type_hash = NULL;
 
@@ -1303,6 +1317,9 @@ md_begin (void)
 
   /* Set the default alignment for the text section.  */
   record_alignment (text_section, riscv_opts.rvc ? 1 : 2);
+
+  /* Draft and vendor settings.  */
+  op_sifive_hash = init_opcode_hash (riscv_extended_opcodes[SIFIVE_EXT], FALSE);
 }
 
 static insn_t
@@ -1397,7 +1414,7 @@ append_insn (struct riscv_cl_insn *ip, expressionS *address_expr,
    the specific opcode hashes.  */
 
 static struct riscv_opcode *
-riscv_find_extended_opcode_hash (char *str ATTRIBUTE_UNUSED)
+riscv_find_extended_opcode_hash (char *str)
 {
   struct riscv_opcode *insn = NULL;
   unsigned int i;
@@ -1409,6 +1426,9 @@ riscv_find_extended_opcode_hash (char *str ATTRIBUTE_UNUSED)
 
       switch (i)
 	{
+	case SIFIVE_EXT:
+	  insn = (struct riscv_opcode *) str_hash_find (op_sifive_hash, str);
+	  continue;
 	default:
 	  break;
 	}
diff --git a/gas/testsuite/gas/riscv/extended/extended.exp b/gas/testsuite/gas/riscv/extended/extended.exp
index 00812fe..bebcdbc 100644
--- a/gas/testsuite/gas/riscv/extended/extended.exp
+++ b/gas/testsuite/gas/riscv/extended/extended.exp
@@ -19,4 +19,5 @@
 # MA 02110-1301, USA.
 
 if [istarget riscv*-*-*] {
+    run_dump_tests "sifive-insns"
 }
diff --git a/gas/testsuite/gas/riscv/extended/sifive-insns.d b/gas/testsuite/gas/riscv/extended/sifive-insns.d
new file mode 100644
index 0000000..fa07028
--- /dev/null
+++ b/gas/testsuite/gas/riscv/extended/sifive-insns.d
@@ -0,0 +1,12 @@
+#as: -march=rv32i_xsifivecdiscarddlone_xsifivecflushdlone_xsifivecflushilone
+#objdump: -dr
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+0:[ 	]+fc050073[ 	]+cflush.d.l1[ 	]+a0
+[ 	]+4:[ 	]+fc250073[ 	]+cdiscard.d.l1[ 	]+a0
+[ 	]+8:[ 	]+fc100073[ 	]+cflush.i.l1
diff --git a/gas/testsuite/gas/riscv/extended/sifive-insns.s b/gas/testsuite/gas/riscv/extended/sifive-insns.s
new file mode 100644
index 0000000..b44dad0
--- /dev/null
+++ b/gas/testsuite/gas/riscv/extended/sifive-insns.s
@@ -0,0 +1,4 @@
+target:
+	cflush.d.l1	x10
+	cdiscard.d.l1	x10
+	cflush.i.l1
diff --git a/include/opcode/riscv-opc-extended.h b/include/opcode/riscv-opc-extended.h
index 8641c4c..19511b9 100644
--- a/include/opcode/riscv-opc-extended.h
+++ b/include/opcode/riscv-opc-extended.h
@@ -20,4 +20,11 @@
 
 #ifndef RISCV_EXTENDED_ENCODING_H
 #define RISCV_EXTENDED_ENCODING_H
+/* SiFive instructions.  */
+#define MATCH_CFLUSH_D_L1	0xfc000073
+#define MASK_CFLUSH_D_L1	0xfff07fff
+#define MATCH_CDISCARD_D_L1	0xfc200073
+#define MASK_CDISCARD_D_L1	0xfff07fff
+#define MATCH_CFLUSH_I_L1	0xfc100073
+#define MASK_CFLUSH_I_L1	0xffffffff
 #endif /* RISCV_EXTENDED_ENCODING_H */
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index 50ccf6f..b35ab1e 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -436,6 +436,15 @@ extern const struct riscv_opcode riscv_insn_types[];
 
 /* Draft and vendor extensions.  */
 
+/* All RISC-V draft or vendor instructions belong to at least one of
+   these classes.  */
+enum riscv_extended_insn_class
+{
+  INSN_CLASS_XSIFIVE_CFLUSHDLONE = INSN_CLASS_EXTENDED,
+  INSN_CLASS_XSIFIVE_CFLUSHILONE,
+  INSN_CLASS_XSIFIVE_CDISCARDDLONE,
+};
+
 extern const struct riscv_opcode *riscv_extended_opcodes[];
 
 #endif /* _RISCV_H_ */
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 6a077d0..9fb0723 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -944,8 +944,21 @@ const struct riscv_opcode riscv_insn_types[] =
 
 /* Draft and vendor extensions.  */
 
+/* SiFive extensions.  */
+const struct riscv_opcode riscv_sifive_opcodes[] =
+{
+/* name, xlen, isa, operands, match, mask, match_func, pinfo.  */
+{"cflush.d.l1",   0, INSN_CLASS_XSIFIVE_CFLUSHDLONE,   "s", MATCH_CFLUSH_D_L1, MASK_CFLUSH_D_L1, match_opcode, 0 },
+{"cdiscard.d.l1", 0, INSN_CLASS_XSIFIVE_CDISCARDDLONE, "s", MATCH_CDISCARD_D_L1, MASK_CDISCARD_D_L1, match_opcode, 0 },
+{"cflush.i.l1",   0, INSN_CLASS_XSIFIVE_CFLUSHILONE,   "",  MATCH_CFLUSH_I_L1, MASK_CFLUSH_I_L1, match_opcode, 0 },
+
+/* Terminate the list.  */
+{0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0 },
+};
+
 /* The supported draft and vendor extensions.  */
 const struct riscv_opcode *riscv_extended_opcodes[] =
 {
+  riscv_sifive_opcodes,
   NULL
 };
-- 
2.7.4



More information about the Binutils mailing list