Skip to content

Commit

Permalink
Merge pull request #19 from huxuan0307/gh-rvv-cpu
Browse files Browse the repository at this point in the history
arch-riscv: Add vslideup.vi and vslidedown.vi
  • Loading branch information
ksco authored Nov 30, 2022
2 parents ccf590e + 46abe54 commit 64cccbc
Show file tree
Hide file tree
Showing 5 changed files with 579 additions and 0 deletions.
28 changes: 28 additions & 0 deletions src/arch/riscv/insts/vector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,34 @@ std::string VectorVMUNARY0MacroInst::generateDisassembly(Addr pc,
return ss.str();
}

std::string VectorSlideMicroInst::generateDisassembly(Addr pc,
const loader::SymbolTable *symtab) const
{
std::stringstream ss;
ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", ";
if (machInst.funct3 == 0x3) {
ss << registerName(srcRegIdx(0)) << ", " << machInst.vecimm;
} else {
ss << registerName(srcRegIdx(1)) << ", " << registerName(srcRegIdx(0));
}
if (machInst.vm == 0) ss << ", v0.t";
return ss.str();
}

std::string VectorSlideMacroInst::generateDisassembly(Addr pc,
const loader::SymbolTable *symtab) const
{
std::stringstream ss;
ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", ";
if (machInst.funct3 == 0x3) {
ss << registerName(srcRegIdx(0)) << ", " << machInst.vecimm;
} else {
ss << registerName(srcRegIdx(1)) << ", " << registerName(srcRegIdx(0));
}
if (machInst.vm == 0) ss << ", v0.t";
return ss.str();
}

std::string VleMicroInst::generateDisassembly(Addr pc,
const loader::SymbolTable *symtab) const
{
Expand Down
29 changes: 29 additions & 0 deletions src/arch/riscv/insts/vector.hh
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,35 @@ class VectorVMUNARY0MacroInst : public VectorMacroInst
Addr pc, const loader::SymbolTable *symtab) const override;
};

class VectorSlideMacroInst : public VectorMacroInst
{
protected:
VectorSlideMacroInst(const char* mnem, ExtMachInst _machInst,
OpClass __opClass)
: VectorMacroInst(mnem, _machInst, __opClass)
{
this->flags[IsVector] = true;
}

std::string generateDisassembly(
Addr pc, const loader::SymbolTable *symtab) const override;
};

class VectorSlideMicroInst : public VectorMicroInst
{
protected:
uint8_t vdIdx;
uint8_t vs2Idx;
VectorSlideMicroInst(const char *mnem, ExtMachInst _machInst,
OpClass __opClass, uint8_t _microVl,
uint8_t _microIdx, uint8_t _vdIdx, uint8_t _vs2Idx)
: VectorMicroInst(mnem, _machInst, __opClass, _microVl, _microIdx)
, vdIdx(_vdIdx), vs2Idx(_vs2Idx)
{}

std::string generateDisassembly(
Addr pc, const loader::SymbolTable *symtab) const override;
};

class VectorMemMicroInst : public VectorMicroInst
{
Expand Down
266 changes: 266 additions & 0 deletions src/arch/riscv/isa/decoder.isa
Original file line number Diff line number Diff line change
Expand Up @@ -3017,6 +3017,69 @@ decode QUADRANT default Unknown::unknown() {
}
}
}}, OPIVI, VectorMiscOp);
0x0e: VectorSlideUpFormat::vslideup_vi({{
const int offset = (int)(uint64_t)(SIMM5);
const int microVlmax = vtype_VLMAX(machInst.vtype8, true);
const int vregOffset = vdIdx - vs2Idx;
const int offsetInVreg = offset - vregOffset * microVlmax;
if (std::abs(offsetInVreg) < uint32_t(microVlmax)) {
const int upperBound = (offsetInVreg >= 0)
? microVlmax - offsetInVreg
: microVlmax + offsetInVreg;
const int vdOffset = (offsetInVreg >= 0)
? offsetInVreg
: 0;
const int vs2Offset = (offsetInVreg >= 0)
? 0
: -offsetInVreg;
const int elemOffset = vdOffset + vdIdx * microVlmax;
for (int i = 0;
i < upperBound && i + vdOffset < microVl;
i++) {
if (this->vm || elem_mask(v0, i + elemOffset)) {
Vd_vu[i + vdOffset] = Vs2_vu[i + vs2Offset];
}
}
}
}}, OPIVI, VectorMiscOp);
0x0f: VectorSlideDownFormat::vslidedown_vi({{
const int offset = (int)(uint64_t)(SIMM5);
const int microVlmax = vtype_VLMAX(machInst.vtype8, true);
const int vregOffset = vs2Idx - vdIdx;
const int offsetInVreg = offset - vregOffset * microVlmax;
const int numVs2s = vtype_regs_per_group(vtype);
if (std::abs(offsetInVreg) < uint32_t(microVlmax)) {
const bool needZeroTail = numVs2s == vs2Idx + 1;
const int upperBound = (offsetInVreg >= 0)
? microVlmax - offsetInVreg
: microVlmax + offsetInVreg;
const int vdOffset = (offsetInVreg >= 0)
? 0
: -offsetInVreg;
const int vs2Offset = (offsetInVreg >= 0)
? offsetInVreg
: 0;
const int elemIdxBase = vdIdx * microVlmax;
vreg_t resVreg;
auto res = resVreg.as<vu>();
for (int i = 0;
i < upperBound && i + vdOffset < microVl;
i++) {
res[i + vdOffset] = Vs2_vu[i + vs2Offset];
}
if (needZeroTail) {
for (int i = upperBound + vdOffset;
i < microVlmax; i++) {
res[i] = 0;
}
}
for (int i = vdOffset; i < microVl ; i++) {
if (vm || elem_mask(v0, i + elemIdxBase)) {
Vd_vu[i] = res[i];
}
}
}
}}, OPIVI, VectorMiscOp);
format VectorIntFormat {
0x10: decode VM {
0x0: vadc_vim({{
Expand Down Expand Up @@ -3209,6 +3272,69 @@ decode QUADRANT default Unknown::unknown() {
Vd_vu[i] = Vs2_vu[i] ^ Rs1_vu;
}}, OPIVX, VectorIntegerArithOp);
}
0x0e: VectorSlideUpFormat::vslideup_vx({{
const int offset = (int)Rs1_vu;
const int microVlmax = vtype_VLMAX(machInst.vtype8, true);
const int vregOffset = vdIdx - vs2Idx;
const int offsetInVreg = offset - vregOffset * microVlmax;
if (std::abs(offsetInVreg) < uint32_t(microVlmax)) {
const int upperBound = (offsetInVreg >= 0)
? microVlmax - offsetInVreg
: microVlmax + offsetInVreg;
const int vdOffset = (offsetInVreg >= 0)
? offsetInVreg
: 0;
const int vs2Offset = (offsetInVreg >= 0)
? 0
: -offsetInVreg;
const int elemOffset = vdOffset + vdIdx * microVlmax;
for (int i = 0;
i < upperBound && i + vdOffset < microVl;
i++) {
if (this->vm || elem_mask(v0, i + elemOffset)) {
Vd_vu[i + vdOffset] = Vs2_vu[i + vs2Offset];
}
}
}
}}, OPIVX, VectorMiscOp);
0x0f: VectorSlideDownFormat::vslidedown_vx({{
const int offset = (int)Rs1_vu;
const int microVlmax = vtype_VLMAX(machInst.vtype8, true);
const int vregOffset = vs2Idx - vdIdx;
const int offsetInVreg = offset - vregOffset * microVlmax;
const int numVs2s = vtype_regs_per_group(vtype);
if (std::abs(offsetInVreg) < uint32_t(microVlmax)) {
const bool needZeroTail = numVs2s == vs2Idx + 1;
const int upperBound = (offsetInVreg >= 0)
? microVlmax - offsetInVreg
: microVlmax + offsetInVreg;
const int vdOffset = (offsetInVreg >= 0)
? 0
: -offsetInVreg;
const int vs2Offset = (offsetInVreg >= 0)
? offsetInVreg
: 0;
const int elemIdxBase = vdIdx * microVlmax;
vreg_t resVreg;
auto res = resVreg.as<vu>();
for (int i = 0;
i < upperBound && i + vdOffset < microVl;
i++) {
res[i + vdOffset] = Vs2_vu[i + vs2Offset];
}
if (needZeroTail) {
for (int i = upperBound + vdOffset;
i < microVlmax; i++) {
res[i] = 0;
}
}
for (int i = vdOffset; i < microVl ; i++) {
if (vm || elem_mask(v0, i + elemIdxBase)) {
Vd_vu[i] = res[i];
}
}
}
}}, OPIVX, VectorMiscOp);
0x0c: VectorGatherFormat::vrgather_vx({{
for (uint32_t i = 0; i < microVl; i++) {
uint32_t ei = i + vs1_idx * vs1_elems + vs1_bias;
Expand Down Expand Up @@ -3446,6 +3572,76 @@ decode QUADRANT default Unknown::unknown() {
false, true).v;
}}, OPFVF, VectorFloatArithOp);
}
0x0e: VectorFloatSlideUpFormat::vfslide1up_vf({{
const int offset = 1;
const int microVlmax = vtype_VLMAX(machInst.vtype8, true);
const int vregOffset = vdIdx - vs2Idx;
const int offsetInVreg = offset - vregOffset * microVlmax;
if (std::abs(offsetInVreg) < uint32_t(microVlmax)) {
const int upperBound = (offsetInVreg >= 0)
? microVlmax - offsetInVreg
: microVlmax + offsetInVreg;
const int vdOffset = (offsetInVreg >= 0)
? offsetInVreg
: 0;
const int vs2Offset = (offsetInVreg >= 0)
? 0
: -offsetInVreg;
const int elemOffset = vdOffset + vdIdx * microVlmax;
for (int i = 0;
i < upperBound && i + vdOffset < microVl;
i++) {
if (this->vm || elem_mask(v0, i + elemOffset)) {
Vd_vu[i + vdOffset] = Vs2_vu[i + vs2Offset];
}
}
// TODO: dirty code
if (vdIdx == 0 && vs2Idx == 0 &&
(this->vm || elem_mask(v0, 0))) {
tmp_d0.as<vu>()[0] = Rs1_vu;
}
}
}}, OPFVF, VectorMiscOp);
0x0f: VectorFloatSlideDownFormat::vfslide1down_vf({{
const int offset = 1;
const int microVlmax = vtype_VLMAX(machInst.vtype8, true);
const int vregOffset = vs2Idx - vdIdx;
const int offsetInVreg = offset - vregOffset * microVlmax;
const int numVs2s = vtype_regs_per_group(vtype);
if (std::abs(offsetInVreg) < uint32_t(microVlmax)) {
const bool needZeroTail = numVs2s == vs2Idx + 1;
const int upperBound = (offsetInVreg >= 0)
? microVlmax - offsetInVreg
: microVlmax + offsetInVreg;
const int vdOffset = (offsetInVreg >= 0)
? 0
: -offsetInVreg;
const int vs2Offset = (offsetInVreg >= 0)
? offsetInVreg
: 0;
const int elemIdxBase = vdIdx * microVlmax;
vreg_t resVreg;
auto res = resVreg.as<vu>();
for (int i = 0;
i < upperBound && i + vdOffset < microVl;
i++) {
res[i + vdOffset] = Vs2_vu[i + vs2Offset];
}
if (needZeroTail) {
for (int i = upperBound + vdOffset;
i < microVlmax; i++) {
res[i] = 0;
}
}
for (int i = vdOffset; i < microVl ; i++) {
if (vm || elem_mask(v0, i + elemIdxBase)) {
Vd_vu[i] = (i + elemIdxBase != machInst.vl - 1)
? res[i]
: Rs1_vu;
}
}
}
}}, OPFVF, VectorMiscOp);
// VRFUNARY0
0x10: decode VS2 {
0x00: decode VM {
Expand Down Expand Up @@ -3647,6 +3843,76 @@ decode QUADRANT default Unknown::unknown() {
Vd_vi[i] = res >> 1;
}}, OPMVX, VectorIntegerArithOp);
}
0x0e: VectorSlideUpFormat::vslide1up_vx({{
const int offset = 1;
const int microVlmax = vtype_VLMAX(machInst.vtype8, true);
const int vregOffset = vdIdx - vs2Idx;
const int offsetInVreg = offset - vregOffset * microVlmax;
if (std::abs(offsetInVreg) < uint32_t(microVlmax)) {
const int upperBound = (offsetInVreg >= 0)
? microVlmax - offsetInVreg
: microVlmax + offsetInVreg;
const int vdOffset = (offsetInVreg >= 0)
? offsetInVreg
: 0;
const int vs2Offset = (offsetInVreg >= 0)
? 0
: -offsetInVreg;
const int elemOffset = vdOffset + vdIdx * microVlmax;
for (int i = 0;
i < upperBound && i + vdOffset < microVl;
i++) {
if (this->vm || elem_mask(v0, i + elemOffset)) {
Vd_vu[i + vdOffset] = Vs2_vu[i + vs2Offset];
}
}
// TODO: dirty code
if (vdIdx == 0 && vs2Idx == 0 &&
(this->vm || elem_mask(v0, 0))) {
tmp_d0.as<vu>()[0] = Rs1_vu;
}
}
}}, OPIVX, VectorMiscOp);
0x0f: VectorSlideDownFormat::vslide1down_vx({{
const int offset = 1;
const int microVlmax = vtype_VLMAX(machInst.vtype8, true);
const int vregOffset = vs2Idx - vdIdx;
const int offsetInVreg = offset - vregOffset * microVlmax;
const int numVs2s = vtype_regs_per_group(vtype);
if (std::abs(offsetInVreg) < uint32_t(microVlmax)) {
const bool needZeroTail = numVs2s == vs2Idx + 1;
const int upperBound = (offsetInVreg >= 0)
? microVlmax - offsetInVreg
: microVlmax + offsetInVreg;
const int vdOffset = (offsetInVreg >= 0)
? 0
: -offsetInVreg;
const int vs2Offset = (offsetInVreg >= 0)
? offsetInVreg
: 0;
const int elemIdxBase = vdIdx * microVlmax;
vreg_t resVreg;
auto res = resVreg.as<vu>();
for (int i = 0;
i < upperBound && i + vdOffset < microVl;
i++) {
res[i + vdOffset] = Vs2_vu[i + vs2Offset];
}
if (needZeroTail) {
for (int i = upperBound + vdOffset;
i < microVlmax; i++) {
res[i] = 0;
}
}
for (int i = vdOffset; i < microVl ; i++) {
if (vm || elem_mask(v0, i + elemIdxBase)) {
Vd_vu[i] = (i + elemIdxBase != machInst.vl - 1)
? res[i]
: Rs1_vu;
}
}
}
}}, OPIVX, VectorMiscOp);
// VRXUNARY0
0x10: decode VS2 {
0x00: decode VM {
Expand Down
Loading

0 comments on commit 64cccbc

Please sign in to comment.