@@ -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 */
@@ -1971,6 +1981,183 @@ static inline bool op_cfsw(rv_insn_t *ir, const uint32_t insn)
19711981#define op_cflwsp OP_UNIMP
19721982#endif /* RV32_HAS(EXT_C) && RV32_HAS(EXT_F) */
19731983
1984+ static inline bool op_ivv (rv_insn_t * ir , const uint32_t insn ) {
1985+ #define MASK 0xfc00707f
1986+ #define MATCH_VADD_VI 0x3057
1987+ #define MATCH_VAND_VI 0x24003057
1988+ #define MATCH_VMADC_VI 0x46003057
1989+ #define MATCH_VMSEQ_VI 0x60003057
1990+ #define MATCH_VMSGT_VI 0x7c003057
1991+ #define MATCH_VMSGTU_VI 0x78003057
1992+ #define MATCH_VMSLE_VI 0x74003057
1993+ #define MATCH_VMSLEU_VI 0x70003057
1994+ #define MATCH_VMSNE_VI 0x64003057
1995+ #define MATCH_VOR_VI 0x28003057
1996+ #define MATCH_VRGATHER_VI 0x30003057
1997+ #define MATCH_VRSUB_VI 0xc003057
1998+ #define MATCH_VSADD_VI 0x84003057
1999+ #define MATCH_VSADDU_VI 0x80003057
2000+ #define MATCH_VSLIDEDOWN_VI 0x3c003057
2001+ #define MATCH_VSLIDEUP_VI 0x38003057
2002+ #define MATCH_VSLL_VI 0x94003057
2003+ #define MATCH_VSRA_VI 0xa4003057
2004+ #define MATCH_VSRL_VI 0xa0003057
2005+ #define MATCH_VSSRA_VI 0xac003057
2006+ #define MATCH_VSSRL_VI 0xa8003057
2007+ #define MATCH_VXOR_VI 0x2c003057
2008+
2009+ ir -> rs1 = decode_rs1 (insn );
2010+ ir -> rs2 = decode_rs2 (insn );
2011+ ir -> vm = decode_rvv_vm (insn );
2012+ switch (insn & MASK ) {
2013+ case MATCH_VADD_VI :
2014+ ir -> opcode = rv_insn_vadd_vi ;
2015+ break ;
2016+ case MATCH_VAND_VI :
2017+ ir -> opcode = rv_insn_vand_vi ;
2018+ break ;
2019+ case MATCH_VMADC_VI :
2020+ ir -> opcode = rv_insn_vmadc_vi ;
2021+ break ;
2022+ case MATCH_VMSEQ_VI :
2023+ ir -> opcode = rv_insn_vmseq_vi ;
2024+ break ;
2025+ case MATCH_VMSGT_VI :
2026+ ir -> opcode = rv_insn_vmsgt_vi ;
2027+ break ;
2028+ case MATCH_VMSGTU_VI :
2029+ ir -> opcode = rv_insn_vmsgtu_vi ;
2030+ break ;
2031+ case MATCH_VMSLE_VI :
2032+ ir -> opcode = rv_insn_vmsle_vi ;
2033+ break ;
2034+ case MATCH_VMSLEU_VI :
2035+ ir -> opcode = rv_insn_vmsleu_vi ;
2036+ break ;
2037+ case MATCH_VMSNE_VI :
2038+ ir -> opcode = rv_insn_vmsne_vi ;
2039+ break ;
2040+ case MATCH_VOR_VI :
2041+ ir -> opcode = rv_insn_vor_vi ;
2042+ break ;
2043+ case MATCH_VRGATHER_VI :
2044+ ir -> opcode = rv_insn_vrgather_vi ;
2045+ break ;
2046+ case MATCH_VRSUB_VI :
2047+ ir -> opcode = rv_insn_vrsub_vi ;
2048+ break ;
2049+ case MATCH_VSADD_VI :
2050+ ir -> opcode = rv_insn_vsadd_vi ;
2051+ break ;
2052+ case MATCH_VSADDU_VI :
2053+ ir -> opcode = rv_insn_vsaddu_vi ;
2054+ break ;
2055+ case MATCH_VSLIDEDOWN_VI :
2056+ ir -> opcode = rv_insn_vslidedown_vi ;
2057+ break ;
2058+ case MATCH_VSLIDEUP_VI :
2059+ ir -> opcode = rv_insn_vslideup_vi ;
2060+ break ;
2061+ case MATCH_VSLL_VI :
2062+ ir -> opcode = rv_insn_vsll_vi ;
2063+ break ;
2064+ case MATCH_VSRA_VI :
2065+ ir -> opcode = rv_insn_vsra_vi ;
2066+ break ;
2067+ case MATCH_VSRL_VI :
2068+ ir -> opcode = rv_insn_vsrl_vi ;
2069+ break ;
2070+ case MATCH_VSSRA_VI :
2071+ ir -> opcode = rv_insn_vssra_vi ;
2072+ break ;
2073+ case MATCH_VSSRL_VI :
2074+ ir -> opcode = rv_insn_vssrl_vi ;
2075+ break ;
2076+ case MATCH_VXOR_VI :
2077+ ir -> opcode = rv_insn_vxor_vi ;
2078+ break ;
2079+ default :
2080+ return false;
2081+ }
2082+ }
2083+
2084+ static inline bool op_fvv (rv_insn_t * ir , const uint32_t insn ) {}
2085+ static inline bool op_mvv (rv_insn_t * ir , const uint32_t insn ) {}
2086+ static inline bool op_ivi (rv_insn_t * ir , const uint32_t insn ) {}
2087+ static inline bool op_ivx (rv_insn_t * ir , const uint32_t insn ) {}
2088+ static inline bool op_fvf (rv_insn_t * ir , const uint32_t insn ) {}
2089+ static inline bool op_mvx (rv_insn_t * ir , const uint32_t insn ) {}
2090+
2091+ /* OP: RVV
2092+ * opcode is 0x57 for VALU and VCFG
2093+ *
2094+ * VALU format:
2095+ * 31 26 25 24 20 19 15 14 12 11 7 6 0
2096+ * funct6 | vm | vs2 | vs1 | 0 0 0 (funct3) | vd |1010111| OP-V (OPIVV)
2097+ * funct6 | vm | vs2 | vs1 | 0 0 1 (funct3) | vd/rd |1010111| OP-V (OPFVV)
2098+ * funct6 | vm | vs2 | vs1 | 0 1 0 (funct3) | vd/rd |1010111| OP-V (OPMVV)
2099+ * funct6 | vm | vs2 | imm[4:0] | 0 1 1 (funct3) | vd |1010111| OP-V (OPIVI)
2100+ * funct6 | vm | vs2 | rs1 | 1 0 0 (funct3) | vd |1010111| OP-V (OPIVX)
2101+ * funct6 | vm | vs2 | rs1 | 1 0 1 (funct3) | vd |1010111| OP-V (OPFVF)
2102+ * funct6 | vm | vs2 | rs1 | 1 1 0 (funct3) | vd/rd |1010111| OP-V (OPMVX)
2103+ * 6 1 5 5 3 5 7
2104+ *
2105+ * Where 'vm' is the bit indicates whether masking is enabled
2106+ * see https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#531-mask-encoding
2107+ *
2108+ * VMEM format:
2109+ *
2110+ * 31 29 28 27 26 25 24 20 19 15 14 12 11 7 6 0
2111+ * nf | mew| mop | vm | lumop | rs1 | width | vd |0000111| VL* unit-stride
2112+ * nf | mew| mop | vm | rs2 | rs1 | width | vd |0000111| VLS* strided
2113+ * nf | mew| mop | vm | vs2 | rs1 | width | vd |0000111| VLX* indexed
2114+ * 3 1 2 1 5 5 3 5 7
2115+ *
2116+ * VCFG format:
2117+ *
2118+ * 31 30 25 24 20 19 15 14 12 11 7 6 0
2119+ * 0 | zimm[10:0] | rs1 | 1 1 1 | rd |1010111| vsetvli
2120+ * 1 | 1| zimm[ 9:0] | uimm[4:0]| 1 1 1 | rd |1010111| vsetivli
2121+ * 1 | 000000 | rs2 | rs1 | 1 1 1 | rd |1010111| vsetvl
2122+ * 1 6 5 5 3 5 7
2123+ *
2124+ * reference:
2125+ * https://github.com/riscv/riscv-isa-manual/blob/main/src/images/wavedrom/valu-format.edn
2126+ * https://github.com/riscv/riscv-isa-manual/blob/main/src/images/wavedrom/v-inst-table.edn
2127+ * https://observablehq.com/@drom/risc-v-v
2128+ *
2129+ * funct3
2130+ * | 0 | 0 | 0 | OPIVV | vector-vector | N/A
2131+ * | 0 | 0 | 1 | OPFVV | vector-vector | N/A
2132+ * | 0 | 1 | 0 | OPMVV | vector-vector | N/A
2133+ * | 0 | 1 | 1 | OPIVI | vector-immediate | `imm[4:0]`
2134+ * | 1 | 0 | 0 | OPIVX | vector-scalar | GPR `x` register `rs1`
2135+ * | 1 | 0 | 1 | OPFVF | vector-scalar | FP `f` register `rs1`
2136+ * | 1 | 1 | 0 | OPMVX | vector-scalar | GPR `x` register `rs1`
2137+ */
2138+ static inline bool op_v (rv_insn_t * ir , const uint32_t insn )
2139+ {
2140+ uint32_t funct3_mask = 0x7000 ;
2141+ switch (insn & funct3_mask ) {
2142+ case 0 :
2143+ return op_ivv (ir , insn );
2144+ case 1 :
2145+ return op_fvv (ir , insn );
2146+ case 2 :
2147+ return op_mvv (ir , insn );
2148+ case 3 :
2149+ return op_ivi (ir , insn );
2150+ case 4 :
2151+ return op_ivx (ir , insn );
2152+ case 5 :
2153+ return op_fvf (ir , insn );
2154+ case 6 :
2155+ return op_mvx (ir , insn );
2156+ default :
2157+ return false;
2158+ }
2159+ }
2160+
19742161/* handler for all unimplemented opcodes */
19752162static inline bool op_unimp (rv_insn_t * ir UNUSED , uint32_t insn UNUSED )
19762163{
@@ -1985,13 +2172,22 @@ bool rv_decode(rv_insn_t *ir, uint32_t insn)
19852172{
19862173 assert (ir );
19872174
2175+ #if RV32_HAS (EXT_RVV )
2176+ #define MASK_OPCODE_RVV 0x57
2177+ #define MASK_OPCODE_RVV_VMEM 0x57
2178+ if (insn & MASK_OPCODE_RVV ) {
2179+ return op_v (ir , insn );
2180+ }
2181+ #endif
2182+
19882183#define OP_UNIMP op_unimp
19892184#define OP (insn ) op_##insn
19902185
19912186 /* RV32 base opcode map */
19922187 /* clang-format off */
19932188 static const decode_t rv_jump_table [] = {
1994- // 000 001 010 011 100 101 110 111
2189+ // insn[4:2]
2190+ // 000 001 010 011 100 101 110 111 // insn[6:5]
19952191 OP (load ), OP (load_fp ), OP (unimp ), OP (misc_mem ), OP (op_imm ), OP (auipc ), OP (unimp ), OP (unimp ), // 00
19962192 OP (store ), OP (store_fp ), OP (unimp ), OP (amo ), OP (op ), OP (lui ), OP (unimp ), OP (unimp ), // 01
19972193 OP (madd ), OP (msub ), OP (nmsub ), OP (nmadd ), OP (op_fp ), OP (unimp ), OP (unimp ), OP (unimp ), // 10
0 commit comments