riscv: Implement simple vec4 ops via floats.

This commit is contained in:
Unknown W. Brackets 2023-07-25 19:11:27 -07:00
parent df313bd296
commit 4e17c59cc2
4 changed files with 67 additions and 3 deletions

View file

@ -125,7 +125,7 @@ void RiscVJit::CompIR_LoadShift(IRInst inst) {
case IROp::Load32Left:
case IROp::Load32Right:
// Should not happen if the pass to split is active.
CompIR_Generic(inst);
DISABLE;
break;
default:
@ -256,7 +256,7 @@ void RiscVJit::CompIR_StoreShift(IRInst inst) {
case IROp::Store32Left:
case IROp::Store32Right:
// Should not happen if the pass to split is active.
CompIR_Generic(inst);
DISABLE;
break;
default:

View file

@ -55,13 +55,48 @@ void RiscVJit::CompIR_VecArith(IRInst inst) {
switch (inst.op) {
case IROp::Vec4Add:
fpr.Map4DirtyInIn(inst.dest, inst.src1, inst.src2);
for (int i = 0; i < 4; ++i)
FADD(32, fpr.R(inst.dest + i), fpr.R(inst.src1 + i), fpr.R(inst.src2 + i));
break;
case IROp::Vec4Sub:
fpr.Map4DirtyInIn(inst.dest, inst.src1, inst.src2);
for (int i = 0; i < 4; ++i)
FSUB(32, fpr.R(inst.dest + i), fpr.R(inst.src1 + i), fpr.R(inst.src2 + i));
break;
case IROp::Vec4Mul:
fpr.Map4DirtyInIn(inst.dest, inst.src1, inst.src2);
for (int i = 0; i < 4; ++i)
FMUL(32, fpr.R(inst.dest + i), fpr.R(inst.src1 + i), fpr.R(inst.src2 + i));
break;
case IROp::Vec4Div:
fpr.Map4DirtyInIn(inst.dest, inst.src1, inst.src2);
for (int i = 0; i < 4; ++i)
FDIV(32, fpr.R(inst.dest + i), fpr.R(inst.src1 + i), fpr.R(inst.src2 + i));
break;
case IROp::Vec4Scale:
fpr.SpillLock(inst.src2);
fpr.MapReg(inst.src2);
fpr.Map4DirtyIn(inst.dest, inst.src1);
fpr.ReleaseSpillLock(inst.src2);
for (int i = 0; i < 4; ++i)
FMUL(32, fpr.R(inst.dest + i), fpr.R(inst.src1 + i), fpr.R(inst.src2));
break;
case IROp::Vec4Neg:
fpr.Map4DirtyIn(inst.dest, inst.src1);
for (int i = 0; i < 4; ++i)
FNEG(32, fpr.R(inst.dest + i), fpr.R(inst.src1 + i));
break;
case IROp::Vec4Abs:
CompIR_Generic(inst);
fpr.Map4DirtyIn(inst.dest, inst.src1);
for (int i = 0; i < 4; ++i)
FABS(32, fpr.R(inst.dest + i), fpr.R(inst.src1 + i));
break;
default:

View file

@ -211,6 +211,32 @@ void RiscVRegCacheFPU::MapDirtyInIn(IRRegIndex rd, IRRegIndex rs, IRRegIndex rt,
ReleaseSpillLock(rt);
}
void RiscVRegCacheFPU::Map4DirtyIn(IRRegIndex rdbase, IRRegIndex rsbase, bool avoidLoad) {
for (int i = 0; i < 4; ++i)
SpillLock(rdbase + i, rsbase + i);
bool load = !avoidLoad || (rdbase < rsbase + 4 && rdbase + 4 > rsbase);
for (int i = 0; i < 4; ++i)
MapReg(rdbase + i, load ? MIPSMap::DIRTY : MIPSMap::NOINIT);
for (int i = 0; i < 4; ++i)
MapReg(rsbase + i);
for (int i = 0; i < 4; ++i)
ReleaseSpillLock(rdbase + i, rsbase + i);
}
void RiscVRegCacheFPU::Map4DirtyInIn(IRRegIndex rdbase, IRRegIndex rsbase, IRRegIndex rtbase, bool avoidLoad) {
for (int i = 0; i < 4; ++i)
SpillLock(rdbase + i, rsbase + i, rtbase + i);
bool load = !avoidLoad || (rdbase < rsbase + 4 && rdbase + 4 > rsbase) || (rdbase < rtbase + 4 && rdbase + 4 > rtbase);
for (int i = 0; i < 4; ++i)
MapReg(rdbase + i, load ? MIPSMap::DIRTY : MIPSMap::NOINIT);
for (int i = 0; i < 4; ++i)
MapReg(rsbase + i);
for (int i = 0; i < 4; ++i)
MapReg(rtbase + i);
for (int i = 0; i < 4; ++i)
ReleaseSpillLock(rdbase + i, rsbase + i, rtbase + i);
}
void RiscVRegCacheFPU::FlushRiscVReg(RiscVReg r) {
_dbg_assert_(r >= F0 && r <= F31);
int reg = r - F0;

View file

@ -64,6 +64,9 @@ public:
void MapInIn(IRRegIndex rd, IRRegIndex rs);
void MapDirtyIn(IRRegIndex rd, IRRegIndex rs, bool avoidLoad = true);
void MapDirtyInIn(IRRegIndex rd, IRRegIndex rs, IRRegIndex rt, bool avoidLoad = true);
void Map4Dirty(IRRegIndex rdbase, bool avoidLoad = true);
void Map4DirtyIn(IRRegIndex rdbase, IRRegIndex rsbase, bool avoidLoad = true);
void Map4DirtyInIn(IRRegIndex rdbase, IRRegIndex rsbase, IRRegIndex rtbase, bool avoidLoad = true);
void FlushAll();
void FlushR(IRRegIndex r);
void DiscardR(IRRegIndex r);