RSP: Move IsBranch into RSPInstruction
This commit is contained in:
parent
0c0a46c1e0
commit
1a83c9b120
|
@ -7,6 +7,7 @@
|
|||
#include <Project64-rsp-core/cpu/RSPCpu.h>
|
||||
#include <Project64-rsp-core/cpu/RSPInstruction.h>
|
||||
#include <Project64-rsp-core/cpu/RSPOpcode.h>
|
||||
#include <Project64-rsp-core/cpu/RspLog.h>
|
||||
#include <Project64-rsp-core/cpu/RspMemory.h>
|
||||
#include <Project64-rsp-core/cpu/RspTypes.h>
|
||||
|
||||
|
@ -244,107 +245,6 @@ bool IsRegisterConstant(uint32_t Reg, uint32_t * Constant)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
IsOpcodeBranch
|
||||
Output:
|
||||
True: Opcode is a branch
|
||||
False: Opcode is not a branch
|
||||
Input: PC
|
||||
*/
|
||||
|
||||
bool IsOpcodeBranch(uint32_t PC, RSPOpcode RspOp)
|
||||
{
|
||||
PC = PC; // Unused
|
||||
|
||||
switch (RspOp.op)
|
||||
{
|
||||
case RSP_REGIMM:
|
||||
switch (RspOp.rt)
|
||||
{
|
||||
case RSP_REGIMM_BLTZ:
|
||||
case RSP_REGIMM_BGEZ:
|
||||
case RSP_REGIMM_BLTZAL:
|
||||
case RSP_REGIMM_BGEZAL:
|
||||
return true;
|
||||
default:
|
||||
//CompilerWarning(stdstr_f(stdstr_f("Unknown opcode in IsOpcodeBranch\n%s",RSPOpcodeName(RspOp.Hex,PC)).c_str());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case RSP_SPECIAL:
|
||||
switch (RspOp.funct)
|
||||
{
|
||||
case RSP_SPECIAL_SLL:
|
||||
case RSP_SPECIAL_SRL:
|
||||
case RSP_SPECIAL_SRA:
|
||||
case RSP_SPECIAL_SLLV:
|
||||
case RSP_SPECIAL_SRLV:
|
||||
case RSP_SPECIAL_SRAV:
|
||||
case RSP_SPECIAL_ADD:
|
||||
case RSP_SPECIAL_ADDU:
|
||||
case RSP_SPECIAL_SUB:
|
||||
case RSP_SPECIAL_SUBU:
|
||||
case RSP_SPECIAL_AND:
|
||||
case RSP_SPECIAL_OR:
|
||||
case RSP_SPECIAL_XOR:
|
||||
case RSP_SPECIAL_NOR:
|
||||
case RSP_SPECIAL_SLT:
|
||||
case RSP_SPECIAL_SLTU:
|
||||
case RSP_SPECIAL_BREAK:
|
||||
break;
|
||||
|
||||
case RSP_SPECIAL_JALR:
|
||||
case RSP_SPECIAL_JR:
|
||||
return true;
|
||||
|
||||
default:
|
||||
//CompilerWarning(stdstr_f("Unknown opcode in IsOpcodeBranch\n%s",RSPOpcodeName(RspOp.Hex,PC)).c_str());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case RSP_J:
|
||||
case RSP_JAL:
|
||||
case RSP_BEQ:
|
||||
case RSP_BNE:
|
||||
case RSP_BLEZ:
|
||||
case RSP_BGTZ:
|
||||
return true;
|
||||
|
||||
case RSP_ADDI:
|
||||
case RSP_ADDIU:
|
||||
case RSP_SLTI:
|
||||
case RSP_SLTIU:
|
||||
case RSP_ANDI:
|
||||
case RSP_ORI:
|
||||
case RSP_XORI:
|
||||
case RSP_LUI:
|
||||
|
||||
case RSP_CP0:
|
||||
case RSP_CP2:
|
||||
break;
|
||||
|
||||
case RSP_LB:
|
||||
case RSP_LH:
|
||||
case RSP_LW:
|
||||
case RSP_LBU:
|
||||
case RSP_LHU:
|
||||
case RSP_SB:
|
||||
case RSP_SH:
|
||||
case RSP_SW:
|
||||
break;
|
||||
|
||||
case RSP_LC2:
|
||||
case RSP_SC2:
|
||||
break;
|
||||
|
||||
default:
|
||||
//CompilerWarning(stdstr_f("Unknown opcode in IsOpcodeBranch\n%s",RSPOpcodeName(RspOp.Hex,PC)).c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
GetInstructionInfo
|
||||
Output: None in regard to return value
|
||||
|
@ -396,30 +296,30 @@ typedef struct
|
|||
|
||||
#pragma warning(pop)
|
||||
|
||||
void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info)
|
||||
void GetInstructionInfo(uint32_t PC, const RSPOpcode & RspOp, OPCODE_INFO * info)
|
||||
{
|
||||
switch (RspOp->op)
|
||||
switch (RspOp.op)
|
||||
{
|
||||
case RSP_REGIMM:
|
||||
switch (RspOp->rt)
|
||||
switch (RspOp.rt)
|
||||
{
|
||||
case RSP_REGIMM_BLTZ:
|
||||
case RSP_REGIMM_BLTZAL:
|
||||
case RSP_REGIMM_BGEZ:
|
||||
case RSP_REGIMM_BGEZAL:
|
||||
info->flags = InvalidOpcode;
|
||||
info->SourceReg0 = RspOp->rs;
|
||||
info->SourceReg0 = RspOp.rs;
|
||||
info->SourceReg1 = UNUSED_OPERAND;
|
||||
break;
|
||||
|
||||
default:
|
||||
CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s", RSPInstruction(PC, RspOp->Value).NameAndParam().c_str()).c_str());
|
||||
CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str());
|
||||
info->flags = InvalidOpcode;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case RSP_SPECIAL:
|
||||
switch (RspOp->funct)
|
||||
switch (RspOp.funct)
|
||||
{
|
||||
case RSP_SPECIAL_BREAK:
|
||||
info->DestReg = UNUSED_OPERAND;
|
||||
|
@ -431,8 +331,8 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info)
|
|||
case RSP_SPECIAL_SLL:
|
||||
case RSP_SPECIAL_SRL:
|
||||
case RSP_SPECIAL_SRA:
|
||||
info->DestReg = RspOp->rd;
|
||||
info->SourceReg0 = RspOp->rt;
|
||||
info->DestReg = RspOp.rd;
|
||||
info->SourceReg0 = RspOp.rt;
|
||||
info->SourceReg1 = UNUSED_OPERAND;
|
||||
info->flags = GPR_Instruction;
|
||||
break;
|
||||
|
@ -449,9 +349,9 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info)
|
|||
case RSP_SPECIAL_NOR:
|
||||
case RSP_SPECIAL_SLT:
|
||||
case RSP_SPECIAL_SLTU:
|
||||
info->DestReg = RspOp->rd;
|
||||
info->SourceReg0 = RspOp->rs;
|
||||
info->SourceReg1 = RspOp->rt;
|
||||
info->DestReg = RspOp.rd;
|
||||
info->SourceReg0 = RspOp.rs;
|
||||
info->SourceReg1 = RspOp.rt;
|
||||
info->flags = GPR_Instruction;
|
||||
break;
|
||||
|
||||
|
@ -462,7 +362,7 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info)
|
|||
break;
|
||||
|
||||
default:
|
||||
CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s", RSPInstruction(PC, RspOp->Value).NameAndParam().c_str()).c_str());
|
||||
CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str());
|
||||
info->flags = InvalidOpcode;
|
||||
break;
|
||||
}
|
||||
|
@ -476,13 +376,13 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info)
|
|||
case RSP_BEQ:
|
||||
case RSP_BNE:
|
||||
info->flags = InvalidOpcode;
|
||||
info->SourceReg0 = RspOp->rt;
|
||||
info->SourceReg1 = RspOp->rs;
|
||||
info->SourceReg0 = RspOp.rt;
|
||||
info->SourceReg1 = RspOp.rs;
|
||||
break;
|
||||
case RSP_BLEZ:
|
||||
case RSP_BGTZ:
|
||||
info->flags = InvalidOpcode;
|
||||
info->SourceReg0 = RspOp->rs;
|
||||
info->SourceReg0 = RspOp.rs;
|
||||
info->SourceReg1 = UNUSED_OPERAND;
|
||||
break;
|
||||
|
||||
|
@ -493,27 +393,27 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info)
|
|||
case RSP_ANDI:
|
||||
case RSP_ORI:
|
||||
case RSP_XORI:
|
||||
info->DestReg = RspOp->rt;
|
||||
info->SourceReg0 = RspOp->rs;
|
||||
info->DestReg = RspOp.rt;
|
||||
info->SourceReg0 = RspOp.rs;
|
||||
info->SourceReg1 = UNUSED_OPERAND;
|
||||
info->flags = GPR_Instruction;
|
||||
break;
|
||||
|
||||
case RSP_LUI:
|
||||
info->DestReg = RspOp->rt;
|
||||
info->DestReg = RspOp.rt;
|
||||
info->SourceReg0 = UNUSED_OPERAND;
|
||||
info->SourceReg1 = UNUSED_OPERAND;
|
||||
info->flags = GPR_Instruction;
|
||||
break;
|
||||
|
||||
case RSP_CP0:
|
||||
switch (RspOp->rs)
|
||||
switch (RspOp.rs)
|
||||
{
|
||||
case RSP_COP0_MF:
|
||||
info->DestReg = RspOp->rt;
|
||||
info->DestReg = RspOp.rt;
|
||||
info->SourceReg0 = UNUSED_OPERAND;
|
||||
info->SourceReg1 = UNUSED_OPERAND;
|
||||
if (RspOp->rd == 0x4 || RspOp->rd == 0x7)
|
||||
if (RspOp.rd == 0x4 || RspOp.rd == 0x7)
|
||||
{
|
||||
info->flags = InvalidOpcode | COPO_MF_Instruction;
|
||||
}
|
||||
|
@ -524,7 +424,7 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info)
|
|||
break;
|
||||
|
||||
case RSP_COP0_MT:
|
||||
info->StoredReg = RspOp->rt;
|
||||
info->StoredReg = RspOp.rt;
|
||||
info->SourceReg0 = UNUSED_OPERAND;
|
||||
info->SourceReg1 = UNUSED_OPERAND;
|
||||
info->flags = GPR_Instruction | Store_Operation;
|
||||
|
@ -533,9 +433,9 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info)
|
|||
break;
|
||||
|
||||
case RSP_CP2:
|
||||
if ((RspOp->rs & 0x10) != 0)
|
||||
if ((RspOp.rs & 0x10) != 0)
|
||||
{
|
||||
switch (RspOp->funct)
|
||||
switch (RspOp.funct)
|
||||
{
|
||||
case RSP_VECTOR_VNOP:
|
||||
info->DestReg = UNUSED_OPERAND;
|
||||
|
@ -557,9 +457,9 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info)
|
|||
case RSP_VECTOR_VNAND:
|
||||
case RSP_VECTOR_VNOR:
|
||||
case RSP_VECTOR_VNXOR:
|
||||
info->DestReg = RspOp->sa;
|
||||
info->SourceReg0 = RspOp->rd;
|
||||
info->SourceReg1 = RspOp->rt;
|
||||
info->DestReg = RspOp.sa;
|
||||
info->SourceReg0 = RspOp.rd;
|
||||
info->SourceReg1 = RspOp.rt;
|
||||
info->flags = VEC_Instruction | VEC_ResetAccum | Accum_Operation;
|
||||
break;
|
||||
case RSP_VECTOR_VMACF:
|
||||
|
@ -568,9 +468,9 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info)
|
|||
case RSP_VECTOR_VMADM:
|
||||
case RSP_VECTOR_VMADN:
|
||||
case RSP_VECTOR_VMADH:
|
||||
info->DestReg = RspOp->sa;
|
||||
info->SourceReg0 = RspOp->rd;
|
||||
info->SourceReg1 = RspOp->rt;
|
||||
info->DestReg = RspOp.sa;
|
||||
info->SourceReg0 = RspOp.rd;
|
||||
info->SourceReg1 = RspOp.rt;
|
||||
info->flags = VEC_Instruction | VEC_Accumulate | Accum_Operation;
|
||||
break;
|
||||
case RSP_VECTOR_VADD:
|
||||
|
@ -584,9 +484,9 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info)
|
|||
case RSP_VECTOR_VEQ:
|
||||
case RSP_VECTOR_VGE:
|
||||
case RSP_VECTOR_VNE:
|
||||
info->DestReg = RspOp->sa;
|
||||
info->SourceReg0 = RspOp->rd;
|
||||
info->SourceReg1 = RspOp->rt;
|
||||
info->DestReg = RspOp.sa;
|
||||
info->SourceReg0 = RspOp.rd;
|
||||
info->SourceReg1 = RspOp.rt;
|
||||
info->flags = VEC_Instruction | VEC_ResetAccum | Accum_Operation | Flag_Instruction;
|
||||
break;
|
||||
|
||||
|
@ -596,45 +496,45 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info)
|
|||
case RSP_VECTOR_VRCPH:
|
||||
case RSP_VECTOR_VRSQL:
|
||||
case RSP_VECTOR_VRSQH:
|
||||
info->DestReg = RspOp->sa;
|
||||
info->SourceReg0 = RspOp->rt;
|
||||
info->DestReg = RspOp.sa;
|
||||
info->SourceReg0 = RspOp.rt;
|
||||
info->SourceReg1 = UNUSED_OPERAND;
|
||||
info->flags = VEC_Instruction | VEC_ResetAccum | Accum_Operation; // Assume reset?
|
||||
break;
|
||||
|
||||
case RSP_VECTOR_VMRG:
|
||||
info->DestReg = RspOp->sa;
|
||||
info->SourceReg0 = RspOp->rt;
|
||||
info->SourceReg1 = RspOp->rd;
|
||||
info->DestReg = RspOp.sa;
|
||||
info->SourceReg0 = RspOp.rt;
|
||||
info->SourceReg1 = RspOp.rd;
|
||||
info->flags = VEC_Instruction | VEC_ResetAccum | Accum_Operation | Flag_Instruction; // Assume reset?
|
||||
break;
|
||||
|
||||
case RSP_VECTOR_VSAW:
|
||||
// info->flags = InvalidOpcode;
|
||||
info->DestReg = RspOp->sa;
|
||||
info->DestReg = RspOp.sa;
|
||||
info->SourceReg0 = UNUSED_OPERAND;
|
||||
info->SourceReg1 = UNUSED_OPERAND;
|
||||
info->flags = VEC_Instruction | Accum_Operation | VEC_Accumulate;
|
||||
break;
|
||||
|
||||
default:
|
||||
CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s", RSPInstruction(PC, RspOp->Value).NameAndParam().c_str()).c_str());
|
||||
CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str());
|
||||
info->flags = InvalidOpcode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (RspOp->rs)
|
||||
switch (RspOp.rs)
|
||||
{
|
||||
case RSP_COP2_CT:
|
||||
info->StoredReg = RspOp->rt;
|
||||
info->StoredReg = RspOp.rt;
|
||||
info->SourceReg0 = UNUSED_OPERAND;
|
||||
info->SourceReg1 = UNUSED_OPERAND;
|
||||
info->flags = GPR_Instruction | Store_Operation | Flag_Instruction;
|
||||
break;
|
||||
case RSP_COP2_CF:
|
||||
info->DestReg = RspOp->rt;
|
||||
info->DestReg = RspOp.rt;
|
||||
info->SourceReg0 = UNUSED_OPERAND;
|
||||
info->SourceReg1 = UNUSED_OPERAND;
|
||||
info->flags = GPR_Instruction | Load_Operation | Flag_Instruction;
|
||||
|
@ -642,19 +542,19 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info)
|
|||
|
||||
// RD is always the vector register, RT is always GPR
|
||||
case RSP_COP2_MT:
|
||||
info->DestReg = RspOp->rd;
|
||||
info->SourceReg0 = RspOp->rt;
|
||||
info->DestReg = RspOp.rd;
|
||||
info->SourceReg0 = RspOp.rt;
|
||||
info->SourceReg1 = UNUSED_OPERAND;
|
||||
info->flags = VEC_Instruction | GPR_Instruction | Load_Operation;
|
||||
break;
|
||||
case RSP_COP2_MF:
|
||||
info->DestReg = RspOp->rt;
|
||||
info->SourceReg0 = RspOp->rd;
|
||||
info->DestReg = RspOp.rt;
|
||||
info->SourceReg0 = RspOp.rd;
|
||||
info->SourceReg1 = UNUSED_OPERAND;
|
||||
info->flags = VEC_Instruction | GPR_Instruction | Store_Operation;
|
||||
break;
|
||||
default:
|
||||
CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s", RSPInstruction(PC, RspOp->Value).NameAndParam().c_str()).c_str());
|
||||
CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str());
|
||||
info->flags = InvalidOpcode;
|
||||
break;
|
||||
}
|
||||
|
@ -665,21 +565,21 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info)
|
|||
case RSP_LW:
|
||||
case RSP_LBU:
|
||||
case RSP_LHU:
|
||||
info->DestReg = RspOp->rt;
|
||||
info->IndexReg = RspOp->base;
|
||||
info->DestReg = RspOp.rt;
|
||||
info->IndexReg = RspOp.base;
|
||||
info->SourceReg1 = UNUSED_OPERAND;
|
||||
info->flags = Load_Operation | GPR_Instruction;
|
||||
break;
|
||||
case RSP_SB:
|
||||
case RSP_SH:
|
||||
case RSP_SW:
|
||||
info->StoredReg = RspOp->rt;
|
||||
info->IndexReg = RspOp->base;
|
||||
info->StoredReg = RspOp.rt;
|
||||
info->IndexReg = RspOp.base;
|
||||
info->SourceReg1 = UNUSED_OPERAND;
|
||||
info->flags = Store_Operation | GPR_Instruction;
|
||||
break;
|
||||
case RSP_LC2:
|
||||
switch (RspOp->rd)
|
||||
switch (RspOp.rd)
|
||||
{
|
||||
case RSP_LSC2_BV:
|
||||
case RSP_LSC2_SV:
|
||||
|
@ -689,8 +589,8 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info)
|
|||
case RSP_LSC2_LV:
|
||||
case RSP_LSC2_UV:
|
||||
case RSP_LSC2_PV:
|
||||
info->DestReg = RspOp->rt;
|
||||
info->IndexReg = RspOp->base;
|
||||
info->DestReg = RspOp.rt;
|
||||
info->IndexReg = RspOp.base;
|
||||
info->SourceReg1 = UNUSED_OPERAND;
|
||||
info->flags = Load_Operation | VEC_Instruction;
|
||||
break;
|
||||
|
@ -699,13 +599,13 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info)
|
|||
info->flags = InvalidOpcode;
|
||||
break;
|
||||
default:
|
||||
CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s", RSPInstruction(PC, RspOp->Value).NameAndParam().c_str()).c_str());
|
||||
CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str());
|
||||
info->flags = InvalidOpcode;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case RSP_SC2:
|
||||
switch (RspOp->rd)
|
||||
switch (RspOp.rd)
|
||||
{
|
||||
case RSP_LSC2_BV:
|
||||
case RSP_LSC2_SV:
|
||||
|
@ -718,8 +618,8 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info)
|
|||
case RSP_LSC2_HV:
|
||||
case RSP_LSC2_FV:
|
||||
case RSP_LSC2_WV:
|
||||
info->DestReg = RspOp->rt;
|
||||
info->IndexReg = RspOp->base;
|
||||
info->DestReg = RspOp.rt;
|
||||
info->IndexReg = RspOp.base;
|
||||
info->SourceReg1 = UNUSED_OPERAND;
|
||||
info->flags = Store_Operation | VEC_Instruction;
|
||||
break;
|
||||
|
@ -727,13 +627,13 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info)
|
|||
info->flags = InvalidOpcode;
|
||||
break;
|
||||
default:
|
||||
CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s", RSPInstruction(PC, RspOp->Value).NameAndParam().c_str()).c_str());
|
||||
CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str());
|
||||
info->flags = InvalidOpcode;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s",RSPOpcodeName(RspOp->Hex,PC)).c_str());
|
||||
/* CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s",RSPOpcodeName(RspOp.Hex,PC)).c_str());
|
||||
*/
|
||||
info->flags = InvalidOpcode;
|
||||
break;
|
||||
|
@ -764,8 +664,8 @@ bool DelaySlotAffectBranch(uint32_t PC)
|
|||
memset(&infoDelay, 0, sizeof(infoDelay));
|
||||
memset(&infoBranch, 0, sizeof(infoBranch));
|
||||
|
||||
GetInstructionInfo(PC, &BranchOp, &infoBranch);
|
||||
GetInstructionInfo(DelayPC, &DelayOp, &infoDelay);
|
||||
GetInstructionInfo(PC, BranchOp, &infoBranch);
|
||||
GetInstructionInfo(DelayPC, DelayOp, &infoDelay);
|
||||
|
||||
if ((infoDelay.flags & COPO_MF_Instruction) == COPO_MF_Instruction)
|
||||
{
|
||||
|
@ -798,17 +698,19 @@ Input: Top, not the current operation, the one above
|
|||
Bottom: The current opcode for re-ordering bubble style
|
||||
*/
|
||||
|
||||
bool CompareInstructions(uint32_t PC, RSPOpcode * Top, RSPOpcode * Bottom)
|
||||
bool CompareInstructions(uint32_t PC, const RSPInstruction & Top, RSPOpcode * Bottom)
|
||||
{
|
||||
OPCODE_INFO info0, info1;
|
||||
uint32_t InstructionType;
|
||||
|
||||
GetInstructionInfo(PC - 4, Top, &info0);
|
||||
GetInstructionInfo(PC, Bottom, &info1);
|
||||
RSPOpcode TopOpcode;
|
||||
TopOpcode.Value = Top.Value();
|
||||
GetInstructionInfo(PC - 4, TopOpcode, &info0);
|
||||
GetInstructionInfo(PC, *Bottom, &info1);
|
||||
|
||||
#ifdef COMPARE_INSTRUCTIONS_VERBOSE
|
||||
CPU_Message("Comparing %s (%X)", RSPOpcodeName(Top->Hex, PC - 4), PC - 4);
|
||||
CPU_Message("to %s (%X)", RSPOpcodeName(Bottom->Hex, PC), PC);
|
||||
CPU_Message("Comparing %s (%X)", Top.NameAndParam().c_str(), Top.Address());
|
||||
CPU_Message("to %s (%X)", RSPInstruction(PC, Bottom->Value).NameAndParam().c_str(), PC);
|
||||
#endif
|
||||
|
||||
// Usually branches and such
|
||||
|
|
|
@ -435,11 +435,10 @@ void CRSPRecompiler::ReOrderInstructions(uint32_t StartPC, uint32_t EndPC)
|
|||
{
|
||||
uint32_t InstructionCount = EndPC - StartPC;
|
||||
uint32_t Count, ReorderedOps, CurrentPC;
|
||||
RSPOpcode PreviousOp, CurrentOp, RspOp;
|
||||
RSPInstruction PreviousOp(StartPC, *(uint32_t *)(m_IMEM + (StartPC & 0xFFC)));
|
||||
RSPOpcode CurrentOp, RspOp;
|
||||
|
||||
PreviousOp.Value = *(uint32_t *)(m_IMEM + (StartPC & 0xFFC));
|
||||
|
||||
if (IsOpcodeBranch(StartPC, PreviousOp))
|
||||
if (PreviousOp.IsBranch())
|
||||
{
|
||||
// The sub block ends here anyway
|
||||
return;
|
||||
|
@ -472,7 +471,7 @@ void CRSPRecompiler::ReOrderInstructions(uint32_t StartPC, uint32_t EndPC)
|
|||
for (Count = 0; Count < InstructionCount; Count += 4)
|
||||
{
|
||||
CurrentPC = StartPC;
|
||||
PreviousOp.Value = *(uint32_t *)(m_IMEM + (CurrentPC & 0xFFC));
|
||||
PreviousOp = RSPInstruction(CurrentPC, *(uint32_t *)(m_IMEM + (CurrentPC & 0xFFC)));
|
||||
ReorderedOps = 0;
|
||||
|
||||
for (;;)
|
||||
|
@ -484,11 +483,11 @@ void CRSPRecompiler::ReOrderInstructions(uint32_t StartPC, uint32_t EndPC)
|
|||
}
|
||||
CurrentOp.Value = *(uint32_t *)(m_IMEM + CurrentPC);
|
||||
|
||||
if (CompareInstructions(CurrentPC, &PreviousOp, &CurrentOp))
|
||||
if (CompareInstructions(CurrentPC, PreviousOp, &CurrentOp))
|
||||
{
|
||||
// Move current opcode up
|
||||
*(uint32_t *)(m_IMEM + CurrentPC - 4) = CurrentOp.Value;
|
||||
*(uint32_t *)(m_IMEM + CurrentPC) = PreviousOp.Value;
|
||||
*(uint32_t *)(m_IMEM + CurrentPC) = PreviousOp.Value();
|
||||
|
||||
ReorderedOps++;
|
||||
|
||||
|
@ -496,7 +495,7 @@ void CRSPRecompiler::ReOrderInstructions(uint32_t StartPC, uint32_t EndPC)
|
|||
CPU_Message("Swapped %X and %X", CurrentPC - 4, CurrentPC);
|
||||
#endif
|
||||
}
|
||||
PreviousOp.Value = *(uint32_t *)(m_IMEM + (CurrentPC & 0xFFC));
|
||||
PreviousOp = RSPInstruction(CurrentPC, *(uint32_t *)(m_IMEM + (CurrentPC & 0xFFC)));
|
||||
|
||||
if (IsOpcodeNop(CurrentPC) && IsOpcodeNop(CurrentPC + 4) && IsOpcodeNop(CurrentPC + 8))
|
||||
{
|
||||
|
@ -734,7 +733,7 @@ void CRSPRecompiler::BuildBranchLabels(void)
|
|||
{
|
||||
RspOp.Value = *(uint32_t *)(RSPInfo.IMEM + i);
|
||||
|
||||
if (IsOpcodeBranch(i, RspOp))
|
||||
if (RSPInstruction(i, RspOp.Value).IsBranch())
|
||||
{
|
||||
if (RspCode.LabelCount >= (sizeof(RspCode.BranchLabels) / sizeof(RspCode.BranchLabels[0])) - 1)
|
||||
{
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
class CRSPSystem;
|
||||
class RSPRegisterHandlerPlugin;
|
||||
class RSPInstruction;
|
||||
|
||||
class CRSPRecompiler
|
||||
{
|
||||
|
@ -74,8 +75,7 @@ extern bool ChangedPC;
|
|||
#define EntireAccum (Low16BitAccum | Middle16BitAccum | High16BitAccum)
|
||||
|
||||
bool DelaySlotAffectBranch(uint32_t PC);
|
||||
bool CompareInstructions(uint32_t PC, RSPOpcode * Top, RSPOpcode * Bottom);
|
||||
bool IsOpcodeBranch(uint32_t PC, RSPOpcode RspOp);
|
||||
bool CompareInstructions(uint32_t PC, const RSPInstruction & Top, RSPOpcode * Bottom);
|
||||
bool IsOpcodeNop(uint32_t PC);
|
||||
|
||||
bool IsRegisterConstant(uint32_t Reg, uint32_t * Constant);
|
||||
|
|
|
@ -7,27 +7,30 @@ class RSPInstruction
|
|||
{
|
||||
public:
|
||||
RSPInstruction(uint32_t Address, uint32_t Instruction);
|
||||
RSPInstruction & operator=(const RSPInstruction &);
|
||||
|
||||
const char * Name();
|
||||
const char * Param();
|
||||
std::string NameAndParam();
|
||||
uint32_t Address() const;
|
||||
bool IsBranch() const;
|
||||
const char * Name() const;
|
||||
const char * Param() const;
|
||||
std::string NameAndParam() const;
|
||||
uint32_t Value() const;
|
||||
|
||||
private:
|
||||
RSPInstruction(void);
|
||||
RSPInstruction(const RSPInstruction &);
|
||||
RSPInstruction & operator=(const RSPInstruction &);
|
||||
|
||||
void DecodeName(void);
|
||||
void DecodeSpecialName(void);
|
||||
void DecodeRegImmName(void);
|
||||
void DecodeCop0Name(void);
|
||||
void DecodeCop2Name(void);
|
||||
void DecodeLSC2Name(const char LoadStoreIdent);
|
||||
void DecodeName(void) const;
|
||||
void DecodeSpecialName(void) const;
|
||||
void DecodeRegImmName(void) const;
|
||||
void DecodeCop0Name(void) const;
|
||||
void DecodeCop2Name(void) const;
|
||||
void DecodeLSC2Name(const char LoadStoreIdent) const;
|
||||
|
||||
static const char * ElementSpecifier(uint32_t Element);
|
||||
|
||||
uint32_t m_Address;
|
||||
RSPOpcode m_Instruction;
|
||||
char m_Name[40];
|
||||
char m_Param[200];
|
||||
mutable char m_Name[40];
|
||||
mutable char m_Param[200];
|
||||
};
|
|
@ -1,6 +1,7 @@
|
|||
#include "RSPInstruction.h"
|
||||
#include "RSPRegisters.h"
|
||||
#include <Common/StdString.h>
|
||||
#include <Settings/Settings.h>
|
||||
|
||||
RSPInstruction::RSPInstruction(uint32_t Address, uint32_t Instruction) :
|
||||
m_Address(Address)
|
||||
|
@ -10,7 +11,102 @@ RSPInstruction::RSPInstruction(uint32_t Address, uint32_t Instruction) :
|
|||
m_Instruction.Value = Instruction;
|
||||
}
|
||||
|
||||
const char * RSPInstruction::Name()
|
||||
RSPInstruction & RSPInstruction::operator=(const RSPInstruction & e)
|
||||
{
|
||||
m_Address = e.m_Address;
|
||||
m_Instruction.Value = e.m_Instruction.Value;
|
||||
memcpy(m_Name, e.m_Name, sizeof(m_Name));
|
||||
memcpy(m_Param, e.m_Param, sizeof(m_Param));
|
||||
return *this;
|
||||
}
|
||||
|
||||
uint32_t RSPInstruction::Address() const
|
||||
{
|
||||
return m_Address;
|
||||
}
|
||||
|
||||
bool RSPInstruction::IsBranch() const
|
||||
{
|
||||
switch (m_Instruction.op)
|
||||
{
|
||||
case RSP_REGIMM:
|
||||
switch (m_Instruction.rt)
|
||||
{
|
||||
case RSP_REGIMM_BLTZ:
|
||||
case RSP_REGIMM_BGEZ:
|
||||
case RSP_REGIMM_BLTZAL:
|
||||
case RSP_REGIMM_BGEZAL:
|
||||
return true;
|
||||
default:
|
||||
#ifdef _DEBUG
|
||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case RSP_SPECIAL:
|
||||
switch (m_Instruction.funct)
|
||||
{
|
||||
case RSP_SPECIAL_SLL:
|
||||
case RSP_SPECIAL_SRL:
|
||||
case RSP_SPECIAL_SRA:
|
||||
case RSP_SPECIAL_SLLV:
|
||||
case RSP_SPECIAL_SRLV:
|
||||
case RSP_SPECIAL_SRAV:
|
||||
case RSP_SPECIAL_ADD:
|
||||
case RSP_SPECIAL_ADDU:
|
||||
case RSP_SPECIAL_SUB:
|
||||
case RSP_SPECIAL_SUBU:
|
||||
case RSP_SPECIAL_AND:
|
||||
case RSP_SPECIAL_OR:
|
||||
case RSP_SPECIAL_XOR:
|
||||
case RSP_SPECIAL_NOR:
|
||||
case RSP_SPECIAL_SLT:
|
||||
case RSP_SPECIAL_SLTU:
|
||||
case RSP_SPECIAL_BREAK:
|
||||
break;
|
||||
case RSP_SPECIAL_JALR:
|
||||
case RSP_SPECIAL_JR:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case RSP_J:
|
||||
case RSP_JAL:
|
||||
case RSP_BEQ:
|
||||
case RSP_BNE:
|
||||
case RSP_BLEZ:
|
||||
case RSP_BGTZ:
|
||||
return true;
|
||||
case RSP_ADDI:
|
||||
case RSP_ADDIU:
|
||||
case RSP_SLTI:
|
||||
case RSP_SLTIU:
|
||||
case RSP_ANDI:
|
||||
case RSP_ORI:
|
||||
case RSP_XORI:
|
||||
case RSP_LUI:
|
||||
case RSP_CP0:
|
||||
case RSP_CP2:
|
||||
case RSP_LB:
|
||||
case RSP_LH:
|
||||
case RSP_LW:
|
||||
case RSP_LBU:
|
||||
case RSP_LHU:
|
||||
case RSP_SB:
|
||||
case RSP_SH:
|
||||
case RSP_SW:
|
||||
case RSP_LC2:
|
||||
case RSP_SC2:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const char * RSPInstruction::Name() const
|
||||
{
|
||||
if (m_Name[0] == '\0')
|
||||
{
|
||||
|
@ -19,7 +115,7 @@ const char * RSPInstruction::Name()
|
|||
return m_Name;
|
||||
}
|
||||
|
||||
const char * RSPInstruction::Param()
|
||||
const char * RSPInstruction::Param() const
|
||||
{
|
||||
if (m_Param[0] == '\0')
|
||||
{
|
||||
|
@ -28,12 +124,17 @@ const char * RSPInstruction::Param()
|
|||
return m_Param;
|
||||
}
|
||||
|
||||
std::string RSPInstruction::NameAndParam()
|
||||
std::string RSPInstruction::NameAndParam() const
|
||||
{
|
||||
return stdstr_f("%s %s", Name(), Param());
|
||||
}
|
||||
|
||||
void RSPInstruction::DecodeName(void)
|
||||
uint32_t RSPInstruction::Value() const
|
||||
{
|
||||
return m_Instruction.Value;
|
||||
}
|
||||
|
||||
void RSPInstruction::DecodeName(void) const
|
||||
{
|
||||
switch (m_Instruction.op)
|
||||
{
|
||||
|
@ -174,7 +275,7 @@ void RSPInstruction::DecodeName(void)
|
|||
}
|
||||
}
|
||||
|
||||
void RSPInstruction::DecodeSpecialName(void)
|
||||
void RSPInstruction::DecodeSpecialName(void) const
|
||||
{
|
||||
switch (m_Instruction.funct)
|
||||
{
|
||||
|
@ -266,7 +367,7 @@ void RSPInstruction::DecodeSpecialName(void)
|
|||
}
|
||||
}
|
||||
|
||||
void RSPInstruction::DecodeRegImmName(void)
|
||||
void RSPInstruction::DecodeRegImmName(void) const
|
||||
{
|
||||
switch (m_Instruction.rt)
|
||||
{
|
||||
|
@ -308,7 +409,7 @@ void RSPInstruction::DecodeRegImmName(void)
|
|||
}
|
||||
}
|
||||
|
||||
void RSPInstruction::DecodeCop0Name(void)
|
||||
void RSPInstruction::DecodeCop0Name(void) const
|
||||
{
|
||||
switch (m_Instruction.rs)
|
||||
{
|
||||
|
@ -326,7 +427,7 @@ void RSPInstruction::DecodeCop0Name(void)
|
|||
}
|
||||
}
|
||||
|
||||
void RSPInstruction::DecodeCop2Name(void)
|
||||
void RSPInstruction::DecodeCop2Name(void) const
|
||||
{
|
||||
if ((m_Instruction.rs & 0x10) == 0)
|
||||
{
|
||||
|
@ -620,7 +721,7 @@ void RSPInstruction::DecodeCop2Name(void)
|
|||
}
|
||||
}
|
||||
|
||||
void RSPInstruction::DecodeLSC2Name(const char LoadStoreIdent)
|
||||
void RSPInstruction::DecodeLSC2Name(const char LoadStoreIdent) const
|
||||
{
|
||||
switch (m_Instruction.rd)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue