mirror of https://github.com/PCSX2/pcsx2.git
Merge pull request #248 from Kingcom/OpcodeFlags
Add flags to R5900 opcodes, use them for the debugger
This commit is contained in:
commit
4512306207
|
@ -32,9 +32,6 @@ extern AppCoreThread CoreThread;
|
|||
R5900DebugInterface r5900Debug;
|
||||
R3000DebugInterface r3000Debug;
|
||||
|
||||
enum { EECAT_GPR, EECAT_CP0, EECAT_CP1, EECAT_CP2F, EECAT_CP2I, EECAT_COUNT };
|
||||
enum { IOPCAT_GPR, IOPCAT_COUNT };
|
||||
|
||||
#ifdef WIN32
|
||||
#define strcasecmp stricmp
|
||||
#endif
|
||||
|
@ -281,12 +278,14 @@ const char* R5900DebugInterface::getRegisterCategoryName(int cat)
|
|||
return "GPR";
|
||||
case EECAT_CP0:
|
||||
return "CP0";
|
||||
case EECAT_CP1:
|
||||
return "CP1";
|
||||
case EECAT_CP2F:
|
||||
return "CP2f";
|
||||
case EECAT_CP2I:
|
||||
return "CP2i";
|
||||
case EECAT_FPR:
|
||||
return "FPR";
|
||||
case EECAT_FCR:
|
||||
return "FCR";
|
||||
case EECAT_VU0F:
|
||||
return "VU0f";
|
||||
case EECAT_VU0I:
|
||||
return "VU0i";
|
||||
default:
|
||||
return "Invalid";
|
||||
}
|
||||
|
@ -297,11 +296,12 @@ int R5900DebugInterface::getRegisterSize(int cat)
|
|||
switch (cat)
|
||||
{
|
||||
case EECAT_GPR:
|
||||
case EECAT_CP2F:
|
||||
case EECAT_VU0F:
|
||||
return 128;
|
||||
case EECAT_CP0:
|
||||
case EECAT_CP1:
|
||||
case EECAT_CP2I:
|
||||
case EECAT_FPR:
|
||||
case EECAT_FCR:
|
||||
case EECAT_VU0I:
|
||||
return 32;
|
||||
default:
|
||||
return 0;
|
||||
|
@ -315,9 +315,10 @@ int R5900DebugInterface::getRegisterCount(int cat)
|
|||
case EECAT_GPR:
|
||||
return 35; // 32 + pc + hi + lo
|
||||
case EECAT_CP0:
|
||||
case EECAT_CP1:
|
||||
case EECAT_CP2F:
|
||||
case EECAT_CP2I:
|
||||
case EECAT_FPR:
|
||||
case EECAT_FCR:
|
||||
case EECAT_VU0F:
|
||||
case EECAT_VU0I:
|
||||
return 32;
|
||||
default:
|
||||
return 0;
|
||||
|
@ -330,11 +331,12 @@ DebugInterface::RegisterType R5900DebugInterface::getRegisterType(int cat)
|
|||
{
|
||||
case EECAT_GPR:
|
||||
case EECAT_CP0:
|
||||
case EECAT_CP2F:
|
||||
case EECAT_CP2I:
|
||||
case EECAT_VU0F:
|
||||
case EECAT_VU0I:
|
||||
case EECAT_FCR:
|
||||
default:
|
||||
return NORMAL;
|
||||
case EECAT_CP1:
|
||||
case EECAT_FPR:
|
||||
return SPECIAL;
|
||||
}
|
||||
}
|
||||
|
@ -357,11 +359,13 @@ const char* R5900DebugInterface::getRegisterName(int cat, int num)
|
|||
}
|
||||
case EECAT_CP0:
|
||||
return R5900::COP0_REG[num];
|
||||
case EECAT_CP1:
|
||||
case EECAT_FPR:
|
||||
return R5900::COP1_REG_FP[num];
|
||||
case EECAT_CP2F:
|
||||
case EECAT_FCR:
|
||||
return R5900::COP1_REG_FCR[num];
|
||||
case EECAT_VU0F:
|
||||
return R5900::COP2_REG_FP[num];
|
||||
case EECAT_CP2I:
|
||||
case EECAT_VU0I:
|
||||
return R5900::COP2_REG_CTL[num];
|
||||
default:
|
||||
return "Invalid";
|
||||
|
@ -393,13 +397,16 @@ u128 R5900DebugInterface::getRegister(int cat, int num)
|
|||
case EECAT_CP0:
|
||||
result = u128::From32(cpuRegs.CP0.r[num]);
|
||||
break;
|
||||
case EECAT_CP1:
|
||||
case EECAT_FPR:
|
||||
result = u128::From32(fpuRegs.fpr[num].UL);
|
||||
break;
|
||||
case EECAT_CP2F:
|
||||
case EECAT_FCR:
|
||||
result = u128::From32(fpuRegs.fprc[num]);
|
||||
break;
|
||||
case EECAT_VU0F:
|
||||
result = VU1.VF[num].UQ;
|
||||
break;
|
||||
case EECAT_CP2I:
|
||||
case EECAT_VU0I:
|
||||
result = u128::From32(VU1.VI[num].UL);
|
||||
break;
|
||||
default:
|
||||
|
@ -416,8 +423,9 @@ wxString R5900DebugInterface::getRegisterString(int cat, int num)
|
|||
{
|
||||
case EECAT_GPR:
|
||||
case EECAT_CP0:
|
||||
case EECAT_FCR:
|
||||
return getRegister(cat,num).ToString();
|
||||
case EECAT_CP1:
|
||||
case EECAT_FPR:
|
||||
{
|
||||
char str[64];
|
||||
sprintf(str,"%f",fpuRegs.fpr[num].f);
|
||||
|
@ -473,13 +481,16 @@ void R5900DebugInterface::setRegister(int cat, int num, u128 newValue)
|
|||
case EECAT_CP0:
|
||||
cpuRegs.CP0.r[num] = newValue._u32[0];
|
||||
break;
|
||||
case EECAT_CP1:
|
||||
case EECAT_FPR:
|
||||
fpuRegs.fpr[num].UL = newValue._u32[0];
|
||||
break;
|
||||
case EECAT_CP2F:
|
||||
case EECAT_FCR:
|
||||
fpuRegs.fprc[num] = newValue._u32[0];
|
||||
break;
|
||||
case EECAT_VU0F:
|
||||
VU1.VF[num].UQ = newValue;
|
||||
break;
|
||||
case EECAT_CP2I:
|
||||
case EECAT_VU0I:
|
||||
VU1.VI[num].UL = newValue._u32[0];
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
#include "MemoryTypes.h"
|
||||
#include "ExpressionParser.h"
|
||||
|
||||
enum { EECAT_GPR, EECAT_CP0, EECAT_FPR, EECAT_FCR, EECAT_VU0F, EECAT_VU0I, EECAT_COUNT };
|
||||
enum { IOPCAT_GPR, IOPCAT_COUNT };
|
||||
|
||||
class DebugInterface
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "SymbolMap.h"
|
||||
#include "DebugInterface.h"
|
||||
#include "../R5900.h"
|
||||
#include "../R5900OpcodeTables.h"
|
||||
|
||||
static std::vector<MIPSAnalyst::AnalyzedFunction> functions;
|
||||
|
||||
|
@ -160,296 +161,182 @@ namespace MIPSAnalyst
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
enum BranchType { NONE, JUMP, BRANCH };
|
||||
struct BranchInfo
|
||||
{
|
||||
BranchType type;
|
||||
bool link;
|
||||
bool likely;
|
||||
bool toRegister;
|
||||
};
|
||||
|
||||
bool getBranchInfo(MipsOpcodeInfo& info)
|
||||
{
|
||||
BranchType type = NONE;
|
||||
bool link = false;
|
||||
bool likely = false;
|
||||
bool toRegister = false;
|
||||
bool met = false;
|
||||
|
||||
u32 op = info.encodedOpcode;
|
||||
|
||||
u32 opNum = MIPS_GET_OP(op);
|
||||
u32 rsNum = MIPS_GET_RS(op);
|
||||
u32 rtNum = MIPS_GET_RT(op);
|
||||
u32 rs = info.cpu->getRegister(0,rsNum);
|
||||
u32 rt = info.cpu->getRegister(0,rtNum);
|
||||
|
||||
switch (MIPS_GET_OP(op))
|
||||
{
|
||||
case 0x00: // special
|
||||
switch (MIPS_GET_FUNC(op))
|
||||
{
|
||||
case 0x08: // jr
|
||||
type = JUMP;
|
||||
toRegister = true;
|
||||
break;
|
||||
case 0x09: // jalr
|
||||
type = JUMP;
|
||||
toRegister = true;
|
||||
link = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x01: // regimm
|
||||
switch (MIPS_GET_RT(op))
|
||||
{
|
||||
case 0x00: // bltz
|
||||
case 0x02: // bltzl
|
||||
case 0x10: // bltzal
|
||||
case 0x12: // bltzall
|
||||
type = BRANCH;
|
||||
met = (((s32)rs) < 0);
|
||||
likely = (rt & 2) != 0;
|
||||
link = rt >= 0x10;
|
||||
break;
|
||||
|
||||
case 0x01: // bgez
|
||||
case 0x03: // bgezl
|
||||
case 0x11: // bgezal
|
||||
case 0x13: // bgezall
|
||||
type = BRANCH;
|
||||
met = (((s32)rs) >= 0);
|
||||
likely = (rt & 2) != 0;
|
||||
link = rt >= 0x10;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x02: // j
|
||||
type = JUMP;
|
||||
break;
|
||||
case 0x03: // jal
|
||||
type = JUMP;
|
||||
link = true;
|
||||
break;
|
||||
|
||||
case 0x04: // beq
|
||||
case 0x14: // beql
|
||||
type = BRANCH;
|
||||
met = (rt == rs);
|
||||
if (MIPS_GET_RT(op) == MIPS_GET_RS(op)) // always true
|
||||
info.isConditional = false;
|
||||
likely = opNum >= 0x10;
|
||||
break;
|
||||
|
||||
case 0x05: // bne
|
||||
case 0x15: // bnel
|
||||
type = BRANCH;
|
||||
met = (rt != rs);
|
||||
if (MIPS_GET_RT(op) == MIPS_GET_RS(op)) // always false
|
||||
info.isConditional = false;
|
||||
likely = opNum >= 0x10;
|
||||
break;
|
||||
|
||||
case 0x06: // blez
|
||||
case 0x16: // blezl
|
||||
type = BRANCH;
|
||||
met = (((s32)rs) <= 0);
|
||||
likely = opNum >= 0x10;
|
||||
break;
|
||||
|
||||
case 0x07: // bgtz
|
||||
case 0x17: // bgtzl
|
||||
type = BRANCH;
|
||||
met = (((s32)rs) > 0);
|
||||
likely = opNum >= 0x10;
|
||||
break;
|
||||
}
|
||||
|
||||
if (type == NONE)
|
||||
return false;
|
||||
|
||||
info.isBranch = true;
|
||||
info.isLinkedBranch = link;
|
||||
info.isLikelyBranch = true;
|
||||
info.isBranchToRegister = toRegister;
|
||||
info.isConditional = type == BRANCH;
|
||||
info.conditionMet = met;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case JUMP:
|
||||
if (toRegister)
|
||||
{
|
||||
info.branchRegisterNum = (int)MIPS_GET_RS(op);
|
||||
info.branchTarget = info.cpu->getRegister(0,info.branchRegisterNum)._u32[0];
|
||||
} else {
|
||||
info.branchTarget = (info.opcodeAddress & 0xF0000000) | ((op&0x03FFFFFF) << 2);
|
||||
}
|
||||
break;
|
||||
case BRANCH:
|
||||
info.branchTarget = info.opcodeAddress + 4 + ((signed short)(op&0xFFFF)<<2);
|
||||
break;
|
||||
case NONE:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool getDataAccessInfo(MipsOpcodeInfo& info)
|
||||
{
|
||||
int size = 0;
|
||||
|
||||
u32 op = info.encodedOpcode;
|
||||
int off = 0;
|
||||
switch (MIPS_GET_OP(op))
|
||||
{
|
||||
case 0x20: // lb
|
||||
case 0x24: // lbu
|
||||
case 0x28: // sb
|
||||
size = 1;
|
||||
break;
|
||||
case 0x21: // lh
|
||||
case 0x25: // lhu
|
||||
case 0x29: // sh
|
||||
size = 2;
|
||||
break;
|
||||
case 0x23: // lw
|
||||
case 0x2B: // sw
|
||||
size = 4;
|
||||
break;
|
||||
case 0x26: // lwr
|
||||
case 0x2E: // swr
|
||||
size = 4;
|
||||
info.lrType = LOADSTORE_RIGHT;
|
||||
break;
|
||||
case 0x22: // lwl
|
||||
case 0x2A: // swl
|
||||
size = 4;
|
||||
off = -3;
|
||||
info.lrType = LOADSTORE_LEFT;
|
||||
break;
|
||||
case 0x37: // ld
|
||||
case 0x3F: // sd
|
||||
size = 8;
|
||||
break;
|
||||
case 0x1B: // ldr
|
||||
case 0x2D: // sdr
|
||||
size = 8;
|
||||
info.lrType = LOADSTORE_RIGHT;
|
||||
break;
|
||||
case 0x1A: // ldl
|
||||
case 0x2C: // sdl
|
||||
size = 8;
|
||||
off = -7;
|
||||
info.lrType = LOADSTORE_LEFT;
|
||||
break;
|
||||
case 0x1E: // lq
|
||||
case 0x1F: // sq
|
||||
size = 16;
|
||||
break;
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
return false;
|
||||
|
||||
info.isDataAccess = true;
|
||||
info.dataSize = size;
|
||||
|
||||
u32 rs = info.cpu->getRegister(0, (int)MIPS_GET_RS(op));
|
||||
s16 imm16 = op & 0xFFFF;
|
||||
info.dataAddress = rs + imm16 + off;
|
||||
|
||||
info.hasRelevantAddress = true;
|
||||
info.releventAddress = info.dataAddress;
|
||||
return true;
|
||||
}
|
||||
|
||||
MipsOpcodeInfo GetOpcodeInfo(DebugInterface* cpu, u32 address) {
|
||||
MipsOpcodeInfo info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
if (cpu->isValidAddress(address) == false) {
|
||||
if (cpu->isValidAddress(address) == false)
|
||||
return info;
|
||||
}
|
||||
|
||||
info.cpu = cpu;
|
||||
info.opcodeAddress = address;
|
||||
info.encodedOpcode = cpu->read32(address);
|
||||
u32 op = info.encodedOpcode;
|
||||
const R5900::OPCODE& opcode = R5900::GetInstruction(op);
|
||||
|
||||
if (getBranchInfo(info) == true)
|
||||
return info;
|
||||
// extract all the branch related information
|
||||
info.isBranch = (opcode.flags & IS_BRANCH) != 0;
|
||||
if (info.isBranch)
|
||||
{
|
||||
info.isLinkedBranch = (opcode.flags & IS_LINKED) != 0;
|
||||
info.isLikelyBranch = (opcode.flags & IS_LIKELY) != 0;
|
||||
|
||||
if (getDataAccessInfo(info) == true)
|
||||
return info;
|
||||
|
||||
// gather relevant address for alu operations
|
||||
// that's usually the value of the dest register
|
||||
switch (MIPS_GET_OP(op)) {
|
||||
case 0: // special
|
||||
switch (MIPS_GET_FUNC(op)) {
|
||||
case 0x0C: // syscall
|
||||
u64 rs,rt;
|
||||
u32 value;
|
||||
switch (opcode.flags & BRANCHTYPE_MASK)
|
||||
{
|
||||
case BRANCHTYPE_JUMP:
|
||||
info.isConditional = false;
|
||||
info.branchTarget = (info.opcodeAddress & 0xF0000000) | ((op&0x03FFFFFF) << 2);
|
||||
break;
|
||||
case BRANCHTYPE_BRANCH:
|
||||
info.isConditional = true;
|
||||
info.branchTarget = info.opcodeAddress + 4 + ((s16)(op&0xFFFF)<<2);
|
||||
|
||||
rs = info.cpu->getRegister(0,MIPS_GET_RS(op))._u64[0];
|
||||
rt = info.cpu->getRegister(0,MIPS_GET_RT(op))._u64[0];
|
||||
switch (opcode.flags & CONDTYPE_MASK)
|
||||
{
|
||||
case CONDTYPE_EQ:
|
||||
info.conditionMet = (rt == rs);
|
||||
if (MIPS_GET_RT(op) == MIPS_GET_RS(op)) // always true
|
||||
info.isConditional = false;
|
||||
break;
|
||||
case CONDTYPE_NE:
|
||||
info.conditionMet = (rt != rs);
|
||||
if (MIPS_GET_RT(op) == MIPS_GET_RS(op)) // always false
|
||||
info.isConditional = false;
|
||||
break;
|
||||
case CONDTYPE_LEZ:
|
||||
info.conditionMet = (((s64)rs) <= 0);
|
||||
break;
|
||||
case CONDTYPE_GTZ:
|
||||
info.conditionMet = (((s64)rs) > 0);
|
||||
break;
|
||||
case CONDTYPE_LTZ:
|
||||
info.conditionMet = (((s64)rs) < 0);
|
||||
break;
|
||||
case CONDTYPE_GEZ:
|
||||
info.conditionMet = (((s64)rs) >= 0);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case BRANCHTYPE_REGISTER:
|
||||
info.isConditional = false;
|
||||
info.isBranchToRegister = true;
|
||||
info.branchRegisterNum = (int)MIPS_GET_RS(op);
|
||||
info.branchTarget = info.cpu->getRegister(0,info.branchRegisterNum)._u32[0];
|
||||
break;
|
||||
case BRANCHTYPE_SYSCALL:
|
||||
info.isConditional = false;
|
||||
info.isSyscall = true;
|
||||
info.branchTarget = 0x80000000+0x180;
|
||||
break;
|
||||
case 0x20: // add
|
||||
case 0x21: // addu
|
||||
info.hasRelevantAddress = true;
|
||||
info.releventAddress = cpu->getRegister(0,MIPS_GET_RS(op))._u32[0]+cpu->getRegister(0,MIPS_GET_RT(op))._u32[0];
|
||||
break;
|
||||
case 0x22: // sub
|
||||
case 0x23: // subu
|
||||
info.hasRelevantAddress = true;
|
||||
info.releventAddress = cpu->getRegister(0,MIPS_GET_RS(op))._u32[0]-cpu->getRegister(0,MIPS_GET_RT(op))._u32[0];
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x08: // addi
|
||||
case 0x09: // adiu
|
||||
info.hasRelevantAddress = true;
|
||||
info.releventAddress = cpu->getRegister(0,MIPS_GET_RS(op))._u32[0]+((s16)(op & 0xFFFF));
|
||||
break;
|
||||
case 0x10: // cop0
|
||||
switch (MIPS_GET_RS(op))
|
||||
{
|
||||
case 0x10: // tlb
|
||||
switch (MIPS_GET_FUNC(op))
|
||||
case BRANCHTYPE_ERET:
|
||||
info.isConditional = false;
|
||||
// probably shouldn't be hard coded like this...
|
||||
if (cpuRegs.CP0.n.Status.b.ERL)
|
||||
{
|
||||
case 0x18: // eret
|
||||
info.isBranch = true;
|
||||
info.isConditional = false;
|
||||
info.branchTarget = cpuRegs.CP0.n.ErrorEPC;
|
||||
} else {
|
||||
info.branchTarget = cpuRegs.CP0.n.EPC;
|
||||
}
|
||||
break;
|
||||
case BRANCHTYPE_BC1:
|
||||
info.isConditional = true;
|
||||
value = info.cpu->getRegister(EECAT_FCR,31)._u32[0] & 0x00800000;
|
||||
info.branchTarget = info.opcodeAddress + 4 + ((s16)(op&0xFFFF)<<2);
|
||||
|
||||
// probably shouldn't be hard coded like this...
|
||||
if (cpuRegs.CP0.n.Status.b.ERL) {
|
||||
info.branchTarget = cpuRegs.CP0.n.ErrorEPC;
|
||||
} else {
|
||||
info.branchTarget = cpuRegs.CP0.n.EPC;
|
||||
}
|
||||
switch (opcode.flags & CONDTYPE_MASK)
|
||||
{
|
||||
case CONDTYPE_EQ:
|
||||
info.conditionMet = value == 0;
|
||||
break;
|
||||
case CONDTYPE_NE:
|
||||
info.conditionMet = value != 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: rest
|
||||
/* // movn, movz
|
||||
if (opInfo & IS_CONDMOVE) {
|
||||
info.isConditional = true;
|
||||
// extract the accessed memory address
|
||||
info.isDataAccess = opcode.flags & IS_MEMORY;
|
||||
if (info.isDataAccess)
|
||||
{
|
||||
if (opcode.flags & IS_LEFT)
|
||||
info.lrType = LOADSTORE_LEFT;
|
||||
else if (opcode.flags & IS_RIGHT)
|
||||
info.lrType = LOADSTORE_RIGHT;
|
||||
|
||||
u32 rs = info.cpu->getRegister(0, (int)MIPS_GET_RS(op));
|
||||
s16 imm16 = op & 0xFFFF;
|
||||
info.dataAddress = rs + imm16;
|
||||
|
||||
u32 rt = cpu->GetRegValue(0, (int)MIPS_GET_RT(op));
|
||||
switch (opInfo & CONDTYPE_MASK) {
|
||||
case CONDTYPE_EQ:
|
||||
info.conditionMet = (rt == 0);
|
||||
switch (opcode.flags & MEMTYPE_MASK)
|
||||
{
|
||||
case MEMTYPE_BYTE:
|
||||
info.dataSize = 1;
|
||||
break;
|
||||
case CONDTYPE_NE:
|
||||
info.conditionMet = (rt != 0);
|
||||
case MEMTYPE_HALF:
|
||||
info.dataSize = 2;
|
||||
break;
|
||||
case MEMTYPE_WORD:
|
||||
info.dataSize = 4;
|
||||
if (info.lrType == LOADSTORE_LEFT)
|
||||
info.dataAddress -= 3;
|
||||
break;
|
||||
case MEMTYPE_DWORD:
|
||||
info.dataSize = 8;
|
||||
if (info.lrType == LOADSTORE_LEFT)
|
||||
info.dataAddress -= 7;
|
||||
break;
|
||||
case MEMTYPE_QWORD:
|
||||
info.dataSize = 16;
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
|
||||
info.hasRelevantAddress = true;
|
||||
info.releventAddress = info.dataAddress;
|
||||
}
|
||||
|
||||
// gather relevant address for alu operations
|
||||
if (opcode.flags & IS_ALU)
|
||||
{
|
||||
u64 rs,rt;
|
||||
rs = info.cpu->getRegister(0,MIPS_GET_RS(op))._u64[0];
|
||||
rt = info.cpu->getRegister(0,MIPS_GET_RT(op))._u64[0];
|
||||
|
||||
switch (opcode.flags & ALUTYPE_MASK)
|
||||
{
|
||||
case ALUTYPE_ADDI:
|
||||
info.hasRelevantAddress = true;
|
||||
info.releventAddress = rs+((s16)(op & 0xFFFF));
|
||||
break;
|
||||
case ALUTYPE_ADD:
|
||||
info.hasRelevantAddress = true;
|
||||
info.releventAddress = rs+rt;
|
||||
break;
|
||||
case ALUTYPE_SUB:
|
||||
info.hasRelevantAddress = true;
|
||||
info.releventAddress = rs-rt;
|
||||
break;
|
||||
case ALUTYPE_CONDMOVE:
|
||||
info.isConditional = true;
|
||||
|
||||
switch (opcode.flags & CONDTYPE_MASK)
|
||||
{
|
||||
case CONDTYPE_EQ:
|
||||
info.conditionMet = (rt == 0);
|
||||
break;
|
||||
case CONDTYPE_NE:
|
||||
info.conditionMet = (rt != 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
|
|
@ -39,40 +39,44 @@ namespace R5900
|
|||
{
|
||||
// Generates an entry for the given opcode name.
|
||||
// Assumes the default function naming schemes for interpreter and recompiler functions.
|
||||
# define MakeOpcode( name, cycles ) \
|
||||
# define MakeOpcode( name, cycles, flags ) \
|
||||
static const OPCODE name = { \
|
||||
#name, \
|
||||
cycles, \
|
||||
flags, \
|
||||
NULL, \
|
||||
::R5900::Interpreter::OpcodeImpl::name, \
|
||||
::R5900::Dynarec::OpcodeImpl::rec##name, \
|
||||
::R5900::OpcodeDisasm::name \
|
||||
}
|
||||
|
||||
# define MakeOpcodeM( name, cycles ) \
|
||||
# define MakeOpcodeM( name, cycles, flags ) \
|
||||
static const OPCODE name = { \
|
||||
#name, \
|
||||
cycles, \
|
||||
flags, \
|
||||
NULL, \
|
||||
::R5900::Interpreter::OpcodeImpl::MMI::name, \
|
||||
::R5900::Dynarec::OpcodeImpl::MMI::rec##name, \
|
||||
::R5900::OpcodeDisasm::name \
|
||||
}
|
||||
|
||||
# define MakeOpcode0( name, cycles ) \
|
||||
# define MakeOpcode0( name, cycles, flags ) \
|
||||
static const OPCODE name = { \
|
||||
#name, \
|
||||
cycles, \
|
||||
flags, \
|
||||
NULL, \
|
||||
::R5900::Interpreter::OpcodeImpl::COP0::name, \
|
||||
::R5900::Dynarec::OpcodeImpl::COP0::rec##name, \
|
||||
::R5900::OpcodeDisasm::name \
|
||||
}
|
||||
|
||||
# define MakeOpcode1( name, cycles ) \
|
||||
# define MakeOpcode1( name, cycles, flags ) \
|
||||
static const OPCODE name = { \
|
||||
#name, \
|
||||
cycles, \
|
||||
flags, \
|
||||
NULL, \
|
||||
::R5900::Interpreter::OpcodeImpl::COP1::name, \
|
||||
::R5900::Dynarec::OpcodeImpl::COP1::rec##name, \
|
||||
|
@ -83,6 +87,7 @@ namespace R5900
|
|||
static const OPCODE name = { \
|
||||
#name, \
|
||||
0, \
|
||||
0, \
|
||||
R5900::Opcodes::Class_##name, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
|
@ -113,10 +118,10 @@ namespace R5900
|
|||
|
||||
using namespace Cycles;
|
||||
|
||||
MakeOpcode( Unknown, Default );
|
||||
MakeOpcode( MMI_Unknown, Default );
|
||||
MakeOpcode( COP0_Unknown, Default );
|
||||
MakeOpcode( COP1_Unknown, Default );
|
||||
MakeOpcode( Unknown, Default, 0 );
|
||||
MakeOpcode( MMI_Unknown, Default, 0 );
|
||||
MakeOpcode( COP0_Unknown, Default, 0 );
|
||||
MakeOpcode( COP1_Unknown, Default, 0 );
|
||||
|
||||
// Class Subset Opcodes
|
||||
// (not really opcodes, but rather entire subsets of other opcode classes)
|
||||
|
@ -135,250 +140,250 @@ namespace R5900
|
|||
|
||||
// Misc Junk
|
||||
|
||||
MakeOpcode( COP2, Default );
|
||||
MakeOpcode( COP2, Default, 0 );
|
||||
|
||||
MakeOpcode( CACHE, Default );
|
||||
MakeOpcode( PREF, Default );
|
||||
MakeOpcode( SYSCALL, Default );
|
||||
MakeOpcode( BREAK, Default );
|
||||
MakeOpcode( SYNC, Default );
|
||||
MakeOpcode( CACHE, Default, 0 );
|
||||
MakeOpcode( PREF, Default, 0 );
|
||||
MakeOpcode( SYSCALL, Default, IS_BRANCH|BRANCHTYPE_SYSCALL );
|
||||
MakeOpcode( BREAK, Default, 0 );
|
||||
MakeOpcode( SYNC, Default, 0 );
|
||||
|
||||
// Branch/Jump Opcodes
|
||||
|
||||
MakeOpcode( J , Default );
|
||||
MakeOpcode( JAL, Default );
|
||||
MakeOpcode( JR, Default );
|
||||
MakeOpcode( JALR, Default );
|
||||
MakeOpcode( J , Default, IS_BRANCH|BRANCHTYPE_JUMP );
|
||||
MakeOpcode( JAL, Default, IS_BRANCH|BRANCHTYPE_JUMP|IS_LINKED );
|
||||
MakeOpcode( JR, Default, IS_BRANCH|BRANCHTYPE_REGISTER );
|
||||
MakeOpcode( JALR, Default, IS_BRANCH|BRANCHTYPE_REGISTER|IS_LINKED );
|
||||
|
||||
MakeOpcode( BEQ, Branch );
|
||||
MakeOpcode( BNE, Branch );
|
||||
MakeOpcode( BLEZ, Branch );
|
||||
MakeOpcode( BGTZ, Branch );
|
||||
MakeOpcode( BEQL, Branch );
|
||||
MakeOpcode( BNEL, Branch );
|
||||
MakeOpcode( BLEZL, Branch );
|
||||
MakeOpcode( BGTZL, Branch );
|
||||
MakeOpcode( BLTZ, Branch );
|
||||
MakeOpcode( BGEZ, Branch );
|
||||
MakeOpcode( BLTZL, Branch );
|
||||
MakeOpcode( BGEZL, Branch );
|
||||
MakeOpcode( BLTZAL, Branch );
|
||||
MakeOpcode( BGEZAL, Branch );
|
||||
MakeOpcode( BLTZALL, Branch );
|
||||
MakeOpcode( BGEZALL, Branch );
|
||||
MakeOpcode( BEQ, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_EQ );
|
||||
MakeOpcode( BNE, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_NE );
|
||||
MakeOpcode( BLEZ, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_LEZ );
|
||||
MakeOpcode( BGTZ, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_GTZ );
|
||||
MakeOpcode( BEQL, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_EQ|IS_LIKELY );
|
||||
MakeOpcode( BNEL, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_NE|IS_LIKELY );
|
||||
MakeOpcode( BLEZL, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_LEZ|IS_LIKELY );
|
||||
MakeOpcode( BGTZL, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_GTZ|IS_LIKELY );
|
||||
MakeOpcode( BLTZ, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_LTZ );
|
||||
MakeOpcode( BGEZ, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_GEZ );
|
||||
MakeOpcode( BLTZL, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_LTZ|IS_LIKELY );
|
||||
MakeOpcode( BGEZL, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_GEZ|IS_LIKELY );
|
||||
MakeOpcode( BLTZAL, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_LTZ|IS_LINKED );
|
||||
MakeOpcode( BGEZAL, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_GEZ|IS_LINKED );
|
||||
MakeOpcode( BLTZALL, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_LTZ|IS_LINKED|IS_LIKELY );
|
||||
MakeOpcode( BGEZALL, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_GEZ|IS_LINKED|IS_LIKELY );
|
||||
|
||||
MakeOpcode( TGEI, Branch );
|
||||
MakeOpcode( TGEIU, Branch );
|
||||
MakeOpcode( TLTI, Branch );
|
||||
MakeOpcode( TLTIU, Branch );
|
||||
MakeOpcode( TEQI, Branch );
|
||||
MakeOpcode( TNEI, Branch );
|
||||
MakeOpcode( TGE, Branch );
|
||||
MakeOpcode( TGEU, Branch );
|
||||
MakeOpcode( TLT, Branch );
|
||||
MakeOpcode( TLTU, Branch );
|
||||
MakeOpcode( TEQ, Branch );
|
||||
MakeOpcode( TNE, Branch );
|
||||
MakeOpcode( TGEI, Branch, 0 );
|
||||
MakeOpcode( TGEIU, Branch, 0 );
|
||||
MakeOpcode( TLTI, Branch, 0 );
|
||||
MakeOpcode( TLTIU, Branch, 0 );
|
||||
MakeOpcode( TEQI, Branch, 0 );
|
||||
MakeOpcode( TNEI, Branch, 0 );
|
||||
MakeOpcode( TGE, Branch, 0 );
|
||||
MakeOpcode( TGEU, Branch, 0 );
|
||||
MakeOpcode( TLT, Branch, 0 );
|
||||
MakeOpcode( TLTU, Branch, 0 );
|
||||
MakeOpcode( TEQ, Branch, 0 );
|
||||
MakeOpcode( TNE, Branch, 0 );
|
||||
|
||||
// Arithmetic
|
||||
|
||||
MakeOpcode( MULT, Mult );
|
||||
MakeOpcode( MULTU, Mult );
|
||||
MakeOpcode( MULT1, Mult );
|
||||
MakeOpcode( MULTU1, Mult );
|
||||
MakeOpcode( MADD, Mult );
|
||||
MakeOpcode( MADDU, Mult );
|
||||
MakeOpcode( MADD1, Mult );
|
||||
MakeOpcode( MADDU1, Mult );
|
||||
MakeOpcode( DIV, Div );
|
||||
MakeOpcode( DIVU, Div );
|
||||
MakeOpcode( DIV1, Div );
|
||||
MakeOpcode( DIVU1, Div );
|
||||
MakeOpcode( MULT, Mult, 0 );
|
||||
MakeOpcode( MULTU, Mult, 0 );
|
||||
MakeOpcode( MULT1, Mult, 0 );
|
||||
MakeOpcode( MULTU1, Mult, 0 );
|
||||
MakeOpcode( MADD, Mult, 0 );
|
||||
MakeOpcode( MADDU, Mult, 0 );
|
||||
MakeOpcode( MADD1, Mult, 0 );
|
||||
MakeOpcode( MADDU1, Mult, 0 );
|
||||
MakeOpcode( DIV, Div, 0 );
|
||||
MakeOpcode( DIVU, Div, 0 );
|
||||
MakeOpcode( DIV1, Div, 0 );
|
||||
MakeOpcode( DIVU1, Div, 0 );
|
||||
|
||||
MakeOpcode( ADDI, Default );
|
||||
MakeOpcode( ADDIU, Default );
|
||||
MakeOpcode( DADDI, Default );
|
||||
MakeOpcode( DADDIU, Default );
|
||||
MakeOpcode( DADD, Default );
|
||||
MakeOpcode( DADDU, Default );
|
||||
MakeOpcode( DSUB, Default );
|
||||
MakeOpcode( DSUBU, Default );
|
||||
MakeOpcode( ADD, Default );
|
||||
MakeOpcode( ADDU, Default );
|
||||
MakeOpcode( SUB, Default );
|
||||
MakeOpcode( SUBU, Default );
|
||||
MakeOpcode( ADDI, Default, IS_ALU|ALUTYPE_ADDI );
|
||||
MakeOpcode( ADDIU, Default, IS_ALU|ALUTYPE_ADDI );
|
||||
MakeOpcode( DADDI, Default, IS_ALU|ALUTYPE_ADDI|IS_64BIT );
|
||||
MakeOpcode( DADDIU, Default, IS_ALU|ALUTYPE_ADDI|IS_64BIT );
|
||||
MakeOpcode( DADD, Default, IS_ALU|ALUTYPE_ADD|IS_64BIT );
|
||||
MakeOpcode( DADDU, Default, IS_ALU|ALUTYPE_ADD|IS_64BIT );
|
||||
MakeOpcode( DSUB, Default, IS_ALU|ALUTYPE_SUB|IS_64BIT );
|
||||
MakeOpcode( DSUBU, Default, IS_ALU|ALUTYPE_SUB|IS_64BIT );
|
||||
MakeOpcode( ADD, Default, IS_ALU|ALUTYPE_ADD );
|
||||
MakeOpcode( ADDU, Default, IS_ALU|ALUTYPE_ADD );
|
||||
MakeOpcode( SUB, Default, IS_ALU|ALUTYPE_SUB );
|
||||
MakeOpcode( SUBU, Default, IS_ALU|ALUTYPE_SUB );
|
||||
|
||||
MakeOpcode( ANDI, Default );
|
||||
MakeOpcode( ORI, Default );
|
||||
MakeOpcode( XORI, Default );
|
||||
MakeOpcode( AND, Default );
|
||||
MakeOpcode( OR, Default );
|
||||
MakeOpcode( XOR, Default );
|
||||
MakeOpcode( NOR, Default );
|
||||
MakeOpcode( SLTI, Default );
|
||||
MakeOpcode( SLTIU, Default );
|
||||
MakeOpcode( SLT, Default );
|
||||
MakeOpcode( SLTU, Default );
|
||||
MakeOpcode( LUI, Default );
|
||||
MakeOpcode( SLL, Default );
|
||||
MakeOpcode( SRL, Default );
|
||||
MakeOpcode( SRA, Default );
|
||||
MakeOpcode( SLLV, Default );
|
||||
MakeOpcode( SRLV, Default );
|
||||
MakeOpcode( SRAV, Default );
|
||||
MakeOpcode( MOVZ, Default );
|
||||
MakeOpcode( MOVN, Default );
|
||||
MakeOpcode( DSLLV, Default );
|
||||
MakeOpcode( DSRLV, Default );
|
||||
MakeOpcode( DSRAV, Default );
|
||||
MakeOpcode( DSLL, Default );
|
||||
MakeOpcode( DSRL, Default );
|
||||
MakeOpcode( DSRA, Default );
|
||||
MakeOpcode( DSLL32, Default );
|
||||
MakeOpcode( DSRL32, Default );
|
||||
MakeOpcode( DSRA32, Default );
|
||||
MakeOpcode( ANDI, Default, 0 );
|
||||
MakeOpcode( ORI, Default, 0 );
|
||||
MakeOpcode( XORI, Default, 0 );
|
||||
MakeOpcode( AND, Default, 0 );
|
||||
MakeOpcode( OR, Default, 0 );
|
||||
MakeOpcode( XOR, Default, 0 );
|
||||
MakeOpcode( NOR, Default, 0 );
|
||||
MakeOpcode( SLTI, Default, 0 );
|
||||
MakeOpcode( SLTIU, Default, 0 );
|
||||
MakeOpcode( SLT, Default, 0 );
|
||||
MakeOpcode( SLTU, Default, 0 );
|
||||
MakeOpcode( LUI, Default, 0 );
|
||||
MakeOpcode( SLL, Default, 0 );
|
||||
MakeOpcode( SRL, Default, 0 );
|
||||
MakeOpcode( SRA, Default, 0 );
|
||||
MakeOpcode( SLLV, Default, 0 );
|
||||
MakeOpcode( SRLV, Default, 0 );
|
||||
MakeOpcode( SRAV, Default, 0 );
|
||||
MakeOpcode( MOVZ, Default, IS_ALU|ALUTYPE_CONDMOVE|CONDTYPE_EQ );
|
||||
MakeOpcode( MOVN, Default, IS_ALU|ALUTYPE_CONDMOVE|CONDTYPE_NE );
|
||||
MakeOpcode( DSLLV, Default, 0 );
|
||||
MakeOpcode( DSRLV, Default, 0 );
|
||||
MakeOpcode( DSRAV, Default, 0 );
|
||||
MakeOpcode( DSLL, Default, 0 );
|
||||
MakeOpcode( DSRL, Default, 0 );
|
||||
MakeOpcode( DSRA, Default, 0 );
|
||||
MakeOpcode( DSLL32, Default, 0 );
|
||||
MakeOpcode( DSRL32, Default, 0 );
|
||||
MakeOpcode( DSRA32, Default, 0 );
|
||||
|
||||
MakeOpcode( MFHI, Default );
|
||||
MakeOpcode( MTHI, Default );
|
||||
MakeOpcode( MFLO, Default );
|
||||
MakeOpcode( MTLO, Default );
|
||||
MakeOpcode( MFSA, Default );
|
||||
MakeOpcode( MTSA, Default );
|
||||
MakeOpcode( MTSAB, Default );
|
||||
MakeOpcode( MTSAH, Default );
|
||||
MakeOpcode( MFHI1, Default );
|
||||
MakeOpcode( MTHI1, Default );
|
||||
MakeOpcode( MFLO1, Default );
|
||||
MakeOpcode( MTLO1, Default );
|
||||
MakeOpcode( MFHI, Default, 0 );
|
||||
MakeOpcode( MTHI, Default, 0 );
|
||||
MakeOpcode( MFLO, Default, 0 );
|
||||
MakeOpcode( MTLO, Default, 0 );
|
||||
MakeOpcode( MFSA, Default, 0 );
|
||||
MakeOpcode( MTSA, Default, 0 );
|
||||
MakeOpcode( MTSAB, Default, 0 );
|
||||
MakeOpcode( MTSAH, Default, 0 );
|
||||
MakeOpcode( MFHI1, Default, 0 );
|
||||
MakeOpcode( MTHI1, Default, 0 );
|
||||
MakeOpcode( MFLO1, Default, 0 );
|
||||
MakeOpcode( MTLO1, Default, 0 );
|
||||
|
||||
// Loads!
|
||||
|
||||
MakeOpcode( LDL, Load );
|
||||
MakeOpcode( LDR, Load );
|
||||
MakeOpcode( LQ, Load );
|
||||
MakeOpcode( LB, Load );
|
||||
MakeOpcode( LH, Load );
|
||||
MakeOpcode( LWL, Load );
|
||||
MakeOpcode( LW, Load );
|
||||
MakeOpcode( LBU, Load );
|
||||
MakeOpcode( LHU, Load );
|
||||
MakeOpcode( LWR, Load );
|
||||
MakeOpcode( LWU, Load );
|
||||
MakeOpcode( LWC1, Load );
|
||||
MakeOpcode( LQC2, Load );
|
||||
MakeOpcode( LD, Load );
|
||||
MakeOpcode( LDL, Load, IS_MEMORY|IS_LOAD|MEMTYPE_DWORD|IS_LEFT );
|
||||
MakeOpcode( LDR, Load, IS_MEMORY|IS_LOAD|MEMTYPE_DWORD|IS_RIGHT );
|
||||
MakeOpcode( LQ, Load, IS_MEMORY|IS_LOAD|MEMTYPE_QWORD );
|
||||
MakeOpcode( LB, Load, IS_MEMORY|IS_LOAD|MEMTYPE_BYTE );
|
||||
MakeOpcode( LH, Load, IS_MEMORY|IS_LOAD|MEMTYPE_HALF );
|
||||
MakeOpcode( LWL, Load, IS_MEMORY|IS_LOAD|MEMTYPE_WORD|IS_LEFT );
|
||||
MakeOpcode( LW, Load, IS_MEMORY|IS_LOAD|MEMTYPE_WORD );
|
||||
MakeOpcode( LBU, Load, IS_MEMORY|IS_LOAD|MEMTYPE_BYTE );
|
||||
MakeOpcode( LHU, Load, IS_MEMORY|IS_LOAD|MEMTYPE_HALF );
|
||||
MakeOpcode( LWR, Load, IS_MEMORY|IS_LOAD|MEMTYPE_WORD|IS_RIGHT );
|
||||
MakeOpcode( LWU, Load, IS_MEMORY|IS_LOAD|MEMTYPE_WORD );
|
||||
MakeOpcode( LWC1, Load, IS_MEMORY|IS_LOAD|MEMTYPE_WORD );
|
||||
MakeOpcode( LQC2, Load, IS_MEMORY|IS_LOAD|MEMTYPE_QWORD );
|
||||
MakeOpcode( LD, Load, IS_MEMORY|IS_LOAD|MEMTYPE_DWORD );
|
||||
|
||||
// Stores!
|
||||
|
||||
MakeOpcode( SQ, Store );
|
||||
MakeOpcode( SB, Store );
|
||||
MakeOpcode( SH, Store );
|
||||
MakeOpcode( SWL, Store );
|
||||
MakeOpcode( SW, Store );
|
||||
MakeOpcode( SDL, Store );
|
||||
MakeOpcode( SDR, Store );
|
||||
MakeOpcode( SWR, Store );
|
||||
MakeOpcode( SWC1, Store );
|
||||
MakeOpcode( SQC2, Store );
|
||||
MakeOpcode( SD, Store );
|
||||
MakeOpcode( SQ, Store, IS_MEMORY|IS_STORE|MEMTYPE_QWORD );
|
||||
MakeOpcode( SB, Store, IS_MEMORY|IS_STORE|MEMTYPE_BYTE );
|
||||
MakeOpcode( SH, Store, IS_MEMORY|IS_STORE|MEMTYPE_HALF );
|
||||
MakeOpcode( SWL, Store, IS_MEMORY|IS_STORE|MEMTYPE_WORD|IS_LEFT );
|
||||
MakeOpcode( SW, Store, IS_MEMORY|IS_STORE|MEMTYPE_WORD );
|
||||
MakeOpcode( SDL, Store, IS_MEMORY|IS_STORE|MEMTYPE_DWORD|IS_LEFT );
|
||||
MakeOpcode( SDR, Store, IS_MEMORY|IS_STORE|MEMTYPE_DWORD|IS_RIGHT );
|
||||
MakeOpcode( SWR, Store, IS_MEMORY|IS_STORE|MEMTYPE_WORD|IS_RIGHT );
|
||||
MakeOpcode( SWC1, Store, IS_MEMORY|IS_STORE|MEMTYPE_WORD );
|
||||
MakeOpcode( SQC2, Store, IS_MEMORY|IS_STORE|MEMTYPE_QWORD );
|
||||
MakeOpcode( SD, Store, IS_MEMORY|IS_STORE|MEMTYPE_DWORD );
|
||||
|
||||
|
||||
// Multimedia Instructions!
|
||||
|
||||
MakeOpcodeM( PLZCW, MMI_Default );
|
||||
MakeOpcodeM( PMFHL, MMI_Default );
|
||||
MakeOpcodeM( PMTHL, MMI_Default );
|
||||
MakeOpcodeM( PSLLH, MMI_Default );
|
||||
MakeOpcodeM( PSRLH, MMI_Default );
|
||||
MakeOpcodeM( PSRAH, MMI_Default );
|
||||
MakeOpcodeM( PSLLW, MMI_Default );
|
||||
MakeOpcodeM( PSRLW, MMI_Default );
|
||||
MakeOpcodeM( PSRAW, MMI_Default );
|
||||
MakeOpcodeM( PLZCW, MMI_Default, 0 );
|
||||
MakeOpcodeM( PMFHL, MMI_Default, 0 );
|
||||
MakeOpcodeM( PMTHL, MMI_Default, 0 );
|
||||
MakeOpcodeM( PSLLH, MMI_Default, 0 );
|
||||
MakeOpcodeM( PSRLH, MMI_Default, 0 );
|
||||
MakeOpcodeM( PSRAH, MMI_Default, 0 );
|
||||
MakeOpcodeM( PSLLW, MMI_Default, 0 );
|
||||
MakeOpcodeM( PSRLW, MMI_Default, 0 );
|
||||
MakeOpcodeM( PSRAW, MMI_Default, 0 );
|
||||
|
||||
MakeOpcodeM( PADDW, MMI_Default );
|
||||
MakeOpcodeM( PADDH, MMI_Default );
|
||||
MakeOpcodeM( PADDB, MMI_Default );
|
||||
MakeOpcodeM( PADDSW, MMI_Default );
|
||||
MakeOpcodeM( PADDSH, MMI_Default );
|
||||
MakeOpcodeM( PADDSB, MMI_Default );
|
||||
MakeOpcodeM( PADDUW, MMI_Default );
|
||||
MakeOpcodeM( PADDUH, MMI_Default );
|
||||
MakeOpcodeM( PADDUB, MMI_Default );
|
||||
MakeOpcodeM( PSUBW, MMI_Default );
|
||||
MakeOpcodeM( PSUBH, MMI_Default );
|
||||
MakeOpcodeM( PSUBB, MMI_Default );
|
||||
MakeOpcodeM( PSUBSW, MMI_Default );
|
||||
MakeOpcodeM( PSUBSH, MMI_Default );
|
||||
MakeOpcodeM( PSUBSB, MMI_Default );
|
||||
MakeOpcodeM( PSUBUW, MMI_Default );
|
||||
MakeOpcodeM( PSUBUH, MMI_Default );
|
||||
MakeOpcodeM( PSUBUB, MMI_Default );
|
||||
MakeOpcodeM( PADDW, MMI_Default, 0 );
|
||||
MakeOpcodeM( PADDH, MMI_Default, 0 );
|
||||
MakeOpcodeM( PADDB, MMI_Default, 0 );
|
||||
MakeOpcodeM( PADDSW, MMI_Default, 0 );
|
||||
MakeOpcodeM( PADDSH, MMI_Default, 0 );
|
||||
MakeOpcodeM( PADDSB, MMI_Default, 0 );
|
||||
MakeOpcodeM( PADDUW, MMI_Default, 0 );
|
||||
MakeOpcodeM( PADDUH, MMI_Default, 0 );
|
||||
MakeOpcodeM( PADDUB, MMI_Default, 0 );
|
||||
MakeOpcodeM( PSUBW, MMI_Default, 0 );
|
||||
MakeOpcodeM( PSUBH, MMI_Default, 0 );
|
||||
MakeOpcodeM( PSUBB, MMI_Default, 0 );
|
||||
MakeOpcodeM( PSUBSW, MMI_Default, 0 );
|
||||
MakeOpcodeM( PSUBSH, MMI_Default, 0 );
|
||||
MakeOpcodeM( PSUBSB, MMI_Default, 0 );
|
||||
MakeOpcodeM( PSUBUW, MMI_Default, 0 );
|
||||
MakeOpcodeM( PSUBUH, MMI_Default, 0 );
|
||||
MakeOpcodeM( PSUBUB, MMI_Default, 0 );
|
||||
|
||||
MakeOpcodeM( PCGTW, MMI_Default );
|
||||
MakeOpcodeM( PMAXW, MMI_Default );
|
||||
MakeOpcodeM( PMAXH, MMI_Default );
|
||||
MakeOpcodeM( PCGTH, MMI_Default );
|
||||
MakeOpcodeM( PCGTB, MMI_Default );
|
||||
MakeOpcodeM( PEXTLW, MMI_Default );
|
||||
MakeOpcodeM( PEXTLH, MMI_Default );
|
||||
MakeOpcodeM( PEXTLB, MMI_Default );
|
||||
MakeOpcodeM( PEXT5, MMI_Default );
|
||||
MakeOpcodeM( PPACW, MMI_Default );
|
||||
MakeOpcodeM( PPACH, MMI_Default );
|
||||
MakeOpcodeM( PPACB, MMI_Default );
|
||||
MakeOpcodeM( PPAC5, MMI_Default );
|
||||
MakeOpcodeM( PCGTW, MMI_Default, 0 );
|
||||
MakeOpcodeM( PMAXW, MMI_Default, 0 );
|
||||
MakeOpcodeM( PMAXH, MMI_Default, 0 );
|
||||
MakeOpcodeM( PCGTH, MMI_Default, 0 );
|
||||
MakeOpcodeM( PCGTB, MMI_Default, 0 );
|
||||
MakeOpcodeM( PEXTLW, MMI_Default, 0 );
|
||||
MakeOpcodeM( PEXTLH, MMI_Default, 0 );
|
||||
MakeOpcodeM( PEXTLB, MMI_Default, 0 );
|
||||
MakeOpcodeM( PEXT5, MMI_Default, 0 );
|
||||
MakeOpcodeM( PPACW, MMI_Default, 0 );
|
||||
MakeOpcodeM( PPACH, MMI_Default, 0 );
|
||||
MakeOpcodeM( PPACB, MMI_Default, 0 );
|
||||
MakeOpcodeM( PPAC5, MMI_Default, 0 );
|
||||
|
||||
MakeOpcodeM( PABSW, MMI_Default );
|
||||
MakeOpcodeM( PABSH, MMI_Default );
|
||||
MakeOpcodeM( PCEQW, MMI_Default );
|
||||
MakeOpcodeM( PMINW, MMI_Default );
|
||||
MakeOpcodeM( PMINH, MMI_Default );
|
||||
MakeOpcodeM( PADSBH, MMI_Default );
|
||||
MakeOpcodeM( PCEQH, MMI_Default );
|
||||
MakeOpcodeM( PCEQB, MMI_Default );
|
||||
MakeOpcodeM( PEXTUW, MMI_Default );
|
||||
MakeOpcodeM( PEXTUH, MMI_Default );
|
||||
MakeOpcodeM( PEXTUB, MMI_Default );
|
||||
MakeOpcodeM( PSLLVW, MMI_Default );
|
||||
MakeOpcodeM( PSRLVW, MMI_Default );
|
||||
MakeOpcodeM( PABSW, MMI_Default, 0 );
|
||||
MakeOpcodeM( PABSH, MMI_Default, 0 );
|
||||
MakeOpcodeM( PCEQW, MMI_Default, 0 );
|
||||
MakeOpcodeM( PMINW, MMI_Default, 0 );
|
||||
MakeOpcodeM( PMINH, MMI_Default, 0 );
|
||||
MakeOpcodeM( PADSBH, MMI_Default, 0 );
|
||||
MakeOpcodeM( PCEQH, MMI_Default, 0 );
|
||||
MakeOpcodeM( PCEQB, MMI_Default, 0 );
|
||||
MakeOpcodeM( PEXTUW, MMI_Default, 0 );
|
||||
MakeOpcodeM( PEXTUH, MMI_Default, 0 );
|
||||
MakeOpcodeM( PEXTUB, MMI_Default, 0 );
|
||||
MakeOpcodeM( PSLLVW, MMI_Default, 0 );
|
||||
MakeOpcodeM( PSRLVW, MMI_Default, 0 );
|
||||
|
||||
MakeOpcodeM( QFSRV, MMI_Default );
|
||||
MakeOpcodeM( QFSRV, MMI_Default, 0 );
|
||||
|
||||
MakeOpcodeM( PMADDH, MMI_Mult );
|
||||
MakeOpcodeM( PHMADH, MMI_Mult );
|
||||
MakeOpcodeM( PMSUBH, MMI_Mult );
|
||||
MakeOpcodeM( PHMSBH, MMI_Mult );
|
||||
MakeOpcodeM( PMULTH, MMI_Mult );
|
||||
MakeOpcodeM( PMADDW, MMI_Mult );
|
||||
MakeOpcodeM( PMSUBW, MMI_Mult );
|
||||
MakeOpcodeM( PMFHI, MMI_Mult );
|
||||
MakeOpcodeM( PMFLO, MMI_Mult );
|
||||
MakeOpcodeM( PMULTW, MMI_Mult );
|
||||
MakeOpcodeM( PMADDUW, MMI_Mult );
|
||||
MakeOpcodeM( PMULTUW, MMI_Mult );
|
||||
MakeOpcodeM( PDIVUW, MMI_Div );
|
||||
MakeOpcodeM( PDIVW, MMI_Div );
|
||||
MakeOpcodeM( PDIVBW, MMI_Div );
|
||||
MakeOpcodeM( PMADDH, MMI_Mult, 0 );
|
||||
MakeOpcodeM( PHMADH, MMI_Mult, 0 );
|
||||
MakeOpcodeM( PMSUBH, MMI_Mult, 0 );
|
||||
MakeOpcodeM( PHMSBH, MMI_Mult, 0 );
|
||||
MakeOpcodeM( PMULTH, MMI_Mult, 0 );
|
||||
MakeOpcodeM( PMADDW, MMI_Mult, 0 );
|
||||
MakeOpcodeM( PMSUBW, MMI_Mult, 0 );
|
||||
MakeOpcodeM( PMFHI, MMI_Mult, 0 );
|
||||
MakeOpcodeM( PMFLO, MMI_Mult, 0 );
|
||||
MakeOpcodeM( PMULTW, MMI_Mult, 0 );
|
||||
MakeOpcodeM( PMADDUW, MMI_Mult, 0 );
|
||||
MakeOpcodeM( PMULTUW, MMI_Mult, 0 );
|
||||
MakeOpcodeM( PDIVUW, MMI_Div, 0 );
|
||||
MakeOpcodeM( PDIVW, MMI_Div, 0 );
|
||||
MakeOpcodeM( PDIVBW, MMI_Div, 0 );
|
||||
|
||||
MakeOpcodeM( PINTH, MMI_Default );
|
||||
MakeOpcodeM( PCPYLD, MMI_Default );
|
||||
MakeOpcodeM( PAND, MMI_Default );
|
||||
MakeOpcodeM( PXOR, MMI_Default );
|
||||
MakeOpcodeM( PEXEH, MMI_Default );
|
||||
MakeOpcodeM( PREVH, MMI_Default );
|
||||
MakeOpcodeM( PEXEW, MMI_Default );
|
||||
MakeOpcodeM( PROT3W, MMI_Default );
|
||||
MakeOpcodeM( PINTH, MMI_Default, 0 );
|
||||
MakeOpcodeM( PCPYLD, MMI_Default, 0 );
|
||||
MakeOpcodeM( PAND, MMI_Default, 0 );
|
||||
MakeOpcodeM( PXOR, MMI_Default, 0 );
|
||||
MakeOpcodeM( PEXEH, MMI_Default, 0 );
|
||||
MakeOpcodeM( PREVH, MMI_Default, 0 );
|
||||
MakeOpcodeM( PEXEW, MMI_Default, 0 );
|
||||
MakeOpcodeM( PROT3W, MMI_Default, 0 );
|
||||
|
||||
MakeOpcodeM( PSRAVW, MMI_Default );
|
||||
MakeOpcodeM( PMTHI, MMI_Default );
|
||||
MakeOpcodeM( PMTLO, MMI_Default );
|
||||
MakeOpcodeM( PINTEH, MMI_Default );
|
||||
MakeOpcodeM( PCPYUD, MMI_Default );
|
||||
MakeOpcodeM( POR, MMI_Default );
|
||||
MakeOpcodeM( PNOR, MMI_Default );
|
||||
MakeOpcodeM( PEXCH, MMI_Default );
|
||||
MakeOpcodeM( PCPYH, MMI_Default );
|
||||
MakeOpcodeM( PEXCW, MMI_Default );
|
||||
MakeOpcodeM( PSRAVW, MMI_Default, 0 );
|
||||
MakeOpcodeM( PMTHI, MMI_Default, 0 );
|
||||
MakeOpcodeM( PMTLO, MMI_Default, 0 );
|
||||
MakeOpcodeM( PINTEH, MMI_Default, 0 );
|
||||
MakeOpcodeM( PCPYUD, MMI_Default, 0 );
|
||||
MakeOpcodeM( POR, MMI_Default, 0 );
|
||||
MakeOpcodeM( PNOR, MMI_Default, 0 );
|
||||
MakeOpcodeM( PEXCH, MMI_Default, 0 );
|
||||
MakeOpcodeM( PCPYH, MMI_Default, 0 );
|
||||
MakeOpcodeM( PEXCW, MMI_Default, 0 );
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// COP0 Instructions
|
||||
|
@ -386,21 +391,21 @@ namespace R5900
|
|||
MakeOpcodeClass( COP0_C0 );
|
||||
MakeOpcodeClass( COP0_BC0 );
|
||||
|
||||
MakeOpcode0( MFC0, CopDefault );
|
||||
MakeOpcode0( MTC0, CopDefault );
|
||||
MakeOpcode0( MFC0, CopDefault, 0 );
|
||||
MakeOpcode0( MTC0, CopDefault, 0 );
|
||||
|
||||
MakeOpcode0( BC0F, Branch );
|
||||
MakeOpcode0( BC0T, Branch );
|
||||
MakeOpcode0( BC0FL, Branch );
|
||||
MakeOpcode0( BC0TL, Branch );
|
||||
MakeOpcode0( BC0F, Branch, 0 );
|
||||
MakeOpcode0( BC0T, Branch, 0 );
|
||||
MakeOpcode0( BC0FL, Branch, 0 );
|
||||
MakeOpcode0( BC0TL, Branch, 0 );
|
||||
|
||||
MakeOpcode0( TLBR, CopDefault );
|
||||
MakeOpcode0( TLBWI, CopDefault );
|
||||
MakeOpcode0( TLBWR, CopDefault );
|
||||
MakeOpcode0( TLBP, CopDefault );
|
||||
MakeOpcode0( ERET, CopDefault );
|
||||
MakeOpcode0( EI, CopDefault );
|
||||
MakeOpcode0( DI, CopDefault );
|
||||
MakeOpcode0( TLBR, CopDefault, 0 );
|
||||
MakeOpcode0( TLBWI, CopDefault, 0 );
|
||||
MakeOpcode0( TLBWR, CopDefault, 0 );
|
||||
MakeOpcode0( TLBP, CopDefault, 0 );
|
||||
MakeOpcode0( ERET, CopDefault, IS_BRANCH|BRANCHTYPE_ERET );
|
||||
MakeOpcode0( EI, CopDefault, 0 );
|
||||
MakeOpcode0( DI, CopDefault, 0 );
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// COP1 Instructions!
|
||||
|
@ -409,44 +414,44 @@ namespace R5900
|
|||
MakeOpcodeClass( COP1_S );
|
||||
MakeOpcodeClass( COP1_W ); // contains CVT_S instruction *only*
|
||||
|
||||
MakeOpcode1( MFC1, CopDefault );
|
||||
MakeOpcode1( CFC1, CopDefault );
|
||||
MakeOpcode1( MTC1, CopDefault );
|
||||
MakeOpcode1( CTC1, CopDefault );
|
||||
MakeOpcode1( MFC1, CopDefault, 0 );
|
||||
MakeOpcode1( CFC1, CopDefault, 0 );
|
||||
MakeOpcode1( MTC1, CopDefault, 0 );
|
||||
MakeOpcode1( CTC1, CopDefault, 0 );
|
||||
|
||||
MakeOpcode1( BC1F, Branch );
|
||||
MakeOpcode1( BC1T, Branch );
|
||||
MakeOpcode1( BC1FL, Branch );
|
||||
MakeOpcode1( BC1TL, Branch );
|
||||
MakeOpcode1( BC1F, Branch, IS_BRANCH|BRANCHTYPE_BC1|CONDTYPE_EQ );
|
||||
MakeOpcode1( BC1T, Branch, IS_BRANCH|BRANCHTYPE_BC1|CONDTYPE_NE );
|
||||
MakeOpcode1( BC1FL, Branch, IS_BRANCH|BRANCHTYPE_BC1|CONDTYPE_EQ|IS_LIKELY );
|
||||
MakeOpcode1( BC1TL, Branch, IS_BRANCH|BRANCHTYPE_BC1|CONDTYPE_NE|IS_LIKELY );
|
||||
|
||||
MakeOpcode1( ADD_S, CopDefault );
|
||||
MakeOpcode1( ADDA_S, CopDefault );
|
||||
MakeOpcode1( SUB_S, CopDefault );
|
||||
MakeOpcode1( SUBA_S, CopDefault );
|
||||
MakeOpcode1( ADD_S, CopDefault, 0 );
|
||||
MakeOpcode1( ADDA_S, CopDefault, 0 );
|
||||
MakeOpcode1( SUB_S, CopDefault, 0 );
|
||||
MakeOpcode1( SUBA_S, CopDefault, 0 );
|
||||
|
||||
MakeOpcode1( ABS_S, CopDefault );
|
||||
MakeOpcode1( MOV_S, CopDefault );
|
||||
MakeOpcode1( NEG_S, CopDefault );
|
||||
MakeOpcode1( MAX_S, CopDefault );
|
||||
MakeOpcode1( MIN_S, CopDefault );
|
||||
MakeOpcode1( ABS_S, CopDefault, 0 );
|
||||
MakeOpcode1( MOV_S, CopDefault, 0 );
|
||||
MakeOpcode1( NEG_S, CopDefault, 0 );
|
||||
MakeOpcode1( MAX_S, CopDefault, 0 );
|
||||
MakeOpcode1( MIN_S, CopDefault, 0 );
|
||||
|
||||
MakeOpcode1( MUL_S, FPU_Mult );
|
||||
MakeOpcode1( DIV_S, 6*8 );
|
||||
MakeOpcode1( SQRT_S, 6*8 );
|
||||
MakeOpcode1( RSQRT_S, 8*8 );
|
||||
MakeOpcode1( MULA_S, FPU_Mult );
|
||||
MakeOpcode1( MADD_S, FPU_Mult );
|
||||
MakeOpcode1( MSUB_S, FPU_Mult );
|
||||
MakeOpcode1( MADDA_S, FPU_Mult );
|
||||
MakeOpcode1( MSUBA_S, FPU_Mult );
|
||||
MakeOpcode1( MUL_S, FPU_Mult, 0 );
|
||||
MakeOpcode1( DIV_S, 6*8, 0 );
|
||||
MakeOpcode1( SQRT_S, 6*8, 0 );
|
||||
MakeOpcode1( RSQRT_S, 8*8, 0 );
|
||||
MakeOpcode1( MULA_S, FPU_Mult, 0 );
|
||||
MakeOpcode1( MADD_S, FPU_Mult, 0 );
|
||||
MakeOpcode1( MSUB_S, FPU_Mult, 0 );
|
||||
MakeOpcode1( MADDA_S, FPU_Mult, 0 );
|
||||
MakeOpcode1( MSUBA_S, FPU_Mult, 0 );
|
||||
|
||||
MakeOpcode1( C_F, CopDefault );
|
||||
MakeOpcode1( C_EQ, CopDefault );
|
||||
MakeOpcode1( C_LT, CopDefault );
|
||||
MakeOpcode1( C_LE, CopDefault );
|
||||
MakeOpcode1( C_F, CopDefault, 0 );
|
||||
MakeOpcode1( C_EQ, CopDefault, 0 );
|
||||
MakeOpcode1( C_LT, CopDefault, 0 );
|
||||
MakeOpcode1( C_LE, CopDefault, 0 );
|
||||
|
||||
MakeOpcode1( CVT_S, CopDefault );
|
||||
MakeOpcode1( CVT_W, CopDefault );
|
||||
MakeOpcode1( CVT_S, CopDefault, 0 );
|
||||
MakeOpcode1( CVT_W, CopDefault, 0 );
|
||||
}
|
||||
|
||||
namespace OpcodeTables
|
||||
|
|
|
@ -28,6 +28,49 @@ void COP2_SPECIAL();
|
|||
void COP2_SPECIAL2();
|
||||
void COP2_Unknown();
|
||||
|
||||
// reserve the lower 8 bits for opcode specific types
|
||||
// which of these are actually used depends on the opcode
|
||||
// flags further below
|
||||
#define MEMTYPE_MASK (0x07 << 0)
|
||||
#define MEMTYPE_BYTE (0x01 << 0)
|
||||
#define MEMTYPE_HALF (0x02 << 0)
|
||||
#define MEMTYPE_WORD (0x03 << 0)
|
||||
#define MEMTYPE_DWORD (0x04 << 0)
|
||||
#define MEMTYPE_QWORD (0x05 << 0)
|
||||
|
||||
#define CONDTYPE_MASK (0x07 << 0)
|
||||
#define CONDTYPE_EQ (0x01 << 0)
|
||||
#define CONDTYPE_NE (0x02 << 0)
|
||||
#define CONDTYPE_LEZ (0x03 << 0)
|
||||
#define CONDTYPE_GTZ (0x04 << 0)
|
||||
#define CONDTYPE_LTZ (0x05 << 0)
|
||||
#define CONDTYPE_GEZ (0x06 << 0)
|
||||
|
||||
#define BRANCHTYPE_MASK (0x07 << 3)
|
||||
#define BRANCHTYPE_JUMP (0x01 << 3)
|
||||
#define BRANCHTYPE_BRANCH (0x02 << 3)
|
||||
#define BRANCHTYPE_SYSCALL (0x03 << 3)
|
||||
#define BRANCHTYPE_ERET (0x04 << 3)
|
||||
#define BRANCHTYPE_REGISTER (0x05 << 3)
|
||||
#define BRANCHTYPE_BC1 (0x06 << 3)
|
||||
|
||||
#define ALUTYPE_MASK (0x07 << 3)
|
||||
#define ALUTYPE_ADD (0x01 << 3)
|
||||
#define ALUTYPE_ADDI (0x02 << 3)
|
||||
#define ALUTYPE_SUB (0x03 << 3)
|
||||
#define ALUTYPE_CONDMOVE (0x04 << 3)
|
||||
|
||||
#define IS_LOAD 0x00000100
|
||||
#define IS_STORE 0x00000200
|
||||
#define IS_BRANCH 0x00000400
|
||||
#define IS_LINKED 0x00001000
|
||||
#define IS_LIKELY 0x00002000
|
||||
#define IS_MEMORY 0x00004000
|
||||
#define IS_CONDMOVE 0x00010000
|
||||
#define IS_ALU 0x00020000
|
||||
#define IS_64BIT 0x00040000
|
||||
#define IS_LEFT 0x00080000
|
||||
#define IS_RIGHT 0x00100000
|
||||
|
||||
namespace R5900
|
||||
{
|
||||
|
@ -79,6 +122,9 @@ namespace R5900
|
|||
// Number of cycles this instruction normally uses.
|
||||
u8 cycles;
|
||||
|
||||
// Information about the opcode
|
||||
u32 flags;
|
||||
|
||||
const OPCODE& (*getsubclass)(u32 op);
|
||||
|
||||
// Process the instruction using the interpreter.
|
||||
|
|
|
@ -1359,45 +1359,9 @@ void recMemcheck(u32 op, u32 bits, bool store)
|
|||
inline bool isBranchOrJump(u32 addr)
|
||||
{
|
||||
u32 op = memRead32(addr);
|
||||
const OPCODE& opcode = GetInstruction(op);
|
||||
|
||||
switch (op >> 26)
|
||||
{
|
||||
case 0x02: // j
|
||||
case 0x03: // jal
|
||||
case 0x04: // beq
|
||||
case 0x05: // bne
|
||||
case 0x06: // blez
|
||||
case 0x07: // bgtz
|
||||
case 0x14: // beql
|
||||
case 0x15: // bnel
|
||||
case 0x16: // blezl
|
||||
case 0x17: // bgtzl
|
||||
return true;
|
||||
case 0x00: // special
|
||||
switch (op & 0x3F)
|
||||
{
|
||||
case 0x08: // jr
|
||||
case 0x09: // jalr
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case 0x01: // regimm
|
||||
switch ((op >> 16) & 0x1F)
|
||||
{
|
||||
case 0x00: // bltz
|
||||
case 0x01: // bgez
|
||||
case 0x02: // bltzl
|
||||
case 0x03: // bgezl
|
||||
case 0x10: // bltzal
|
||||
case 0x11: // bgezal
|
||||
case 0x12: // bltzall
|
||||
case 0x13: // bgezall
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
return (opcode.flags & IS_BRANCH) != 0;
|
||||
}
|
||||
|
||||
// The next two functions return 0 if no breakpoint is needed,
|
||||
|
@ -1419,39 +1383,18 @@ int isMemcheckNeeded(u32 pc)
|
|||
{
|
||||
if (CBreakPoints::GetMemChecks().size() == 0)
|
||||
return 0;
|
||||
|
||||
|
||||
u32 addr = pc;
|
||||
if (isBranchOrJump(addr))
|
||||
addr += 4;
|
||||
|
||||
u32 op = memRead32(addr);
|
||||
const OPCODE& opcode = GetInstruction(op);
|
||||
|
||||
switch (op >> 26)
|
||||
{
|
||||
case 0x20: // lb
|
||||
case 0x21: // lh
|
||||
case 0x22: // lwl
|
||||
case 0x23: // lw
|
||||
case 0x24: // lbu
|
||||
case 0x25: // lhu
|
||||
case 0x26: // lwr
|
||||
case 0x28: // sb
|
||||
case 0x29: // sh
|
||||
case 0x2A: // swl
|
||||
case 0x2B: // sw
|
||||
case 0x2E: // swr
|
||||
case 0x37: // ld
|
||||
case 0x1B: // ldr
|
||||
case 0x3F: // sd
|
||||
case 0x3D: // sdr
|
||||
case 0x1A: // ldl
|
||||
case 0x2C: // sdl
|
||||
case 0x1E: // lq
|
||||
case 0x1F: // sq
|
||||
if ((opcode.flags & IS_MEMORY) && (opcode.flags & MEMTYPE_MASK) != 0)
|
||||
return addr == pc ? 1 : 2;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void encodeBreakpoint()
|
||||
|
@ -1470,50 +1413,27 @@ void encodeMemcheck()
|
|||
return;
|
||||
|
||||
u32 op = memRead32(needed == 2 ? pc+4 : pc);
|
||||
switch (cpuRegs.code >> 26)
|
||||
const OPCODE& opcode = GetInstruction(op);
|
||||
|
||||
bool store = (opcode.flags & IS_STORE) != 0;
|
||||
switch (opcode.flags & MEMTYPE_MASK)
|
||||
{
|
||||
case 0x20: // lb
|
||||
case 0x24: // lbu
|
||||
recMemcheck(op,8,false);
|
||||
case MEMTYPE_BYTE:
|
||||
recMemcheck(op,8,store);
|
||||
break;
|
||||
case 0x28: // sb
|
||||
recMemcheck(op,8,true);
|
||||
case MEMTYPE_HALF:
|
||||
recMemcheck(op,16,store);
|
||||
break;
|
||||
case 0x21: // lh
|
||||
case 0x25: // lhu
|
||||
recMemcheck(op,16,false);
|
||||
case MEMTYPE_WORD:
|
||||
recMemcheck(op,32,store);
|
||||
break;
|
||||
case 0x22: // lwl
|
||||
case 0x23: // lw
|
||||
case 0x26: // lwr
|
||||
recMemcheck(op,32,false);
|
||||
case MEMTYPE_DWORD:
|
||||
recMemcheck(op,64,store);
|
||||
break;
|
||||
case 0x29: // sh
|
||||
recMemcheck(op,16,true);
|
||||
break;
|
||||
case 0x2A: // swl
|
||||
case 0x2B: // sw
|
||||
case 0x2E: // swr
|
||||
recMemcheck(op,32,true);
|
||||
break;
|
||||
case 0x37: // ld
|
||||
case 0x1B: // ldr
|
||||
case 0x1A: // ldl
|
||||
recMemcheck(op,64,false);
|
||||
break;
|
||||
case 0x3F: // sd
|
||||
case 0x3D: // sdr
|
||||
case 0x2C: // sdl
|
||||
recMemcheck(op,64,true);
|
||||
break;
|
||||
case 0x1E: // lq
|
||||
recMemcheck(op,128,false);
|
||||
break;
|
||||
case 0x1F: // sq
|
||||
recMemcheck(op,128,true);
|
||||
case MEMTYPE_QWORD:
|
||||
recMemcheck(op,128,store);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void recompileNextInstruction(int delayslot)
|
||||
|
|
Loading…
Reference in New Issue