#if defined(__amd64__) || defined(_M_X64) #include "RspRecompilerCPU-x64.h" #include "RspCodeBlock.h" #include #include #include #include #include #include #include #include #include extern CLog * CPULog; p_Recompfunc RSP_Recomp_Opcode[64]; p_Recompfunc RSP_Recomp_RegImm[32]; p_Recompfunc RSP_Recomp_Special[64]; p_Recompfunc RSP_Recomp_Cop0[32]; p_Recompfunc RSP_Recomp_Cop2[32]; p_Recompfunc RSP_Recomp_Vector[64]; p_Recompfunc RSP_Recomp_Lc2[32]; p_Recompfunc RSP_Recomp_Sc2[32]; CRSPRecompiler::CRSPRecompiler(CRSPSystem & System) : m_System(System), m_RecompilerOps(System, *this), m_NextInstruction(RSPPIPELINE_NORMAL), m_BlockID(0), m_CompilePC(0), m_OpCode(System.m_OpCode), m_Assembler(nullptr) { m_Environment = asmjit::Environment::host(); BuildRecompilerCPU(); } CRSPRecompiler::~CRSPRecompiler() { if (m_Assembler != nullptr) { delete m_Assembler; m_Assembler = nullptr; } } void CRSPRecompiler::AddBranchJump(uint32_t Target) { BranchTargets::iterator it = m_BranchTargets.find(Target); if (it == m_BranchTargets.end()) { asmjit::Label Label = m_Assembler->newLabel(); m_BranchTargets[Target] = Label; m_Assembler->AddLabelSymbol(Label, stdstr_f("0x%X", Target).c_str()); } } bool CRSPRecompiler::FindBranchJump(uint32_t Target, asmjit::Label & Jump) { BranchTargets::iterator it = m_BranchTargets.find(Target); if (it != m_BranchTargets.end()) { Jump = m_BranchTargets[Target]; return true; } return false; } void CRSPRecompiler::BuildRecompilerCPU(void) { RSP_Recomp_Opcode[0] = &CRSPRecompilerOps::SPECIAL; RSP_Recomp_Opcode[1] = &CRSPRecompilerOps::REGIMM; RSP_Recomp_Opcode[2] = &CRSPRecompilerOps::J; RSP_Recomp_Opcode[3] = &CRSPRecompilerOps::JAL; RSP_Recomp_Opcode[4] = &CRSPRecompilerOps::BEQ; RSP_Recomp_Opcode[5] = &CRSPRecompilerOps::BNE; RSP_Recomp_Opcode[6] = &CRSPRecompilerOps::BLEZ; RSP_Recomp_Opcode[7] = &CRSPRecompilerOps::BGTZ; RSP_Recomp_Opcode[8] = &CRSPRecompilerOps::ADDI; RSP_Recomp_Opcode[9] = &CRSPRecompilerOps::ADDIU; RSP_Recomp_Opcode[10] = &CRSPRecompilerOps::SLTI; RSP_Recomp_Opcode[11] = &CRSPRecompilerOps::SLTIU; RSP_Recomp_Opcode[12] = &CRSPRecompilerOps::ANDI; RSP_Recomp_Opcode[13] = &CRSPRecompilerOps::ORI; RSP_Recomp_Opcode[14] = &CRSPRecompilerOps::XORI; RSP_Recomp_Opcode[15] = &CRSPRecompilerOps::LUI; RSP_Recomp_Opcode[16] = &CRSPRecompilerOps::COP0; RSP_Recomp_Opcode[17] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[18] = &CRSPRecompilerOps::COP2; RSP_Recomp_Opcode[19] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[20] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[21] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[22] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[23] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[24] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[25] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[26] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[27] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[28] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[29] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[30] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[31] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[32] = &CRSPRecompilerOps::LB; RSP_Recomp_Opcode[33] = &CRSPRecompilerOps::LH; RSP_Recomp_Opcode[34] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[35] = &CRSPRecompilerOps::LW; RSP_Recomp_Opcode[36] = &CRSPRecompilerOps::LBU; RSP_Recomp_Opcode[37] = &CRSPRecompilerOps::LHU; RSP_Recomp_Opcode[38] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[39] = &CRSPRecompilerOps::LWU; RSP_Recomp_Opcode[40] = &CRSPRecompilerOps::SB; RSP_Recomp_Opcode[41] = &CRSPRecompilerOps::SH; RSP_Recomp_Opcode[42] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[43] = &CRSPRecompilerOps::SW; RSP_Recomp_Opcode[44] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[45] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[46] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[47] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[48] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[49] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[50] = &CRSPRecompilerOps::LC2; RSP_Recomp_Opcode[51] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[52] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[53] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[54] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[55] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[56] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[57] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[58] = &CRSPRecompilerOps::SC2; RSP_Recomp_Opcode[59] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[60] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[61] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[62] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Opcode[63] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[0] = &CRSPRecompilerOps::Special_SLL; RSP_Recomp_Special[1] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[2] = &CRSPRecompilerOps::Special_SRL; RSP_Recomp_Special[3] = &CRSPRecompilerOps::Special_SRA; RSP_Recomp_Special[4] = &CRSPRecompilerOps::Special_SLLV; RSP_Recomp_Special[5] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[6] = &CRSPRecompilerOps::Special_SRLV; RSP_Recomp_Special[7] = &CRSPRecompilerOps::Special_SRAV; RSP_Recomp_Special[8] = &CRSPRecompilerOps::Special_JR; RSP_Recomp_Special[9] = &CRSPRecompilerOps::Special_JALR; RSP_Recomp_Special[10] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[11] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[12] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[13] = &CRSPRecompilerOps::Special_BREAK; RSP_Recomp_Special[14] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[15] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[16] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[17] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[18] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[19] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[20] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[21] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[22] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[23] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[24] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[25] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[26] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[27] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[28] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[29] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[30] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[31] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[32] = &CRSPRecompilerOps::Special_ADD; RSP_Recomp_Special[33] = &CRSPRecompilerOps::Special_ADDU; RSP_Recomp_Special[34] = &CRSPRecompilerOps::Special_SUB; RSP_Recomp_Special[35] = &CRSPRecompilerOps::Special_SUBU; RSP_Recomp_Special[36] = &CRSPRecompilerOps::Special_AND; RSP_Recomp_Special[37] = &CRSPRecompilerOps::Special_OR; RSP_Recomp_Special[38] = &CRSPRecompilerOps::Special_XOR; RSP_Recomp_Special[39] = &CRSPRecompilerOps::Special_NOR; RSP_Recomp_Special[40] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[41] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[42] = &CRSPRecompilerOps::Special_SLT; RSP_Recomp_Special[43] = &CRSPRecompilerOps::Special_SLTU; RSP_Recomp_Special[44] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[45] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[46] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[47] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[48] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[49] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[50] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[51] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[52] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[53] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[54] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[55] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[56] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[57] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[58] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[59] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[60] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[61] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[62] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Special[63] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[0] = &CRSPRecompilerOps::RegImm_BLTZ; RSP_Recomp_RegImm[1] = &CRSPRecompilerOps::RegImm_BGEZ; RSP_Recomp_RegImm[2] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[3] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[4] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[5] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[6] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[7] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[8] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[9] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[10] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[11] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[12] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[13] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[14] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[15] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[16] = &CRSPRecompilerOps::RegImm_BLTZAL; RSP_Recomp_RegImm[17] = &CRSPRecompilerOps::RegImm_BGEZAL; RSP_Recomp_RegImm[18] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[19] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[20] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[21] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[22] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[23] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[24] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[25] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[26] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[27] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[28] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[29] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[30] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_RegImm[31] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[0] = &CRSPRecompilerOps::Cop0_MF; RSP_Recomp_Cop0[1] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[2] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[3] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[4] = &CRSPRecompilerOps::Cop0_MT; RSP_Recomp_Cop0[5] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[6] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[7] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[8] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[9] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[10] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[11] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[12] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[13] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[14] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[15] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[16] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[17] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[18] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[19] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[20] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[21] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[22] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[23] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[24] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[25] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[26] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[27] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[28] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[29] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[30] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop0[31] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop2[0] = &CRSPRecompilerOps::Cop2_MF; RSP_Recomp_Cop2[1] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop2[2] = &CRSPRecompilerOps::Cop2_CF; RSP_Recomp_Cop2[3] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop2[4] = &CRSPRecompilerOps::Cop2_MT; RSP_Recomp_Cop2[5] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop2[6] = &CRSPRecompilerOps::Cop2_CT; RSP_Recomp_Cop2[7] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop2[8] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop2[9] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop2[10] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop2[11] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop2[12] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop2[13] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop2[14] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop2[15] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Cop2[16] = &CRSPRecompilerOps::COP2_VECTOR; RSP_Recomp_Cop2[17] = &CRSPRecompilerOps::COP2_VECTOR; RSP_Recomp_Cop2[18] = &CRSPRecompilerOps::COP2_VECTOR; RSP_Recomp_Cop2[19] = &CRSPRecompilerOps::COP2_VECTOR; RSP_Recomp_Cop2[20] = &CRSPRecompilerOps::COP2_VECTOR; RSP_Recomp_Cop2[21] = &CRSPRecompilerOps::COP2_VECTOR; RSP_Recomp_Cop2[22] = &CRSPRecompilerOps::COP2_VECTOR; RSP_Recomp_Cop2[23] = &CRSPRecompilerOps::COP2_VECTOR; RSP_Recomp_Cop2[24] = &CRSPRecompilerOps::COP2_VECTOR; RSP_Recomp_Cop2[25] = &CRSPRecompilerOps::COP2_VECTOR; RSP_Recomp_Cop2[26] = &CRSPRecompilerOps::COP2_VECTOR; RSP_Recomp_Cop2[27] = &CRSPRecompilerOps::COP2_VECTOR; RSP_Recomp_Cop2[28] = &CRSPRecompilerOps::COP2_VECTOR; RSP_Recomp_Cop2[29] = &CRSPRecompilerOps::COP2_VECTOR; RSP_Recomp_Cop2[30] = &CRSPRecompilerOps::COP2_VECTOR; RSP_Recomp_Cop2[31] = &CRSPRecompilerOps::COP2_VECTOR; RSP_Recomp_Vector[0] = &CRSPRecompilerOps::Vector_VMULF; RSP_Recomp_Vector[1] = &CRSPRecompilerOps::Vector_VMULU; RSP_Recomp_Vector[2] = &CRSPRecompilerOps::Vector_VRNDP; RSP_Recomp_Vector[3] = &CRSPRecompilerOps::Vector_VMULQ; RSP_Recomp_Vector[4] = &CRSPRecompilerOps::Vector_VMUDL; RSP_Recomp_Vector[5] = &CRSPRecompilerOps::Vector_VMUDM; RSP_Recomp_Vector[6] = &CRSPRecompilerOps::Vector_VMUDN; RSP_Recomp_Vector[7] = &CRSPRecompilerOps::Vector_VMUDH; RSP_Recomp_Vector[8] = &CRSPRecompilerOps::Vector_VMACF; RSP_Recomp_Vector[9] = &CRSPRecompilerOps::Vector_VMACU; RSP_Recomp_Vector[10] = &CRSPRecompilerOps::Vector_VRNDN; RSP_Recomp_Vector[11] = &CRSPRecompilerOps::Vector_VMACQ; RSP_Recomp_Vector[12] = &CRSPRecompilerOps::Vector_VMADL; RSP_Recomp_Vector[13] = &CRSPRecompilerOps::Vector_VMADM; RSP_Recomp_Vector[14] = &CRSPRecompilerOps::Vector_VMADN; RSP_Recomp_Vector[15] = &CRSPRecompilerOps::Vector_VMADH; RSP_Recomp_Vector[16] = &CRSPRecompilerOps::Vector_VADD; RSP_Recomp_Vector[17] = &CRSPRecompilerOps::Vector_VSUB; RSP_Recomp_Vector[18] = &CRSPRecompilerOps::Vector_Reserved; RSP_Recomp_Vector[19] = &CRSPRecompilerOps::Vector_VABS; RSP_Recomp_Vector[20] = &CRSPRecompilerOps::Vector_VADDC; RSP_Recomp_Vector[21] = &CRSPRecompilerOps::Vector_VSUBC; RSP_Recomp_Vector[22] = &CRSPRecompilerOps::Vector_Reserved; RSP_Recomp_Vector[23] = &CRSPRecompilerOps::Vector_Reserved; RSP_Recomp_Vector[24] = &CRSPRecompilerOps::Vector_Reserved; RSP_Recomp_Vector[25] = &CRSPRecompilerOps::Vector_Reserved; RSP_Recomp_Vector[26] = &CRSPRecompilerOps::Vector_Reserved; RSP_Recomp_Vector[27] = &CRSPRecompilerOps::Vector_Reserved; RSP_Recomp_Vector[28] = &CRSPRecompilerOps::Vector_Reserved; RSP_Recomp_Vector[29] = &CRSPRecompilerOps::Vector_VSAW; RSP_Recomp_Vector[30] = &CRSPRecompilerOps::Vector_Reserved; RSP_Recomp_Vector[31] = &CRSPRecompilerOps::Vector_Reserved; RSP_Recomp_Vector[32] = &CRSPRecompilerOps::Vector_VLT; RSP_Recomp_Vector[33] = &CRSPRecompilerOps::Vector_VEQ; RSP_Recomp_Vector[34] = &CRSPRecompilerOps::Vector_VNE; RSP_Recomp_Vector[35] = &CRSPRecompilerOps::Vector_VGE; RSP_Recomp_Vector[36] = &CRSPRecompilerOps::Vector_VCL; RSP_Recomp_Vector[37] = &CRSPRecompilerOps::Vector_VCH; RSP_Recomp_Vector[38] = &CRSPRecompilerOps::Vector_VCR; RSP_Recomp_Vector[39] = &CRSPRecompilerOps::Vector_VMRG; RSP_Recomp_Vector[40] = &CRSPRecompilerOps::Vector_VAND; RSP_Recomp_Vector[41] = &CRSPRecompilerOps::Vector_VNAND; RSP_Recomp_Vector[42] = &CRSPRecompilerOps::Vector_VOR; RSP_Recomp_Vector[43] = &CRSPRecompilerOps::Vector_VNOR; RSP_Recomp_Vector[44] = &CRSPRecompilerOps::Vector_VXOR; RSP_Recomp_Vector[45] = &CRSPRecompilerOps::Vector_VNXOR; RSP_Recomp_Vector[46] = &CRSPRecompilerOps::Vector_Reserved; RSP_Recomp_Vector[47] = &CRSPRecompilerOps::Vector_Reserved; RSP_Recomp_Vector[48] = &CRSPRecompilerOps::Vector_VRCP; RSP_Recomp_Vector[49] = &CRSPRecompilerOps::Vector_VRCPL; RSP_Recomp_Vector[50] = &CRSPRecompilerOps::Vector_VRCPH; RSP_Recomp_Vector[51] = &CRSPRecompilerOps::Vector_VMOV; RSP_Recomp_Vector[52] = &CRSPRecompilerOps::Vector_VRSQ; RSP_Recomp_Vector[53] = &CRSPRecompilerOps::Vector_VRSQL; RSP_Recomp_Vector[54] = &CRSPRecompilerOps::Vector_VRSQH; RSP_Recomp_Vector[55] = &CRSPRecompilerOps::Vector_VNOOP; RSP_Recomp_Vector[56] = &CRSPRecompilerOps::Vector_Reserved; RSP_Recomp_Vector[57] = &CRSPRecompilerOps::Vector_Reserved; RSP_Recomp_Vector[58] = &CRSPRecompilerOps::Vector_Reserved; RSP_Recomp_Vector[59] = &CRSPRecompilerOps::Vector_Reserved; RSP_Recomp_Vector[60] = &CRSPRecompilerOps::Vector_Reserved; RSP_Recomp_Vector[61] = &CRSPRecompilerOps::Vector_Reserved; RSP_Recomp_Vector[62] = &CRSPRecompilerOps::Vector_Reserved; RSP_Recomp_Vector[63] = &CRSPRecompilerOps::Vector_VNOOP; RSP_Recomp_Lc2[0] = &CRSPRecompilerOps::Opcode_LBV; RSP_Recomp_Lc2[1] = &CRSPRecompilerOps::Opcode_LSV; RSP_Recomp_Lc2[2] = &CRSPRecompilerOps::Opcode_LLV; RSP_Recomp_Lc2[3] = &CRSPRecompilerOps::Opcode_LDV; RSP_Recomp_Lc2[4] = &CRSPRecompilerOps::Opcode_LQV; RSP_Recomp_Lc2[5] = &CRSPRecompilerOps::Opcode_LRV; RSP_Recomp_Lc2[6] = &CRSPRecompilerOps::Opcode_LPV; RSP_Recomp_Lc2[7] = &CRSPRecompilerOps::Opcode_LUV; RSP_Recomp_Lc2[8] = &CRSPRecompilerOps::Opcode_LHV; RSP_Recomp_Lc2[9] = &CRSPRecompilerOps::Opcode_LFV; RSP_Recomp_Lc2[10] = &CRSPRecompilerOps::Opcode_LWV; RSP_Recomp_Lc2[11] = &CRSPRecompilerOps::Opcode_LTV; RSP_Recomp_Lc2[12] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Lc2[13] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Lc2[14] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Lc2[15] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Lc2[16] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Lc2[17] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Lc2[18] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Lc2[19] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Lc2[20] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Lc2[21] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Lc2[22] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Lc2[23] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Lc2[24] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Lc2[25] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Lc2[26] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Lc2[27] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Lc2[28] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Lc2[29] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Lc2[30] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Lc2[31] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Sc2[0] = &CRSPRecompilerOps::Opcode_SBV; RSP_Recomp_Sc2[1] = &CRSPRecompilerOps::Opcode_SSV; RSP_Recomp_Sc2[2] = &CRSPRecompilerOps::Opcode_SLV; RSP_Recomp_Sc2[3] = &CRSPRecompilerOps::Opcode_SDV; RSP_Recomp_Sc2[4] = &CRSPRecompilerOps::Opcode_SQV; RSP_Recomp_Sc2[5] = &CRSPRecompilerOps::Opcode_SRV; RSP_Recomp_Sc2[6] = &CRSPRecompilerOps::Opcode_SPV; RSP_Recomp_Sc2[7] = &CRSPRecompilerOps::Opcode_SUV; RSP_Recomp_Sc2[8] = &CRSPRecompilerOps::Opcode_SHV; RSP_Recomp_Sc2[9] = &CRSPRecompilerOps::Opcode_SFV; RSP_Recomp_Sc2[10] = &CRSPRecompilerOps::Opcode_SWV; RSP_Recomp_Sc2[11] = &CRSPRecompilerOps::Opcode_STV; RSP_Recomp_Sc2[12] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Sc2[13] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Sc2[14] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Sc2[15] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Sc2[16] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Sc2[17] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Sc2[18] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Sc2[19] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Sc2[20] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Sc2[21] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Sc2[22] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Sc2[23] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Sc2[24] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Sc2[25] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Sc2[26] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Sc2[27] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Sc2[28] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Sc2[29] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Sc2[30] = &CRSPRecompilerOps::UnknownOpcode; RSP_Recomp_Sc2[31] = &CRSPRecompilerOps::UnknownOpcode; } void CRSPRecompiler::Reset() { if (m_Assembler != nullptr) { m_Assembler->Reset(); } } void CRSPRecompiler::CompileCodeBlock(RspCodeBlock & block) { SetupRspAssembler(); m_CurrentBlock = █ void * funcPtr = RecompPos; m_CompilePC = block.GetStartAddress(); Log("====== Block %d ======", m_BlockID++); Log("asm code at: %016llX", (uint64_t)funcPtr); Log("Jump table: %X", Table); Log("Start of block: %X", m_CompilePC); Log("====== Recompiled code ======"); m_RecompilerOps.EnterCodeBlock(); const RspCodeBlock::Addresses & branchTargets = block.GetBranchTargets(); for (uint32_t Target : branchTargets) { AddBranchJump(Target); } /*if (Compiler.bReOrdering) { memcpy(IMEM_SAVE, RSPInfo.IMEM, 0x1000); ReOrderSubBlock(&m_CurrentBlock); }*/ const RSPInstructions & instructions = block.GetInstructions(); for (size_t instructionIndex = 0, instructionCount = instructions.size(); instructionIndex < instructionCount;) { const RSPInstruction & instruction = instructions[instructionIndex]; m_CompilePC = instruction.Address(); m_OpCode.Value = instruction.Value(); if (m_NextInstruction == RSPPIPELINE_NORMAL) { BranchTargets::const_iterator labelItr = m_BranchTargets.find(m_CompilePC); if (labelItr != m_BranchTargets.end()) { m_Assembler->bind(labelItr->second); } } (m_RecompilerOps.*RSP_Recomp_Opcode[m_OpCode.op])(); switch (m_NextInstruction) { case RSPPIPELINE_NORMAL: instructionIndex += 1; break; case RSPPIPELINE_DO_DELAY_SLOT: m_NextInstruction = RSPPIPELINE_DELAY_SLOT; instructionIndex += 1; break; case RSPPIPELINE_DO_DELAY_SLOT_TASK_EXIT: m_NextInstruction = RSPPIPELINE_DELAY_SLOT_TASK_EXIT; instructionIndex += 1; break; case RSPPIPELINE_DELAY_SLOT: m_NextInstruction = RSPPIPELINE_DELAY_SLOT_DONE; instructionIndex -= 1; break; case RSPPIPELINE_DELAY_SLOT_DONE: m_NextInstruction = RSPPIPELINE_NORMAL; instructionIndex += 2; break; case RSPPIPELINE_DELAY_SLOT_EXIT: m_NextInstruction = RSPPIPELINE_DELAY_SLOT_EXIT_DONE; instructionIndex -= 1; break; case RSPPIPELINE_DELAY_SLOT_TASK_EXIT: m_NextInstruction = RSPPIPELINE_DELAY_SLOT_TASK_EXIT_DONE; instructionIndex -= 1; break; case RSPPIPELINE_FINISH_TASK_SUB_BLOCK: m_NextInstruction = RSPPIPELINE_FINISH_BLOCK; break; case RSPPIPELINE_FINISH_BLOCK: break; default: g_Notify->BreakPoint(__FILE__, __LINE__); instructionIndex -= 1; break; } } block.SetCompiledLocation(funcPtr); m_CodeHolder.relocateToBase((uint64_t)funcPtr); size_t codeSize = m_CodeHolder.codeSize(); m_CodeHolder.copyFlattenedData(funcPtr, codeSize); RecompPos += codeSize; if (LogAsmCode && !m_CodeLog.empty() && CPULog != nullptr) { CPULog->Log(m_CodeLog.c_str()); CPULog->Log("\r\n"); CPULog->Flush(); m_CodeLog.clear(); } m_CurrentBlock = nullptr; } void * CRSPRecompiler::CompileHLETask(uint32_t Address, RspCodeBlocks & Functions, const uint32_t EndBlockAddress) { void * funcPtr = nullptr; bool compile = true; if (compile) { // have code block in CRSPRecompiler and pass to RspCodeBlock, so it is the owner and sub functions are analysised once RspCodeBlock CodeInfo(m_System, Address, RspCodeType_TASK, EndBlockAddress, Functions); RspCodeBlock::Addresses FunctionCalls = CodeInfo.GetFunctionCalls(); for (RspCodeBlock::Addresses::iterator itr = FunctionCalls.begin(); itr != FunctionCalls.end(); itr++) { RspCodeBlocks::iterator funcitr = Functions.find(*itr); if (funcitr == Functions.end()) { return nullptr; } RspCodeBlockPtr & FuncCodeBlock = funcitr->second; if (FuncCodeBlock->GetCompiledLocation() == nullptr) { CompileCodeBlock(*FuncCodeBlock); } } CompileCodeBlock(CodeInfo); funcPtr = CodeInfo.GetCompiledLocation(); } else { funcPtr = RecompPos; if (LogAsmCode) { Log("====== Block %d ======", m_BlockID++); Log("asm code at: %016llX", (uint64_t)funcPtr); Log("Jump table: %X", Table); Log("Start of block: %X", Address); Log("====== Recompiled code ======"); } SetupRspAssembler(); m_Assembler->push(asmjit::x86::rbp); m_Assembler->mov(asmjit::x86::rbp, asmjit::x86::rsp); m_Assembler->sub(asmjit::x86::rsp, 0x30); if (Profiling) { m_Assembler->mov(asmjit::x86::rcx, asmjit::imm((uintptr_t)Address)); m_Assembler->CallFunc(AddressOf(&StartTimer), "StartTimer"); } m_Assembler->mov(asmjit::x86::rcx, asmjit::imm((uintptr_t)&m_System)); m_Assembler->mov(asmjit::x86::rdx, asmjit::imm(0x10000)); m_Assembler->mov(asmjit::x86::r8, asmjit::imm(0x118)); m_Assembler->CallFunc(AddressOf(&CRSPSystem::ExecuteOps), "CRSPSystem::ExecuteOps"); if (Profiling) { m_Assembler->CallFunc(AddressOf(&StopTimer), "StopTimer"); } m_Assembler->add(asmjit::x86::rsp, 0x30); m_Assembler->pop(asmjit::x86::rbp); m_Assembler->ret(); m_Assembler->finalize(); m_CodeHolder.relocateToBase((uint64_t)funcPtr); size_t codeSize = m_CodeHolder.codeSize(); m_CodeHolder.copyFlattenedData(funcPtr, codeSize); RecompPos += codeSize; } if (LogAsmCode && !m_CodeLog.empty() && CPULog != nullptr) { CPULog->Log(m_CodeLog.c_str()); CPULog->Log("\r\n"); CPULog->Flush(); m_CodeLog.clear(); } return funcPtr; } void CRSPRecompiler::Log(_Printf_format_string_ const char * Text, ...) { if (!LogAsmCode) { return; } va_list args; va_start(args, Text); #pragma warning(push) #pragma warning(disable : 4996) size_t nlen = _vscprintf(Text, args) + 1; char * buffer = (char *)alloca(nlen * sizeof(char)); buffer[nlen - 1] = 0; if (buffer != nullptr) { vsprintf(buffer, Text, args); m_CodeLog += buffer; m_CodeLog += "\n"; } #pragma warning(pop) va_end(args); } void CRSPRecompiler::handleError(asmjit::Error /*err*/, const char * /*message*/, asmjit::BaseEmitter * /*origin*/) { g_Notify->BreakPoint(__FILE__, __LINE__); } void CRSPRecompiler::SetupRspAssembler() { if (m_Assembler != nullptr) { delete m_Assembler; m_Assembler = nullptr; } m_CodeHolder.reset(); m_CodeHolder.init(m_Environment); m_CodeHolder.setErrorHandler(this); m_CodeHolder.setLogger(LogAsmCode ? nullptr : nullptr); m_Assembler = new RspAssembler(&m_CodeHolder, m_CodeLog); m_Assembler->setLogger(LogAsmCode ? m_Assembler : nullptr); } void * CRSPRecompiler::GetAddressOf(int value, ...) { void * Address; va_list ap; va_start(ap, value); Address = va_arg(ap, void *); va_end(ap); return Address; } #endif