Skip to content

Commit 27bb878

Browse files
5265325Zhibo Hong
andauthored
arch-riscv: Fix incorrect vector unit-stride segment load instructions (gem5#2021)
This PR fixed the bug(gem5#1668) of vector unit-stride segment load, which is caused by incorrect tail/mask handling logic. Change-Id: I1a2b3c4d5e6f7890abcdef0123456789abcdef Co-authored-by: Zhibo Hong <[email protected]>
1 parent 1787354 commit 27bb878

File tree

3 files changed

+64
-9
lines changed

3 files changed

+64
-9
lines changed

src/arch/riscv/insts/vector.cc

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -654,36 +654,63 @@ VlSegDeIntrlvMicroInst::VlSegDeIntrlvMicroInst(ExtMachInst extMachInst,
654654
uint32_t index = VecMemInternalReg0 + i + (microIdx * _numSrcs);
655655
setSrcRegIdx(_numSrcRegs++, vecRegClass[index]);
656656
}
657+
658+
if (!extMachInst.vtype8.vta
659+
|| (!extMachInst.vm && !extMachInst.vtype8.vma)) {
660+
oldDstIdx = _numSrcRegs;
661+
setSrcRegIdx(_numSrcRegs++, destRegIdxArr[0]);
662+
}
663+
if (!extMachInst.vm) {
664+
vmsrcIdx = _numSrcRegs;
665+
setSrcRegIdx(_numSrcRegs++, vecRegClass[0]);
666+
}
657667
}
658668

659669
Fault
660670
VlSegDeIntrlvMicroInst::execute(ExecContext* xc, trace::InstRecord* traceData) const
661671
{
662672
vreg_t& tmp_d0 = *(vreg_t *)xc->getWritableRegOperand(this, 0);
663673
auto Vd = tmp_d0.as<uint8_t>();
664-
const uint32_t elems_per_vreg = micro_vl;
674+
const uint32_t elems_per_vreg = micro_vl;
665675
vreg_t tmp_s;
666676
auto s = tmp_s.as<uint8_t>();
667677
uint32_t elem = 0;
668678
uint32_t index = field;
679+
680+
vreg_t tmp_v0;
681+
uint8_t *v0;
682+
if (!machInst.vm) {
683+
xc->getRegOperand(this, vmsrcIdx, &tmp_v0);
684+
v0 = tmp_v0.as<uint8_t>();
685+
}
686+
687+
const size_t micro_vlmax = vlen / width_EEW(machInst.width);
688+
689+
if (!machInst.vtype8.vta || (!machInst.vm && !machInst.vtype8.vma)) {
690+
RiscvISA::vreg_t old_vd;
691+
xc->getRegOperand(this, oldDstIdx, &old_vd);
692+
tmp_d0 = old_vd;
693+
} else {
694+
tmp_d0.set(0xff);
695+
}
696+
669697
for (uint32_t i = 0; i < numSrcs; i++) {
670698
xc->getRegOperand(this, i, &tmp_s);
671699
s = tmp_s.as<uint8_t>();
672700

673-
// copy tail/inactive elements from vtmp src
674-
if (i == field) {
675-
tmp_d0 = tmp_s;
676-
}
677-
678701
while (index < (i + 1) * elems_per_vreg)
679702
{
680-
memcpy(Vd + (elem * sizeOfElement),
681-
s + ((index % elems_per_vreg) * sizeOfElement),
682-
sizeOfElement);
703+
size_t ei = elem + micro_vlmax * microIdx;
704+
if (machInst.vm || elem_mask(v0, ei)) {
705+
memcpy(Vd + (elem * sizeOfElement),
706+
s + ((index % elems_per_vreg) * sizeOfElement),
707+
sizeOfElement);
708+
}
683709
index += numSrcs;
684710
elem++;
685711
}
686712
}
713+
687714
if (traceData) {
688715
traceData->setData(vecRegClass, &tmp_d0);
689716
}

src/arch/riscv/isa/templates/vector_mem.isa

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1384,6 +1384,18 @@ def template VlSegConstructor {{
13841384
remaining_vl = this->vl;
13851385
micro_vl = std::min(remaining_vl, micro_vlmax);
13861386
for (int i = 0; i < num_microops && micro_vl > 0; ++i) {
1387+
bool illegal = (_machInst.vd + i + (f * num_microops)) >= 32;
1388+
if (illegal) {
1389+
microop = new VectorNopMicroInst(_machInst,
1390+
std::make_shared<IllegalInstFault>("vd is illegal",
1391+
_machInst));
1392+
this->microops.push_back(microop);
1393+
this->microops.front()->setFlag(IsFirstMicroop);
1394+
this->microops.back()->setFlag(IsLastMicroop);
1395+
this->flags[IsVector] = true;
1396+
return;
1397+
}
1398+
13871399
microop = new %(class_name)sMicro(_machInst, micro_vl, i,
13881400
num_microops, f, NFIELDS,
13891401
elen, vlen);
@@ -1630,6 +1642,18 @@ def template VsSegConstructor {{
16301642
remaining_vl = this->vl;
16311643
micro_vl = std::min(remaining_vl, micro_vlmax);
16321644
for (int i = 0; i < num_microops && micro_vl > 0; ++i) {
1645+
bool illegal = (_machInst.vs3 + i + (f * num_microops)) >= 32;
1646+
if (illegal) {
1647+
microop = new VectorNopMicroInst(_machInst,
1648+
std::make_shared<IllegalInstFault>("vs3 is illegal",
1649+
_machInst));
1650+
this->microops.push_back(microop);
1651+
this->microops.front()->setFlag(IsFirstMicroop);
1652+
this->microops.back()->setFlag(IsLastMicroop);
1653+
this->flags[IsVector] = true;
1654+
return;
1655+
}
1656+
16331657
microop = new VsSegIntrlvMicroInst(_machInst, micro_vl,
16341658
_machInst.vs3, NFIELDS, i, num_microops, f, elen, vlen,
16351659
size_per_elem);

src/cpu/o3/FuncUnitConfig.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ class ReadPort(FUDesc):
141141
OpDesc(opClass="FloatMemRead"),
142142
OpDesc(opClass="SimdUnitStrideLoad"),
143143
OpDesc(opClass="SimdUnitStrideMaskLoad"),
144+
OpDesc(opClass="SimdUnitStrideSegmentedLoad"),
144145
OpDesc(opClass="SimdStridedLoad"),
145146
OpDesc(opClass="SimdIndexedLoad"),
146147
OpDesc(opClass="SimdUnitStrideFaultOnlyFirstLoad"),
@@ -157,6 +158,7 @@ class WritePort(FUDesc):
157158
OpDesc(opClass="FloatMemWrite"),
158159
OpDesc(opClass="SimdUnitStrideStore"),
159160
OpDesc(opClass="SimdUnitStrideMaskStore"),
161+
OpDesc(opClass="SimdUnitStrideSegmentedStore"),
160162
OpDesc(opClass="SimdStridedStore"),
161163
OpDesc(opClass="SimdIndexedStore"),
162164
OpDesc(opClass="SimdWholeRegisterStore"),
@@ -175,6 +177,8 @@ class RdWrPort(FUDesc):
175177
OpDesc(opClass="SimdUnitStrideStore"),
176178
OpDesc(opClass="SimdUnitStrideMaskLoad"),
177179
OpDesc(opClass="SimdUnitStrideMaskStore"),
180+
OpDesc(opClass="SimdUnitStrideSegmentedLoad"),
181+
OpDesc(opClass="SimdUnitStrideSegmentedStore"),
178182
OpDesc(opClass="SimdStridedLoad"),
179183
OpDesc(opClass="SimdStridedStore"),
180184
OpDesc(opClass="SimdIndexedLoad"),

0 commit comments

Comments
 (0)