Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 1f4ad39

Browse files
committedDec 30, 2024·
wip
1 parent 2e8cf99 commit 1f4ad39

File tree

4 files changed

+515
-486
lines changed

4 files changed

+515
-486
lines changed
 

‎src/decode.c

Lines changed: 88 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1982,7 +1982,8 @@ static inline bool op_cfsw(rv_insn_t *ir, const uint32_t insn)
19821982
#define op_cflwsp OP_UNIMP
19831983
#endif /* RV32_HAS(EXT_C) && RV32_HAS(EXT_F) */
19841984

1985-
static inline bool op_ivv(rv_insn_t *ir, const uint32_t insn) {
1985+
static inline bool op_ivv(rv_insn_t *ir, const uint32_t insn)
1986+
{
19861987
#define MASK 0xfc00707f
19871988
#define MATCH_VADD_VI 0x3057
19881989
#define MATCH_VAND_VI 0x24003057
@@ -2011,74 +2012,74 @@ static inline bool op_ivv(rv_insn_t *ir, const uint32_t insn) {
20112012
ir->rs2 = decode_rs2(insn);
20122013
ir->vm = decode_rvv_vm(insn);
20132014
switch (insn & MASK) {
2014-
case MATCH_VADD_VI:
2015+
case MATCH_VADD_VI:
20152016
ir->opcode = rv_insn_vadd_vi;
2016-
break;
2017-
case MATCH_VAND_VI:
2017+
break;
2018+
case MATCH_VAND_VI:
20182019
ir->opcode = rv_insn_vand_vi;
2019-
break;
2020-
case MATCH_VMADC_VI:
2020+
break;
2021+
case MATCH_VMADC_VI:
20212022
ir->opcode = rv_insn_vmadc_vi;
2022-
break;
2023-
case MATCH_VMSEQ_VI:
2023+
break;
2024+
case MATCH_VMSEQ_VI:
20242025
ir->opcode = rv_insn_vmseq_vi;
2025-
break;
2026-
case MATCH_VMSGT_VI:
2026+
break;
2027+
case MATCH_VMSGT_VI:
20272028
ir->opcode = rv_insn_vmsgt_vi;
2028-
break;
2029-
case MATCH_VMSGTU_VI:
2029+
break;
2030+
case MATCH_VMSGTU_VI:
20302031
ir->opcode = rv_insn_vmsgtu_vi;
2031-
break;
2032-
case MATCH_VMSLE_VI:
2032+
break;
2033+
case MATCH_VMSLE_VI:
20332034
ir->opcode = rv_insn_vmsle_vi;
2034-
break;
2035-
case MATCH_VMSLEU_VI:
2035+
break;
2036+
case MATCH_VMSLEU_VI:
20362037
ir->opcode = rv_insn_vmsleu_vi;
2037-
break;
2038-
case MATCH_VMSNE_VI:
2038+
break;
2039+
case MATCH_VMSNE_VI:
20392040
ir->opcode = rv_insn_vmsne_vi;
2040-
break;
2041-
case MATCH_VOR_VI:
2041+
break;
2042+
case MATCH_VOR_VI:
20422043
ir->opcode = rv_insn_vor_vi;
2043-
break;
2044-
case MATCH_VRGATHER_VI:
2044+
break;
2045+
case MATCH_VRGATHER_VI:
20452046
ir->opcode = rv_insn_vrgather_vi;
2046-
break;
2047-
case MATCH_VRSUB_VI:
2047+
break;
2048+
case MATCH_VRSUB_VI:
20482049
ir->opcode = rv_insn_vrsub_vi;
2049-
break;
2050-
case MATCH_VSADD_VI:
2050+
break;
2051+
case MATCH_VSADD_VI:
20512052
ir->opcode = rv_insn_vsadd_vi;
2052-
break;
2053-
case MATCH_VSADDU_VI:
2053+
break;
2054+
case MATCH_VSADDU_VI:
20542055
ir->opcode = rv_insn_vsaddu_vi;
2055-
break;
2056-
case MATCH_VSLIDEDOWN_VI:
2056+
break;
2057+
case MATCH_VSLIDEDOWN_VI:
20572058
ir->opcode = rv_insn_vslidedown_vi;
2058-
break;
2059-
case MATCH_VSLIDEUP_VI:
2059+
break;
2060+
case MATCH_VSLIDEUP_VI:
20602061
ir->opcode = rv_insn_vslideup_vi;
2061-
break;
2062-
case MATCH_VSLL_VI:
2062+
break;
2063+
case MATCH_VSLL_VI:
20632064
ir->opcode = rv_insn_vsll_vi;
2064-
break;
2065-
case MATCH_VSRA_VI:
2065+
break;
2066+
case MATCH_VSRA_VI:
20662067
ir->opcode = rv_insn_vsra_vi;
2067-
break;
2068-
case MATCH_VSRL_VI:
2068+
break;
2069+
case MATCH_VSRL_VI:
20692070
ir->opcode = rv_insn_vsrl_vi;
2070-
break;
2071-
case MATCH_VSSRA_VI:
2071+
break;
2072+
case MATCH_VSSRA_VI:
20722073
ir->opcode = rv_insn_vssra_vi;
2073-
break;
2074-
case MATCH_VSSRL_VI:
2074+
break;
2075+
case MATCH_VSSRL_VI:
20752076
ir->opcode = rv_insn_vssrl_vi;
2076-
break;
2077-
case MATCH_VXOR_VI:
2077+
break;
2078+
case MATCH_VXOR_VI:
20782079
ir->opcode = rv_insn_vxor_vi;
2079-
break;
2080-
default:
2081-
return false;
2080+
break;
2081+
default:
2082+
return false;
20822083
}
20832084
}
20842085

@@ -2090,43 +2091,45 @@ static inline bool op_fvf(rv_insn_t *ir, const uint32_t insn) {}
20902091
static inline bool op_mvx(rv_insn_t *ir, const uint32_t insn) {}
20912092

20922093
/* OP: RVV
2093-
* opcode is 0x57 for VALU and VCFG
2094+
* opcode is 0x57 for VALU and VCFG
20942095
*
20952096
* VALU format:
20962097
* 31 26 25 24 20 19 15 14 12 11 7 6 0
2097-
* funct6 | vm | vs2 | vs1 | 0 0 0 (funct3) | vd |1010111| OP-V (OPIVV)
2098-
* funct6 | vm | vs2 | vs1 | 0 0 1 (funct3) | vd/rd |1010111| OP-V (OPFVV)
2099-
* funct6 | vm | vs2 | vs1 | 0 1 0 (funct3) | vd/rd |1010111| OP-V (OPMVV)
2100-
* funct6 | vm | vs2 | imm[4:0] | 0 1 1 (funct3) | vd |1010111| OP-V (OPIVI)
2101-
* funct6 | vm | vs2 | rs1 | 1 0 0 (funct3) | vd |1010111| OP-V (OPIVX)
2102-
* funct6 | vm | vs2 | rs1 | 1 0 1 (funct3) | vd |1010111| OP-V (OPFVF)
2103-
* funct6 | vm | vs2 | rs1 | 1 1 0 (funct3) | vd/rd |1010111| OP-V (OPMVX)
2104-
* 6 1 5 5 3 5 7
2105-
*
2098+
* funct6 | vm | vs2 | vs1 | 0 0 0 (funct3) | vd |1010111|
2099+
* OP-V (OPIVV) funct6 | vm | vs2 | vs1 | 0 0 1 (funct3) | vd/rd
2100+
* |1010111| OP-V (OPFVV) funct6 | vm | vs2 | vs1 | 0 1 0 (funct3)
2101+
* | vd/rd |1010111| OP-V (OPMVV) funct6 | vm | vs2 | imm[4:0] | 0 1 1
2102+
* (funct3) | vd |1010111| OP-V (OPIVI) funct6 | vm | vs2 | rs1
2103+
* | 1 0 0 (funct3) | vd |1010111| OP-V (OPIVX) funct6 | vm | vs2 |
2104+
* rs1 | 1 0 1 (funct3) | vd |1010111| OP-V (OPFVF) funct6 | vm | vs2
2105+
* | rs1 | 1 1 0 (funct3) | vd/rd |1010111| OP-V (OPMVX) 6 1 5 5
2106+
* 3 5 7
2107+
*
21062108
* Where 'vm' is the bit indicates whether masking is enabled
2107-
* see https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#531-mask-encoding
2108-
*
2109+
* see
2110+
* https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#531-mask-encoding
2111+
*
21092112
* VMEM format:
2110-
*
2113+
*
21112114
* 31 29 28 27 26 25 24 20 19 15 14 12 11 7 6 0
2112-
* nf | mew| mop | vm | lumop | rs1 | width | vd |0000111| VL* unit-stride
2113-
* nf | mew| mop | vm | rs2 | rs1 | width | vd |0000111| VLS* strided
2114-
* nf | mew| mop | vm | vs2 | rs1 | width | vd |0000111| VLX* indexed
2115-
* 3 1 2 1 5 5 3 5 7
2116-
*
2115+
* nf | mew| mop | vm | lumop | rs1 | width | vd |0000111| VL*
2116+
* unit-stride nf | mew| mop | vm | rs2 | rs1 | width | vd
2117+
* |0000111| VLS* strided nf | mew| mop | vm | vs2 | rs1 | width | vd
2118+
* |0000111| VLX* indexed 3 1 2 1 5 5 3 5 7
2119+
*
21172120
* VCFG format:
2118-
*
2121+
*
21192122
* 31 30 25 24 20 19 15 14 12 11 7 6 0
21202123
* 0 | zimm[10:0] | rs1 | 1 1 1 | rd |1010111| vsetvli
21212124
* 1 | 1| zimm[ 9:0] | uimm[4:0]| 1 1 1 | rd |1010111| vsetivli
21222125
* 1 | 000000 | rs2 | rs1 | 1 1 1 | rd |1010111| vsetvl
21232126
* 1 6 5 5 3 5 7
2124-
*
2127+
*
21252128
* reference:
21262129
* https://github.com/riscv/riscv-isa-manual/blob/main/src/images/wavedrom/valu-format.edn
21272130
* https://github.com/riscv/riscv-isa-manual/blob/main/src/images/wavedrom/v-inst-table.edn
21282131
* https://observablehq.com/@drom/risc-v-v
2129-
*
2132+
*
21302133
* funct3
21312134
* | 0 | 0 | 0 | OPIVV | vector-vector | N/A
21322135
* | 0 | 0 | 1 | OPFVV | vector-vector | N/A
@@ -2140,22 +2143,22 @@ static inline bool op_v(rv_insn_t *ir, const uint32_t insn)
21402143
{
21412144
uint32_t funct3_mask = 0x7000;
21422145
switch ((insn & funct3_mask) >> 7) {
2143-
case 0:
2144-
return op_ivv(ir, insn);
2145-
case 1:
2146-
return op_fvv(ir, insn);
2147-
case 2:
2148-
return op_mvv(ir, insn);
2149-
case 3:
2150-
return op_ivi(ir, insn);
2151-
case 4:
2152-
return op_ivx(ir, insn);
2153-
case 5:
2154-
return op_fvf(ir, insn);
2155-
case 6:
2156-
return op_mvx(ir, insn);
2157-
default:
2158-
return false;
2146+
case 0:
2147+
return op_ivv(ir, insn);
2148+
case 1:
2149+
return op_fvv(ir, insn);
2150+
case 2:
2151+
return op_mvv(ir, insn);
2152+
case 3:
2153+
return op_ivi(ir, insn);
2154+
case 4:
2155+
return op_ivx(ir, insn);
2156+
case 5:
2157+
return op_fvf(ir, insn);
2158+
case 6:
2159+
return op_mvx(ir, insn);
2160+
default:
2161+
return false;
21592162
}
21602163

21612164
if ((insn & MASK_VSETVLI) == MATCH_VSETVLI) {
@@ -2167,7 +2170,7 @@ static inline bool op_v(rv_insn_t *ir, const uint32_t insn)
21672170
// vsetivli
21682171
ir->rd = (insn >> 7) & 0x1f;
21692172
ir->uimm = (insn >> 15) & 0x1f;
2170-
ir->zimm = (insn >> 20) & 0x3ff; // zimm[9:0]
2173+
ir->zimm = (insn >> 20) & 0x3ff; // zimm[9:0]
21712174

21722175
} else if ((insn & MASK_VSETVL) == MATCH_VSETVL) {
21732176
// vsetvl

‎src/encoding.h

Lines changed: 357 additions & 346 deletions
Large diffs are not rendered by default.

‎src/riscv_private.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,10 @@ struct riscv_internal {
136136
#endif
137137

138138
#if RV32_HAS(EXT_RVV)
139-
#define VLEN 128 // FIXME should not use a const and not even here for VLEN
140-
uint8_t V1[(VLEN>>3)];
141-
uint8_t V2[(VLEN>>3)];
142-
uint8_t Vd[(VLEN>>3)];
139+
#define VLEN 128 // FIXME should not use a const and not even here for VLEN
140+
uint8_t V1[(VLEN >> 3)];
141+
uint8_t V2[(VLEN >> 3)];
142+
uint8_t Vd[(VLEN >> 3)];
143143
uint8_t vl; /* current vl size */
144144
uint8_t lmul;
145145
uint8_t sew; /* current sew size */

‎src/rv32_vector.c

Lines changed: 66 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,82 @@
11
/* RV32 RVV Instruction Set */
22

33

4-
RVOP(vsetvli, {
5-
// | `vlmul[2:0]` | LMUL | #groups | VLMAX | Registers grouped with register `n` |
6-
// |--------------|--------|---------|-----------------|--------------------------------------------------|
7-
// | `1 0 0` | - | - | - | Reserved |
8-
// | `1 0 1` | `1/8` | 32 | `VLEN/SEW/8` | `v_n` (single register in group) |
9-
// | `1 1 0` | `1/4` | 32 | `VLEN/SEW/4` | `v_n` (single register in group) |
10-
// | `1 1 1` | `1/2` | 32 | `VLEN/SEW/2` | `v_n` (single register in group) |
11-
// | `0 0 0` | `1` | 32 | `VLEN/SEW` | `v_n` (single register in group) |
12-
// | `0 0 1` | `2` | 16 | `2*VLEN/SEW` | `v_n`, `v_n+1` |
13-
// | `0 1 0` | `4` | 8 | `4*VLEN/SEW` | `v_n`, ..., `v_n+3` |
14-
// | `0 1 1` | `8` | 4 | `8*VLEN/SEW` | `v_n`, ..., `v_n+7` |
15-
rv->lmul = 1<<(ir->zimm & 0x3);
16-
if (ir->zimm & 0x4) {
17-
rv->lmul = 1;
18-
}
4+
RVOP(
5+
vsetvli,
6+
{
7+
// | `vlmul[2:0]` | LMUL | #groups | VLMAX | Registers
8+
// grouped with register `n` |
9+
// |--------------|--------|---------|-----------------|--------------------------------------------------|
10+
// | `1 0 0` | - | - | - | Reserved | | `1
11+
// 0 1` | `1/8` | 32 | `VLEN/SEW/8` | `v_n` (single
12+
// register in group) | | `1 1 0` | `1/4` | 32 |
13+
// `VLEN/SEW/4` | `v_n` (single register in group) |
14+
// | `1 1 1` | `1/2` | 32 | `VLEN/SEW/2` | `v_n` (single
15+
// register in group) | | `0 0 0` | `1` | 32 |
16+
// `VLEN/SEW` | `v_n` (single register in group) |
17+
// | `0 0 1` | `2` | 16 | `2*VLEN/SEW` | `v_n`, `v_n+1`
18+
// | | `0 1 0` | `4` | 8 | `4*VLEN/SEW` | `v_n`, ...,
19+
// `v_n+3` | | `0 1 1` | `8` | 4 |
20+
// `8*VLEN/SEW` | `v_n`, ..., `v_n+7` |
21+
rv->lmul = 1 << (ir->zimm & 0x3);
22+
if (ir->zimm & 0x4) {
23+
rv->lmul = 1;
24+
}
1925

20-
// | `vsew[2:0]` | SEW |
21-
// |-------------|----------|
22-
// | 0 0 0 | 8 |
23-
// | 0 0 1 | 16 |
24-
// | 0 1 0 | 32 |
25-
// | 0 1 1 | 64 |
26-
// | 1 X X | Reserved |
27-
rv->sew = 8 << (ir->zimm & 0xf);
28-
}, GEN({/* no operation */}))
26+
// | `vsew[2:0]` | SEW |
27+
// |-------------|----------|
28+
// | 0 0 0 | 8 |
29+
// | 0 0 1 | 16 |
30+
// | 0 1 0 | 32 |
31+
// | 0 1 1 | 64 |
32+
// | 1 X X | Reserved |
33+
rv->sew = 8 << (ir->zimm & 0xf);
34+
},
35+
GEN({/* no operation */}))
2936

30-
#define ADD_VV(BIT) \
31-
static inline *int##BIT##_t add_vv_i##BIT##(int##BIT##_t *a, int##BIT##_t *b, size_t size) { \
32-
int##BIT##_t c[size];\
33-
for (int i = 0; i < size; i++) {\
34-
c[i]=a[i]+b[i];\
35-
}\
36-
return c;\
37-
}
37+
#define ADD_VV(BIT) \
38+
static inline *int##BIT##_t add_vv_i##BIT##(int##BIT##_t *a, \
39+
int##BIT##_t *b, size_t size) \
40+
{ \
41+
int##BIT##_t c[size]; \
42+
for (int i = 0; i < size; i++) { \
43+
c[i] = a[i] + b[i]; \
44+
} \
45+
return c; \
46+
}
3847
ADD_VV(8)
3948
ADD_VV(16)
4049
ADD_VV(32)
4150
ADD_VV(64)
4251

4352

4453
RVOP(vadd_vi, { rv->V1[rv_reg_zero] = 0; }, GEN({/* no operation */}))
45-
RVOP(vadd_vv, {
46-
switch (rv->sew) {
47-
case 8:
48-
rv->Vd = (* int8_t)add_vv_i8((*int8_t)rv->V1, (*int8_t)rv->V2, rv-vl/8);
49-
break;
50-
case 16:
51-
rv->Vd = (* int8_t)add_vv_i16((*int16_t)rv->V1, (*int16_t)rv->V2, rv-vl/16);
52-
break;
53-
case 32:
54-
rv->Vd = (* int8_t)add_vv_i32((*int32_t)rv->V1, (*int32_t)rv->V2, rv-vl/32);
55-
break;
56-
case 64:
57-
rv->Vd = (* int8_t)add_vv_i64((*int64_t)rv->V1, (*int64_t)rv->V2, rv-vl/64);
58-
break;
59-
60-
default:
61-
break;
62-
}
54+
RVOP(
55+
vadd_vv,
56+
{
57+
switch (rv->sew) {
58+
case 8:
59+
rv->Vd = (*int8_t) add_vv_i8((*int8_t) rv->V1, (*int8_t) rv->V2,
60+
rv - vl / 8);
61+
break;
62+
case 16:
63+
rv->Vd = (*int8_t) add_vv_i16((*int16_t) rv->V1, (*int16_t) rv->V2,
64+
rv - vl / 16);
65+
break;
66+
case 32:
67+
rv->Vd = (*int8_t) add_vv_i32((*int32_t) rv->V1, (*int32_t) rv->V2,
68+
rv - vl / 32);
69+
break;
70+
case 64:
71+
rv->Vd = (*int8_t) add_vv_i64((*int64_t) rv->V1, (*int64_t) rv->V2,
72+
rv - vl / 64);
73+
break;
6374

64-
}, GEN({/* no operation */}))
75+
default:
76+
break;
77+
}
78+
},
79+
GEN({/* no operation */}))
6580
RVOP(vand_vi, { rv->Vd[rv_reg_zero] = 0; }, GEN({/* no operation */}))
6681
RVOP(vand_vv, { rv->Vd[rv_reg_zero] = 0; }, GEN({/* no operation */}))
6782
RVOP(vmadc_vi, { rv->Vd[rv_reg_zero] = 0; }, GEN({/* no operation */}))

0 commit comments

Comments
 (0)
Please sign in to comment.