@@ -118,6 +118,16 @@ static inline uint32_t decode_r4type_rs3(const uint32_t insn)
118
118
}
119
119
#endif
120
120
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
+
121
131
#if RV32_HAS (EXT_C )
122
132
enum {
123
133
/* clang-format off */
@@ -1791,6 +1801,165 @@ static inline bool op_cfsw(rv_insn_t *ir, const uint32_t insn)
1791
1801
#define op_cflwsp OP_UNIMP
1792
1802
#endif /* RV32_HAS(EXT_C) && RV32_HAS(EXT_F) */
1793
1803
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
1913
+ * 31 26 25 24 20 19 15 14 12 11 7 6 0
1914
+ * funct6 | vm | vs2 | vs1 | 0 0 0 (funct3) | vd |1010111| OP-V (OPIVV)
1915
+ * funct6 | vm | vs2 | vs1 | 0 0 1 (funct3) | vd/rd |1010111| OP-V (OPFVV)
1916
+ * funct6 | vm | vs2 | vs1 | 0 1 0 (funct3) | vd/rd |1010111| OP-V (OPMVV)
1917
+ * funct6 | vm | vs2 | imm[4:0] | 0 1 1 (funct3) | vd |1010111| OP-V (OPIVI)
1918
+ * funct6 | vm | vs2 | rs1 | 1 0 0 (funct3) | vd |1010111| OP-V (OPIVX)
1919
+ * funct6 | vm | vs2 | rs1 | 1 0 1 (funct3) | vd |1010111| OP-V (OPFVF)
1920
+ * funct6 | vm | vs2 | rs1 | 1 1 0 (funct3) | vd/rd |1010111| OP-V (OPMVX)
1921
+ * 6 1 5 5 3 5 7
1922
+ *
1923
+ * Where 'vm' is the bit indicates whether masking is enabled
1924
+ * see https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#531-mask-encoding
1925
+ *
1926
+ * reference:
1927
+ * https://github.com/riscv/riscv-isa-manual/blob/main/src/images/wavedrom/valu-format.edn
1928
+ * https://github.com/riscv/riscv-isa-manual/blob/main/src/images/wavedrom/v-inst-table.edn
1929
+ * https://observablehq.com/@drom/risc-v-v
1930
+ *
1931
+ * funct3
1932
+ * | 0 | 0 | 0 | OPIVV | vector-vector | N/A
1933
+ * | 0 | 0 | 1 | OPFVV | vector-vector | N/A
1934
+ * | 0 | 1 | 0 | OPMVV | vector-vector | N/A
1935
+ * | 0 | 1 | 1 | OPIVI | vector-immediate | `imm[4:0]`
1936
+ * | 1 | 0 | 0 | OPIVX | vector-scalar | GPR `x` register `rs1`
1937
+ * | 1 | 0 | 1 | OPFVF | vector-scalar | FP `f` register `rs1`
1938
+ * | 1 | 1 | 0 | OPMVX | vector-scalar | GPR `x` register `rs1`
1939
+ */
1940
+ static inline bool op_v (rv_insn_t * ir , const uint32_t insn )
1941
+ {
1942
+ uint32_t funct3_mask = 0x7000 ;
1943
+ switch (insn & funct3_mask ) {
1944
+ case 0 :
1945
+ return op_ivv (ir , insn );
1946
+ case 1 :
1947
+ return op_fvv (ir , insn );
1948
+ case 2 :
1949
+ return op_mvv (ir , insn );
1950
+ case 3 :
1951
+ return op_ivi (ir , insn );
1952
+ case 4 :
1953
+ return op_ivx (ir , insn );
1954
+ case 5 :
1955
+ return op_fvf (ir , insn );
1956
+ case 6 :
1957
+ return op_mvx (ir , insn );
1958
+ default :
1959
+ return false;
1960
+ }
1961
+ }
1962
+
1794
1963
/* handler for all unimplemented opcodes */
1795
1964
static inline bool op_unimp (rv_insn_t * ir UNUSED , uint32_t insn UNUSED )
1796
1965
{
@@ -1800,18 +1969,28 @@ static inline bool op_unimp(rv_insn_t *ir UNUSED, uint32_t insn UNUSED)
1800
1969
/* RV32 decode handler type */
1801
1970
typedef bool (* decode_t )(rv_insn_t * ir , uint32_t insn );
1802
1971
1972
+ #if RV32_HAS (EXT_RVV )
1973
+ #define MASK_OPCODE_RVV 0x57
1974
+ #endif
1803
1975
/* decode RISC-V instruction */
1804
1976
bool rv_decode (rv_insn_t * ir , uint32_t insn )
1805
1977
{
1806
1978
assert (ir );
1807
1979
1980
+ #if RV32_HAS (EXT_RVV )
1981
+ if (insn & MASK_OPCODE_RVV ) {
1982
+ return op_v (ir , insn );
1983
+ }
1984
+ #endif
1985
+
1808
1986
#define OP_UNIMP op_unimp
1809
1987
#define OP (insn ) op_##insn
1810
1988
1811
1989
/* RV32 base opcode map */
1812
1990
/* clang-format off */
1813
1991
static const decode_t rv_jump_table [] = {
1814
- // 000 001 010 011 100 101 110 111
1992
+ // insn[4:2]
1993
+ // 000 001 010 011 100 101 110 111 // insn[6:5]
1815
1994
OP (load ), OP (load_fp ), OP (unimp ), OP (misc_mem ), OP (op_imm ), OP (auipc ), OP (unimp ), OP (unimp ), // 00
1816
1995
OP (store ), OP (store_fp ), OP (unimp ), OP (amo ), OP (op ), OP (lui ), OP (unimp ), OP (unimp ), // 01
1817
1996
OP (madd ), OP (msub ), OP (nmsub ), OP (nmadd ), OP (op_fp ), OP (unimp ), OP (unimp ), OP (unimp ), // 10
0 commit comments