aboutsummaryrefslogtreecommitdiff
path: root/opcodes/riscv-opc.c
diff options
context:
space:
mode:
Diffstat (limited to 'opcodes/riscv-opc.c')
-rw-r--r--opcodes/riscv-opc.c160
1 files changed, 160 insertions, 0 deletions
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index df59d93..3465d13 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -2238,9 +2238,169 @@ const struct riscv_opcode riscv_draft_opcodes[] =
{0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0 },
};
+
+/* Vendor T-HEAD opcodes. */
+/*
+ ARG format:
+
+ "Xgm@n": encode GPR with m bit at opcode[m+n-1:n].
+ "Xg5@0": encode GPR with 5 bit at opcode[4:0].
+ "Xg5@8": encode GPR with 5 bit at opcode[12:8].
+
+ "XIm@n": m bits unsigned immediate at opcode[m+n-1:n].
+ "XI5@0": 5 bits unsigned immediate at opcode[4:0].
+ "XI4@8": 4 bits unsigned immediate at opcode[11:8].
+
+ "XSm@n": m bits signed immediate at opcode[m+n-1:n].
+ "XS5@0": 5 bits signed immediate at opcode[4:0].
+ "XS4@8": 4 bits signed immediate at opcode[11:8].
+
+ "XFm@n": m bits FR at opcode[m+n-1:n].
+ "XF5@0": 5 bits FR at opcode[4:0].
+ "XF5@0": 5 bits FR at opcode[4:0].
+*/
+
+static int
+match_thead_rd1_rd2_neq_rs1(const struct riscv_opcode *op,
+ insn_t insn,
+ int constraints,
+ const char **error)
+{
+ int rd1 = (insn & MASK_RD) >> OP_SH_RD;
+ int rd2 = (insn & MASK_RS2) >> OP_SH_RS2;
+ int rs1 = (insn & MASK_RS1) >> OP_SH_RS1;
+
+ /* FIXME: add xlen check. */
+ return match_opcode (op, insn, constraints, error) && rd1 != rs1 && rd2 != rs1;
+}
+
+/* The vendor extension opcodes for T-HEAD. */
+struct riscv_opcode riscv_vendor_thead_opcodes[] =
+{
+ {"wsc", 0, INSN_CLASS_THEADC_OR_THEADE, "", MATCH_WSC, MASK_WSC, match_opcode, 0},
+ {"dcache.iall", 0, INSN_CLASS_THEADC_OR_THEADE, "", MATCH_DCACHE_IALL, MASK_DCACHE_IALL, match_opcode, 0},
+ {"dcache.call", 0, INSN_CLASS_THEADC_OR_THEADE, "", MATCH_DCACHE_CALL, MASK_DCACHE_CALL, match_opcode, 0},
+ {"dcache.ciall", 0, INSN_CLASS_THEADC_OR_THEADE, "", MATCH_DCACHE_CIALL, MASK_DCACHE_CIALL, match_opcode, 0},
+ {"dcache.isw", 0, INSN_CLASS_THEADC_OR_THEADE, "s", MATCH_DCACHE_ISW, MASK_DCACHE_ISW, match_opcode, 0},
+ {"dcache.csw", 0, INSN_CLASS_THEADC_OR_THEADE, "s", MATCH_DCACHE_CSW, MASK_DCACHE_CSW, match_opcode, 0},
+ {"dcache.cisw", 0, INSN_CLASS_THEADC_OR_THEADE, "s", MATCH_DCACHE_CISW, MASK_DCACHE_CISW, match_opcode, 0},
+ {"dcache.iva", 0, INSN_CLASS_THEADC, "s", MATCH_DCACHE_IVA, MASK_DCACHE_IVA, match_opcode, 0},
+ {"dcache.cva", 0, INSN_CLASS_THEADC, "s", MATCH_DCACHE_CVA, MASK_DCACHE_CVA, match_opcode, 0},
+ {"dcache.cval1", 0, INSN_CLASS_THEADC, "s", MATCH_DCACHE_CVAL1, MASK_DCACHE_CVAL1, match_opcode, 0},
+ {"dcache.civa", 0, INSN_CLASS_THEADC, "s", MATCH_DCACHE_CIVA, MASK_DCACHE_CIVA, match_opcode, 0},
+ {"dcache.ipa", 0, INSN_CLASS_THEADC_OR_THEADE, "s", MATCH_DCACHE_IPA, MASK_DCACHE_IPA, match_opcode, 0},
+ {"dcache.cpa", 0, INSN_CLASS_THEADC_OR_THEADE, "s", MATCH_DCACHE_CPA, MASK_DCACHE_CPA, match_opcode, 0},
+ {"dcache.cpal1", 0, INSN_CLASS_THEADC, "s", MATCH_DCACHE_CPAL1, MASK_DCACHE_CPAL1, match_opcode, 0},
+ {"dcache.cipa", 0, INSN_CLASS_THEADC_OR_THEADE, "s", MATCH_DCACHE_CIPA, MASK_DCACHE_CIPA, match_opcode, 0},
+ {"icache.iall", 0, INSN_CLASS_THEADC_OR_THEADE_OR_THEADSE, "", MATCH_ICACHE_IALL, MASK_ICACHE_IALL, match_opcode, 0},
+ {"icache.iall", 0, INSN_CLASS_THEADSE, "", MATCH_ICACHE_IALL, MASK_ICACHE_IALL, match_opcode, INSN_ALIAS},
+ {"icache.ialls", 0, INSN_CLASS_THEADC, "", MATCH_ICACHE_IALLS, MASK_ICACHE_IALLS, match_opcode, 0},
+ {"icache.iva", 0, INSN_CLASS_THEADC, "s", MATCH_ICACHE_IVA, MASK_ICACHE_IVA, match_opcode, 0},
+ {"icache.ipa", 0, INSN_CLASS_THEADC_OR_THEADE, "s", MATCH_ICACHE_IPA, MASK_ICACHE_IPA, match_opcode, 0},
+ {"l2cache.iall", 0, INSN_CLASS_THEADC, "", MATCH_L2CACHE_IALL, MASK_L2CACHE_IALL, match_opcode, 0},
+ {"l2cache.call", 0, INSN_CLASS_THEADC, "", MATCH_L2CACHE_CALL, MASK_L2CACHE_CALL, match_opcode, 0},
+ {"l2cache.ciall", 0, INSN_CLASS_THEADC_OR_THEADE, "", MATCH_L2CACHE_CIALL, MASK_L2CACHE_CIALL, match_opcode, 0},
+ {"sync", 0, INSN_CLASS_THEADC_OR_THEADE, "", MATCH_SYNC, MASK_SYNC, match_opcode, 0},
+ {"sync.i", 0, INSN_CLASS_THEADC_OR_THEADE, "", MATCH_SYNC_I, MASK_SYNC_I, match_opcode, 0},
+ {"sync.s", 0, INSN_CLASS_THEADC, "", MATCH_SYNC_S, MASK_SYNC_S, match_opcode, 0},
+ {"sync.is", 0, INSN_CLASS_THEADC, "", MATCH_SYNC_IS, MASK_SYNC_IS, match_opcode, 0},
+ {"tstnbz", 0, INSN_CLASS_THEADC_OR_THEADE, "d,s", MATCH_TSTNBZ, MASK_TSTNBZ, match_opcode, 0},
+ {"mula", 0, INSN_CLASS_THEADC_OR_THEADE, "d,s,t", MATCH_MULA, MASK_MULA, match_opcode, 0},
+ {"muls", 0, INSN_CLASS_THEADC_OR_THEADE, "d,s,t", MATCH_MULS, MASK_MULS, match_opcode, 0},
+ {"mulah", 0, INSN_CLASS_THEADC_OR_THEADE, "d,s,t", MATCH_MULAH, MASK_MULAH, match_opcode, 0},
+ {"mulsh", 0, INSN_CLASS_THEADC_OR_THEADE, "d,s,t", MATCH_MULSH, MASK_MULSH, match_opcode, 0},
+ {"sfence.vmas", 0, INSN_CLASS_THEADC, "s,t", MATCH_SFENCE_VMAS, MASK_SFENCE_VMAS, match_opcode, 0},
+ {"mveqz", 0, INSN_CLASS_THEADC_OR_THEADE, "d,s,t", MATCH_MVEQZ, MASK_MVEQZ, match_opcode, 0},
+ {"mvnez", 0, INSN_CLASS_THEADC_OR_THEADE, "d,s,t", MATCH_MVNEZ, MASK_MVNEZ, match_opcode, 0},
+ {"mulaw", 0, INSN_CLASS_THEADC_OR_THEADE, "d,s,t", MATCH_MULAW, MASK_MULAW, match_opcode, 0},
+ {"mulsw", 0, INSN_CLASS_THEADC_OR_THEADE, "d,s,t", MATCH_MULSW, MASK_MULSW, match_opcode, 0},
+ {"ext", 64, INSN_CLASS_THEADC, "d,s,XI6@26,XI6@20", MATCH_EXT, MASK_EXT, match_opcode, 0 },
+ {"ext", 32, INSN_CLASS_THEADE, "d,s,XI5@26,XI5@20", MATCH_EXT, (MASK_EXT | (1U<<25) | (1U<<31)), match_opcode, 0 },
+ {"extu", 64, INSN_CLASS_THEADC, "d,s,XI6@26,XI6@20", MATCH_EXTU, MASK_EXTU, match_opcode, 0 },
+ {"extu", 32, INSN_CLASS_THEADE, "d,s,XI5@26,XI5@20", MATCH_EXTU, (MASK_EXTU | (1U<<25) | (1U<<31)), match_opcode, 0 },
+ {"ff1", 0, INSN_CLASS_THEADC_OR_THEADE, "d,s", MATCH_FF1, MASK_FF1, match_opcode, 0},
+ {"ff0", 0, INSN_CLASS_THEADC_OR_THEADE, "d,s", MATCH_FF0, MASK_FF1, match_opcode, 0},
+ {"rev", 0, INSN_CLASS_THEADC_OR_THEADE, "d,s", MATCH_REV, MASK_REV, match_opcode, 0},
+ {"lrb", 0, INSN_CLASS_THEADC_OR_THEADE, "d,s,t,XI2@25", MATCH_LRB, MASK_LRB, match_opcode, 0 },
+ {"lrbu", 0, INSN_CLASS_THEADC_OR_THEADE, "d,s,t,XI2@25", MATCH_LRBU, MASK_LRBU, match_opcode, 0 },
+ {"lrh", 0, INSN_CLASS_THEADC_OR_THEADE, "d,s,t,XI2@25", MATCH_LRH, MASK_LRH, match_opcode, 0 },
+ {"lrhu", 0, INSN_CLASS_THEADC_OR_THEADE, "d,s,t,XI2@25", MATCH_LRHU, MASK_LRHU, match_opcode, 0 },
+ {"lrw", 0, INSN_CLASS_THEADC_OR_THEADE, "d,s,t,XI2@25", MATCH_LRW, MASK_LRW, match_opcode, 0 },
+ {"lrwu", 0, INSN_CLASS_THEADC_OR_THEADE, "d,s,t,XI2@25", MATCH_LRWU, MASK_LRWU, match_opcode, 0 },
+ {"srb", 0, INSN_CLASS_THEADC_OR_THEADE, "d,s,t,XI2@25", MATCH_SRB, MASK_SRB, match_opcode, 0 },
+ {"srh", 0, INSN_CLASS_THEADC_OR_THEADE, "d,s,t,XI2@25", MATCH_SRH, MASK_SRH, match_opcode, 0 },
+ {"srw", 0, INSN_CLASS_THEADC_OR_THEADE, "d,s,t,XI2@25", MATCH_SRW, MASK_SRW, match_opcode, 0 },
+ {"lrd", 0, INSN_CLASS_THEADC, "d,s,t,XI2@25", MATCH_LRD, MASK_LRD, match_opcode, 0 },
+ {"srd", 0, INSN_CLASS_THEADC, "d,s,t,XI2@25", MATCH_SRD, MASK_SRD, match_opcode, 0 },
+ {"lurb", 0, INSN_CLASS_THEADC, "d,s,t,XI2@25", MATCH_LURB, MASK_LURB, match_opcode, 0 },
+ {"lurbu", 0, INSN_CLASS_THEADC, "d,s,t,XI2@25", MATCH_LURBU, MASK_LURBU, match_opcode, 0 },
+ {"lurh", 0, INSN_CLASS_THEADC, "d,s,t,XI2@25", MATCH_LURH, MASK_LURH, match_opcode, 0 },
+ {"lurhu", 0, INSN_CLASS_THEADC, "d,s,t,XI2@25", MATCH_LURHU, MASK_LURHU, match_opcode, 0 },
+ {"lurw", 0, INSN_CLASS_THEADC, "d,s,t,XI2@25", MATCH_LURW, MASK_LURW, match_opcode, 0 },
+ {"lurwu", 0, INSN_CLASS_THEADC, "d,s,t,XI2@25", MATCH_LURWU, MASK_LURWU, match_opcode, 0 },
+ {"lurd", 0, INSN_CLASS_THEADC, "d,s,t,XI2@25", MATCH_LURD, MASK_LURD, match_opcode, 0 },
+ {"surb", 0, INSN_CLASS_THEADC, "d,s,t,XI2@25", MATCH_SURB, MASK_SURB, match_opcode, 0 },
+ {"surh", 0, INSN_CLASS_THEADC, "d,s,t,XI2@25", MATCH_SURH, MASK_SURH, match_opcode, 0 },
+ {"surw", 0, INSN_CLASS_THEADC, "d,s,t,XI2@25", MATCH_SURW, MASK_SURW, match_opcode, 0 },
+ {"surd", 0, INSN_CLASS_THEADC, "d,s,t,XI2@25", MATCH_SURD, MASK_SURD, match_opcode, 0 },
+ {"tst", 64, INSN_CLASS_THEADC, "d,s,XI6@20", MATCH_TST, MASK_TST, match_opcode, 0 },
+ {"tst", 32, INSN_CLASS_THEADE, "d,s,XI5@20", MATCH_TST, (MASK_TST | (1U << 25)), match_opcode, INSN_ALIAS},
+ {"srriw", 0, INSN_CLASS_THEADC, "d,s,XI5@20", MATCH_SRRIW, MASK_SRRIW, match_opcode, 0 },
+ {"srri", 0, INSN_CLASS_THEADC_OR_THEADE, "d,s,XI6@20", MATCH_SRRI, MASK_SRRI, match_opcode, 0 },
+ {"addsl", 0, INSN_CLASS_THEADC_OR_THEADE, "d,s,t,XI2@25", MATCH_ADDSL, MASK_ADDSL, match_opcode, 0 },
+ {"lwd", 0, INSN_CLASS_THEADC, "d,t,(s),XI2@25", MATCH_LWD, MASK_LWD, match_thead_rd1_rd2_neq_rs1, 0 },
+ {"ldd", 0, INSN_CLASS_THEADC, "d,t,(s),XI2@25", MATCH_LDD, MASK_LDD, match_thead_rd1_rd2_neq_rs1, 0 },
+ {"swd", 0, INSN_CLASS_THEADC, "d,t,(s),XI2@25", MATCH_SWD, MASK_SWD, match_opcode, 0 },
+ {"sdd", 0, INSN_CLASS_THEADC, "d,t,(s),XI2@25", MATCH_SDD, MASK_SDD, match_opcode, 0 },
+ {"sdia", 0, INSN_CLASS_THEADC, "d,(s),XS5@20,XI2@25", MATCH_SDIA, MASK_SDIA, match_opcode, 0 },
+ {"sdib", 0, INSN_CLASS_THEADC, "d,(s),XS5@20,XI2@25", MATCH_SDIB, MASK_SDIB, match_opcode, 0 },
+ {"lwud", 0, INSN_CLASS_THEADC, "d,t,(s),XI2@25", MATCH_LWUD, MASK_LWUD, match_thead_rd1_rd2_neq_rs1, 0 },
+ {"swia", 0, INSN_CLASS_THEADC_OR_THEADE, "d,(s),XS5@20,XI2@25", MATCH_SWIA, MASK_SWIA, match_opcode, 0},
+ {"swib", 0, INSN_CLASS_THEADC_OR_THEADE, "d,(s),XS5@20,XI2@25", MATCH_SWIB, MASK_SWIB, match_opcode, 0},
+ {"shia", 0, INSN_CLASS_THEADC_OR_THEADE, "d,(s),XS5@20,XI2@25", MATCH_SHIA, MASK_SHIA, match_opcode, 0},
+ {"shib", 0, INSN_CLASS_THEADC_OR_THEADE, "d,(s),XS5@20,XI2@25", MATCH_SHIB, MASK_SHIB, match_opcode, 0},
+ {"sbia", 0, INSN_CLASS_THEADC_OR_THEADE, "d,(s),XS5@20,XI2@25", MATCH_SBIA, MASK_SBIA, match_opcode, 0},
+ {"sbib", 0, INSN_CLASS_THEADC_OR_THEADE, "d,(s),XS5@20,XI2@25", MATCH_SBIB, MASK_SBIB, match_opcode, 0},
+ {"lwuia", 0, INSN_CLASS_THEADC_OR_THEADE, "d,(s),XS5@20,XI2@25", MATCH_LWUIA, MASK_LWUIA, match_opcode, 0},
+ {"lwuib", 0, INSN_CLASS_THEADC_OR_THEADE, "d,(s),XS5@20,XI2@25", MATCH_LWUIB, MASK_LWUIB, match_opcode, 0},
+ {"lhuia", 0, INSN_CLASS_THEADC_OR_THEADE, "d,(s),XS5@20,XI2@25", MATCH_LHUIA, MASK_LHUIA, match_opcode, 0},
+ {"lhuib", 0, INSN_CLASS_THEADC_OR_THEADE, "d,(s),XS5@20,XI2@25", MATCH_LHUIB, MASK_LHUIB, match_opcode, 0},
+ {"lbuia", 0, INSN_CLASS_THEADC_OR_THEADE, "d,(s),XS5@20,XI2@25", MATCH_LBUIA, MASK_LBUIA, match_opcode, 0},
+ {"lbuib", 0, INSN_CLASS_THEADC_OR_THEADE, "d,(s),XS5@20,XI2@25", MATCH_LBUIB, MASK_LBUIB, match_opcode, 0},
+ {"ldia", 0, INSN_CLASS_THEADC, "d,(s),XS5@20,XI2@25", MATCH_LDIA, MASK_LDIA, match_opcode, 0},
+ {"ldib", 0, INSN_CLASS_THEADC, "d,(s),XS5@20,XI2@25", MATCH_LDIB, MASK_LDIB, match_opcode, 0},
+ {"lwia", 0, INSN_CLASS_THEADC_OR_THEADE, "d,(s),XS5@20,XI2@25", MATCH_LWIA, MASK_LWIA, match_opcode, 0},
+ {"lwib", 0, INSN_CLASS_THEADC_OR_THEADE, "d,(s),XS5@20,XI2@25", MATCH_LWIB, MASK_LWIB, match_opcode, 0},
+ {"lhia", 0, INSN_CLASS_THEADC_OR_THEADE, "d,(s),XS5@20,XI2@25", MATCH_LHIA, MASK_LHIA, match_opcode, 0},
+ {"lhib", 0, INSN_CLASS_THEADC_OR_THEADE, "d,(s),XS5@20,XI2@25", MATCH_LHIB, MASK_LHIB, match_opcode, 0},
+ {"lbia", 0, INSN_CLASS_THEADC_OR_THEADE, "d,(s),XS5@20,XI2@25", MATCH_LBIA, MASK_LBIA, match_opcode, 0},
+ {"lbib", 0, INSN_CLASS_THEADC_OR_THEADE, "d,(s),XS5@20,XI2@25", MATCH_LBIB, MASK_LBIB, match_opcode, 0},
+ {"fsurd", 0, INSN_CLASS_THEADC, "D,s,t,XI2@25", MATCH_FSURD, MASK_FSURD, match_opcode, 0},
+ {"revw", 0, INSN_CLASS_THEADC, "d,s", MATCH_REVW, MASK_REVW, match_opcode, 0},
+ {"fsurw", 0, INSN_CLASS_THEADC, "D,s,t,XI2@25", MATCH_FSURW, MASK_FSURW, match_opcode, 0},
+ {"flurd", 0, INSN_CLASS_THEADC, "D,s,t,XI2@25", MATCH_FLURD, MASK_FLURD, match_opcode, 0},
+ {"flurw", 0, INSN_CLASS_THEADC, "D,s,t,XI2@25", MATCH_FLURW, MASK_FLURW, match_opcode, 0},
+ {"fsrd", 0, INSN_CLASS_THEADC, "D,s,t,XI2@25", MATCH_FSRD, MASK_FSRD, match_opcode, 0},
+ {"fsrw", 0, INSN_CLASS_THEADC, "D,s,t,XI2@25", MATCH_FSRW, MASK_FSRW, match_opcode, 0},
+ {"flrd", 0, INSN_CLASS_THEADC, "D,s,t,XI2@25", MATCH_FLRD, MASK_FLRD, match_opcode, 0},
+ {"flrw", 0, INSN_CLASS_THEADC, "D,s,t,XI2@25", MATCH_FLRW, MASK_FLRW, match_opcode, 0},
+
+ /* THEADE only. */
+ {"ipush", 0, INSN_CLASS_THEADE, "", MATCH_IPUSH, MASK_IPUSH, match_opcode, 0},
+ {"ipop", 0, INSN_CLASS_THEADE, "", MATCH_IPOP, MASK_IPOP, match_opcode, 0},
+ /* Float move. */
+ {"fmv.x.hw", 32, INSN_CLASS_THEADE, "d,S", MATCH_FMV_X_HW, MASK_FMV_X_HW, match_opcode, 0},
+ {"fmv.hw.x", 32, INSN_CLASS_THEADE, "D,s", MATCH_FMV_HW_X, MASK_FMV_HW_X, match_opcode, 0},
+
+
+ {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
+
+};
+
/* The supported extended extensions. */
const struct riscv_opcode *riscv_extended_opcodes[] =
{
riscv_draft_opcodes,
+ riscv_vendor_thead_opcodes,
NULL
};