Browse Source

rvv: add new whole reg load/store instructions

Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com>
pull/519/head
Chih-Min Chao 6 years ago
parent
commit
effb92a5ec
  1. 60
      riscv/decode.h
  2. 72
      riscv/encoding.h
  3. 9
      riscv/insns/vl1r_v.h
  4. 2
      riscv/insns/vl1re16_v.h
  5. 2
      riscv/insns/vl1re32_v.h
  6. 2
      riscv/insns/vl1re64_v.h
  7. 2
      riscv/insns/vl1re8_v.h
  8. 2
      riscv/insns/vl2re16_v.h
  9. 2
      riscv/insns/vl2re32_v.h
  10. 2
      riscv/insns/vl2re64_v.h
  11. 2
      riscv/insns/vl2re8_v.h
  12. 2
      riscv/insns/vl4re16_v.h
  13. 2
      riscv/insns/vl4re32_v.h
  14. 2
      riscv/insns/vl4re64_v.h
  15. 2
      riscv/insns/vl4re8_v.h
  16. 2
      riscv/insns/vl8re16_v.h
  17. 2
      riscv/insns/vl8re32_v.h
  18. 2
      riscv/insns/vl8re64_v.h
  19. 2
      riscv/insns/vl8re8_v.h
  20. 9
      riscv/insns/vs1r_v.h
  21. 2
      riscv/insns/vs2r_v.h
  22. 2
      riscv/insns/vs4r_v.h
  23. 2
      riscv/insns/vs8r_v.h
  24. 20
      riscv/riscv.mk.in
  25. 27
      spike_main/disasm.cc

60
riscv/decode.h

@ -1753,6 +1753,66 @@ for (reg_t i = 0; i < P.VU.vlmax && P.VU.vl != 0; ++i) { \
} \
p->VU.vstart = 0;
#define VI_LD_WHOLE(elt_width) \
require_vector_novtype(true); \
const reg_t baseAddr = RS1; \
const reg_t vd = insn.rd(); \
const reg_t len = insn.v_nf() + 1; \
require_align(vd, len); \
const reg_t elt_per_reg = P.VU.vlenb / sizeof(elt_width ## _t); \
const reg_t size = len * elt_per_reg; \
if (P.VU.vstart < size) { \
reg_t i = P.VU.vstart / elt_per_reg; \
reg_t off = P.VU.vstart % elt_per_reg; \
if (off) { \
for (reg_t pos = off; pos < elt_per_reg; ++pos) { \
auto val = MMU.load_## elt_width(baseAddr + \
P.VU.vstart * sizeof(elt_width ## _t)); \
P.VU.elt<elt_width ## _t>(vd + i, pos, true) = val; \
P.VU.vstart++; \
} \
++i; \
} \
for (; i < len; ++i) { \
for (reg_t pos = 0; pos < elt_per_reg; ++pos) { \
auto val = MMU.load_## elt_width(baseAddr + \
P.VU.vstart * sizeof(elt_width ## _t)); \
P.VU.elt<elt_width ## _t>(vd + i, pos, true) = val; \
P.VU.vstart++; \
} \
} \
} \
P.VU.vstart = 0; \
#define VI_ST_WHOLE \
require_vector_novtype(true); \
const reg_t baseAddr = RS1; \
const reg_t vs3 = insn.rd(); \
const reg_t len = insn.v_nf() + 1; \
require_align(vs3, len); \
const reg_t size = len * P.VU.vlenb; \
\
if (P.VU.vstart < size) { \
reg_t i = P.VU.vstart / P.VU.vlenb; \
reg_t off = P.VU.vstart % P.VU.vlenb; \
if (off) { \
for (reg_t pos = off; pos < P.VU.vlenb; ++pos) { \
auto val = P.VU.elt<uint8_t>(vs3 + i, pos); \
MMU.store_uint8(baseAddr + P.VU.vstart, val); \
P.VU.vstart++; \
} \
i++; \
} \
for (; i < len; ++i) { \
for (reg_t pos = 0; pos < P.VU.vlenb; ++pos) { \
auto val = P.VU.elt<uint8_t>(vs3 + i, pos); \
MMU.store_uint8(baseAddr + P.VU.vstart, val); \
P.VU.vstart++; \
} \
} \
} \
P.VU.vstart = 0;
//
// vector: amo
//

72
riscv/encoding.h

@ -1092,10 +1092,46 @@
#define MASK_VLE512FF_V 0x1df0707f
#define MATCH_VLE1024FF_V 0x11007007
#define MASK_VLE1024FF_V 0x1df0707f
#define MATCH_VL1R_V 0x2800007
#define MASK_VL1R_V 0xfff0707f
#define MATCH_VL1RE8_V 0x2800007
#define MASK_VL1RE8_V 0xfff0707f
#define MATCH_VL1RE16_V 0x2805007
#define MASK_VL1RE16_V 0xfff0707f
#define MATCH_VL1RE32_V 0x2806007
#define MASK_VL1RE32_V 0xfff0707f
#define MATCH_VL1RE64_V 0x2807007
#define MASK_VL1RE64_V 0xfff0707f
#define MATCH_VL2RE8_V 0x22800007
#define MASK_VL2RE8_V 0xfff0707f
#define MATCH_VL2RE16_V 0x22805007
#define MASK_VL2RE16_V 0xfff0707f
#define MATCH_VL2RE32_V 0x22806007
#define MASK_VL2RE32_V 0xfff0707f
#define MATCH_VL2RE64_V 0x22807007
#define MASK_VL2RE64_V 0xfff0707f
#define MATCH_VL4RE8_V 0x62800007
#define MASK_VL4RE8_V 0xfff0707f
#define MATCH_VL4RE16_V 0x62805007
#define MASK_VL4RE16_V 0xfff0707f
#define MATCH_VL4RE32_V 0x62806007
#define MASK_VL4RE32_V 0xfff0707f
#define MATCH_VL4RE64_V 0x62807007
#define MASK_VL4RE64_V 0xfff0707f
#define MATCH_VL8RE8_V 0xe2800007
#define MASK_VL8RE8_V 0xfff0707f
#define MATCH_VL8RE16_V 0xe2805007
#define MASK_VL8RE16_V 0xfff0707f
#define MATCH_VL8RE32_V 0xe2806007
#define MASK_VL8RE32_V 0xfff0707f
#define MATCH_VL8RE64_V 0xe2807007
#define MASK_VL8RE64_V 0xfff0707f
#define MATCH_VS1R_V 0x2800027
#define MASK_VS1R_V 0xfff0707f
#define MATCH_VS2R_V 0x22800027
#define MASK_VS2R_V 0xfff0707f
#define MATCH_VS4R_V 0x62800027
#define MASK_VS4R_V 0xfff0707f
#define MATCH_VS8R_V 0xe2800027
#define MASK_VS8R_V 0xfff0707f
#define MATCH_VFADD_VF 0x5057
#define MASK_VFADD_VF 0xfc00707f
#define MATCH_VFSUB_VF 0x8005057
@ -1802,6 +1838,14 @@
#define MASK_VAMOMAXUEI64_V 0xf800707f
#define MATCH_VMVNFR_V 0x9e003057
#define MASK_VMVNFR_V 0xfe00707f
#define MATCH_VL1R_V 0x2800007
#define MASK_VL1R_V 0xfff0707f
#define MATCH_VL2R_V 0x2805007
#define MASK_VL2R_V 0xfff0707f
#define MATCH_VL4R_V 0x2806007
#define MASK_VL4R_V 0xfff0707f
#define MATCH_VL8R_V 0x2807007
#define MASK_VL8R_V 0xfff0707f
#define CSR_FFLAGS 0x1
#define CSR_FRM 0x2
#define CSR_FCSR 0x3
@ -2503,8 +2547,26 @@ DECLARE_INSN(vle128ff_v, MATCH_VLE128FF_V, MASK_VLE128FF_V)
DECLARE_INSN(vle256ff_v, MATCH_VLE256FF_V, MASK_VLE256FF_V)
DECLARE_INSN(vle512ff_v, MATCH_VLE512FF_V, MASK_VLE512FF_V)
DECLARE_INSN(vle1024ff_v, MATCH_VLE1024FF_V, MASK_VLE1024FF_V)
DECLARE_INSN(vl1r_v, MATCH_VL1R_V, MASK_VL1R_V)
DECLARE_INSN(vl1re8_v, MATCH_VL1RE8_V, MASK_VL1RE8_V)
DECLARE_INSN(vl1re16_v, MATCH_VL1RE16_V, MASK_VL1RE16_V)
DECLARE_INSN(vl1re32_v, MATCH_VL1RE32_V, MASK_VL1RE32_V)
DECLARE_INSN(vl1re64_v, MATCH_VL1RE64_V, MASK_VL1RE64_V)
DECLARE_INSN(vl2re8_v, MATCH_VL2RE8_V, MASK_VL2RE8_V)
DECLARE_INSN(vl2re16_v, MATCH_VL2RE16_V, MASK_VL2RE16_V)
DECLARE_INSN(vl2re32_v, MATCH_VL2RE32_V, MASK_VL2RE32_V)
DECLARE_INSN(vl2re64_v, MATCH_VL2RE64_V, MASK_VL2RE64_V)
DECLARE_INSN(vl4re8_v, MATCH_VL4RE8_V, MASK_VL4RE8_V)
DECLARE_INSN(vl4re16_v, MATCH_VL4RE16_V, MASK_VL4RE16_V)
DECLARE_INSN(vl4re32_v, MATCH_VL4RE32_V, MASK_VL4RE32_V)
DECLARE_INSN(vl4re64_v, MATCH_VL4RE64_V, MASK_VL4RE64_V)
DECLARE_INSN(vl8re8_v, MATCH_VL8RE8_V, MASK_VL8RE8_V)
DECLARE_INSN(vl8re16_v, MATCH_VL8RE16_V, MASK_VL8RE16_V)
DECLARE_INSN(vl8re32_v, MATCH_VL8RE32_V, MASK_VL8RE32_V)
DECLARE_INSN(vl8re64_v, MATCH_VL8RE64_V, MASK_VL8RE64_V)
DECLARE_INSN(vs1r_v, MATCH_VS1R_V, MASK_VS1R_V)
DECLARE_INSN(vs2r_v, MATCH_VS2R_V, MASK_VS2R_V)
DECLARE_INSN(vs4r_v, MATCH_VS4R_V, MASK_VS4R_V)
DECLARE_INSN(vs8r_v, MATCH_VS8R_V, MASK_VS8R_V)
DECLARE_INSN(vfadd_vf, MATCH_VFADD_VF, MASK_VFADD_VF)
DECLARE_INSN(vfsub_vf, MATCH_VFSUB_VF, MASK_VFSUB_VF)
DECLARE_INSN(vfmin_vf, MATCH_VFMIN_VF, MASK_VFMIN_VF)
@ -2858,6 +2920,10 @@ DECLARE_INSN(vamomaxei64_v, MATCH_VAMOMAXEI64_V, MASK_VAMOMAXEI64_V)
DECLARE_INSN(vamominuei64_v, MATCH_VAMOMINUEI64_V, MASK_VAMOMINUEI64_V)
DECLARE_INSN(vamomaxuei64_v, MATCH_VAMOMAXUEI64_V, MASK_VAMOMAXUEI64_V)
DECLARE_INSN(vmvnfr_v, MATCH_VMVNFR_V, MASK_VMVNFR_V)
DECLARE_INSN(vl1r_v, MATCH_VL1R_V, MASK_VL1R_V)
DECLARE_INSN(vl2r_v, MATCH_VL2R_V, MASK_VL2R_V)
DECLARE_INSN(vl4r_v, MATCH_VL4R_V, MASK_VL4R_V)
DECLARE_INSN(vl8r_v, MATCH_VL8R_V, MASK_VL8R_V)
#endif
#ifdef DECLARE_CSR
DECLARE_CSR(fflags, CSR_FFLAGS)

9
riscv/insns/vl1r_v.h

@ -1,9 +0,0 @@
// vl1r.v vd, (rs1)
require_vector_novtype(true);
const reg_t baseAddr = RS1;
const reg_t vd = insn.rd();
for (reg_t i = P.VU.vstart; i < P.VU.vlenb; ++i) {
auto val = MMU.load_uint8(baseAddr + i);
P.VU.elt<uint8_t>(vd, i, true) = val;
}
P.VU.vstart = 0;

2
riscv/insns/vl1re16_v.h

@ -0,0 +1,2 @@
// vl1re16.v vd, (rs1)
VI_LD_WHOLE(uint16);

2
riscv/insns/vl1re32_v.h

@ -0,0 +1,2 @@
// vl1re32.v vd, (rs1)
VI_LD_WHOLE(uint32);

2
riscv/insns/vl1re64_v.h

@ -0,0 +1,2 @@
// vl1re64.v vd, (rs1)
VI_LD_WHOLE(uint64);

2
riscv/insns/vl1re8_v.h

@ -0,0 +1,2 @@
// vl1re8.v vd, (rs1)
VI_LD_WHOLE(uint8);

2
riscv/insns/vl2re16_v.h

@ -0,0 +1,2 @@
// vl2e16.v vd, (rs1)
VI_LD_WHOLE(uint16);

2
riscv/insns/vl2re32_v.h

@ -0,0 +1,2 @@
// vl2re32.v vd, (rs1)
VI_LD_WHOLE(uint32);

2
riscv/insns/vl2re64_v.h

@ -0,0 +1,2 @@
// vl2re64.v vd, (rs1)
VI_LD_WHOLE(uint64);

2
riscv/insns/vl2re8_v.h

@ -0,0 +1,2 @@
// vl2re8.v vd, (rs1)
VI_LD_WHOLE(uint8);

2
riscv/insns/vl4re16_v.h

@ -0,0 +1,2 @@
// vl4re16.v vd, (rs1)
VI_LD_WHOLE(uint16);

2
riscv/insns/vl4re32_v.h

@ -0,0 +1,2 @@
// vl4re32.v vd, (rs1)
VI_LD_WHOLE(uint32);

2
riscv/insns/vl4re64_v.h

@ -0,0 +1,2 @@
// vl4re64.v vd, (rs1)
VI_LD_WHOLE(uint64);

2
riscv/insns/vl4re8_v.h

@ -0,0 +1,2 @@
// vl4re8.v vd, (rs1)
VI_LD_WHOLE(uint8);

2
riscv/insns/vl8re16_v.h

@ -0,0 +1,2 @@
// vl8re16.v vd, (rs1)
VI_LD_WHOLE(uint16);

2
riscv/insns/vl8re32_v.h

@ -0,0 +1,2 @@
// vl8re32.v vd, (rs1)
VI_LD_WHOLE(uint32);

2
riscv/insns/vl8re64_v.h

@ -0,0 +1,2 @@
// vl8re64.v vd, (rs1)
VI_LD_WHOLE(uint64);

2
riscv/insns/vl8re8_v.h

@ -0,0 +1,2 @@
// vl8re8.v vd, (rs1)
VI_LD_WHOLE(uint8);

9
riscv/insns/vs1r_v.h

@ -1,9 +1,2 @@
// vs1r.v vs3, (rs1)
require_vector_novtype(true);
const reg_t baseAddr = RS1;
const reg_t vs3 = insn.rd();
for (reg_t i = P.VU.vstart; i < P.VU.vlenb; ++i) {
auto val = P.VU.elt<uint8_t>(vs3, i);
MMU.store_uint8(baseAddr + i, val);
}
P.VU.vstart = 0;
VI_ST_WHOLE

2
riscv/insns/vs2r_v.h

@ -0,0 +1,2 @@
// vs2r.v vs3, (rs1)
VI_ST_WHOLE

2
riscv/insns/vs4r_v.h

@ -0,0 +1,2 @@
// vs4r.v vs3, (rs1)
VI_ST_WHOLE

2
riscv/insns/vs8r_v.h

@ -0,0 +1,2 @@
// vs8r.v vs3, (rs1)
VI_ST_WHOLE

20
riscv/riscv.mk.in

@ -709,6 +709,22 @@ riscv_insn_ext_v_ldst = \
vle16ff_v \
vle32ff_v \
vle64ff_v \
vl1re8_v \
vl2re8_v \
vl4re8_v \
vl8re8_v \
vl1re16_v \
vl2re16_v \
vl4re16_v \
vl8re16_v \
vl1re32_v \
vl2re32_v \
vl4re32_v \
vl8re32_v \
vl1re64_v \
vl2re64_v \
vl4re64_v \
vl8re64_v \
vse8_v \
vse16_v \
vse32_v \
@ -725,8 +741,10 @@ riscv_insn_ext_v_ldst = \
vsuxei16_v \
vsuxei32_v \
vsuxei64_v \
vl1r_v \
vs1r_v \
vs2r_v \
vs4r_v \
vs8r_v \
riscv_insn_ext_v_ctrl = \
vsetvli \

27
spike_main/disasm.cc

@ -794,10 +794,33 @@ disassembler_t::disassembler_t(int xlen)
));
}
}
const custom_fmt_t template_insn2[] = {
{match_vl1re8_v, mask_vl1re8_v, "vl%dre%d.v", v_ld_unit},
};
for (reg_t i = 0, nf = 7; nf < 4; i++, nf >>= 1) {
for (auto item : template_insn) {
const reg_t match_nf = nf << 29;
char buf[128];
sprintf(buf, item.fmt, nf + 1, 8 << elt);
add_insn(new disasm_insn_t(
buf, item.match | match_nf, item.mask | mask_nf, item.arg
));
}
}
}
DISASM_INSN("vl1r.v", vl1r_v, 0, {&vd, &v_address});
DISASM_INSN("vs1r.v", vs1r_v, 0, {&vs3, &v_address});
#define DISASM_ST_WHOLE_INSN(name, nf) \
add_insn(new disasm_insn_t(#name, match_vs1r_v | (nf << 29), \
mask_vs1r_v | mask_nf, \
{&vs3, &v_address}));
DISASM_ST_WHOLE_INSN(vs1r.v, 0);
DISASM_ST_WHOLE_INSN(vs2r.v, 1);
DISASM_ST_WHOLE_INSN(vs4r.v, 3);
DISASM_ST_WHOLE_INSN(vs8r.v, 7);
#undef DISASM_ST_WHOLE_INSN
#define DISASM_OPIV_VXI_INSN(name, sign, suf) \
add_insn(new disasm_insn_t(#name "." #suf "v", \

Loading…
Cancel
Save