mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
riscv: Reduce bloat in jit fallbacks.
This commit is contained in:
parent
b97b7f3663
commit
a8edf5fa24
4 changed files with 79 additions and 19 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ void RiscVJit::CompIR_Exit(IRInst inst) {
|
|||
|
||||
case IROp::ExitToPC:
|
||||
FlushAll();
|
||||
QuickJ(R_RA, dispatcher_);
|
||||
QuickJ(R_RA, dispatcherCheckCoreState_);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue