mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-26 23:10:38 +00:00
softjit: Add register cache for softjit.
This commit is contained in:
parent
91787e63d9
commit
9fed7ea732
@ -479,6 +479,10 @@ SingleFunc GetSingleFunc(const PixelFuncID &id) {
|
||||
return jitted;
|
||||
}
|
||||
|
||||
return jitCache->GenericSingle(id);
|
||||
}
|
||||
|
||||
SingleFunc PixelJitCache::GenericSingle(const PixelFuncID &id) {
|
||||
if (id.clearMode) {
|
||||
switch (id.fbFormat) {
|
||||
case GE_FORMAT_565:
|
||||
@ -568,4 +572,82 @@ SingleFunc PixelJitCache::GetSingle(const PixelFuncID &id) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void PixelRegCache::Reset() {
|
||||
regs.clear();
|
||||
}
|
||||
|
||||
void PixelRegCache::Release(PixelRegCache::Reg r, PixelRegCache::Type t) {
|
||||
for (auto ® : regs) {
|
||||
if (reg.reg == r && reg.type == t) {
|
||||
reg.purpose = INVALID;
|
||||
reg.locked = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
RegStatus newStatus;
|
||||
newStatus.reg = r;
|
||||
newStatus.purpose = INVALID;
|
||||
newStatus.type = t;
|
||||
regs.push_back(newStatus);
|
||||
}
|
||||
|
||||
void PixelRegCache::Unlock(PixelRegCache::Reg r, PixelRegCache::Type t) {
|
||||
for (auto ® : regs) {
|
||||
if (reg.reg == r && reg.type == t) {
|
||||
reg.locked = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_assert_msg_(false, "softjit Unlock() reg that isn't there");
|
||||
}
|
||||
|
||||
bool PixelRegCache::Has(PixelRegCache::Purpose p, PixelRegCache::Type t) {
|
||||
for (auto ® : regs) {
|
||||
if (reg.purpose == p && reg.type == t) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
PixelRegCache::Reg PixelRegCache::Find(PixelRegCache::Purpose p, PixelRegCache::Type t) {
|
||||
for (auto ® : regs) {
|
||||
if (reg.purpose == p && reg.type == t) {
|
||||
reg.locked = true;
|
||||
return reg.reg;
|
||||
}
|
||||
}
|
||||
_assert_msg_(false, "softjit Find() reg that isn't there (%d)", p);
|
||||
return Reg(-1);
|
||||
}
|
||||
|
||||
PixelRegCache::Reg PixelRegCache::Alloc(PixelRegCache::Purpose p, PixelRegCache::Type t) {
|
||||
_assert_msg_(!Has(p, t), "softjit Alloc() reg duplicate");
|
||||
RegStatus *best = nullptr;
|
||||
for (auto ® : regs) {
|
||||
if (reg.locked || reg.type != t)
|
||||
continue;
|
||||
|
||||
if (best == nullptr)
|
||||
best = ®
|
||||
// Prefer a free/purposeless reg.
|
||||
if (reg.purpose == INVALID || reg.purpose >= TEMP0) {
|
||||
best = ®
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (best) {
|
||||
best->locked = true;
|
||||
best->purpose = p;
|
||||
return best->reg;
|
||||
}
|
||||
|
||||
_assert_msg_(false, "softjit Alloc() reg with none free (%d)", p);
|
||||
return Reg();
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "ppsspp_config.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#if PPSSPP_ARCH(ARM)
|
||||
#include "Common/ArmEmitter.h"
|
||||
@ -59,6 +60,50 @@ void Shutdown();
|
||||
|
||||
bool DescribeCodePtr(const u8 *ptr, std::string &name);
|
||||
|
||||
struct PixelRegCache {
|
||||
enum Purpose {
|
||||
INVALID,
|
||||
GSTATE,
|
||||
CONST_BASE,
|
||||
ALPHA,
|
||||
|
||||
// Above this can only be temps.
|
||||
TEMP0,
|
||||
TEMP1,
|
||||
TEMP2,
|
||||
TEMP3,
|
||||
TEMP4,
|
||||
TEMP5,
|
||||
};
|
||||
enum Type {
|
||||
T_GEN,
|
||||
T_VEC,
|
||||
};
|
||||
|
||||
#if PPSSPP_ARCH(X86) || PPSSPP_ARCH(AMD64)
|
||||
typedef Gen::X64Reg Reg;
|
||||
#else
|
||||
typedef int Reg;
|
||||
#endif
|
||||
|
||||
struct RegStatus {
|
||||
Reg reg;
|
||||
Purpose purpose;
|
||||
Type type;
|
||||
bool locked = false;
|
||||
};
|
||||
|
||||
void Reset();
|
||||
void Release(Reg r, Type t);
|
||||
void Unlock(Reg r, Type t);
|
||||
bool Has(Purpose p, Type t);
|
||||
Reg Find(Purpose p, Type t);
|
||||
Reg Alloc(Purpose p, Type t);
|
||||
|
||||
private:
|
||||
std::vector<RegStatus> regs;
|
||||
};
|
||||
|
||||
#if PPSSPP_ARCH(ARM)
|
||||
class PixelJitCache : public ArmGen::ARMXCodeBlock {
|
||||
#elif PPSSPP_ARCH(ARM64)
|
||||
@ -75,6 +120,7 @@ public:
|
||||
|
||||
// Returns a pointer to the code to run.
|
||||
SingleFunc GetSingle(const PixelFuncID &id);
|
||||
SingleFunc GenericSingle(const PixelFuncID &id);
|
||||
void Clear();
|
||||
|
||||
std::string DescribeCodePtr(const u8 *ptr);
|
||||
@ -86,8 +132,12 @@ private:
|
||||
Arm64Gen::ARM64FloatEmitter fp;
|
||||
#endif
|
||||
|
||||
PixelRegCache::Reg GetGState();
|
||||
PixelRegCache::Reg GetConstBase();
|
||||
|
||||
std::unordered_map<PixelFuncID, SingleFunc> cache_;
|
||||
std::unordered_map<PixelFuncID, const u8 *> addresses_;
|
||||
PixelRegCache regCache_;
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -29,7 +29,43 @@ using namespace Gen;
|
||||
|
||||
namespace Rasterizer {
|
||||
|
||||
#if PPSSPP_PLATFORM(WINDOWS)
|
||||
static const X64Reg argXReg = RCX;
|
||||
static const X64Reg argYReg = RDX;
|
||||
static const X64Reg argZReg = R8;
|
||||
static const X64Reg argFogReg = R9;
|
||||
static const X64Reg argColorReg = XMM4;
|
||||
|
||||
// Must save: RBX, RSP, RBP, RDI, RSI, R12-R15, XMM6-15
|
||||
#else
|
||||
static const X64Reg argXReg = RDI;
|
||||
static const X64Reg argYReg = RSI;
|
||||
static const X64Reg argZReg = RDX;
|
||||
static const X64Reg argFogReg = RCX;
|
||||
static const X64Reg argColorReg = XMM0;
|
||||
|
||||
// Must save: RBX, RSP, RBP, R12-R15
|
||||
#endif
|
||||
|
||||
SingleFunc PixelJitCache::CompileSingle(const PixelFuncID &id) {
|
||||
// Setup the reg cache.
|
||||
regCache_.Reset();
|
||||
regCache_.Release(RAX, PixelRegCache::T_GEN);
|
||||
regCache_.Release(R10, PixelRegCache::T_GEN);
|
||||
regCache_.Release(R11, PixelRegCache::T_GEN);
|
||||
regCache_.Release(XMM1, PixelRegCache::T_VEC);
|
||||
regCache_.Release(XMM2, PixelRegCache::T_VEC);
|
||||
regCache_.Release(XMM3, PixelRegCache::T_VEC);
|
||||
regCache_.Release(XMM5, PixelRegCache::T_VEC);
|
||||
|
||||
#if !PPSSPP_PLATFORM(WINDOWS)
|
||||
regCache_.Release(R8, PixelRegCache::T_GEN);
|
||||
regCache_.Release(R9, PixelRegCache::T_GEN);
|
||||
regCache_.Release(XMM4, PixelRegCache::T_VEC);
|
||||
#else
|
||||
regCache_.Release(XMM0, PixelRegCache::T_VEC);
|
||||
#endif
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user