Merge pull request #1291 from reicast/fh/rec-cpp-blockchecks
Block checks for rec-cpp
This commit is contained in:
commit
9379fe18bd
|
@ -20,7 +20,6 @@
|
|||
#define SHIL_MODE 2
|
||||
#include "hw/sh4/dyna/shil_canonical.h"
|
||||
|
||||
|
||||
#define MIPS_COUNTER 0
|
||||
|
||||
struct DynaRBI : RuntimeBlockInfo
|
||||
|
@ -35,8 +34,6 @@ struct DynaRBI : RuntimeBlockInfo
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
int cycle_counter;
|
||||
extern int mips_counter;
|
||||
|
||||
|
@ -73,7 +70,6 @@ void ngen_init()
|
|||
{
|
||||
}
|
||||
|
||||
|
||||
void ngen_GetFeatures(ngen_features* dst)
|
||||
{
|
||||
dst->InterpreterFallback = false;
|
||||
|
@ -90,6 +86,11 @@ u32* GetRegPtr(u32 reg)
|
|||
return Sh4_int_GetRegisterPtr((Sh4RegType)reg);
|
||||
}
|
||||
|
||||
void ngen_blockcheckfail(u32 pc) {
|
||||
printf("REC CPP: SMC invalidation at %08X\n", pc);
|
||||
rdv_BlockCheckFail(pc);
|
||||
}
|
||||
|
||||
class opcodeExec {
|
||||
public:
|
||||
virtual void execute() = 0;
|
||||
|
@ -813,6 +814,44 @@ struct opcode_blockend : public opcodeExec {
|
|||
}
|
||||
};
|
||||
|
||||
template <int sz>
|
||||
struct opcode_check_block : public opcodeExec {
|
||||
RuntimeBlockInfo* block;
|
||||
vector<u8> code;
|
||||
void* ptr;
|
||||
|
||||
opcodeExec* setup(RuntimeBlockInfo* block) {
|
||||
this->block = block;
|
||||
ptr = GetMemPtr(block->addr, 4);
|
||||
code.resize(sz == -1 ? block->sh4_code_size : sz);
|
||||
memcpy(&code[0], ptr, sz == -1 ? block->sh4_code_size : sz);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
void execute() {
|
||||
switch (sz)
|
||||
{
|
||||
case 4:
|
||||
if (*(u32 *)ptr != *(u32 *)&code[0])
|
||||
ngen_blockcheckfail(block->addr);
|
||||
break;
|
||||
case 6:
|
||||
if (*(u32 *)ptr != *(u32 *)&code[0] || *((u16 *)ptr + 2) != *((u16 *)&code[0] + 2))
|
||||
ngen_blockcheckfail(block->addr);
|
||||
break;
|
||||
case 8:
|
||||
if (*(u32 *)ptr != *(u32 *)&code[0] || *((u32 *)ptr + 1) != *((u32 *)&code[0] + 1))
|
||||
ngen_blockcheckfail(block->addr);
|
||||
break;
|
||||
default:
|
||||
if (memcmp(ptr, &code[0], block->sh4_code_size) != 0)
|
||||
ngen_blockcheckfail(block->addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(_DEBUG)
|
||||
#define DREP_1(x, phrase) if (x < cnt) ops[x]->execute(); else return;
|
||||
#define DREP_2(x, phrase) DREP_1(x, phrase) DREP_1(x+1, phrase)
|
||||
|
@ -1163,8 +1202,8 @@ public:
|
|||
opcodeExec** ptrsg;
|
||||
void compile(RuntimeBlockInfo* block, bool force_checks, bool reset, bool staging, bool optimise) {
|
||||
|
||||
//we need an extra one for the end opcode
|
||||
auto ptrs = fnnCtor_forreal(block->oplist.size() + 1)(block->guest_cycles);
|
||||
//we need an extra one for the end opcode and optionally one more for block check
|
||||
auto ptrs = fnnCtor_forreal(block->oplist.size() + 1 + (force_checks ? 1 : 0))(block->guest_cycles);
|
||||
|
||||
ptrsg = ptrs.ptrs;
|
||||
|
||||
|
@ -1177,9 +1216,30 @@ public:
|
|||
emit_Skip(emit_FreeSpace()-16);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < block->oplist.size(); i++) {
|
||||
size_t i = 0;
|
||||
if (force_checks)
|
||||
{
|
||||
opcodeExec* op;
|
||||
switch (block->sh4_code_size)
|
||||
{
|
||||
case 4:
|
||||
op = (new opcode_check_block<4>())->setup(block);
|
||||
break;
|
||||
case 6:
|
||||
op = (new opcode_check_block<6>())->setup(block);
|
||||
break;
|
||||
case 8:
|
||||
op = (new opcode_check_block<8>())->setup(block);
|
||||
break;
|
||||
default:
|
||||
op = (new opcode_check_block<-1>())->setup(block);
|
||||
break;
|
||||
}
|
||||
ptrs.ptrs[i++] = op;
|
||||
}
|
||||
for (size_t opnum = 0; opnum < block->oplist.size(); opnum++, i++) {
|
||||
opcode_index = i;
|
||||
shil_opcode& op = block->oplist[i];
|
||||
shil_opcode& op = block->oplist[opnum];
|
||||
switch (op.op) {
|
||||
|
||||
case shop_ifb:
|
||||
|
@ -1454,7 +1514,7 @@ public:
|
|||
CASEWS(BET_Cond_1);
|
||||
}
|
||||
|
||||
ptrs.ptrs[block->oplist.size()] = op;
|
||||
ptrs.ptrs[i] = op;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue