Make all unknown opcodes behave consistently.
Consistently fall back to the interpreter for unknown instructions, and make sure GetOpInfo() always returns a non-null pointer.
This commit is contained in:
parent
e640ef9d7b
commit
985087c7e2
|
@ -13,6 +13,8 @@ struct GekkoOPTemplate
|
||||||
GekkoOPInfo opinfo;
|
GekkoOPInfo opinfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static GekkoOPInfo unknownopinfo = { "unknown_instruction", OPTYPE_UNKNOWN, FL_ENDBLOCK, 0, 0, 0, 0 };
|
||||||
|
|
||||||
static GekkoOPTemplate primarytable[] =
|
static GekkoOPTemplate primarytable[] =
|
||||||
{
|
{
|
||||||
{4, Interpreter::RunTable4, {"RunTable4", OPTYPE_SUBTABLE | (4<<24), 0, 0, 0, 0, 0}},
|
{4, Interpreter::RunTable4, {"RunTable4", OPTYPE_SUBTABLE | (4<<24), 0, 0, 0, 0, 0}},
|
||||||
|
@ -85,14 +87,6 @@ static GekkoOPTemplate primarytable[] =
|
||||||
{61, Interpreter::psq_stu, {"psq_stu", OPTYPE_STOREPS, FL_IN_FLOAT_S | FL_OUT_A | FL_IN_A | FL_USE_FPU | FL_LOADSTORE, 1, 0, 0, 0}},
|
{61, Interpreter::psq_stu, {"psq_stu", OPTYPE_STOREPS, FL_IN_FLOAT_S | FL_OUT_A | FL_IN_A | FL_USE_FPU | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||||
|
|
||||||
//missing: 0, 5, 6, 9, 22, 30, 62, 58
|
//missing: 0, 5, 6, 9, 22, 30, 62, 58
|
||||||
{0, Interpreter::unknown_instruction, {"unknown_instruction", OPTYPE_UNKNOWN, FL_ENDBLOCK, 0, 0, 0, 0}},
|
|
||||||
{5, Interpreter::unknown_instruction, {"unknown_instruction", OPTYPE_UNKNOWN, FL_ENDBLOCK, 0, 0, 0, 0}},
|
|
||||||
{6, Interpreter::unknown_instruction, {"unknown_instruction", OPTYPE_UNKNOWN, FL_ENDBLOCK, 0, 0, 0, 0}},
|
|
||||||
{9, Interpreter::unknown_instruction, {"unknown_instruction", OPTYPE_UNKNOWN, FL_ENDBLOCK, 0, 0, 0, 0}},
|
|
||||||
{22, Interpreter::unknown_instruction, {"unknown_instruction", OPTYPE_UNKNOWN, FL_ENDBLOCK, 0, 0, 0, 0}},
|
|
||||||
{30, Interpreter::unknown_instruction, {"unknown_instruction", OPTYPE_UNKNOWN, FL_ENDBLOCK, 0, 0, 0, 0}},
|
|
||||||
{62, Interpreter::unknown_instruction, {"unknown_instruction", OPTYPE_UNKNOWN, FL_ENDBLOCK, 0, 0, 0, 0}},
|
|
||||||
{58, Interpreter::unknown_instruction, {"unknown_instruction", OPTYPE_UNKNOWN, FL_ENDBLOCK, 0, 0, 0, 0}},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static GekkoOPTemplate table4[] =
|
static GekkoOPTemplate table4[] =
|
||||||
|
@ -364,10 +358,16 @@ void InitTables()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//clear
|
//clear
|
||||||
|
for (int i = 0; i < 64; i++)
|
||||||
|
{
|
||||||
|
Interpreter::m_opTable[i] = Interpreter::unknown_instruction;
|
||||||
|
m_infoTable[i] = &unknownopinfo;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 32; i++)
|
for (int i = 0; i < 32; i++)
|
||||||
{
|
{
|
||||||
Interpreter::m_opTable59[i] = Interpreter::unknown_instruction;
|
Interpreter::m_opTable59[i] = Interpreter::unknown_instruction;
|
||||||
m_infoTable59[i] = nullptr;
|
m_infoTable59[i] = &unknownopinfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 1024; i++)
|
for (int i = 0; i < 1024; i++)
|
||||||
|
@ -376,10 +376,10 @@ void InitTables()
|
||||||
Interpreter::m_opTable19[i] = Interpreter::unknown_instruction;
|
Interpreter::m_opTable19[i] = Interpreter::unknown_instruction;
|
||||||
Interpreter::m_opTable31[i] = Interpreter::unknown_instruction;
|
Interpreter::m_opTable31[i] = Interpreter::unknown_instruction;
|
||||||
Interpreter::m_opTable63[i] = Interpreter::unknown_instruction;
|
Interpreter::m_opTable63[i] = Interpreter::unknown_instruction;
|
||||||
m_infoTable4[i] = nullptr;
|
m_infoTable4[i] = &unknownopinfo;
|
||||||
m_infoTable19[i] = nullptr;
|
m_infoTable19[i] = &unknownopinfo;
|
||||||
m_infoTable31[i] = nullptr;
|
m_infoTable31[i] = &unknownopinfo;
|
||||||
m_infoTable63[i] = nullptr;
|
m_infoTable63[i] = &unknownopinfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& tpl : primarytable)
|
for (auto& tpl : primarytable)
|
||||||
|
|
|
@ -246,11 +246,6 @@ void Jit64::WriteCallInterpreter(UGeckoInstruction inst)
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Jit64::unknown_instruction(UGeckoInstruction inst)
|
|
||||||
{
|
|
||||||
PanicAlert("unknown_instruction %08x - Fix me ;)", inst.hex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Jit64::FallBackToInterpreter(UGeckoInstruction _inst)
|
void Jit64::FallBackToInterpreter(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
WriteCallInterpreter(_inst.hex);
|
WriteCallInterpreter(_inst.hex);
|
||||||
|
|
|
@ -152,7 +152,6 @@ public:
|
||||||
void FloatCompare(UGeckoInstruction inst, bool upper = false);
|
void FloatCompare(UGeckoInstruction inst, bool upper = false);
|
||||||
|
|
||||||
// OPCODES
|
// OPCODES
|
||||||
void unknown_instruction(UGeckoInstruction _inst);
|
|
||||||
void FallBackToInterpreter(UGeckoInstruction _inst);
|
void FallBackToInterpreter(UGeckoInstruction _inst);
|
||||||
void DoNothing(UGeckoInstruction _inst);
|
void DoNothing(UGeckoInstruction _inst);
|
||||||
void HLEFunction(UGeckoInstruction _inst);
|
void HLEFunction(UGeckoInstruction _inst);
|
||||||
|
|
|
@ -398,15 +398,15 @@ void InitTables()
|
||||||
//clear
|
//clear
|
||||||
for (auto& tpl : dynaOpTable59)
|
for (auto& tpl : dynaOpTable59)
|
||||||
{
|
{
|
||||||
tpl = &Jit64::unknown_instruction;
|
tpl = &Jit64::FallBackToInterpreter;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 1024; i++)
|
for (int i = 0; i < 1024; i++)
|
||||||
{
|
{
|
||||||
dynaOpTable4 [i] = &Jit64::unknown_instruction;
|
dynaOpTable4 [i] = &Jit64::FallBackToInterpreter;
|
||||||
dynaOpTable19[i] = &Jit64::unknown_instruction;
|
dynaOpTable19[i] = &Jit64::FallBackToInterpreter;
|
||||||
dynaOpTable31[i] = &Jit64::unknown_instruction;
|
dynaOpTable31[i] = &Jit64::FallBackToInterpreter;
|
||||||
dynaOpTable63[i] = &Jit64::unknown_instruction;
|
dynaOpTable63[i] = &Jit64::FallBackToInterpreter;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& tpl : primarytable)
|
for (auto& tpl : primarytable)
|
||||||
|
|
|
@ -305,12 +305,6 @@ void JitIL::WriteCallInterpreter(UGeckoInstruction inst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitIL::unknown_instruction(UGeckoInstruction inst)
|
|
||||||
{
|
|
||||||
// CCPU::Break();
|
|
||||||
PanicAlert("unknown_instruction %08x - Fix me ;)", inst.hex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JitIL::FallBackToInterpreter(UGeckoInstruction _inst)
|
void JitIL::FallBackToInterpreter(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
ibuild.EmitFallBackToInterpreter(
|
ibuild.EmitFallBackToInterpreter(
|
||||||
|
|
|
@ -99,7 +99,6 @@ public:
|
||||||
void WriteCode(u32 exitAddress);
|
void WriteCode(u32 exitAddress);
|
||||||
|
|
||||||
// OPCODES
|
// OPCODES
|
||||||
void unknown_instruction(UGeckoInstruction _inst) override;
|
|
||||||
void FallBackToInterpreter(UGeckoInstruction _inst) override;
|
void FallBackToInterpreter(UGeckoInstruction _inst) override;
|
||||||
void DoNothing(UGeckoInstruction _inst) override;
|
void DoNothing(UGeckoInstruction _inst) override;
|
||||||
void HLEFunction(UGeckoInstruction _inst) override;
|
void HLEFunction(UGeckoInstruction _inst) override;
|
||||||
|
|
|
@ -403,15 +403,15 @@ void InitTables()
|
||||||
//clear
|
//clear
|
||||||
for (auto& tpl : dynaOpTable59)
|
for (auto& tpl : dynaOpTable59)
|
||||||
{
|
{
|
||||||
tpl = &JitIL::unknown_instruction;
|
tpl = &JitIL::FallBackToInterpreter;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 1024; i++)
|
for (int i = 0; i < 1024; i++)
|
||||||
{
|
{
|
||||||
dynaOpTable4 [i] = &JitIL::unknown_instruction;
|
dynaOpTable4 [i] = &JitIL::FallBackToInterpreter;
|
||||||
dynaOpTable19[i] = &JitIL::unknown_instruction;
|
dynaOpTable19[i] = &JitIL::FallBackToInterpreter;
|
||||||
dynaOpTable31[i] = &JitIL::unknown_instruction;
|
dynaOpTable31[i] = &JitIL::FallBackToInterpreter;
|
||||||
dynaOpTable63[i] = &JitIL::unknown_instruction;
|
dynaOpTable63[i] = &JitIL::FallBackToInterpreter;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& tpl : primarytable)
|
for (auto& tpl : primarytable)
|
||||||
|
|
|
@ -64,10 +64,6 @@ void JitArm::WriteCallInterpreter(UGeckoInstruction inst)
|
||||||
MOVI2R(R12, (u32)instr);
|
MOVI2R(R12, (u32)instr);
|
||||||
BL(R12);
|
BL(R12);
|
||||||
}
|
}
|
||||||
void JitArm::unknown_instruction(UGeckoInstruction inst)
|
|
||||||
{
|
|
||||||
PanicAlert("unknown_instruction %08x - Fix me ;)", inst.hex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JitArm::FallBackToInterpreter(UGeckoInstruction _inst)
|
void JitArm::FallBackToInterpreter(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
|
|
|
@ -134,7 +134,6 @@ public:
|
||||||
void SafeLoadToReg(ArmGen::ARMReg dest, s32 addr, s32 offsetReg, int accessSize, s32 offset, bool signExtend, bool reverse, bool update);
|
void SafeLoadToReg(ArmGen::ARMReg dest, s32 addr, s32 offsetReg, int accessSize, s32 offset, bool signExtend, bool reverse, bool update);
|
||||||
|
|
||||||
// OPCODES
|
// OPCODES
|
||||||
void unknown_instruction(UGeckoInstruction _inst);
|
|
||||||
void FallBackToInterpreter(UGeckoInstruction _inst);
|
void FallBackToInterpreter(UGeckoInstruction _inst);
|
||||||
void DoNothing(UGeckoInstruction _inst);
|
void DoNothing(UGeckoInstruction _inst);
|
||||||
void HLEFunction(UGeckoInstruction _inst);
|
void HLEFunction(UGeckoInstruction _inst);
|
||||||
|
|
|
@ -402,15 +402,15 @@ void InitTables()
|
||||||
//clear
|
//clear
|
||||||
for (int i = 0; i < 32; i++)
|
for (int i = 0; i < 32; i++)
|
||||||
{
|
{
|
||||||
dynaOpTable59[i] = &JitArm::unknown_instruction;
|
dynaOpTable59[i] = &JitArm::FallBackToInterpreter;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 1024; i++)
|
for (int i = 0; i < 1024; i++)
|
||||||
{
|
{
|
||||||
dynaOpTable4 [i] = &JitArm::unknown_instruction;
|
dynaOpTable4 [i] = &JitArm::FallBackToInterpreter;
|
||||||
dynaOpTable19[i] = &JitArm::unknown_instruction;
|
dynaOpTable19[i] = &JitArm::FallBackToInterpreter;
|
||||||
dynaOpTable31[i] = &JitArm::unknown_instruction;
|
dynaOpTable31[i] = &JitArm::FallBackToInterpreter;
|
||||||
dynaOpTable63[i] = &JitArm::unknown_instruction;
|
dynaOpTable63[i] = &JitArm::FallBackToInterpreter;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < (int)(sizeof(primarytable) / sizeof(GekkoOPTemplate)); i++)
|
for (int i = 0; i < (int)(sizeof(primarytable) / sizeof(GekkoOPTemplate)); i++)
|
||||||
|
|
|
@ -43,11 +43,6 @@ void JitArm64::Shutdown()
|
||||||
asm_routines.Shutdown();
|
asm_routines.Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::unknown_instruction(UGeckoInstruction inst)
|
|
||||||
{
|
|
||||||
WARN_LOG(DYNA_REC, "unknown_instruction %08x - Fix me ;)", inst.hex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JitArm64::FallBackToInterpreter(UGeckoInstruction inst)
|
void JitArm64::FallBackToInterpreter(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
gpr.Flush(FlushMode::FLUSH_INTERPRETER, js.op);
|
gpr.Flush(FlushMode::FLUSH_INTERPRETER, js.op);
|
||||||
|
|
|
@ -57,7 +57,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// OPCODES
|
// OPCODES
|
||||||
void unknown_instruction(UGeckoInstruction inst);
|
|
||||||
void FallBackToInterpreter(UGeckoInstruction inst);
|
void FallBackToInterpreter(UGeckoInstruction inst);
|
||||||
void DoNothing(UGeckoInstruction inst);
|
void DoNothing(UGeckoInstruction inst);
|
||||||
void HLEFunction(UGeckoInstruction inst);
|
void HLEFunction(UGeckoInstruction inst);
|
||||||
|
|
|
@ -400,15 +400,15 @@ void InitTables()
|
||||||
//clear
|
//clear
|
||||||
for (int i = 0; i < 32; i++)
|
for (int i = 0; i < 32; i++)
|
||||||
{
|
{
|
||||||
dynaOpTable59[i] = &JitArm64::unknown_instruction;
|
dynaOpTable59[i] = &JitArm64::FallBackToInterpreter;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 1024; i++)
|
for (int i = 0; i < 1024; i++)
|
||||||
{
|
{
|
||||||
dynaOpTable4 [i] = &JitArm64::unknown_instruction;
|
dynaOpTable4 [i] = &JitArm64::FallBackToInterpreter;
|
||||||
dynaOpTable19[i] = &JitArm64::unknown_instruction;
|
dynaOpTable19[i] = &JitArm64::FallBackToInterpreter;
|
||||||
dynaOpTable31[i] = &JitArm64::unknown_instruction;
|
dynaOpTable31[i] = &JitArm64::FallBackToInterpreter;
|
||||||
dynaOpTable63[i] = &JitArm64::unknown_instruction;
|
dynaOpTable63[i] = &JitArm64::FallBackToInterpreter;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < (int)(sizeof(primarytable) / sizeof(GekkoOPTemplate)); i++)
|
for (int i = 0; i < (int)(sizeof(primarytable) / sizeof(GekkoOPTemplate)); i++)
|
||||||
|
|
|
@ -32,7 +32,6 @@ public:
|
||||||
virtual const CommonAsmRoutinesBase *GetAsmRoutines() = 0;
|
virtual const CommonAsmRoutinesBase *GetAsmRoutines() = 0;
|
||||||
|
|
||||||
// OPCODES
|
// OPCODES
|
||||||
virtual void unknown_instruction(UGeckoInstruction inst) = 0;
|
|
||||||
virtual void FallBackToInterpreter(UGeckoInstruction inst) = 0;
|
virtual void FallBackToInterpreter(UGeckoInstruction inst) = 0;
|
||||||
virtual void DoNothing(UGeckoInstruction inst) = 0;
|
virtual void DoNothing(UGeckoInstruction inst) = 0;
|
||||||
virtual void HLEFunction(UGeckoInstruction inst) = 0;
|
virtual void HLEFunction(UGeckoInstruction inst) = 0;
|
||||||
|
|
|
@ -681,11 +681,6 @@ u32 PPCAnalyzer::Analyze(u32 address, CodeBlock *block, CodeBuffer *buffer, u32
|
||||||
num_inst++;
|
num_inst++;
|
||||||
memset(&code[i], 0, sizeof(CodeOp));
|
memset(&code[i], 0, sizeof(CodeOp));
|
||||||
GekkoOPInfo *opinfo = GetOpInfo(inst);
|
GekkoOPInfo *opinfo = GetOpInfo(inst);
|
||||||
if (!opinfo)
|
|
||||||
{
|
|
||||||
PanicAlert("Invalid PowerPC opcode: %x.", inst.hex);
|
|
||||||
Crash();
|
|
||||||
}
|
|
||||||
|
|
||||||
code[i].opinfo = opinfo;
|
code[i].opinfo = opinfo;
|
||||||
code[i].address = address;
|
code[i].address = address;
|
||||||
|
|
Loading…
Reference in New Issue