riscv: Reduce bloat in jit fallbacks.

This commit is contained in:
Unknown W. Brackets 2023-07-23 23:52:50 -07:00
parent b97b7f3663
commit a8edf5fa24
4 changed files with 79 additions and 19 deletions

View file

@ -455,6 +455,7 @@ void IRFrontend::Comp_Syscall(MIPSOpcode op) {
}
void IRFrontend::Comp_Break(MIPSOpcode op) {
ir.Write(IROp::SetPCConst, 0, ir.AddConstant(GetCompilerPC()));
ir.Write(IROp::Break);
js.compiling = false;
}

View file

@ -55,7 +55,7 @@ void RiscVJit::CompIR_Exit(IRInst inst) {
case IROp::ExitToPC:
FlushAll();
QuickJ(R_RA, dispatcher_);
QuickJ(R_RA, dispatcherCheckCoreState_);
break;
default:

View file

@ -15,7 +15,12 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "Common/Profiler/Profiler.h"
#include "Core/Core.h"
#include "Core/HLE/HLE.h"
#include "Core/HLE/ReplaceTables.h"
#include "Core/MemMap.h"
#include "Core/MIPS/MIPSTables.h"
#include "Core/MIPS/RiscV/RiscVJit.h"
#include "Core/MIPS/RiscV/RiscVRegCache.h"
@ -98,10 +103,61 @@ void RiscVJit::CompIR_System(IRInst inst) {
switch (inst.op) {
case IROp::Interpret:
// IR protects us against this being a branching instruction (well, hopefully.)
FlushAll();
SaveStaticRegisters();
LI(X10, (int32_t)inst.constant);
QuickCallFunction((const u8 *)MIPSGetInterpretFunc(MIPSOpcode(inst.constant)));
LoadStaticRegisters();
break;
case IROp::Syscall:
FlushAll();
SaveStaticRegisters();
#ifdef USE_PROFILER
// When profiling, we can't skip CallSyscall, since it times syscalls.
LI(X10, (int32_t)inst.constant);
QuickCallFunction(&CallSyscall);
#else
// Skip the CallSyscall where possible.
{
MIPSOpcode op(inst.constant);
void *quickFunc = GetQuickSyscallFunc(op);
if (quickFunc) {
LI(X10, (uintptr_t)GetSyscallFuncPointer(op));
QuickCallFunction((const u8 *)quickFunc);
} else {
LI(X10, (int32_t)inst.constant);
QuickCallFunction(&CallSyscall);
}
}
#endif
LoadStaticRegisters();
// This is always followed by an ExitToPC, where we check coreState.
break;
case IROp::CallReplacement:
FlushAll();
SaveStaticRegisters();
QuickCallFunction(GetReplacementFunc(inst.constant)->replaceFunc);
LoadStaticRegisters();
SUB(DOWNCOUNTREG, DOWNCOUNTREG, X10);
break;
case IROp::Break:
CompIR_Generic(inst);
FlushAll();
// This doesn't naturally have restore/apply around it.
RestoreRoundingMode(true);
SaveStaticRegisters();
MovFromPC(X10);
QuickCallFunction(&Core_Break);
LoadStaticRegisters();
ApplyRoundingMode(true);
MovFromPC(SCRATCH1);
ADDI(SCRATCH1, SCRATCH1, 4);
QuickJ(R_RA, dispatcherPCInSCRATCH1_);
break;
default:

View file

@ -107,13 +107,6 @@ bool RiscVJit::CompileBlock(u32 em_address, std::vector<IRInst> &instructions, u
return true;
}
static u32 DoIRInst(uint64_t value) {
IRInst inst;
memcpy(&inst, &value, sizeof(inst));
return IRInterpret(currentMIPS, &inst, 1);
}
void RiscVJit::CompileIRInst(IRInst inst) {
switch (inst.op) {
case IROp::Nop:
@ -392,9 +385,15 @@ void RiscVJit::CompileIRInst(IRInst inst) {
}
}
static u32 DoIRInst(uint64_t value) {
IRInst inst;
memcpy(&inst, &value, sizeof(inst));
return IRInterpret(currentMIPS, &inst, 1);
}
void RiscVJit::CompIR_Generic(IRInst inst) {
// For now, we're gonna do it the slow and ugly way.
// Maybe there's a smarter way to fallback?
// If we got here, we're going the slow way.
uint64_t value;
memcpy(&value, &inst, sizeof(inst));
@ -403,14 +402,18 @@ void RiscVJit::CompIR_Generic(IRInst inst) {
SaveStaticRegisters();
QuickCallFunction(&DoIRInst);
LoadStaticRegisters();
// Result in X10 aka SCRATCH1.
_assert_(X10 == SCRATCH1);
if (BInRange(dispatcherPCInSCRATCH1_)) {
BNE(X10, R_ZERO, dispatcherPCInSCRATCH1_);
} else {
FixupBranch skip = BEQ(X10, R_ZERO);
QuickJ(R_RA, dispatcherPCInSCRATCH1_);
SetJumpTarget(skip);
// We only need to check the return value if it's a potential exit.
if ((GetIRMeta(inst.op)->flags & IRFLAG_EXIT) != 0) {
// Result in X10 aka SCRATCH1.
_assert_(X10 == SCRATCH1);
if (BInRange(dispatcherPCInSCRATCH1_)) {
BNE(X10, R_ZERO, dispatcherPCInSCRATCH1_);
} else {
FixupBranch skip = BEQ(X10, R_ZERO);
QuickJ(R_RA, dispatcherPCInSCRATCH1_);
SetJumpTarget(skip);
}
}
}