@@ -1243,6 +1243,9 @@ static struct riscv_supported_ext riscv_supported_vendor_x_ext[] =
{"xtheadmemidx", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"xtheadmempair", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"xtheadsync", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"xsfcdiscarddlone", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"xsfcflushdlone", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"xsfcflushilone", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{NULL, 0, 0, 0, 0}
};
@@ -2434,6 +2437,12 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
return riscv_subset_supports (rps, "xtheadmempair");
case INSN_CLASS_XTHEADSYNC:
return riscv_subset_supports (rps, "xtheadsync");
+ case INSN_CLASS_XSF_CDISCARDDLONE:
+ return riscv_subset_supports (rps, "xsfcdiscarddlone");
+ case INSN_CLASS_XSF_CFLUSHDLONE:
+ return riscv_subset_supports (rps, "xsfcflushdlone");
+ case INSN_CLASS_XSF_CFLUSHILONE:
+ return riscv_subset_supports (rps, "xsfcflushilone");
default:
rps->error_handler
(_("internal: unreachable INSN_CLASS_*"));
@@ -2588,6 +2597,12 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
return "xtheadmempair";
case INSN_CLASS_XTHEADSYNC:
return "xtheadsync";
+ case INSN_CLASS_XSF_CDISCARDDLONE:
+ return "xsfcdiscarddlone";
+ case INSN_CLASS_XSF_CFLUSHDLONE:
+ return "xsfcflushdlone";
+ case INSN_CLASS_XSF_CFLUSHILONE:
+ return "xsfcflushilone";
default:
rps->error_handler
(_("internal: unreachable INSN_CLASS_*"));
new file mode 100644
@@ -0,0 +1,12 @@
+#as: -march=rv32i_xsfcdiscarddlone_xsfcflushdlone_xsfcflushilone
+#objdump: -dr
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ ]+0:[ ]+fc050073[ ]+sf.cflush.d.l1[ ]+a0
+[ ]+4:[ ]+fc250073[ ]+sf.cdiscard.d.l1[ ]+a0
+[ ]+8:[ ]+fc100073[ ]+sf.cflush.i.l1
new file mode 100644
@@ -0,0 +1,4 @@
+target:
+ sf.cflush.d.l1 x10
+ sf.cdiscard.d.l1 x10
+ sf.cflush.i.l1
@@ -2332,6 +2332,13 @@
#define MASK_TH_SYNC_IS 0xffffffff
#define MATCH_TH_SYNC_S 0x0190000b
#define MASK_TH_SYNC_S 0xffffffff
+/* Vendor-specific SiFive cache control instructions. */
+#define MATCH_SF_CFLUSH_D_L1 0xfc000073
+#define MASK_SF_CFLUSH_D_L1 0xfff07fff
+#define MATCH_SF_CDISCARD_D_L1 0xfc200073
+#define MASK_SF_CDISCARD_D_L1 0xfff07fff
+#define MATCH_SF_CFLUSH_I_L1 0xfc100073
+#define MASK_SF_CFLUSH_I_L1 0xffffffff
/* Unprivileged Counter/Timers CSR addresses. */
#define CSR_CYCLE 0xc00
#define CSR_TIME 0xc01
@@ -3186,6 +3193,10 @@ DECLARE_INSN(th_sync, MATCH_TH_SYNC, MASK_TH_SYNC)
DECLARE_INSN(th_sync_i, MATCH_TH_SYNC_I, MASK_TH_SYNC_I)
DECLARE_INSN(th_sync_is, MATCH_TH_SYNC_IS, MASK_TH_SYNC_IS)
DECLARE_INSN(th_sync_s, MATCH_TH_SYNC_S, MASK_TH_SYNC_S)
+/* Vendor-specific SiFive cache control instructions. */
+DECLARE_INSN(sf_cflush_d_l1, MATCH_SF_CFLUSH_D_L1, MASK_SF_CFLUSH_D_L1)
+DECLARE_INSN(sf_cdiscard_d_l1, MATCH_SF_CDISCARD_D_L1, MASK_SF_CDISCARD_D_L1)
+DECLARE_INSN(sf_cflush_i_l1, MATCH_SF_CFLUSH_I_L1, MASK_SF_CFLUSH_I_L1)
#endif /* DECLARE_INSN */
#ifdef DECLARE_CSR
/* Unprivileged Counter/Timers CSRs. */
@@ -420,6 +420,9 @@ enum riscv_insn_class
INSN_CLASS_XTHEADMEMIDX,
INSN_CLASS_XTHEADMEMPAIR,
INSN_CLASS_XTHEADSYNC,
+ INSN_CLASS_XSF_CDISCARDDLONE,
+ INSN_CLASS_XSF_CFLUSHDLONE,
+ INSN_CLASS_XSF_CFLUSHILONE,
};
/* This structure holds information for a particular instruction. */
@@ -2001,6 +2001,11 @@ const struct riscv_opcode riscv_opcodes[] =
{"th.sync.is", 0, INSN_CLASS_XTHEADSYNC, "", MATCH_TH_SYNC_IS, MASK_TH_SYNC_IS, match_opcode, 0},
{"th.sync.s", 0, INSN_CLASS_XTHEADSYNC, "", MATCH_TH_SYNC_S, MASK_TH_SYNC_S, match_opcode, 0},
+/* Vendor-specific SiFive cache control instructions. */
+{"sf.cflush.d.l1", 0, INSN_CLASS_XSF_CFLUSHDLONE, "s", MATCH_SF_CFLUSH_D_L1, MASK_SF_CFLUSH_D_L1, match_opcode, 0 },
+{"sf.cdiscard.d.l1", 0, INSN_CLASS_XSF_CDISCARDDLONE, "s", MATCH_SF_CDISCARD_D_L1, MASK_SF_CDISCARD_D_L1, match_opcode, 0 },
+{"sf.cflush.i.l1", 0, INSN_CLASS_XSF_CFLUSHILONE, "", MATCH_SF_CFLUSH_I_L1, MASK_SF_CFLUSH_I_L1, match_opcode, 0 },
+
/* Terminate the list. */
{0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
};