Merge pull request #3656 from unknownbrackets/mips-minor

Fix bad nice delay slot detection
This commit is contained in:
Henrik Rydgård 2013-09-06 00:26:18 -07:00
commit b34e02ee20
6 changed files with 54 additions and 49 deletions

View File

@ -788,7 +788,7 @@ int sceDisplayAdjustAccumulatedHcount(int value) {
int sceDisplayGetAccumulatedHcount() {
u32 accumHCount = __DisplayGetAccumulatedHcount();
DEBUG_LOG(HLE, "%lld=sceDisplayGetAccumulatedHcount()", accumHCount);
DEBUG_LOG(HLE, "%d=sceDisplayGetAccumulatedHcount()", accumHCount);
hleEatCycles(235);
return accumHCount;
}

View File

@ -34,34 +34,34 @@ namespace MIPSAnalyst
// Only can ever output a single reg.
MIPSGPReg GetOutGPReg(MIPSOpcode op) {
MIPSInfo opinfo = MIPSGetInfo(op);
if ((opinfo & IS_VFPU) == 0) {
if (opinfo & OUT_RT) {
return MIPS_GET_RT(op);
}
if (opinfo & OUT_RD) {
return MIPS_GET_RD(op);
}
if (opinfo & OUT_RA) {
return MIPS_REG_RA;
}
if (opinfo & OUT_RT) {
return MIPS_GET_RT(op);
}
if (opinfo & OUT_RD) {
return MIPS_GET_RD(op);
}
if (opinfo & OUT_RA) {
return MIPS_REG_RA;
}
return MIPS_REG_INVALID;
}
bool ReadsFromGPReg(MIPSOpcode op, MIPSGPReg reg) {
MIPSInfo info = MIPSGetInfo(op);
if ((info & IS_VFPU) == 0) {
if ((info & IN_RS) != 0 && MIPS_GET_RS(op) == reg) {
return true;
}
if ((info & IN_RT) != 0 && MIPS_GET_RT(op) == reg) {
return true;
}
if ((info & IN_RS) != 0 && MIPS_GET_RS(op) == reg) {
return true;
}
if ((info & IN_RT) != 0 && MIPS_GET_RT(op) == reg) {
return true;
}
return false;
}
bool IsDelaySlotNiceReg(MIPSOpcode branchOp, MIPSOpcode op, MIPSGPReg reg1, MIPSGPReg reg2) {
MIPSInfo info = MIPSGetInfo(op);
if (info & IS_CONDBRANCH) {
return false;
}
// $0 is never an out reg, it's always 0.
if (reg1 != MIPS_REG_ZERO && GetOutGPReg(op) == reg1) {
return false;
@ -74,12 +74,19 @@ namespace MIPSAnalyst
}
bool IsDelaySlotNiceVFPU(MIPSOpcode branchOp, MIPSOpcode op) {
// TODO: There may be IS_VFPU cases which are safe...
return (MIPSGetInfo(op) & IS_VFPU) == 0;
MIPSInfo info = MIPSGetInfo(op);
if (info & IS_CONDBRANCH) {
return false;
}
return (info & OUT_VFPU_CC) == 0;
}
bool IsDelaySlotNiceFPU(MIPSOpcode branchOp, MIPSOpcode op) {
return (MIPSGetInfo(op) & OUT_FPUFLAG) == 0;
MIPSInfo info = MIPSGetInfo(op);
if (info & IS_CONDBRANCH) {
return false;
}
return (info & OUT_FPUFLAG) == 0;
}
bool IsSyscall(MIPSOpcode op) {
@ -405,23 +412,17 @@ namespace MIPSAnalyst
{
std::vector<MIPSGPReg> vec;
MIPSInfo info = MIPSGetInfo(op);
if ((info & IS_VFPU) == 0)
{
if (info & IN_RS) vec.push_back(MIPS_GET_RS(op));
if (info & IN_RT) vec.push_back(MIPS_GET_RT(op));
}
if (info & IN_RS) vec.push_back(MIPS_GET_RS(op));
if (info & IN_RT) vec.push_back(MIPS_GET_RT(op));
return vec;
}
std::vector<MIPSGPReg> GetOutputRegs(MIPSOpcode op)
{
std::vector<MIPSGPReg> vec;
MIPSInfo info = MIPSGetInfo(op);
if ((info & IS_VFPU) == 0)
{
if (info & OUT_RD) vec.push_back(MIPS_GET_RD(op));
if (info & OUT_RT) vec.push_back(MIPS_GET_RT(op));
if (info & OUT_RA) vec.push_back(MIPS_REG_RA);
}
if (info & OUT_RD) vec.push_back(MIPS_GET_RD(op));
if (info & OUT_RT) vec.push_back(MIPS_GET_RT(op));
if (info & OUT_RA) vec.push_back(MIPS_REG_RA);
return vec;
}

View File

@ -1365,6 +1365,7 @@ namespace MIPSInt
}
else
{
Reporting::ReportMessage("Trying to interpret instruction that can't be interpreted (BADVTFM)");
_dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted (BADVTFM)");
}
WriteVector(d, sz, vd);
@ -1675,7 +1676,7 @@ namespace MIPSInt
}
else
{
_dbg_assert_msg_(CPU,0,"Bad Imm3 in cmov");
ERROR_LOG_REPORT(CPU, "Bad Imm3 in cmov: %d", imm3);
}
ApplyPrefixD(d, sz);
WriteVector(d, sz, vd);
@ -1756,6 +1757,7 @@ bad:
break;
default:
Reporting::ReportMessage("CrossQuat instruction with wrong size");
_dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted");
break;
}

View File

@ -356,10 +356,10 @@ const MIPSInstruction tableCop2[32] = // 010010 xxxxx ..... ................
const MIPSInstruction tableCop2BC2[4] = // 010010 01000 ...xx ................
{
INSTR("bvf", &Jit::Comp_VBranch, Dis_VBranch, Int_VBranch, IS_CONDBRANCH|IN_IMM16|IN_OTHER|DELAYSLOT|IS_VFPU),
INSTR("bvt", &Jit::Comp_VBranch, Dis_VBranch, Int_VBranch, IS_CONDBRANCH|IN_IMM16|IN_OTHER|DELAYSLOT|IS_VFPU),
INSTR("bvfl", &Jit::Comp_VBranch, Dis_VBranch, Int_VBranch, IS_CONDBRANCH|IN_IMM16|IN_OTHER|DELAYSLOT|LIKELY|IS_VFPU),
INSTR("bvtl", &Jit::Comp_VBranch, Dis_VBranch, Int_VBranch, IS_CONDBRANCH|IN_IMM16|IN_OTHER|DELAYSLOT|LIKELY|IS_VFPU),
INSTR("bvf", &Jit::Comp_VBranch, Dis_VBranch, Int_VBranch, IS_CONDBRANCH|IN_IMM16|IN_VFPU_CC|DELAYSLOT|IS_VFPU),
INSTR("bvt", &Jit::Comp_VBranch, Dis_VBranch, Int_VBranch, IS_CONDBRANCH|IN_IMM16|IN_VFPU_CC|DELAYSLOT|IS_VFPU),
INSTR("bvfl", &Jit::Comp_VBranch, Dis_VBranch, Int_VBranch, IS_CONDBRANCH|IN_IMM16|IN_VFPU_CC|DELAYSLOT|LIKELY|IS_VFPU),
INSTR("bvtl", &Jit::Comp_VBranch, Dis_VBranch, Int_VBranch, IS_CONDBRANCH|IN_IMM16|IN_VFPU_CC|DELAYSLOT|LIKELY|IS_VFPU),
};
const MIPSInstruction tableCop0[32] = // 010000 xxxxx ..... ................
@ -545,7 +545,7 @@ const MIPSInstruction tableVFPU1[8] = // 011001 xxx ....... . ....... . .......
const MIPSInstruction tableVFPU3[8] = // 011011 xxx ....... . ....... . .......
{
INSTR("vcmp", &Jit::Comp_Vcmp, Dis_Vcmp, Int_Vcmp, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INSTR("vcmp", &Jit::Comp_Vcmp, Dis_Vcmp, Int_Vcmp, IN_OTHER|OUT_VFPU_CC|IS_VFPU|OUT_EAT_PREFIX),
INVALID,
INSTR("vmin", &Jit::Comp_VecDo3, Dis_VectorSet3, Int_Vminmax, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INSTR("vmax", &Jit::Comp_VecDo3, Dis_VectorSet3, Int_Vminmax, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
@ -573,7 +573,7 @@ const MIPSInstruction tableVFPU4Jump[32] = // 110100 xxxxx ..... . ....... . ...
INSTR("vf2id", &Jit::Comp_Vf2i, Dis_Vf2i, Int_Vf2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
//20
INSTR("vi2f", &Jit::Comp_Vi2f, Dis_Vf2i, Int_Vi2f, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INSTR("vcmov", &Jit::Comp_Vcmov, Dis_Vcmov, Int_Vcmov, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INSTR("vcmov", &Jit::Comp_Vcmov, Dis_Vcmov, Int_Vcmov, IN_OTHER|IN_VFPU_CC|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INVALID,
INVALID,
//24 - 110100 11 ........ . ....... . .......

View File

@ -70,17 +70,19 @@ struct MIPSInfo {
#define IN_MEM 0x00010000
#define IN_OTHER 0x00020000
#define IN_FPUFLAG 0x00040000
#define IN_VFPU_CC 0x00080000
#define OUT_RT 0x00080000
#define OUT_RD 0x00100000
#define OUT_RA 0x00200000
#define OUT_MEM 0x00400000
#define OUT_OTHER 0x00800000
#define OUT_FPUFLAG 0x01000000
#define OUT_EAT_PREFIX 0x02000000
#define OUT_RT 0x00100000
#define OUT_RD 0x00200000
#define OUT_RA 0x00400000
#define OUT_MEM 0x00800000
#define OUT_OTHER 0x01000000
#define OUT_FPUFLAG 0x02000000
#define OUT_VFPU_CC 0x04000000
#define OUT_EAT_PREFIX 0x08000000
#define VFPU_NO_PREFIX 0x04000000
#define IS_VFPU 0x08000000
#define VFPU_NO_PREFIX 0x10000000
#define IS_VFPU 0x20000000
#ifndef CDECL
#define CDECL

View File

@ -466,7 +466,7 @@ void Jit::BranchVFPUFlag(MIPSOpcode op, Gen::CCFlags cc, bool likely)
if (!likely && delaySlotIsNice)
CompileDelaySlot(DELAYSLOT_NICE);
if (delaySlotIsBranch && (signed short)(delaySlotOp & 0xFFFF) != (signed short)(op & 0xFFFF) - 1)
ERROR_LOG(JIT, "VFPU branch in VFPU delay slot at %08x with different target %d / %d", js.compilerPC, (signed short)(delaySlotOp & 0xFFFF), (signed short)(op & 0xFFFF) - 1);
ERROR_LOG_REPORT(JIT, "VFPU branch in VFPU delay slot at %08x with different target %d / %d", js.compilerPC, (signed short)(delaySlotOp & 0xFFFF), (signed short)(op & 0xFFFF) - 1);
// THE CONDITION
int imm3 = (op >> 18) & 7;