Assorted cleanup in the MIPS emulation

This commit is contained in:
Henrik Rydgard 2013-12-10 13:06:57 +01:00
parent 108edd4093
commit 2d8429ac48
19 changed files with 40 additions and 34 deletions

View File

@ -216,7 +216,6 @@ u8* MemArena::Find4GBBase()
#else // 32 bit #else // 32 bit
#ifdef _WIN32 #ifdef _WIN32
// The highest thing in any 1GB section of memory space is the locked cache. We only need to fit it.
u8* base = (u8*)VirtualAlloc(0, 0x10000000, MEM_RESERVE, PAGE_READWRITE); u8* base = (u8*)VirtualAlloc(0, 0x10000000, MEM_RESERVE, PAGE_READWRITE);
if (base) { if (base) {
VirtualFree(base, 0, MEM_RELEASE); VirtualFree(base, 0, MEM_RELEASE);
@ -244,8 +243,6 @@ u8* MemArena::Find4GBBase()
// if (!(a_flags & MV_FAKE_VMEM) && (b_flags & MV_FAKE_VMEM)) // if (!(a_flags & MV_FAKE_VMEM) && (b_flags & MV_FAKE_VMEM))
// continue; // continue;
static bool Memory_TryBase(u8 *base, const MemoryView *views, int num_views, u32 flags, MemArena *arena) { static bool Memory_TryBase(u8 *base, const MemoryView *views, int num_views, u32 flags, MemArena *arena) {
// OK, we know where to find free space. Now grab it! // OK, we know where to find free space. Now grab it!
// We just mimic the popular BAT setup. // We just mimic the popular BAT setup.
@ -384,6 +381,7 @@ u8 *MemoryMap_Setup(const MemoryView *views, int num_views, u32 flags, MemArena
u8 *base = MemArena::Find4GBBase(); u8 *base = MemArena::Find4GBBase();
if (!Memory_TryBase(base, views, num_views, flags, arena)) if (!Memory_TryBase(base, views, num_views, flags, arena))
{ {
ERROR_LOG(MEMMAP, "MemoryMap_Setup: Failed finding a memory base.");
PanicAlert("MemoryMap_Setup: Failed finding a memory base."); PanicAlert("MemoryMap_Setup: Failed finding a memory base.");
return 0; return 0;
} }

View File

@ -36,6 +36,7 @@
// Currently known non working ones should have DISABLE. // Currently known non working ones should have DISABLE.
// #define CONDITIONAL_DISABLE { fpr.ReleaseSpillLocksAndDiscardTemps(); Comp_Generic(op); return; } // #define CONDITIONAL_DISABLE { fpr.ReleaseSpillLocksAndDiscardTemps(); Comp_Generic(op); return; }
#define CONDITIONAL_DISABLE ; #define CONDITIONAL_DISABLE ;
#define DISABLE { fpr.ReleaseSpillLocksAndDiscardTemps(); Comp_Generic(op); return; } #define DISABLE { fpr.ReleaseSpillLocksAndDiscardTemps(); Comp_Generic(op); return; }
#define NEON_IF_AVAILABLE(func) { if (jo.useNEONVFPU) { func(op); return; } } #define NEON_IF_AVAILABLE(func) { if (jo.useNEONVFPU) { func(op); return; } }
@ -51,8 +52,6 @@
#define _IMM16 (signed short)(op & 0xFFFF) #define _IMM16 (signed short)(op & 0xFFFF)
#define _IMM26 (op & 0x03FFFFFF) #define _IMM26 (op & 0x03FFFFFF)
namespace MIPSComp namespace MIPSComp
{ {
// Vector regs can overlap in all sorts of swizzled ways. // Vector regs can overlap in all sorts of swizzled ways.
@ -604,6 +603,7 @@ namespace MIPSComp
} }
void Jit::Comp_VDot(MIPSOpcode op) { void Jit::Comp_VDot(MIPSOpcode op) {
NEON_IF_AVAILABLE(CompNEON_VDot);
CONDITIONAL_DISABLE; CONDITIONAL_DISABLE;
if (js.HasUnknownPrefix()) { if (js.HasUnknownPrefix()) {
DISABLE; DISABLE;
@ -1689,6 +1689,8 @@ namespace MIPSComp
SetCC(CC_AL); SetCC(CC_AL);
} }
} }
ApplyPrefixD(dregs, sz);
fpr.ReleaseSpillLocksAndDiscardTemps(); fpr.ReleaseSpillLocksAndDiscardTemps();
} }

View File

@ -149,12 +149,6 @@ void Jit::ClearCacheAt(u32 em_address, int length)
blocks.InvalidateICache(em_address, length); blocks.InvalidateICache(em_address, length);
} }
void Jit::CompileAt(u32 addr)
{
MIPSOpcode op = Memory::Read_Instruction(addr);
MIPSCompileOp(op);
}
void Jit::EatInstruction(MIPSOpcode op) { void Jit::EatInstruction(MIPSOpcode op) {
MIPSInfo info = MIPSGetInfo(op); MIPSInfo info = MIPSGetInfo(op);
if (info & DELAYSLOT) { if (info & DELAYSLOT) {
@ -188,6 +182,7 @@ void Jit::CompileDelaySlot(int flags)
_MSR(true, false, R8); // Restore flags register _MSR(true, false, R8); // Restore flags register
} }
void Jit::Compile(u32 em_address) { void Jit::Compile(u32 em_address) {
if (GetSpaceLeft() < 0x10000 || blocks.IsFull()) { if (GetSpaceLeft() < 0x10000 || blocks.IsFull()) {
ClearCache(); ClearCache();

View File

@ -52,6 +52,7 @@ class Jit : public ArmGen::ARMXCodeBlock
{ {
public: public:
Jit(MIPSState *mips); Jit(MIPSState *mips);
void DoState(PointerWrap &p); void DoState(PointerWrap &p);
static void DoDummyState(PointerWrap &p); static void DoDummyState(PointerWrap &p);
@ -70,7 +71,6 @@ public:
} }
void CompileDelaySlot(int flags); void CompileDelaySlot(int flags);
void CompileAt(u32 addr);
void EatInstruction(MIPSOpcode op); void EatInstruction(MIPSOpcode op);
void Comp_RunBlock(MIPSOpcode op); void Comp_RunBlock(MIPSOpcode op);

View File

@ -217,14 +217,16 @@ int binary_search(JitBlock blocks[], const u8 *baseoff, int imin, int imax)
return -1; return -1;
} }
int JitBlockCache::GetBlockNumberFromEmuHackOp(MIPSOpcode inst) const { int JitBlockCache::GetBlockNumberFromEmuHackOp(MIPSOpcode inst, bool ignoreBad) const {
if (!num_blocks || !MIPS_IS_EMUHACK(inst)) // definitely not a JIT block if (!num_blocks || !MIPS_IS_EMUHACK(inst)) // definitely not a JIT block
return -1; return -1;
int off = (inst & MIPS_EMUHACK_VALUE_MASK); int off = (inst & MIPS_EMUHACK_VALUE_MASK);
const u8 *baseoff = codeBlock_->GetBasePtr() + off; const u8 *baseoff = codeBlock_->GetBasePtr() + off;
if (baseoff < codeBlock_->GetBasePtr() || baseoff >= codeBlock_->GetCodePtr()) { if (baseoff < codeBlock_->GetBasePtr() || baseoff >= codeBlock_->GetCodePtr()) {
ERROR_LOG(JIT, "JitBlockCache: Invalid Emuhack Op %08x", inst.encoding); if (!ignoreBad) {
ERROR_LOG(JIT, "JitBlockCache: Invalid Emuhack Op %08x", inst.encoding);
}
return -1; return -1;
} }

View File

@ -107,7 +107,7 @@ public:
// Returns a list of block numbers - only one block can start at a particular address, but they CAN overlap. // Returns a list of block numbers - only one block can start at a particular address, but they CAN overlap.
// This one is slow so should only be used for one-shots from the debugger UI, not for anything during runtime. // This one is slow so should only be used for one-shots from the debugger UI, not for anything during runtime.
void GetBlockNumbersFromAddress(u32 em_address, std::vector<int> *block_numbers); void GetBlockNumbersFromAddress(u32 em_address, std::vector<int> *block_numbers);
int GetBlockNumberFromEmuHackOp(MIPSOpcode inst) const; int GetBlockNumberFromEmuHackOp(MIPSOpcode inst, bool ignoreBad = false) const;
u32 GetAddressFromBlockPtr(const u8 *ptr) const; u32 GetAddressFromBlockPtr(const u8 *ptr) const;

View File

@ -123,7 +123,7 @@ namespace MIPSComp {
prefixTFlag = PREFIX_KNOWN_DIRTY; prefixTFlag = PREFIX_KNOWN_DIRTY;
prefixT = 0xE4; prefixT = 0xE4;
} }
if ((prefixDFlag & PREFIX_KNOWN) == 0 || prefixD != 0x0 || VfpuWriteMask() != 0) { if ((prefixDFlag & PREFIX_KNOWN) == 0 || prefixD != 0x0) {
prefixDFlag = PREFIX_KNOWN_DIRTY; prefixDFlag = PREFIX_KNOWN_DIRTY;
prefixD = 0x0; prefixD = 0x0;
} }

View File

@ -136,4 +136,8 @@ namespace MIPSCodeUtils
bool IsVFPUBranch(MIPSOpcode op) { bool IsVFPUBranch(MIPSOpcode op) {
return (MIPSGetInfo(op) & (IS_VFPU | IS_CONDBRANCH)) == (IS_VFPU | IS_CONDBRANCH); return (MIPSGetInfo(op) & (IS_VFPU | IS_CONDBRANCH)) == (IS_VFPU | IS_CONDBRANCH);
} }
bool IsBranch(MIPSOpcode op) {
return (MIPSGetInfo(op) & IS_CONDBRANCH) == IS_CONDBRANCH;
}
} }

View File

@ -58,4 +58,5 @@ namespace MIPSCodeUtils
u32 GetJumpTarget(u32 addr); u32 GetJumpTarget(u32 addr);
u32 GetSureBranchTarget(u32 addr); u32 GetSureBranchTarget(u32 addr);
bool IsVFPUBranch(MIPSOpcode op); bool IsVFPUBranch(MIPSOpcode op);
bool IsBranch(MIPSOpcode op);
} }

View File

@ -61,6 +61,14 @@ namespace MIPSDis
sprintf(out, "%s\t --- unknown ---", MIPSGetName(op)); sprintf(out, "%s\t --- unknown ---", MIPSGetName(op));
} }
void Dis_Cache(MIPSOpcode op, char *out)
{
int imm = (s16)(op & 0xFFFF);
int rs = _RS;
int func = (op >> 16) & 0x1F;
sprintf(out, "%s\tfunc=%i, %s(%s)", MIPSGetName(op), func, RN(rs), SignedHex(imm));
}
void Dis_mxc1(MIPSOpcode op, char *out) void Dis_mxc1(MIPSOpcode op, char *out)
{ {
int fs = _FS; int fs = _FS;

View File

@ -34,6 +34,7 @@ namespace MIPSDis
void Dis_RelBranch2(MIPSOpcode op, char *out); void Dis_RelBranch2(MIPSOpcode op, char *out);
void Dis_RelBranch(MIPSOpcode op, char *out); void Dis_RelBranch(MIPSOpcode op, char *out);
void Dis_Generic(MIPSOpcode op, char *out); void Dis_Generic(MIPSOpcode op, char *out);
void Dis_Cache(MIPSOpcode op, char *out);
void Dis_IType(MIPSOpcode op, char *out); void Dis_IType(MIPSOpcode op, char *out);
void Dis_IType1(MIPSOpcode op, char *out); void Dis_IType1(MIPSOpcode op, char *out);
void Dis_ITypeMem(MIPSOpcode op, char *out); void Dis_ITypeMem(MIPSOpcode op, char *out);

View File

@ -147,7 +147,7 @@ const MIPSInstruction tableImmediate[64] = // xxxxxx ..... ..... ...............
INVALID, INVALID,
INVALID, INVALID,
INSTR("swr", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_WORD), INSTR("swr", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_WORD),
INSTR("cache", &Jit::Comp_Cache, Dis_Generic, Int_Cache, IN_MEM|IN_IMM16|IN_RS_ADDR|IN_OTHER|OUT_OTHER), INSTR("cache", &Jit::Comp_Cache, Dis_Cache, Int_Cache, IN_MEM|IN_IMM16|IN_RS_ADDR|IN_OTHER|OUT_OTHER),
//48 //48
INSTR("ll", &Jit::Comp_Generic, Dis_Generic, Int_StoreSync, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|OUT_OTHER|MEMTYPE_WORD), INSTR("ll", &Jit::Comp_Generic, Dis_Generic, Int_StoreSync, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|OUT_OTHER|MEMTYPE_WORD),
INSTR("lwc1", &Jit::Comp_FPULS, Dis_FPULS, Int_FPULS, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_OTHER|MEMTYPE_FLOAT), INSTR("lwc1", &Jit::Comp_FPULS, Dis_FPULS, Int_FPULS, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_OTHER|MEMTYPE_FLOAT),

View File

@ -86,6 +86,7 @@ struct MIPSInfo {
#define VFPU_NO_PREFIX 0x10000000 #define VFPU_NO_PREFIX 0x10000000
#define IS_VFPU 0x20000000 #define IS_VFPU 0x20000000
#define IS_FPU 0x40000000
#ifndef CDECL #ifndef CDECL
#define CDECL #define CDECL

View File

@ -259,7 +259,7 @@ MatrixSize GetMtxSize(MIPSOpcode op)
a += (b<<1); a += (b<<1);
switch (a) switch (a)
{ {
case 0: ERROR_LOG_REPORT(CPU, "Unexpected matrix size 1x1."); return M_2x2; case 0: return M_4x4; // This error pretty much only happens in disassembly of junk: // ERROR_LOG_REPORT(CPU, "Unexpected matrix size 1x1."); return M_2x2;
case 1: return M_2x2; case 1: return M_2x2;
case 2: return M_3x3; case 2: return M_3x3;
case 3: return M_4x4; case 3: return M_4x4;

View File

@ -492,7 +492,6 @@ void Jit::BranchVFPUFlag(MIPSOpcode op, Gen::CCFlags cc, bool likely)
// THE CONDITION // THE CONDITION
int imm3 = (op >> 18) & 7; int imm3 = (op >> 18) & 7;
//int val = (mips_->vfpuCtrl[VFPU_CTRL_CC] >> imm3) & 1;
TEST(32, M((void *)&(mips_->vfpuCtrl[VFPU_CTRL_CC])), Imm32(1 << imm3)); TEST(32, M((void *)&(mips_->vfpuCtrl[VFPU_CTRL_CC])), Imm32(1 << imm3));
u32 notTakenTarget = js.compilerPC + (delaySlotIsBranch ? 4 : 8); u32 notTakenTarget = js.compilerPC + (delaySlotIsBranch ? 4 : 8);

View File

@ -722,6 +722,9 @@ void Jit::Comp_Vcmov(MIPSOpcode op) {
SetJumpTarget(skip); SetJumpTarget(skip);
} }
} }
ApplyPrefixD(dregs, sz);
fpr.ReleaseSpillLocks(); fpr.ReleaseSpillLocks();
} }
@ -1142,6 +1145,10 @@ void Jit::Comp_Vi2f(MIPSOpcode op) {
// Translation of ryg's half_to_float5_SSE2 // Translation of ryg's half_to_float5_SSE2
void Jit::Comp_Vh2f(MIPSOpcode op) { void Jit::Comp_Vh2f(MIPSOpcode op) {
CONDITIONAL_DISABLE;
if (js.HasUnknownPrefix())
DISABLE;
#define SSE_CONST4(name, val) static const u32 MEMORY_ALIGNED16(name[4]) = { (val), (val), (val), (val) } #define SSE_CONST4(name, val) static const u32 MEMORY_ALIGNED16(name[4]) = { (val), (val), (val), (val) }
SSE_CONST4(mask_nosign, 0x7fff); SSE_CONST4(mask_nosign, 0x7fff);
@ -1150,11 +1157,6 @@ void Jit::Comp_Vh2f(MIPSOpcode op) {
SSE_CONST4(exp_infnan, 255 << 23); SSE_CONST4(exp_infnan, 255 << 23);
#undef SSE_CONST4 #undef SSE_CONST4
CONDITIONAL_DISABLE;
if (js.HasUnknownPrefix())
DISABLE;
VectorSize sz = GetVecSize(op); VectorSize sz = GetVecSize(op);
VectorSize outsize; VectorSize outsize;
switch (sz) { switch (sz) {

View File

@ -243,13 +243,6 @@ void Jit::CompileDelaySlot(int flags, RegCacheState *state)
LOAD_FLAGS; // restore flag! LOAD_FLAGS; // restore flag!
} }
void Jit::CompileAt(u32 addr)
{
CheckJitBreakpoint(addr, 0);
MIPSOpcode op = Memory::Read_Instruction(addr);
MIPSCompileOp(op);
}
void Jit::EatInstruction(MIPSOpcode op) void Jit::EatInstruction(MIPSOpcode op)
{ {
MIPSInfo info = MIPSGetInfo(op); MIPSInfo info = MIPSGetInfo(op);

View File

@ -58,7 +58,8 @@ class Jit : public Gen::XCodeBlock
{ {
public: public:
Jit(MIPSState *mips); Jit(MIPSState *mips);
~Jit(); virtual ~Jit();
void DoState(PointerWrap &p); void DoState(PointerWrap &p);
static void DoDummyState(PointerWrap &p); static void DoDummyState(PointerWrap &p);
@ -76,7 +77,6 @@ public:
return asm_.IsInSpace(p); return asm_.IsInSpace(p);
} }
void CompileAt(u32 addr);
void Comp_RunBlock(MIPSOpcode op); void Comp_RunBlock(MIPSOpcode op);
// Ops // Ops

View File

@ -150,7 +150,7 @@ Opcode Read_Instruction(u32 address)
if (MIPS_IS_EMUHACK(inst) && MIPSComp::jit) if (MIPS_IS_EMUHACK(inst) && MIPSComp::jit)
{ {
JitBlockCache *bc = MIPSComp::jit->GetBlockCache(); JitBlockCache *bc = MIPSComp::jit->GetBlockCache();
int block_num = bc->GetBlockNumberFromEmuHackOp(inst); int block_num = bc->GetBlockNumberFromEmuHackOp(inst, true);
if (block_num >= 0) { if (block_num >= 0) {
return bc->GetOriginalFirstOp(block_num); return bc->GetOriginalFirstOp(block_num);
} else { } else {