Rerwrote GetOpcodeInfo and adapted MipsTables for it

This commit is contained in:
Kingcom 2013-07-30 11:29:30 +02:00
parent 32f1ca91fd
commit 723f242f0c
6 changed files with 153 additions and 142 deletions

View File

@ -532,36 +532,6 @@ namespace MIPSAnalyst
return vec;
}
void opInfoSetJump(MipsOpcodeInfo& inf, bool link, u32 target, int reg = -1)
{
inf.isBranch = true;
inf.isLinkedBranch = link;
inf.branchTarget = target;
if (reg != -1)
{
inf.isBranchToRegister = true;
inf.branchRegisterNum = reg;
}
}
inline void opInfoSetBranch(MipsOpcodeInfo& inf, u32 target, bool conditionMet)
{
inf.isBranch = true;
inf.isConditionalBranch = true;
inf.branchConditionMet = conditionMet;
inf.branchTarget = target;
}
inline void opInfoSetDataAccess(MipsOpcodeInfo& inf, int dataSize)
{
inf.isDataAccess = true;
inf.dataSize = dataSize;
s16 imm16 = inf.encodedOpcode & 0xFFFF;
inf.dataAddress = inf.cpu->GetRegValue(0,MIPS_GET_RS(inf.encodedOpcode)) + imm16;
}
MipsOpcodeInfo GetOpcodeInfo(DebugInterface* cpu, u32 address)
{
MipsOpcodeInfo info;
@ -570,91 +540,113 @@ namespace MIPSAnalyst
info.cpu = cpu;
info.opcodeAddress = address;
info.encodedOpcode = Memory::Read_Instruction(address);
u32 op = info.encodedOpcode;
// read everything that could be used
u32 rt = cpu->GetRegValue(0,MIPS_GET_RT(op));
u32 rd = cpu->GetRegValue(0,MIPS_GET_RD(op));
u32 rs = cpu->GetRegValue(0,MIPS_GET_RS(op));
int rsNum = MIPS_GET_RS(op);
int rtNum = MIPS_GET_RT(op);
u32 jumpTarget = GetJumpTarget(address);
u32 branchTarget = GetBranchTarget(address);
switch (MIPS_GET_OP(op))
u32 op = info.encodedOpcode;
u32 opInfo = MIPSGetInfo(op);
info.isLikelyBranch = (opInfo & LIKELY) != 0;
//j , jal, ...
if (opInfo & IS_JUMP)
{
case 0: // special
switch (MIPS_GET_FUNC(op))
info.isBranch = true;
if (opInfo & OUT_RA) // link
{
case 8: // jr
opInfoSetJump(info,false,rs,rsNum);
info.isLinkedBranch = true;
}
if (opInfo & IN_RS) // to register
{
info.isBranchToRegister = true;
info.branchRegisterNum = MIPS_GET_RS(op);
info.branchTarget = cpu->GetRegValue(0,info.branchRegisterNum);
} else { // to immediate
info.branchTarget = GetJumpTarget(address);
}
}
// movn, movz
if (opInfo & IS_CONDMOVE)
{
info.isConditional = true;
u32 rt = cpu->GetRegValue(0,MIPS_GET_RT(op));
switch (opInfo & CONDTYPE_MASK)
{
case CONDTYPE_EQ:
info.conditionMet = (rt == 0);
break;
case 9: // jalr
opInfoSetJump(info,true,rs,rsNum);
case CONDTYPE_NE:
info.conditionMet = (rt != 0);
break;
}
break;
case 1: // regimm
switch (rtNum)
}
// beq, bgtz, ...
if (opInfo & IS_CONDBRANCH)
{
info.isBranch = true;
info.isConditional = true;
info.branchTarget = GetBranchTarget(address);
if (opInfo & OUT_RA) // link
{
info.isLinkedBranch = true;
}
break;
case 2: // j
opInfoSetJump(info,false,jumpTarget);
break;
case 3: // jal
opInfoSetJump(info,true,jumpTarget);
break;
case 4: // beq
opInfoSetBranch(info,branchTarget,rt == rs);
if (rtNum == rsNum) // pretend to be unconditional when it de facto is
u32 rt = cpu->GetRegValue(0,MIPS_GET_RT(op));
u32 rs = cpu->GetRegValue(0,MIPS_GET_RS(op));
switch (opInfo & CONDTYPE_MASK)
{
info.isConditionalBranch = false;
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 true
{
info.isConditional = false;
}
break;
case CONDTYPE_LEZ:
info.conditionMet = (((s32)rs) <= 0);
break;
case CONDTYPE_GTZ:
info.conditionMet = (((s32)rs) > 0);
break;
case CONDTYPE_LTZ:
info.conditionMet = (((s32)rs) < 0);
break;
case CONDTYPE_GEZ:
info.conditionMet = (((s32)rs) >= 0);
break;
}
break;
case 20: // beql
opInfoSetBranch(info,branchTarget,rt == rs);
info.isLikelyBranch = true;
case 5: // bne
opInfoSetBranch(info,branchTarget,rt != rs);
break;
case 21: // bnel
opInfoSetBranch(info,branchTarget,rt != rs);
info.isLikelyBranch = true;
case 6: // blez
opInfoSetBranch(info,branchTarget,((s32)rs) <= 0);
break;
case 22: // blezl
opInfoSetBranch(info,branchTarget,((s32)rs) <= 0);
info.isLikelyBranch = true;
case 7: // bgtz
opInfoSetBranch(info,branchTarget,((s32)rs) > 0);
break;
case 23: // bgtzl
opInfoSetBranch(info,branchTarget,((s32)rs) > 0);
info.isLikelyBranch = true;
break;
}
case 32: // lb
case 36: // lb
case 40: // sb
opInfoSetDataAccess(info,1);
break;
case 33: // lh
case 37: // lh
case 41: // sh
opInfoSetDataAccess(info,2);
break;
case 34: // lwl
case 35: // lw
case 38: // lwr
case 42: // swl
case 43: // sw
case 46: // swr
opInfoSetDataAccess(info,4);
break;
// lw, sh, ...
if ((opInfo & IN_MEM) || (opInfo & OUT_MEM))
{
info.isDataAccess = true;
switch (opInfo & MEMTYPE_MASK)
{
case MEMTYPE_BYTE:
info.dataSize = 1;
break;
case MEMTYPE_HWORD:
info.dataSize = 2;
break;
case MEMTYPE_WORD:
info.dataSize = 4;
break;
}
u32 rs = cpu->GetRegValue(0,MIPS_GET_RS(op));
s16 imm16 = op & 0xFFFF;
info.dataAddress = rs + imm16;
}
return info;

View File

@ -71,14 +71,16 @@ namespace MIPSAnalyst
DebugInterface* cpu;
u32 opcodeAddress;
u32 encodedOpcode;
// shared between branches and conditional moves
bool isConditional;
bool conditionMet;
// branches
u32 branchTarget;
bool isBranch;
bool isLinkedBranch;
bool isLikelyBranch;
bool isConditionalBranch;
bool branchConditionMet;
bool isBranchToRegister;
int branchRegisterNum;

View File

@ -94,10 +94,10 @@ const MIPSInstruction tableImmediate[64] = //xxxxxx .....
ENCODING(RegI),
INSTR("j", &Jit::Comp_Jump, Dis_JumpType, Int_JumpType, IS_JUMP|IN_IMM26|DELAYSLOT),
INSTR("jal", &Jit::Comp_Jump, Dis_JumpType, Int_JumpType, IS_JUMP|IN_IMM26|OUT_RA|DELAYSLOT),
INSTR("beq", &Jit::Comp_RelBranch, Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_RS|IN_RT|DELAYSLOT),
INSTR("bne", &Jit::Comp_RelBranch, Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_RS|IN_RT|DELAYSLOT),
INSTR("blez", &Jit::Comp_RelBranch, Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_RS|DELAYSLOT),
INSTR("bgtz", &Jit::Comp_RelBranch, Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_RS|DELAYSLOT),
INSTR("beq", &Jit::Comp_RelBranch, Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_RS|IN_RT|DELAYSLOT|CONDTYPE_EQ),
INSTR("bne", &Jit::Comp_RelBranch, Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_RS|IN_RT|DELAYSLOT|CONDTYPE_NE),
INSTR("blez", &Jit::Comp_RelBranch, Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_RS|DELAYSLOT|CONDTYPE_LEZ),
INSTR("bgtz", &Jit::Comp_RelBranch, Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_RS|DELAYSLOT|CONDTYPE_GTZ),
//8
INSTR("addi", &Jit::Comp_IType, Dis_addi, Int_IType, IN_RS|IN_IMM16|OUT_RT),
INSTR("addiu", &Jit::Comp_IType, Dis_addi, Int_IType, IN_RS|IN_IMM16|OUT_RT),
@ -113,10 +113,10 @@ const MIPSInstruction tableImmediate[64] = //xxxxxx .....
ENCODING(Cop2), //cop2
INVALID, //copU
INSTR("beql", &Jit::Comp_RelBranch, Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_RS|IN_RT|DELAYSLOT|LIKELY), //L = likely
INSTR("bnel", &Jit::Comp_RelBranch, Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_RS|IN_RT|DELAYSLOT|LIKELY),
INSTR("blezl", &Jit::Comp_RelBranch, Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_RS|DELAYSLOT|LIKELY),
INSTR("bgtzl", &Jit::Comp_RelBranch, Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_RS|DELAYSLOT|LIKELY),
INSTR("beql", &Jit::Comp_RelBranch, Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_RS|IN_RT|DELAYSLOT|LIKELY|CONDTYPE_EQ), //L = likely
INSTR("bnel", &Jit::Comp_RelBranch, Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_RS|IN_RT|DELAYSLOT|LIKELY|CONDTYPE_NE),
INSTR("blezl", &Jit::Comp_RelBranch, Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_RS|DELAYSLOT|LIKELY|CONDTYPE_LEZ),
INSTR("bgtzl", &Jit::Comp_RelBranch, Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_RS|DELAYSLOT|LIKELY|CONDTYPE_GTZ),
//24
{VFPU0},
{VFPU1},
@ -127,22 +127,22 @@ const MIPSInstruction tableImmediate[64] = //xxxxxx .....
{-2},
{Spe3},//special3
//32
INSTR("lb", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT),
INSTR("lh", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT),
INSTR("lwl", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT),
INSTR("lw", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT),
INSTR("lbu", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT),
INSTR("lhu", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT),
INSTR("lwr", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT),
INSTR("lb", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_BYTE),
INSTR("lh", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_HWORD),
INSTR("lwl", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_WORD),
INSTR("lw", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_WORD),
INSTR("lbu", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_BYTE),
INSTR("lhu", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_HWORD),
INSTR("lwr", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_WORD),
{-2},
//40
INSTR("sb", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM),
INSTR("sh", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM),
INSTR("swl", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM),
INSTR("sw", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM),
INSTR("sb", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_BYTE),
INSTR("sh", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_HWORD),
INSTR("swl", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_WORD),
INSTR("sw", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_WORD),
{-2},
{-2},
INSTR("swr", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM),
INSTR("swr", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_WORD),
INSTR("cache", &Jit::Comp_Generic, Dis_Generic, Int_Cache, 0),
//48
INSTR("ll", &Jit::Comp_Generic, Dis_Generic, Int_StoreSync, 0),
@ -178,10 +178,10 @@ const MIPSInstruction tableSpecial[64] = /// 000000 ...... ...... .......... xxx
INSTR("srav", &Jit::Comp_ShiftType, Dis_VarShiftType, Int_ShiftType, OUT_RD|IN_RT|IN_RS_SHIFT),
//8
INSTR("jr", &Jit::Comp_JumpReg, Dis_JumpRegType, Int_JumpRegType, DELAYSLOT),
INSTR("jalr", &Jit::Comp_JumpReg, Dis_JumpRegType, Int_JumpRegType, DELAYSLOT),
INSTR("movz", &Jit::Comp_RType3, Dis_RType3, Int_RType3, OUT_RD|IN_RS|IN_RT),
INSTR("movn", &Jit::Comp_RType3, Dis_RType3, Int_RType3, OUT_RD|IN_RS|IN_RT),
INSTR("jr", &Jit::Comp_JumpReg, Dis_JumpRegType, Int_JumpRegType, IS_JUMP|IN_RS|DELAYSLOT),
INSTR("jalr", &Jit::Comp_JumpReg, Dis_JumpRegType, Int_JumpRegType, IS_JUMP|IN_RS|OUT_RA|DELAYSLOT),
INSTR("movz", &Jit::Comp_RType3, Dis_RType3, Int_RType3, OUT_RD|IN_RS|IN_RT|IS_CONDMOVE|CONDTYPE_EQ),
INSTR("movn", &Jit::Comp_RType3, Dis_RType3, Int_RType3, OUT_RD|IN_RS|IN_RT|IS_CONDMOVE|CONDTYPE_NE),
INSTR("syscall", &Jit::Comp_Syscall, Dis_Syscall, Int_Syscall,0),
INSTR("break", &Jit::Comp_Break, Dis_Generic, Int_Break, 0),
{-2},
@ -327,10 +327,10 @@ const MIPSInstruction tableSpecial3[64] =
const MIPSInstruction tableRegImm[32] =
{
INSTR("bltz", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|DELAYSLOT),
INSTR("bgez", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|DELAYSLOT),
INSTR("bltzl", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|DELAYSLOT|LIKELY),
INSTR("bgezl", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|DELAYSLOT|LIKELY),
INSTR("bltz", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|DELAYSLOT|CONDTYPE_LTZ),
INSTR("bgez", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|DELAYSLOT|CONDTYPE_GEZ),
INSTR("bltzl", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|DELAYSLOT|LIKELY|CONDTYPE_LTZ),
INSTR("bgezl", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|DELAYSLOT|LIKELY|CONDTYPE_GEZ),
{-2},
{-2},
{-2},
@ -345,10 +345,10 @@ const MIPSInstruction tableRegImm[32] =
INSTR("tnei", &Jit::Comp_Generic, Dis_Generic, 0, 0),
{-2},
INSTR("bltzal", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|OUT_RA|DELAYSLOT),
INSTR("bgezal", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|OUT_RA|DELAYSLOT),
INSTR("bltzall", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|OUT_RA|DELAYSLOT|LIKELY), //L = likely
INSTR("bgezall", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|OUT_RA|DELAYSLOT|LIKELY),
INSTR("bltzal", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|OUT_RA|DELAYSLOT|CONDTYPE_LTZ),
INSTR("bgezal", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|OUT_RA|DELAYSLOT|CONDTYPE_GEZ),
INSTR("bltzall", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|OUT_RA|DELAYSLOT|LIKELY|CONDTYPE_LTZ), //L = likely
INSTR("bgezall", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|OUT_RA|DELAYSLOT|LIKELY|CONDTYPE_GEZ),
{-2},
{-2},
{-2},

View File

@ -19,6 +19,23 @@
#include "../../Globals.h"
#define CONDTYPE_MASK 0x00000007
#define CONDTYPE_EQ 0x00000001
#define CONDTYPE_NE 0x00000002
#define CONDTYPE_LEZ 0x00000003
#define CONDTYPE_GTZ 0x00000004
#define CONDTYPE_LTZ 0x00000005
#define CONDTYPE_GEZ 0x00000006
// as long as the other flags are checked,
// there is no way to misinterprete these
// as CONDTYPE_X
#define MEMTYPE_MASK 0x00000003
#define MEMTYPE_BYTE 0x00000001
#define MEMTYPE_HWORD 0x00000002
#define MEMTYPE_WORD 0x00000003
#define IS_CONDMOVE 0x00000008
#define DELAYSLOT 0x00000010
#define BAD_INSTRUCTION 0x00000020
#define UNCONDITIONAL 0x00000040

View File

@ -406,9 +406,9 @@ void CtrlDisAsmView::onPaint(WPARAM wParam, LPARAM lParam)
parseDisasm(dizz,opcode,arguments);
// display whether the condition of a branch is met
if (info.isConditionalBranch && address == debugger->getPC())
if (info.isConditional && address == debugger->getPC())
{
strcat(arguments,info.branchConditionMet ? " ; true" : " ; false");
strcat(arguments,info.conditionMet ? " ; true" : " ; false");
}
int length = (int) strlen(arguments);
@ -418,7 +418,7 @@ void CtrlDisAsmView::onPaint(WPARAM wParam, LPARAM lParam)
TextOut(hdc,pixelPositions.opcodeStart,rowY1+2,opcode,(int)strlen(opcode));
SelectObject(hdc,font);
if (info.isConditionalBranch)
if (info.isBranch && info.isConditional)
{
branches[numBranches].src=rowY1 + rowHeight/2;
branches[numBranches].srcAddr=address/instructionSize;

View File

@ -293,7 +293,7 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam)
u32 breakpointAddress = cpu->GetPC()+cpu->getInstructionSize(0);
if (info.isBranch)
{
if (info.isConditionalBranch == false)
if (info.isConditional == false)
{
if (info.isLinkedBranch) // jal, jalr
{