@@ -118,6 +118,16 @@ static inline uint32_t decode_r4type_rs3(const uint32_t insn)
118118}
119119#endif
120120
121+ #if RV32_HAS (EXT_RVV )
122+ /* decode RVV vm field
123+ * vm = inst[25]
124+ */
125+ static inline uint32_t decode_rvv_vm (const uint32_t insn )
126+ {
127+ return (insn >> 25 ) & 0x1 ;
128+ }
129+ #endif
130+
121131#if RV32_HAS (EXT_C )
122132enum {
123133 /* clang-format off */
@@ -1791,6 +1801,183 @@ static inline bool op_cfsw(rv_insn_t *ir, const uint32_t insn)
17911801#define op_cflwsp OP_UNIMP
17921802#endif /* RV32_HAS(EXT_C) && RV32_HAS(EXT_F) */
17931803
1804+ static inline bool op_ivv (rv_insn_t * ir , const uint32_t insn ) {
1805+ #define MASK 0xfc00707f
1806+ #define MATCH_VADD_VI 0x3057
1807+ #define MATCH_VAND_VI 0x24003057
1808+ #define MATCH_VMADC_VI 0x46003057
1809+ #define MATCH_VMSEQ_VI 0x60003057
1810+ #define MATCH_VMSGT_VI 0x7c003057
1811+ #define MATCH_VMSGTU_VI 0x78003057
1812+ #define MATCH_VMSLE_VI 0x74003057
1813+ #define MATCH_VMSLEU_VI 0x70003057
1814+ #define MATCH_VMSNE_VI 0x64003057
1815+ #define MATCH_VOR_VI 0x28003057
1816+ #define MATCH_VRGATHER_VI 0x30003057
1817+ #define MATCH_VRSUB_VI 0xc003057
1818+ #define MATCH_VSADD_VI 0x84003057
1819+ #define MATCH_VSADDU_VI 0x80003057
1820+ #define MATCH_VSLIDEDOWN_VI 0x3c003057
1821+ #define MATCH_VSLIDEUP_VI 0x38003057
1822+ #define MATCH_VSLL_VI 0x94003057
1823+ #define MATCH_VSRA_VI 0xa4003057
1824+ #define MATCH_VSRL_VI 0xa0003057
1825+ #define MATCH_VSSRA_VI 0xac003057
1826+ #define MATCH_VSSRL_VI 0xa8003057
1827+ #define MATCH_VXOR_VI 0x2c003057
1828+
1829+ ir -> rs1 = decode_rs1 (insn );
1830+ ir -> rs2 = decode_rs2 (insn );
1831+ ir -> vm = decode_rvv_vm (insn );
1832+ switch (insn & MASK ) {
1833+ case MATCH_VADD_VI :
1834+ ir -> opcode = rv_insn_vadd_vi ;
1835+ break ;
1836+ case MATCH_VAND_VI :
1837+ ir -> opcode = rv_insn_vand_vi ;
1838+ break ;
1839+ case MATCH_VMADC_VI :
1840+ ir -> opcode = rv_insn_vmadc_vi ;
1841+ break ;
1842+ case MATCH_VMSEQ_VI :
1843+ ir -> opcode = rv_insn_vmseq_vi ;
1844+ break ;
1845+ case MATCH_VMSGT_VI :
1846+ ir -> opcode = rv_insn_vmsgt_vi ;
1847+ break ;
1848+ case MATCH_VMSGTU_VI :
1849+ ir -> opcode = rv_insn_vmsgtu_vi ;
1850+ break ;
1851+ case MATCH_VMSLE_VI :
1852+ ir -> opcode = rv_insn_vmsle_vi ;
1853+ break ;
1854+ case MATCH_VMSLEU_VI :
1855+ ir -> opcode = rv_insn_vmsleu_vi ;
1856+ break ;
1857+ case MATCH_VMSNE_VI :
1858+ ir -> opcode = rv_insn_vmsne_vi ;
1859+ break ;
1860+ case MATCH_VOR_VI :
1861+ ir -> opcode = rv_insn_vor_vi ;
1862+ break ;
1863+ case MATCH_VRGATHER_VI :
1864+ ir -> opcode = rv_insn_vrgather_vi ;
1865+ break ;
1866+ case MATCH_VRSUB_VI :
1867+ ir -> opcode = rv_insn_vrsub_vi ;
1868+ break ;
1869+ case MATCH_VSADD_VI :
1870+ ir -> opcode = rv_insn_vsadd_vi ;
1871+ break ;
1872+ case MATCH_VSADDU_VI :
1873+ ir -> opcode = rv_insn_vsaddu_vi ;
1874+ break ;
1875+ case MATCH_VSLIDEDOWN_VI :
1876+ ir -> opcode = rv_insn_vslidedown_vi ;
1877+ break ;
1878+ case MATCH_VSLIDEUP_VI :
1879+ ir -> opcode = rv_insn_vslideup_vi ;
1880+ break ;
1881+ case MATCH_VSLL_VI :
1882+ ir -> opcode = rv_insn_vsll_vi ;
1883+ break ;
1884+ case MATCH_VSRA_VI :
1885+ ir -> opcode = rv_insn_vsra_vi ;
1886+ break ;
1887+ case MATCH_VSRL_VI :
1888+ ir -> opcode = rv_insn_vsrl_vi ;
1889+ break ;
1890+ case MATCH_VSSRA_VI :
1891+ ir -> opcode = rv_insn_vssra_vi ;
1892+ break ;
1893+ case MATCH_VSSRL_VI :
1894+ ir -> opcode = rv_insn_vssrl_vi ;
1895+ break ;
1896+ case MATCH_VXOR_VI :
1897+ ir -> opcode = rv_insn_vxor_vi ;
1898+ break ;
1899+ default :
1900+ return false;
1901+ }
1902+ }
1903+
1904+ static inline bool op_fvv (rv_insn_t * ir , const uint32_t insn ) {}
1905+ static inline bool op_mvv (rv_insn_t * ir , const uint32_t insn ) {}
1906+ static inline bool op_ivi (rv_insn_t * ir , const uint32_t insn ) {}
1907+ static inline bool op_ivx (rv_insn_t * ir , const uint32_t insn ) {}
1908+ static inline bool op_fvf (rv_insn_t * ir , const uint32_t insn ) {}
1909+ static inline bool op_mvx (rv_insn_t * ir , const uint32_t insn ) {}
1910+
1911+ /* OP: RVV
1912+ * opcode is 0x57 for VALU and VCFG
1913+ *
1914+ * VALU format:
1915+ * 31 26 25 24 20 19 15 14 12 11 7 6 0
1916+ * funct6 | vm | vs2 | vs1 | 0 0 0 (funct3) | vd |1010111| OP-V (OPIVV)
1917+ * funct6 | vm | vs2 | vs1 | 0 0 1 (funct3) | vd/rd |1010111| OP-V (OPFVV)
1918+ * funct6 | vm | vs2 | vs1 | 0 1 0 (funct3) | vd/rd |1010111| OP-V (OPMVV)
1919+ * funct6 | vm | vs2 | imm[4:0] | 0 1 1 (funct3) | vd |1010111| OP-V (OPIVI)
1920+ * funct6 | vm | vs2 | rs1 | 1 0 0 (funct3) | vd |1010111| OP-V (OPIVX)
1921+ * funct6 | vm | vs2 | rs1 | 1 0 1 (funct3) | vd |1010111| OP-V (OPFVF)
1922+ * funct6 | vm | vs2 | rs1 | 1 1 0 (funct3) | vd/rd |1010111| OP-V (OPMVX)
1923+ * 6 1 5 5 3 5 7
1924+ *
1925+ * Where 'vm' is the bit indicates whether masking is enabled
1926+ * see https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#531-mask-encoding
1927+ *
1928+ * VMEM format:
1929+ *
1930+ * 31 29 28 27 26 25 24 20 19 15 14 12 11 7 6 0
1931+ * nf | mew| mop | vm | lumop | rs1 | width | vd |0000111| VL* unit-stride
1932+ * nf | mew| mop | vm | rs2 | rs1 | width | vd |0000111| VLS* strided
1933+ * nf | mew| mop | vm | vs2 | rs1 | width | vd |0000111| VLX* indexed
1934+ * 3 1 2 1 5 5 3 5 7
1935+ *
1936+ * VCFG format:
1937+ *
1938+ * 31 30 25 24 20 19 15 14 12 11 7 6 0
1939+ * 0 | zimm[10:0] | rs1 | 1 1 1 | rd |1010111| vsetvli
1940+ * 1 | 1| zimm[ 9:0] | uimm[4:0]| 1 1 1 | rd |1010111| vsetivli
1941+ * 1 | 000000 | rs2 | rs1 | 1 1 1 | rd |1010111| vsetvl
1942+ * 1 6 5 5 3 5 7
1943+ *
1944+ * reference:
1945+ * https://github.com/riscv/riscv-isa-manual/blob/main/src/images/wavedrom/valu-format.edn
1946+ * https://github.com/riscv/riscv-isa-manual/blob/main/src/images/wavedrom/v-inst-table.edn
1947+ * https://observablehq.com/@drom/risc-v-v
1948+ *
1949+ * funct3
1950+ * | 0 | 0 | 0 | OPIVV | vector-vector | N/A
1951+ * | 0 | 0 | 1 | OPFVV | vector-vector | N/A
1952+ * | 0 | 1 | 0 | OPMVV | vector-vector | N/A
1953+ * | 0 | 1 | 1 | OPIVI | vector-immediate | `imm[4:0]`
1954+ * | 1 | 0 | 0 | OPIVX | vector-scalar | GPR `x` register `rs1`
1955+ * | 1 | 0 | 1 | OPFVF | vector-scalar | FP `f` register `rs1`
1956+ * | 1 | 1 | 0 | OPMVX | vector-scalar | GPR `x` register `rs1`
1957+ */
1958+ static inline bool op_v (rv_insn_t * ir , const uint32_t insn )
1959+ {
1960+ uint32_t funct3_mask = 0x7000 ;
1961+ switch (insn & funct3_mask ) {
1962+ case 0 :
1963+ return op_ivv (ir , insn );
1964+ case 1 :
1965+ return op_fvv (ir , insn );
1966+ case 2 :
1967+ return op_mvv (ir , insn );
1968+ case 3 :
1969+ return op_ivi (ir , insn );
1970+ case 4 :
1971+ return op_ivx (ir , insn );
1972+ case 5 :
1973+ return op_fvf (ir , insn );
1974+ case 6 :
1975+ return op_mvx (ir , insn );
1976+ default :
1977+ return false;
1978+ }
1979+ }
1980+
17941981/* handler for all unimplemented opcodes */
17951982static inline bool op_unimp (rv_insn_t * ir UNUSED , uint32_t insn UNUSED )
17961983{
@@ -1805,13 +1992,22 @@ bool rv_decode(rv_insn_t *ir, uint32_t insn)
18051992{
18061993 assert (ir );
18071994
1995+ #if RV32_HAS (EXT_RVV )
1996+ #define MASK_OPCODE_RVV 0x57
1997+ #define MASK_OPCODE_RVV_VMEM 0x57
1998+ if (insn & MASK_OPCODE_RVV ) {
1999+ return op_v (ir , insn );
2000+ }
2001+ #endif
2002+
18082003#define OP_UNIMP op_unimp
18092004#define OP (insn ) op_##insn
18102005
18112006 /* RV32 base opcode map */
18122007 /* clang-format off */
18132008 static const decode_t rv_jump_table [] = {
1814- // 000 001 010 011 100 101 110 111
2009+ // insn[4:2]
2010+ // 000 001 010 011 100 101 110 111 // insn[6:5]
18152011 OP (load ), OP (load_fp ), OP (unimp ), OP (misc_mem ), OP (op_imm ), OP (auipc ), OP (unimp ), OP (unimp ), // 00
18162012 OP (store ), OP (store_fp ), OP (unimp ), OP (amo ), OP (op ), OP (lui ), OP (unimp ), OP (unimp ), // 01
18172013 OP (madd ), OP (msub ), OP (nmsub ), OP (nmadd ), OP (op_fp ), OP (unimp ), OP (unimp ), OP (unimp ), // 10
0 commit comments