mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
riscv: Implement simple vec4 ops via floats.
This commit is contained in:
parent
df313bd296
commit
4e17c59cc2
4 changed files with 67 additions and 3 deletions
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue