Jit64: implement tw/twi more accurately
Fixes issue 7253.
This commit is contained in:
parent
a1374dd4ba
commit
4cce79e744
|
@ -2,6 +2,8 @@
|
|||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "Core/PowerPC/Jit64/Jit.h"
|
||||
#include "Core/PowerPC/Jit64/JitAsm.h"
|
||||
#include "Core/PowerPC/Jit64/JitRegCache.h"
|
||||
|
@ -2183,56 +2185,33 @@ void Jit64::twx(UGeckoInstruction inst)
|
|||
gpr.Flush(FLUSH_ALL);
|
||||
fpr.Flush(FLUSH_ALL);
|
||||
|
||||
MOV(8, R(AL), Imm8(inst.TO));
|
||||
|
||||
if (inst.OPCD == 3) // twi
|
||||
CMP(32, gpr.R(a), gpr.R(inst.RB));
|
||||
else // tw
|
||||
CMP(32, gpr.R(a), Imm32((s32)(s16)inst.SIMM_16));
|
||||
|
||||
FixupBranch al = J_CC(CC_L);
|
||||
FixupBranch ag = J_CC(CC_G);
|
||||
FixupBranch ae = J_CC(CC_Z);
|
||||
// FIXME: will never be reached. But also no known code uses it...
|
||||
_assert_msg_(DYNA_REC, (inst.TO & 3) == 0, "Seems like something actually does use this.");
|
||||
FixupBranch ll = J_CC(CC_NO);
|
||||
FixupBranch lg = J_CC(CC_O);
|
||||
std::vector<FixupBranch> fixups;
|
||||
CCFlags conditions[] = { CC_A, CC_B, CC_E, CC_G, CC_L };
|
||||
|
||||
SetJumpTarget(al);
|
||||
TEST(8, R(AL), Imm8(16));
|
||||
FixupBranch exit1 = J_CC(CC_NZ);
|
||||
FixupBranch take1 = J();
|
||||
SetJumpTarget(ag);
|
||||
TEST(8, R(AL), Imm8(8));
|
||||
FixupBranch exit2 = J_CC(CC_NZ);
|
||||
FixupBranch take2 = J();
|
||||
SetJumpTarget(ae);
|
||||
TEST(8, R(AL), Imm8(4));
|
||||
FixupBranch exit3 = J_CC(CC_NZ);
|
||||
FixupBranch take3 = J();
|
||||
SetJumpTarget(ll);
|
||||
TEST(8, R(AL), Imm8(2));
|
||||
FixupBranch exit4 = J_CC(CC_NZ);
|
||||
FixupBranch take4 = J();
|
||||
SetJumpTarget(lg);
|
||||
TEST(8, R(AL), Imm8(1));
|
||||
FixupBranch exit5 = J_CC(CC_NZ);
|
||||
FixupBranch take5 = J();
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
if (inst.TO & (1 << i))
|
||||
{
|
||||
FixupBranch f = J_CC(conditions[i]);
|
||||
fixups.push_back(f);
|
||||
}
|
||||
}
|
||||
FixupBranch dont_trap = J();
|
||||
|
||||
SetJumpTarget(take1);
|
||||
SetJumpTarget(take2);
|
||||
SetJumpTarget(take3);
|
||||
SetJumpTarget(take4);
|
||||
SetJumpTarget(take5);
|
||||
for (const FixupBranch& fixup : fixups)
|
||||
{
|
||||
SetJumpTarget(fixup);
|
||||
}
|
||||
LOCK();
|
||||
OR(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_PROGRAM));
|
||||
WriteExceptionExit();
|
||||
|
||||
SetJumpTarget(exit1);
|
||||
SetJumpTarget(exit2);
|
||||
SetJumpTarget(exit3);
|
||||
SetJumpTarget(exit4);
|
||||
SetJumpTarget(exit5);
|
||||
SetJumpTarget(dont_trap);
|
||||
|
||||
if (!analyzer.HasOption(PPCAnalyst::PPCAnalyzer::OPTION_CONDITIONAL_CONTINUE))
|
||||
WriteExit(js.compilerPC + 4);
|
||||
|
|
Loading…
Reference in New Issue