diff --git a/Source/Core/Common/Src/MathUtil.h b/Source/Core/Common/Src/MathUtil.h index c3957e7ab9..6e5c698a51 100644 --- a/Source/Core/Common/Src/MathUtil.h +++ b/Source/Core/Common/Src/MathUtil.h @@ -47,6 +47,7 @@ union IntFloat { inline bool IsNAN(double d) { + return d !=d; IntDouble x; x.d = d; return ( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) && ((x.i & DOUBLE_FRAC) != DOUBLE_ZERO) ); diff --git a/Source/Core/Core/Src/Debugger/PPCDebugInterface.cpp b/Source/Core/Core/Src/Debugger/PPCDebugInterface.cpp index 24f06f938f..674d40ab4d 100644 --- a/Source/Core/Core/Src/Debugger/PPCDebugInterface.cpp +++ b/Source/Core/Core/Src/Debugger/PPCDebugInterface.cpp @@ -111,13 +111,13 @@ bool PPCDebugInterface::isBreakpoint(unsigned int address) void PPCDebugInterface::setBreakpoint(unsigned int address) { if (PowerPC::breakpoints.Add(address)) - jit.NotifyBreakpoint(address, true); + jit->NotifyBreakpoint(address, true); } void PPCDebugInterface::clearBreakpoint(unsigned int address) { if (PowerPC::breakpoints.Remove(address)) - jit.NotifyBreakpoint(address, false); + jit->NotifyBreakpoint(address, false); } void PPCDebugInterface::clearAllBreakpoints() {} diff --git a/Source/Core/Core/Src/HW/Memmap.cpp b/Source/Core/Core/Src/HW/Memmap.cpp index a58d171dc9..70421a2620 100644 --- a/Source/Core/Core/Src/HW/Memmap.cpp +++ b/Source/Core/Core/Src/HW/Memmap.cpp @@ -538,7 +538,7 @@ u32 Read_Instruction(const u32 em_address) { UGeckoInstruction inst = ReadUnchecked_U32(em_address); if (inst.OPCD == 0) - inst.hex = jit.GetBlockCache()->GetOriginalCode(em_address); + inst.hex = jit->GetBlockCache()->GetOriginalCode(em_address); if (inst.OPCD == 1) return HLE::GetOrigInstruction(em_address); else diff --git a/Source/Core/Core/Src/MemTools.cpp b/Source/Core/Core/Src/MemTools.cpp index fad78282a5..2345869d83 100644 --- a/Source/Core/Core/Src/MemTools.cpp +++ b/Source/Core/Core/Src/MemTools.cpp @@ -65,7 +65,7 @@ LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs) PVOID codeAddr = pPtrs->ExceptionRecord->ExceptionAddress; unsigned char *codePtr = (unsigned char*)codeAddr; - if (!jit.IsInCodeSpace(codePtr)) { + if (!jit->IsInCodeSpace(codePtr)) { // Let's not prevent debugging. return (DWORD)EXCEPTION_CONTINUE_SEARCH; } @@ -95,7 +95,7 @@ LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs) //We could emulate the memory accesses here, but then they would still be around to take up //execution resources. Instead, we backpatch into a generic memory call and retry. - const u8 *new_rip = jit.BackPatch(codePtr, accessType, emAddress, ctx); + const u8 *new_rip = jit->BackPatch(codePtr, accessType, emAddress, ctx); // Rip/Eip needs to be updated. if (new_rip) @@ -190,7 +190,7 @@ void sigsegv_handler(int signal, siginfo_t *info, void *raw_context) #else u8 *fault_instruction_ptr = (u8 *)CREG_EIP(ctx); #endif - if (!jit.IsInCodeSpace(fault_instruction_ptr)) { + if (!jit->IsInCodeSpace(fault_instruction_ptr)) { // Let's not prevent debugging. return; } @@ -217,7 +217,7 @@ void sigsegv_handler(int signal, siginfo_t *info, void *raw_context) fake_ctx.Eax = CREG_EAX(ctx); fake_ctx.Eip = CREG_EIP(ctx); #endif - const u8 *new_rip = jit.BackPatch(fault_instruction_ptr, access_type, em_address, &fake_ctx); + const u8 *new_rip = jit->BackPatch(fault_instruction_ptr, access_type, em_address, &fake_ctx); if (new_rip) { #ifdef _M_X64 CREG_RAX(ctx) = fake_ctx.Rax; diff --git a/Source/Core/Core/Src/PowerPC/CoreGeneralize.cpp b/Source/Core/Core/Src/PowerPC/CoreGeneralize.cpp new file mode 100644 index 0000000000..d55b60e1f9 --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/CoreGeneralize.cpp @@ -0,0 +1,2 @@ + +#include "CoreGeneralize.h" diff --git a/Source/Core/Core/Src/PowerPC/CoreGeneralize.h b/Source/Core/Core/Src/PowerPC/CoreGeneralize.h new file mode 100644 index 0000000000..984e6610bb --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/CoreGeneralize.h @@ -0,0 +1,273 @@ +// Copyright (C) 2003-2009 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ +#ifndef _CORE_GENERALIZE_H +#define _CORE_GENERALIZE_H +#include "PPCAnalyst.h" +#include "JitCommon/JitCache.h" +#include "Jit64/JitRegCache.h" // These two Jit Includes NEED to be dropped +#include "x64Emitter.h" +#include "x64Analyzer.h" +#include "Jit64IL/IR.h" + +#ifndef _WIN32 + + // A bit of a hack to get things building under linux. We manually fill in this structure as needed + // from the real context. + struct CONTEXT + { + #ifdef _M_X64 + u64 Rip; + u64 Rax; + #else + u32 Eip; + u32 Eax; + #endif + }; + +#endif + +class TrampolineCache : public Gen::XCodeBlock +{ +public: + void Init(); + void Shutdown(); + + const u8 *GetReadTrampoline(const InstructionInfo &info); + const u8 *GetWriteTrampoline(const InstructionInfo &info); +}; + + +class cCore : public Gen::XCodeBlock +{ + private: + struct JitState + { + u32 compilerPC; + u32 next_compilerPC; + u32 blockStart; + bool cancel; + UGeckoInstruction next_inst; // for easy peephole opt. + int blockSize; + int instructionNumber; + int downcountAmount; + int block_flags; + + bool isLastInstruction; + bool blockSetsQuantizers; + + int fifoBytesThisBlock; + + PPCAnalyst::BlockStats st; + PPCAnalyst::BlockRegStats gpa; + PPCAnalyst::BlockRegStats fpa; + PPCAnalyst::CodeOp *op; + u8* rewriteStart; + + JitBlock *curBlock; + }; + + struct JitOptions + { + bool optimizeStack; + bool assumeFPLoadFromMem; + bool enableBlocklink; + bool fpAccurateFlags; + bool enableFastMem; + bool optimizeGatherPipe; + bool fastInterrupts; + bool accurateSinglePrecision; + }; + + JitBlockCache blocks; + TrampolineCache trampolines; + #if !(defined JITTEST && JITTEST) + GPRRegCache gpr; + FPURegCache fpr; + #endif + + // The default code buffer. We keep it around to not have to alloc/dealloc a + // large chunk of memory for each recompiled block. + PPCAnalyst::CodeBuffer code_buffer; + +public: + cCore() : code_buffer(32000){} + + ~cCore(){} + + + JitState js; + JitOptions jo; + IREmitter::IRBuilder ibuild; + + // Initialization, etc + + virtual void Init() = 0; + virtual void Shutdown() = 0; + + // Jit! + + virtual void Jit(u32 em_address) = 0; + virtual const u8* DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buffer, JitBlock *b) = 0; + + virtual JitBlockCache *GetBlockCache() { return &blocks; } + + virtual void NotifyBreakpoint(u32 em_address, bool set) = 0; + + virtual void ClearCache() = 0; + + // Run! + + virtual void Run() = 0; + virtual void SingleStep() = 0; + + const u8 *BackPatch(u8 *codePtr, int accessType, u32 em_address, CONTEXT *ctx); + +#define JIT_OPCODE 0 + // Utilities for use by opcodes + + virtual void WriteExit(u32 destination, int exit_num) = 0; + virtual void WriteExitDestInEAX(int exit_num) = 0; + virtual void WriteExceptionExit(u32 exception) = 0; + virtual void WriteRfiExitDestInEAX() = 0; + virtual void WriteCallInterpreter(UGeckoInstruction _inst) = 0; + virtual void Cleanup() = 0; + + virtual void UnsafeLoadRegToReg(Gen::X64Reg reg_addr, Gen::X64Reg reg_value, int accessSize, s32 offset = 0, bool signExtend = false) = 0; + virtual void UnsafeWriteRegToReg(Gen::X64Reg reg_value, Gen::X64Reg reg_addr, int accessSize, s32 offset = 0) = 0; + virtual void SafeLoadRegToEAX(Gen::X64Reg reg, int accessSize, s32 offset, bool signExtend = false) = 0; + virtual void SafeWriteRegToReg(Gen::X64Reg reg_value, Gen::X64Reg reg_addr, int accessSize, s32 offset) = 0; + + virtual void WriteToConstRamAddress(int accessSize, const Gen::OpArg& arg, u32 address) = 0; + virtual void WriteFloatToConstRamAddress(const Gen::X64Reg& xmm_reg, u32 address) = 0; + virtual void GenerateCarry(Gen::X64Reg temp_reg) = 0; + + virtual void ForceSinglePrecisionS(Gen::X64Reg xmm) = 0; + virtual void ForceSinglePrecisionP(Gen::X64Reg xmm) = 0; + virtual void JitClearCA() = 0; + virtual void JitSetCA() = 0; + virtual void tri_op(int d, int a, int b, bool reversible, void (XEmitter::*op)(Gen::X64Reg, Gen::OpArg)) = 0; + typedef u32 (*Operation)(u32 a, u32 b); + virtual void regimmop(int d, int a, bool binary, u32 value, Operation doop, void (XEmitter::*op)(int, const Gen::OpArg&, const Gen::OpArg&), bool Rc = false, bool carry = false) = 0; + virtual void fp_tri_op(int d, int a, int b, bool reversible, bool dupe, void (XEmitter::*op)(Gen::X64Reg, Gen::OpArg)) = 0; + + void WriteCode(); + + // OPCODES + virtual void unknown_instruction(UGeckoInstruction _inst) = 0; + virtual void Default(UGeckoInstruction _inst) = 0; + virtual void DoNothing(UGeckoInstruction _inst) = 0; + virtual void HLEFunction(UGeckoInstruction _inst) = 0; + + void DynaRunTable4(UGeckoInstruction _inst); + void DynaRunTable19(UGeckoInstruction _inst); + void DynaRunTable31(UGeckoInstruction _inst); + void DynaRunTable59(UGeckoInstruction _inst); + void DynaRunTable63(UGeckoInstruction _inst); + + virtual void addx(UGeckoInstruction inst) = 0; + virtual void orx(UGeckoInstruction inst) = 0; + virtual void xorx(UGeckoInstruction inst) = 0; + virtual void andx(UGeckoInstruction inst) = 0; + virtual void mulli(UGeckoInstruction inst) = 0; + virtual void mulhwux(UGeckoInstruction inst) = 0; + virtual void mullwx(UGeckoInstruction inst) = 0; + virtual void divwux(UGeckoInstruction inst) = 0; + virtual void srawix(UGeckoInstruction inst) = 0; + virtual void srawx(UGeckoInstruction inst) = 0; + virtual void addex(UGeckoInstruction inst) = 0; + virtual void addzex(UGeckoInstruction inst) = 0; + + virtual void extsbx(UGeckoInstruction inst) = 0; + virtual void extshx(UGeckoInstruction inst) = 0; + + virtual void sc(UGeckoInstruction _inst) = 0; + virtual void rfi(UGeckoInstruction _inst) = 0; + + virtual void bx(UGeckoInstruction inst) = 0; + virtual void bclrx(UGeckoInstruction _inst) = 0; + virtual void bcctrx(UGeckoInstruction _inst) = 0; + virtual void bcx(UGeckoInstruction inst) = 0; + + virtual void mtspr(UGeckoInstruction inst) = 0; + virtual void mfspr(UGeckoInstruction inst) = 0; + virtual void mtmsr(UGeckoInstruction inst) = 0; + virtual void mfmsr(UGeckoInstruction inst) = 0; + virtual void mftb(UGeckoInstruction inst) = 0; + virtual void mtcrf(UGeckoInstruction inst) = 0; + virtual void mfcr(UGeckoInstruction inst) = 0; + + virtual void reg_imm(UGeckoInstruction inst) = 0; + + virtual void ps_sel(UGeckoInstruction inst) = 0; + virtual void ps_mr(UGeckoInstruction inst) = 0; + virtual void ps_sign(UGeckoInstruction inst) = 0; //aggregate + virtual void ps_arith(UGeckoInstruction inst) = 0; //aggregate + virtual void ps_mergeXX(UGeckoInstruction inst) = 0; + virtual void ps_maddXX(UGeckoInstruction inst) = 0; + virtual void ps_rsqrte(UGeckoInstruction inst) = 0; + virtual void ps_sum(UGeckoInstruction inst) = 0; + virtual void ps_muls(UGeckoInstruction inst) = 0; + + virtual void fp_arith_s(UGeckoInstruction inst) = 0; + + virtual void fcmpx(UGeckoInstruction inst) = 0; + virtual void fmrx(UGeckoInstruction inst) = 0; + + virtual void cmpXX(UGeckoInstruction inst) = 0; + + virtual void cntlzwx(UGeckoInstruction inst) = 0; + + virtual void lfs(UGeckoInstruction inst) = 0; + virtual void lfd(UGeckoInstruction inst) = 0; + virtual void stfd(UGeckoInstruction inst) = 0; + virtual void stfs(UGeckoInstruction inst) = 0; + virtual void stfsx(UGeckoInstruction inst) = 0; + virtual void psq_l(UGeckoInstruction inst) = 0; + virtual void psq_st(UGeckoInstruction inst) = 0; + + virtual void fmaddXX(UGeckoInstruction inst) = 0; + virtual void stX(UGeckoInstruction inst) = 0; //stw sth stb + virtual void lXz(UGeckoInstruction inst) = 0; + virtual void lha(UGeckoInstruction inst) = 0; + virtual void rlwinmx(UGeckoInstruction inst) = 0; + virtual void rlwimix(UGeckoInstruction inst) = 0; + virtual void rlwnmx(UGeckoInstruction inst) = 0; + virtual void negx(UGeckoInstruction inst) = 0; + virtual void slwx(UGeckoInstruction inst) = 0; + virtual void srwx(UGeckoInstruction inst) = 0; + virtual void dcbz(UGeckoInstruction inst) = 0; + virtual void lfsx(UGeckoInstruction inst) = 0; + + virtual void subfic(UGeckoInstruction inst) = 0; + virtual void subfcx(UGeckoInstruction inst) = 0; + virtual void subfx(UGeckoInstruction inst) = 0; + virtual void subfex(UGeckoInstruction inst) = 0; + + virtual void lXzx(UGeckoInstruction inst) = 0; + //virtual void lbzx(UGeckoInstruction inst) = 0; + //virtual void lwzx(UGeckoInstruction inst) = 0; + virtual void lhax(UGeckoInstruction inst) = 0; + + //virtual void lwzux(UGeckoInstruction inst) = 0; + + virtual void stXx(UGeckoInstruction inst) = 0; + + virtual void lmw(UGeckoInstruction inst) = 0; + virtual void stmw(UGeckoInstruction inst) = 0; +}; +extern cCore *jit; // jit to retain backwards compatibility +#endif diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp index 290212ceff..4900114dd1 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp @@ -35,7 +35,7 @@ #include "../../Core.h" #include "Interpreter.h" #include "MathUtil.h" -#ifndef _mm_cvttsd_si32 // No SSE2 support +#if !defined(_mm_cvttsd_si32) // No SSE2 support #define _mm_set_sd #define _mm_cvttsd_si32 truncl #define _mm_cvtsd_si32 lrint diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp index 81b219566a..d40ba9fab4 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp @@ -179,8 +179,6 @@ static void CheckForNans() } } -Jit64 jit; - int CODE_SIZE = 1024*1024*16; namespace CPUCompare @@ -190,7 +188,7 @@ namespace CPUCompare void Jit(u32 em_address) { - jit.Jit(em_address); + jit->Jit(em_address); } void Jit64::Init() diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h index 48e65a4f9d..3274617387 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h @@ -50,6 +50,7 @@ #include "JitRegCache.h" #include "x64Emitter.h" #include "x64Analyzer.h" +#include "../CoreGeneralize.h" #ifdef _WIN32 #include @@ -63,23 +64,6 @@ void Jit(u32 em_address); -#ifndef _WIN32 - - // A bit of a hack to get things building under linux. We manually fill in this structure as needed - // from the real context. - struct CONTEXT - { - #ifdef _M_X64 - u64 Rip; - u64 Rax; - #else - u32 Eip; - u32 Eax; - #endif - }; - -#endif - // Use these to control the instruction selection // #define INSTRUCTION_START Default(inst); return; // #define INSTRUCTION_START PPCTables::CountInstruction(inst); @@ -87,18 +71,7 @@ void Jit(u32 em_address); /////////////////////////////////// -class TrampolineCache : public Gen::XCodeBlock -{ -public: - void Init(); - void Shutdown(); - - const u8 *GetReadTrampoline(const InstructionInfo &info); - const u8 *GetWriteTrampoline(const InstructionInfo &info); -}; - - -class Jit64 : public Gen::XCodeBlock +class Jit64 : public cCore { private: struct JitState @@ -230,6 +203,7 @@ public: void srawix(UGeckoInstruction inst); void srawx(UGeckoInstruction inst); void addex(UGeckoInstruction inst); + void addzex(UGeckoInstruction inst); void extsbx(UGeckoInstruction inst); void extshx(UGeckoInstruction inst); @@ -302,6 +276,7 @@ public: void lhax(UGeckoInstruction inst); void lwzux(UGeckoInstruction inst); + void lXzx(UGeckoInstruction inst); void stXx(UGeckoInstruction inst); @@ -309,7 +284,5 @@ public: void stmw(UGeckoInstruction inst); }; -extern Jit64 jit; - #endif // _JIT_H #endif // JITTEST diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp b/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp index d144a3bcd9..ad7a7ff8f2 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp @@ -70,7 +70,7 @@ void AsmRoutineManager::Generate() #ifndef _M_IX86 // Two statically allocated registers. MOV(64, R(RBX), Imm64((u64)Memory::base)); - MOV(64, R(R15), Imm64((u64)jit.GetBlockCache()->GetCodePointers())); //It's below 2GB so 32 bits are good enough + MOV(64, R(R15), Imm64((u64)jit->GetBlockCache()->GetCodePointers())); //It's below 2GB so 32 bits are good enough #endif const u8 *outerLoop = GetCodePtr(); diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp index 78b3fabe7a..2096bbac42 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp @@ -246,7 +246,11 @@ gpr.UnlockAll(); } - + void Jit64::addzex(UGeckoInstruction inst) + { + Default(inst); + return; + } void Jit64::orx(UGeckoInstruction inst) { if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITIntegerOff) diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp index 7d01b617e5..06ed31c912 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp @@ -35,31 +35,76 @@ #include "JitAsm.h" #include "JitRegCache.h" - void Jit64::lbzx(UGeckoInstruction inst) + void Jit64::lXzx(UGeckoInstruction inst) { if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStoreOff || Core::g_CoreStartupParameter.bJITLoadStorelbzxOff) {Default(inst); return;} // turn off from debugger INSTRUCTION_START; - + int a = inst.RA, b = inst.RB, d = inst.RD; - gpr.Lock(a, b, d); - gpr.FlushLockX(ABI_PARAM1); - if (b == d || a == d) - gpr.LoadToX64(d, true, true); - else - gpr.LoadToX64(d, false, true); - MOV(32, R(ABI_PARAM1), gpr.R(b)); - if (a) - ADD(32, R(ABI_PARAM1), gpr.R(a)); -#if 0 - SafeLoadRegToEAX(ABI_PARAM1, 8, 0); - MOV(32, gpr.R(d), R(EAX)); -#else - UnsafeLoadRegToReg(ABI_PARAM1, gpr.RX(d), 8, 0, false); -#endif - gpr.UnlockAll(); - gpr.UnlockAllX(); + switch(inst.OPCD) + { + case 23: //lwzx + gpr.Lock(a, b, d); + gpr.FlushLockX(ABI_PARAM1); + if (b == d || a == d) + gpr.LoadToX64(d, true, true); + else + gpr.LoadToX64(d, false, true); + MOV(32, R(ABI_PARAM1), gpr.R(b)); + if (a) + ADD(32, R(ABI_PARAM1), gpr.R(a)); + #if 1 + SafeLoadRegToEAX(ABI_PARAM1, 32, 0); + MOV(32, gpr.R(d), R(EAX)); + #else + UnsafeLoadRegToReg(ABI_PARAM1, gpr.RX(d), 32, 0, false); + #endif + gpr.UnlockAll(); + gpr.UnlockAllX(); + break; + case 55: //lwzux + if (!a || a == d || a == b) + { + Default(inst); + return; + } + gpr.Lock(a, b, d); + + gpr.LoadToX64(d, b == d, true); + gpr.LoadToX64(a, true, true); + ADD(32, gpr.R(a), gpr.R(b)); + MOV(32, R(EAX), gpr.R(a)); + SafeLoadRegToEAX(EAX, 32, 0, false); + MOV(32, gpr.R(d), R(EAX)); + + gpr.UnlockAll(); + break; + case 87: //lbzx + gpr.Lock(a, b, d); + gpr.FlushLockX(ABI_PARAM1); + if (b == d || a == d) + gpr.LoadToX64(d, true, true); + else + gpr.LoadToX64(d, false, true); + MOV(32, R(ABI_PARAM1), gpr.R(b)); + if (a) + ADD(32, R(ABI_PARAM1), gpr.R(a)); + #if 0 + SafeLoadRegToEAX(ABI_PARAM1, 8, 0); + MOV(32, gpr.R(d), R(EAX)); + #else + UnsafeLoadRegToReg(ABI_PARAM1, gpr.RX(d), 8, 0, false); + #endif + gpr.UnlockAll(); + gpr.UnlockAllX(); + break; + default: + Default(inst); + return; + break; + } } void Jit64::lwzx(UGeckoInstruction inst) @@ -119,7 +164,15 @@ || Core::g_CoreStartupParameter.bJITLoadStorelXzOff) {Default(inst); return;} // turn off from debugger INSTRUCTION_START; - + switch(inst.OPCD) + { + case 33: // lwzu + case 35: // lbzu + case 41: // lhzu + Default(inst); + return; + break; + } int d = inst.RD; int a = inst.RA; @@ -253,31 +306,6 @@ return; } - void Jit64::lwzux(UGeckoInstruction inst) - { - if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStoreOff) - {Default(inst); return;} // turn off from debugger - INSTRUCTION_START; - - int a = inst.RA, b = inst.RB, d = inst.RD; - if (!a || a == d || a == b) - { - Default(inst); - return; - } - gpr.Lock(a, b, d); - - gpr.LoadToX64(d, b == d, true); - gpr.LoadToX64(a, true, true); - ADD(32, gpr.R(a), gpr.R(b)); - MOV(32, R(EAX), gpr.R(a)); - SafeLoadRegToEAX(EAX, 32, 0, false); - MOV(32, gpr.R(d), R(EAX)); - - gpr.UnlockAll(); - return; - } - // Zero cache line. void Jit64::dcbz(UGeckoInstruction inst) { diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/Jit_Util.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Util.cpp similarity index 97% rename from Source/Core/Core/Src/PowerPC/JitCommon/Jit_Util.cpp rename to Source/Core/Core/Src/PowerPC/Jit64/Jit_Util.cpp index e75b10a8cc..8ac3e7c528 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/Jit_Util.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Util.cpp @@ -28,16 +28,17 @@ #include "x64Emitter.h" #include "ABI.h" -#ifdef JITTEST +#if defined JITTEST && JITTEST #include "../Jit64IL/Jit.h" -#include "JitCache.h" +#include "../JitCommon/JitCache.h" #include "../Jit64IL/JitAsm.h" #else #include "../Jit64/Jit.h" -#include "JitCache.h" +#include "../JitCommon/JitCache.h" #include "../Jit64/JitAsm.h" #include "../Jit64/JitRegCache.h" #endif +#include "../CoreGeneralize.h" using namespace Gen; diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp index d3abb65c5c..c9ffb4a4c3 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp @@ -52,7 +52,7 @@ using namespace IREmitter; using namespace Gen; struct RegInfo { - Jit64* Jit; + Jit64IL* Jit; IRBuilder* Build; InstLoc FirstI; std::vector IInfo; @@ -65,7 +65,7 @@ struct RegInfo { unsigned numProfiledLoads; unsigned exitNumber; - RegInfo(Jit64* j, InstLoc f, unsigned insts) : Jit(j), FirstI(f), IInfo(insts) { + RegInfo(Jit64IL* j, InstLoc f, unsigned insts) : Jit(j), FirstI(f), IInfo(insts) { for (unsigned i = 0; i < 16; i++) { regs[i] = 0; fregs[i] = 0; @@ -296,7 +296,7 @@ static void fregNormalRegClear(RegInfo& RI, InstLoc I) { } static void regEmitBinInst(RegInfo& RI, InstLoc I, - void (Jit64::*op)(int, const OpArg&, + void (Jit64IL::*op)(int, const OpArg&, const OpArg&), bool commutable = false) { X64Reg reg; @@ -327,7 +327,7 @@ static void regEmitBinInst(RegInfo& RI, InstLoc I, } static void fregEmitBinInst(RegInfo& RI, InstLoc I, - void (Jit64::*op)(X64Reg, OpArg)) { + void (Jit64IL::*op)(X64Reg, OpArg)) { X64Reg reg; if (RI.IInfo[I - RI.FirstI] & 4) { reg = fregEnsureInReg(RI, getOp1(I)); @@ -561,7 +561,7 @@ static void regEmitMemStore(RegInfo& RI, InstLoc I, unsigned Size) { regClearInst(RI, getOp1(I)); } -static void regEmitShiftInst(RegInfo& RI, InstLoc I, void (Jit64::*op)(int, OpArg, OpArg)) +static void regEmitShiftInst(RegInfo& RI, InstLoc I, void (Jit64IL::*op)(int, OpArg, OpArg)) { X64Reg reg = regBinLHSReg(RI, I); if (isImm(*getOp2(I))) { @@ -630,7 +630,7 @@ static void regWriteExit(RegInfo& RI, InstLoc dest) { } } -static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile, bool MakeProfile) { +static void DoWriteCode(IRBuilder* ibuild, Jit64IL* Jit, bool UseProfile, bool MakeProfile) { //printf("Writing block: %x\n", js.blockStart); RegInfo RI(Jit, ibuild->getFirstInst(), ibuild->getNumInsts()); RI.Build = ibuild; @@ -977,27 +977,27 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile, bool Mak } case And: { if (!thisUsed) break; - regEmitBinInst(RI, I, &Jit64::AND, true); + regEmitBinInst(RI, I, &Jit64IL::AND, true); break; } case Xor: { if (!thisUsed) break; - regEmitBinInst(RI, I, &Jit64::XOR, true); + regEmitBinInst(RI, I, &Jit64IL::XOR, true); break; } case Sub: { if (!thisUsed) break; - regEmitBinInst(RI, I, &Jit64::SUB); + regEmitBinInst(RI, I, &Jit64IL::SUB); break; } case Or: { if (!thisUsed) break; - regEmitBinInst(RI, I, &Jit64::OR, true); + regEmitBinInst(RI, I, &Jit64IL::OR, true); break; } case Add: { if (!thisUsed) break; - regEmitBinInst(RI, I, &Jit64::ADD, true); + regEmitBinInst(RI, I, &Jit64IL::ADD, true); break; } case Mul: { @@ -1020,22 +1020,22 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile, bool Mak } case Rol: { if (!thisUsed) break; - regEmitShiftInst(RI, I, &Jit64::ROL); + regEmitShiftInst(RI, I, &Jit64IL::ROL); break; } case Shl: { if (!thisUsed) break; - regEmitShiftInst(RI, I, &Jit64::SHL); + regEmitShiftInst(RI, I, &Jit64IL::SHL); break; } case Shrl: { if (!thisUsed) break; - regEmitShiftInst(RI, I, &Jit64::SHR); + regEmitShiftInst(RI, I, &Jit64IL::SHR); break; } case Sarl: { if (!thisUsed) break; - regEmitShiftInst(RI, I, &Jit64::SAR); + regEmitShiftInst(RI, I, &Jit64IL::SAR); break; } case ICmpEq: { @@ -1359,17 +1359,17 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile, bool Mak } case FSMul: { if (!thisUsed) break; - fregEmitBinInst(RI, I, &Jit64::MULSS); + fregEmitBinInst(RI, I, &Jit64IL::MULSS); break; } case FSAdd: { if (!thisUsed) break; - fregEmitBinInst(RI, I, &Jit64::ADDSS); + fregEmitBinInst(RI, I, &Jit64IL::ADDSS); break; } case FSSub: { if (!thisUsed) break; - fregEmitBinInst(RI, I, &Jit64::SUBSS); + fregEmitBinInst(RI, I, &Jit64IL::SUBSS); break; } case FSRSqrt: { @@ -1382,17 +1382,17 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile, bool Mak } case FDMul: { if (!thisUsed) break; - fregEmitBinInst(RI, I, &Jit64::MULSD); + fregEmitBinInst(RI, I, &Jit64IL::MULSD); break; } case FDAdd: { if (!thisUsed) break; - fregEmitBinInst(RI, I, &Jit64::ADDSD); + fregEmitBinInst(RI, I, &Jit64IL::ADDSD); break; } case FDSub: { if (!thisUsed) break; - fregEmitBinInst(RI, I, &Jit64::SUBSD); + fregEmitBinInst(RI, I, &Jit64IL::SUBSD); break; } case FDCmpCR: { @@ -1426,17 +1426,17 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile, bool Mak } case FPAdd: { if (!thisUsed) break; - fregEmitBinInst(RI, I, &Jit64::ADDPS); + fregEmitBinInst(RI, I, &Jit64IL::ADDPS); break; } case FPMul: { if (!thisUsed) break; - fregEmitBinInst(RI, I, &Jit64::MULPS); + fregEmitBinInst(RI, I, &Jit64IL::MULPS); break; } case FPSub: { if (!thisUsed) break; - fregEmitBinInst(RI, I, &Jit64::SUBPS); + fregEmitBinInst(RI, I, &Jit64IL::SUBPS); break; } case FPMerge00: { @@ -1614,13 +1614,17 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile, bool Mak Jit->UD2(); } -void Jit64::WriteCode() { +void Jit64IL::WriteCode() { DoWriteCode(&ibuild, this, false, Core::GetStartupParameter().bJITProfiledReJIT); } - void ProfiledReJit() { - jit.SetCodePtr(jit.js.rewriteStart); - DoWriteCode(&jit.ibuild, &jit, true, false); - jit.js.curBlock->codeSize = (int)(jit.GetCodePtr() - jit.js.rewriteStart); - jit.GetBlockCache()->FinalizeBlock(jit.js.curBlock->blockNum, jit.jo.enableBlocklink, jit.js.curBlock->normalEntry); + Jit64IL *jitil = dynamic_cast(jit); + if(jitil) + jitil->ProfiledReJit(); +} +void Jit64IL::ProfiledReJit() { + jit->SetCodePtr(jit->js.rewriteStart); + DoWriteCode(&jit->ibuild, this, true, false); + jit->js.curBlock->codeSize = (int)(jit->GetCodePtr() - jit->js.rewriteStart); + jit->GetBlockCache()->FinalizeBlock(jit->js.curBlock->blockNum, jit->jo.enableBlocklink, jit->js.curBlock->normalEntry); } diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit.cpp index b69ca1a908..8829d8d93f 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit.cpp @@ -156,8 +156,6 @@ ps_adds1 */ -Jit64 jit; - int CODE_SIZE = 1024*1024*16; namespace CPUCompare @@ -167,10 +165,10 @@ namespace CPUCompare void Jit(u32 em_address) { - jit.Jit(em_address); + jit->Jit(em_address); } -void Jit64::Init() +void Jit64IL::Init() { asm_routines.compareEnabled = ::Core::g_CoreStartupParameter.bRunCompareClient; if (Core::g_CoreStartupParameter.bJITUnlimitedCache) @@ -200,14 +198,14 @@ void Jit64::Init() asm_routines.Init(); } -void Jit64::ClearCache() +void Jit64IL::ClearCache() { blocks.Clear(); trampolines.ClearCodeSpace(); ClearCodeSpace(); } -void Jit64::Shutdown() +void Jit64IL::Shutdown() { FreeCodeSpace(); @@ -217,7 +215,7 @@ void Jit64::Shutdown() } -void Jit64::WriteCallInterpreter(UGeckoInstruction inst) +void Jit64IL::WriteCallInterpreter(UGeckoInstruction inst) { if (js.isLastInstruction) { @@ -233,32 +231,32 @@ void Jit64::WriteCallInterpreter(UGeckoInstruction inst) } } -void Jit64::unknown_instruction(UGeckoInstruction inst) +void Jit64IL::unknown_instruction(UGeckoInstruction inst) { // CCPU::Break(); PanicAlert("unknown_instruction %08x - Fix me ;)", inst.hex); } -void Jit64::Default(UGeckoInstruction _inst) +void Jit64IL::Default(UGeckoInstruction _inst) { ibuild.EmitInterpreterFallback( ibuild.EmitIntConst(_inst.hex), ibuild.EmitIntConst(js.compilerPC)); } -void Jit64::HLEFunction(UGeckoInstruction _inst) +void Jit64IL::HLEFunction(UGeckoInstruction _inst) { ABI_CallFunctionCC((void*)&HLE::Execute, js.compilerPC, _inst.hex); MOV(32, R(EAX), M(&NPC)); WriteExitDestInEAX(0); } -void Jit64::DoNothing(UGeckoInstruction _inst) +void Jit64IL::DoNothing(UGeckoInstruction _inst) { // Yup, just don't do anything. } -void Jit64::NotifyBreakpoint(u32 em_address, bool set) +void Jit64IL::NotifyBreakpoint(u32 em_address, bool set) { int block_num = blocks.GetBlockNumberFromStartAddress(em_address); if (block_num >= 0) @@ -296,13 +294,13 @@ void ImHere() been_here[PC] = 1; } -void Jit64::Cleanup() +void Jit64IL::Cleanup() { if (jo.optimizeGatherPipe && js.fifoBytesThisBlock > 0) ABI_CallFunction((void *)&GPFifo::CheckGatherPipe); } -void Jit64::WriteExit(u32 destination, int exit_num) +void Jit64IL::WriteExit(u32 destination, int exit_num) { Cleanup(); SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount)); @@ -327,7 +325,7 @@ void Jit64::WriteExit(u32 destination, int exit_num) } } -void Jit64::WriteExitDestInEAX(int exit_num) +void Jit64IL::WriteExitDestInEAX(int exit_num) { MOV(32, M(&PC), R(EAX)); Cleanup(); @@ -335,7 +333,7 @@ void Jit64::WriteExitDestInEAX(int exit_num) JMP(asm_routines.dispatcher, true); } -void Jit64::WriteRfiExitDestInEAX() +void Jit64IL::WriteRfiExitDestInEAX() { MOV(32, M(&PC), R(EAX)); Cleanup(); @@ -343,7 +341,7 @@ void Jit64::WriteRfiExitDestInEAX() JMP(asm_routines.testExceptions, true); } -void Jit64::WriteExceptionExit(u32 exception) +void Jit64IL::WriteExceptionExit(u32 exception) { Cleanup(); OR(32, M(&PowerPC::ppcState.Exceptions), Imm32(exception)); @@ -351,14 +349,14 @@ void Jit64::WriteExceptionExit(u32 exception) JMP(asm_routines.testExceptions, true); } -void STACKALIGN Jit64::Run() +void STACKALIGN Jit64IL::Run() { CompiledCode pExecAddr = (CompiledCode)asm_routines.enterCode; pExecAddr(); //Will return when PowerPC::state changes } -void Jit64::SingleStep() +void Jit64IL::SingleStep() { // NOT USED, NOT TESTED, PROBABLY NOT WORKING YET // PanicAlert("Single"); @@ -370,7 +368,7 @@ void Jit64::SingleStep() pExecAddr();*/ } -void STACKALIGN Jit64::Jit(u32 em_address) +void STACKALIGN Jit64IL::Jit(u32 em_address) { if (GetSpaceLeft() < 0x10000 || blocks.IsFull()) { @@ -387,7 +385,7 @@ void STACKALIGN Jit64::Jit(u32 em_address) blocks.FinalizeBlock(block_num, jo.enableBlocklink, DoJit(em_address, &code_buffer, b)); } -const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buffer, JitBlock *b) +const u8* Jit64IL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buffer, JitBlock *b) { if (em_address == 0) PanicAlert("ERROR : Trying to compile at 0. LR=%08x", LR); diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit.h b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit.h index e5c16bf1bc..b5b93d48f4 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit.h +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit.h @@ -34,6 +34,7 @@ #include "../JitCommon/JitCache.h" #include "x64Emitter.h" #include "x64Analyzer.h" +#include "../CoreGeneralize.h" #include "IR.h" #ifdef _WIN32 @@ -41,20 +42,6 @@ #include #else - -// A bit of a hack to get things building under linux. We manually fill in this structure as needed -// from the real context. -struct CONTEXT -{ -#ifdef _M_X64 - u64 Rip; - u64 Rax; -#else - u32 Eip; - u32 Eax; -#endif -}; - #endif // #define INSTRUCTION_START Default(inst); return; @@ -73,19 +60,7 @@ struct CONTEXT #define DISABLE64 #endif - -class TrampolineCache : public Gen::XCodeBlock -{ -public: - void Init(); - void Shutdown(); - - const u8 *GetReadTrampoline(const InstructionInfo &info); - const u8 *GetWriteTrampoline(const InstructionInfo &info); -}; - - -class Jit64 : public Gen::XCodeBlock +class Jit64IL : public cCore { private: struct JitState @@ -134,8 +109,8 @@ private: PPCAnalyst::CodeBuffer code_buffer; public: - Jit64() : code_buffer(32000) {} - ~Jit64() {} + Jit64IL() : code_buffer(32000) {} + ~Jit64IL() {} JitState js; JitOptions jo; @@ -163,6 +138,7 @@ public: void SingleStep(); const u8 *BackPatch(u8 *codePtr, int accessType, u32 em_address, CONTEXT *ctx); + void ProfiledReJit(); #define JIT_OPCODE 0 @@ -295,7 +271,6 @@ public: void stmw(UGeckoInstruction inst); }; -extern Jit64 jit; void Jit(u32 em_address); diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitAsm.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitAsm.cpp index ee18b629d6..e266943e35 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitAsm.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitAsm.cpp @@ -70,7 +70,7 @@ void AsmRoutineManager::Generate() #ifndef _M_IX86 // Two statically allocated registers. MOV(64, R(RBX), Imm64((u64)Memory::base)); - MOV(64, R(R15), Imm64((u64)jit.GetBlockCache()->GetCodePointers())); //It's below 2GB so 32 bits are good enough + MOV(64, R(R15), Imm64((u64)jit->GetBlockCache()->GetCodePointers())); //It's below 2GB so 32 bits are good enough #endif // INT3(); diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Branch.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Branch.cpp index e98368324c..8bdfa8c064 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Branch.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Branch.cpp @@ -44,17 +44,17 @@ using namespace Gen; -void Jit64::sc(UGeckoInstruction inst) +void Jit64IL::sc(UGeckoInstruction inst) { ibuild.EmitSystemCall(ibuild.EmitIntConst(js.compilerPC)); } -void Jit64::rfi(UGeckoInstruction inst) +void Jit64IL::rfi(UGeckoInstruction inst) { ibuild.EmitRFIExit(); } -void Jit64::bx(UGeckoInstruction inst) +void Jit64IL::bx(UGeckoInstruction inst) { NORMALBRANCH_START INSTRUCTION_START; @@ -113,7 +113,7 @@ static IREmitter::InstLoc TestBranch(IREmitter::IRBuilder& ibuild, UGeckoInstruc return Test; } -void Jit64::bcx(UGeckoInstruction inst) +void Jit64IL::bcx(UGeckoInstruction inst) { NORMALBRANCH_START if (inst.LK) @@ -144,7 +144,7 @@ void Jit64::bcx(UGeckoInstruction inst) ibuild.EmitBranchUncond(ibuild.EmitIntConst(js.compilerPC + 4)); } -void Jit64::bcctrx(UGeckoInstruction inst) +void Jit64IL::bcctrx(UGeckoInstruction inst) { NORMALBRANCH_START if ((inst.BO & 4) == 0) { @@ -173,7 +173,7 @@ void Jit64::bcctrx(UGeckoInstruction inst) ibuild.EmitBranchUncond(destination); } -void Jit64::bclrx(UGeckoInstruction inst) +void Jit64IL::bclrx(UGeckoInstruction inst) { NORMALBRANCH_START if (inst.hex == 0x4e800020) { diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_FloatingPoint.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_FloatingPoint.cpp index d69f65dfa5..f06adcde77 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_FloatingPoint.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_FloatingPoint.cpp @@ -27,7 +27,7 @@ //#define INSTRUCTION_START Default(inst); return; #define INSTRUCTION_START -void Jit64::fp_arith_s(UGeckoInstruction inst) +void Jit64IL::fp_arith_s(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(FloatingPoint) @@ -66,7 +66,7 @@ void Jit64::fp_arith_s(UGeckoInstruction inst) ibuild.EmitStoreFReg(val, inst.FD); } -void Jit64::fmaddXX(UGeckoInstruction inst) +void Jit64IL::fmaddXX(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(FloatingPoint) @@ -91,7 +91,7 @@ void Jit64::fmaddXX(UGeckoInstruction inst) ibuild.EmitStoreFReg(val, inst.FD); } -void Jit64::fmrx(UGeckoInstruction inst) +void Jit64IL::fmrx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(FloatingPoint) @@ -103,7 +103,7 @@ void Jit64::fmrx(UGeckoInstruction inst) ibuild.EmitStoreFReg(val, inst.FD); } -void Jit64::fcmpx(UGeckoInstruction inst) +void Jit64IL::fcmpx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(FloatingPoint) diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Integer.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Integer.cpp index 2f87c15c26..53e462d12e 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Integer.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Integer.cpp @@ -37,7 +37,7 @@ static void ComputeRC(IREmitter::IRBuilder& ibuild, ibuild.EmitStoreCR(res, 0); } -void Jit64::reg_imm(UGeckoInstruction inst) +void Jit64IL::reg_imm(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) @@ -105,7 +105,7 @@ void Jit64::reg_imm(UGeckoInstruction inst) } } -void Jit64::cmpXX(UGeckoInstruction inst) +void Jit64IL::cmpXX(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) @@ -129,7 +129,7 @@ void Jit64::cmpXX(UGeckoInstruction inst) ibuild.EmitStoreCR(res, inst.CRFD); } -void Jit64::orx(UGeckoInstruction inst) +void Jit64IL::orx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) @@ -142,7 +142,7 @@ void Jit64::orx(UGeckoInstruction inst) // m_GPR[_inst.RA] = m_GPR[_inst.RS] ^ m_GPR[_inst.RB]; -void Jit64::xorx(UGeckoInstruction inst) +void Jit64IL::xorx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) @@ -153,7 +153,7 @@ void Jit64::xorx(UGeckoInstruction inst) ComputeRC(ibuild, val); } -void Jit64::andx(UGeckoInstruction inst) +void Jit64IL::andx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) @@ -164,7 +164,7 @@ void Jit64::andx(UGeckoInstruction inst) ComputeRC(ibuild, val); } -void Jit64::extsbx(UGeckoInstruction inst) +void Jit64IL::extsbx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) @@ -175,7 +175,7 @@ void Jit64::extsbx(UGeckoInstruction inst) ComputeRC(ibuild, val); } -void Jit64::extshx(UGeckoInstruction inst) +void Jit64IL::extshx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) @@ -186,7 +186,7 @@ void Jit64::extshx(UGeckoInstruction inst) ComputeRC(ibuild, val); } -void Jit64::subfic(UGeckoInstruction inst) +void Jit64IL::subfic(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) @@ -205,7 +205,7 @@ void Jit64::subfic(UGeckoInstruction inst) ibuild.EmitStoreCarry(test); } -void Jit64::subfcx(UGeckoInstruction inst) +void Jit64IL::subfcx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) @@ -222,7 +222,7 @@ void Jit64::subfcx(UGeckoInstruction inst) ComputeRC(ibuild, val); } -void Jit64::subfex(UGeckoInstruction inst) +void Jit64IL::subfex(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) @@ -243,7 +243,7 @@ void Jit64::subfex(UGeckoInstruction inst) ComputeRC(ibuild, val); } -void Jit64::subfx(UGeckoInstruction inst) +void Jit64IL::subfx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) @@ -255,7 +255,7 @@ void Jit64::subfx(UGeckoInstruction inst) ComputeRC(ibuild, val); } -void Jit64::mulli(UGeckoInstruction inst) +void Jit64IL::mulli(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) @@ -264,7 +264,7 @@ void Jit64::mulli(UGeckoInstruction inst) ibuild.EmitStoreGReg(val, inst.RD); } -void Jit64::mullwx(UGeckoInstruction inst) +void Jit64IL::mullwx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) @@ -275,7 +275,7 @@ void Jit64::mullwx(UGeckoInstruction inst) ComputeRC(ibuild, val); } -void Jit64::mulhwux(UGeckoInstruction inst) +void Jit64IL::mulhwux(UGeckoInstruction inst) { Default(inst); return; #if 0 @@ -310,7 +310,7 @@ void Jit64::mulhwux(UGeckoInstruction inst) } // skipped some of the special handling in here - if we get crashes, let the interpreter handle this op -void Jit64::divwux(UGeckoInstruction inst) { +void Jit64IL::divwux(UGeckoInstruction inst) { Default(inst); return; #if 0 int a = inst.RA, b = inst.RB, d = inst.RD; @@ -343,7 +343,7 @@ u32 Helper_Mask(u8 mb, u8 me) ); } -void Jit64::addx(UGeckoInstruction inst) +void Jit64IL::addx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) @@ -354,7 +354,7 @@ void Jit64::addx(UGeckoInstruction inst) ComputeRC(ibuild, val); } -void Jit64::addzex(UGeckoInstruction inst) +void Jit64IL::addzex(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) @@ -368,7 +368,7 @@ void Jit64::addzex(UGeckoInstruction inst) ComputeRC(ibuild, val); } // This can be optimized -void Jit64::addex(UGeckoInstruction inst) +void Jit64IL::addex(UGeckoInstruction inst) { Default(inst); return; #if 0 @@ -399,7 +399,7 @@ void Jit64::addex(UGeckoInstruction inst) #endif } -void Jit64::rlwinmx(UGeckoInstruction inst) +void Jit64IL::rlwinmx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) @@ -413,7 +413,7 @@ void Jit64::rlwinmx(UGeckoInstruction inst) } -void Jit64::rlwimix(UGeckoInstruction inst) +void Jit64IL::rlwimix(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) @@ -429,7 +429,7 @@ void Jit64::rlwimix(UGeckoInstruction inst) ComputeRC(ibuild, val); } -void Jit64::rlwnmx(UGeckoInstruction inst) +void Jit64IL::rlwnmx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) @@ -442,7 +442,7 @@ void Jit64::rlwnmx(UGeckoInstruction inst) ComputeRC(ibuild, val); } -void Jit64::negx(UGeckoInstruction inst) +void Jit64IL::negx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) @@ -453,7 +453,7 @@ void Jit64::negx(UGeckoInstruction inst) ComputeRC(ibuild, val); } -void Jit64::srwx(UGeckoInstruction inst) +void Jit64IL::srwx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) @@ -472,7 +472,7 @@ void Jit64::srwx(UGeckoInstruction inst) ComputeRC(ibuild, val); } -void Jit64::slwx(UGeckoInstruction inst) +void Jit64IL::slwx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) @@ -491,7 +491,7 @@ void Jit64::slwx(UGeckoInstruction inst) ComputeRC(ibuild, val); } -void Jit64::srawx(UGeckoInstruction inst) +void Jit64IL::srawx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) @@ -514,7 +514,7 @@ void Jit64::srawx(UGeckoInstruction inst) ibuild.EmitStoreCarry(test); } -void Jit64::srawix(UGeckoInstruction inst) +void Jit64IL::srawix(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) @@ -531,7 +531,7 @@ void Jit64::srawix(UGeckoInstruction inst) } // count leading zeroes -void Jit64::cntlzwx(UGeckoInstruction inst) +void Jit64IL::cntlzwx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStore.cpp index 8749a49467..2e4457dc18 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStore.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStore.cpp @@ -37,7 +37,7 @@ //#define INSTRUCTION_START Default(inst); return; #define INSTRUCTION_START -void Jit64::lhax(UGeckoInstruction inst) +void Jit64IL::lhax(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(LoadStore) @@ -49,7 +49,7 @@ void Jit64::lhax(UGeckoInstruction inst) ibuild.EmitStoreGReg(val, inst.RD); } -void Jit64::lXz(UGeckoInstruction inst) +void Jit64IL::lXz(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(LoadStore) @@ -69,7 +69,7 @@ void Jit64::lXz(UGeckoInstruction inst) ibuild.EmitStoreGReg(val, inst.RD); } -void Jit64::lha(UGeckoInstruction inst) +void Jit64IL::lha(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(LoadStore) @@ -82,7 +82,7 @@ void Jit64::lha(UGeckoInstruction inst) ibuild.EmitStoreGReg(val, inst.RD); } -void Jit64::lXzx(UGeckoInstruction inst) +void Jit64IL::lXzx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(LoadStore) @@ -104,7 +104,7 @@ void Jit64::lXzx(UGeckoInstruction inst) } // Zero cache line. -void Jit64::dcbz(UGeckoInstruction inst) +void Jit64IL::dcbz(UGeckoInstruction inst) { Default(inst); return; @@ -129,7 +129,7 @@ void Jit64::dcbz(UGeckoInstruction inst) #endif } -void Jit64::stX(UGeckoInstruction inst) +void Jit64IL::stX(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(LoadStore) @@ -148,7 +148,7 @@ void Jit64::stX(UGeckoInstruction inst) } } -void Jit64::stXx(UGeckoInstruction inst) +void Jit64IL::stXx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(LoadStore) @@ -167,7 +167,7 @@ void Jit64::stXx(UGeckoInstruction inst) } // A few games use these heavily in video codecs. -void Jit64::lmw(UGeckoInstruction inst) +void Jit64IL::lmw(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(LoadStore) @@ -182,7 +182,7 @@ void Jit64::lmw(UGeckoInstruction inst) } } -void Jit64::stmw(UGeckoInstruction inst) +void Jit64IL::stmw(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(LoadStore) diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStoreFloating.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStoreFloating.cpp index 7d79e5eaae..19e68b4ff5 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStoreFloating.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStoreFloating.cpp @@ -41,7 +41,7 @@ // and pshufb could help a lot. // Also add hacks for things like lfs/stfs the same reg consecutively, that is, simple memory moves. -void Jit64::lfs(UGeckoInstruction inst) +void Jit64IL::lfs(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(LoadStoreFloating) @@ -54,7 +54,7 @@ void Jit64::lfs(UGeckoInstruction inst) } -void Jit64::lfd(UGeckoInstruction inst) +void Jit64IL::lfd(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(LoadStoreFloating) @@ -68,7 +68,7 @@ void Jit64::lfd(UGeckoInstruction inst) } -void Jit64::stfd(UGeckoInstruction inst) +void Jit64IL::stfd(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(LoadStoreFloating) @@ -83,7 +83,7 @@ void Jit64::stfd(UGeckoInstruction inst) } -void Jit64::stfs(UGeckoInstruction inst) +void Jit64IL::stfs(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(LoadStoreFloating) @@ -99,7 +99,7 @@ void Jit64::stfs(UGeckoInstruction inst) } -void Jit64::stfsx(UGeckoInstruction inst) +void Jit64IL::stfsx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(LoadStoreFloating) @@ -113,7 +113,7 @@ void Jit64::stfsx(UGeckoInstruction inst) } -void Jit64::lfsx(UGeckoInstruction inst) +void Jit64IL::lfsx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(LoadStoreFloating) diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStorePaired.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStorePaired.cpp index 20896175d2..ae7a734879 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStorePaired.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStorePaired.cpp @@ -38,7 +38,7 @@ //#define INSTRUCTION_START Default(inst); return; #define INSTRUCTION_START -void Jit64::psq_st(UGeckoInstruction inst) +void Jit64IL::psq_st(UGeckoInstruction inst) { INSTRUCTION_START DISABLE64 @@ -54,7 +54,7 @@ void Jit64::psq_st(UGeckoInstruction inst) ibuild.EmitStorePaired(val, addr, inst.I); } -void Jit64::psq_l(UGeckoInstruction inst) +void Jit64IL::psq_l(UGeckoInstruction inst) { INSTRUCTION_START DISABLE64 diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Paired.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Paired.cpp index 19583b2e6a..599e305eef 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Paired.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Paired.cpp @@ -25,27 +25,27 @@ #include "Jit.h" -void Jit64::ps_mr(UGeckoInstruction inst) +void Jit64IL::ps_mr(UGeckoInstruction inst) { Default(inst); return; } -void Jit64::ps_sel(UGeckoInstruction inst) +void Jit64IL::ps_sel(UGeckoInstruction inst) { Default(inst); return; } -void Jit64::ps_sign(UGeckoInstruction inst) +void Jit64IL::ps_sign(UGeckoInstruction inst) { Default(inst); return; } -void Jit64::ps_rsqrte(UGeckoInstruction inst) +void Jit64IL::ps_rsqrte(UGeckoInstruction inst) { Default(inst); return; } -void Jit64::ps_arith(UGeckoInstruction inst) +void Jit64IL::ps_arith(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Paired) @@ -74,7 +74,7 @@ void Jit64::ps_arith(UGeckoInstruction inst) ibuild.EmitStoreFReg(val, inst.FD); } -void Jit64::ps_sum(UGeckoInstruction inst) +void Jit64IL::ps_sum(UGeckoInstruction inst) { // FIXME: This operation strikes me as a bit strange... // perhaps we can optimize it depending on the users? @@ -95,7 +95,7 @@ void Jit64::ps_sum(UGeckoInstruction inst) } -void Jit64::ps_muls(UGeckoInstruction inst) +void Jit64IL::ps_muls(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Paired) @@ -120,7 +120,7 @@ void Jit64::ps_muls(UGeckoInstruction inst) //TODO: find easy cases and optimize them, do a breakout like ps_arith -void Jit64::ps_mergeXX(UGeckoInstruction inst) +void Jit64IL::ps_mergeXX(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Paired) @@ -153,7 +153,7 @@ void Jit64::ps_mergeXX(UGeckoInstruction inst) } -void Jit64::ps_maddXX(UGeckoInstruction inst) +void Jit64IL::ps_maddXX(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Paired) diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_SystemRegisters.cpp index acfb86149d..7df2092c38 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_SystemRegisters.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_SystemRegisters.cpp @@ -31,7 +31,7 @@ //#define INSTRUCTION_START Default(inst); return; #define INSTRUCTION_START - void Jit64::mtspr(UGeckoInstruction inst) + void Jit64IL::mtspr(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(SystemRegisters) @@ -63,7 +63,7 @@ } } - void Jit64::mfspr(UGeckoInstruction inst) + void Jit64IL::mfspr(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(SystemRegisters) @@ -96,7 +96,7 @@ // ======================================================================================= // Don't interpret this, if we do we get thrown out // -------------- - void Jit64::mtmsr(UGeckoInstruction inst) + void Jit64IL::mtmsr(UGeckoInstruction inst) { ibuild.EmitStoreMSR(ibuild.EmitLoadGReg(inst.RS)); ibuild.EmitBranchUncond(ibuild.EmitIntConst(js.compilerPC + 4)); @@ -104,21 +104,21 @@ // ============== - void Jit64::mfmsr(UGeckoInstruction inst) + void Jit64IL::mfmsr(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(SystemRegisters) ibuild.EmitStoreGReg(ibuild.EmitLoadMSR(), inst.RD); } - void Jit64::mftb(UGeckoInstruction inst) + void Jit64IL::mftb(UGeckoInstruction inst) { INSTRUCTION_START; JITDISABLE(SystemRegisters) mfspr(inst); } - void Jit64::mfcr(UGeckoInstruction inst) + void Jit64IL::mfcr(UGeckoInstruction inst) { Default(inst); return; #if 0 @@ -139,7 +139,7 @@ #endif } - void Jit64::mtcrf(UGeckoInstruction inst) + void Jit64IL::mtcrf(UGeckoInstruction inst) { Default(inst); return; #if 0 diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Util.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Util.cpp new file mode 100644 index 0000000000..34dfbe443b --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Util.cpp @@ -0,0 +1,184 @@ +// Copyright (C) 2003-2009 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Common.h" +#include "Thunk.h" + +#include "../PowerPC.h" +#include "../../Core.h" +#include "../../HW/GPFifo.h" +#include "../../HW/CommandProcessor.h" +#include "../../HW/PixelEngine.h" +#include "../../HW/Memmap.h" +#include "../PPCTables.h" +#include "x64Emitter.h" +#include "ABI.h" + +#if !(defined JITTEST && JITTEST) +#include "../Jit64IL/Jit.h" +#include "../JitCommon/JitCache.h" +#include "../Jit64IL/JitAsm.h" +#else +#include "../Jit64/Jit.h" +#include "../JitCommon/JitCache.h" +#include "../Jit64/JitAsm.h" +#include "../Jit64/JitRegCache.h" +#endif +#include "../CoreGeneralize.h" + +using namespace Gen; +void Jit64IL::JitClearCA() +{ + AND(32, M(&PowerPC::ppcState.spr[SPR_XER]), Imm32(~XER_CA_MASK)); //XER.CA = 0 +} + +void Jit64IL::JitSetCA() +{ + OR(32, M(&PowerPC::ppcState.spr[SPR_XER]), Imm32(XER_CA_MASK)); //XER.CA = 1 +} + void Jit64IL::GenerateCarry(Gen::X64Reg temp_reg) + { + // Not needed + } + void Jit64IL::tri_op(int d, int a, int b, bool reversible, void (XEmitter::*op)(Gen::X64Reg, Gen::OpArg)) +{ + //Not Needed +} +void Jit64IL::regimmop(int d, int a, bool binary, u32 value, Operation doop, void (XEmitter::*op)(int, const Gen::OpArg&, const Gen::OpArg&), bool Rc, bool carry) +{ + // Not Needed +} +void Jit64IL::fp_tri_op(int d, int a, int b, bool reversible, bool dupe, void (XEmitter::*op)(Gen::X64Reg, Gen::OpArg)) +{ + // Not Needed +} +void Jit64IL::UnsafeLoadRegToReg(X64Reg reg_addr, X64Reg reg_value, int accessSize, s32 offset, bool signExtend) +{ +#ifdef _M_IX86 + AND(32, R(reg_addr), Imm32(Memory::MEMVIEW32_MASK)); + MOVZX(32, accessSize, reg_value, MDisp(reg_addr, (u32)Memory::base + offset)); +#else + MOVZX(32, accessSize, reg_value, MComplex(RBX, reg_addr, SCALE_1, offset)); +#endif + if (accessSize == 32) + { + BSWAP(32, reg_value); + } + else if (accessSize == 16) + { + BSWAP(32, reg_value); + if (signExtend) + SAR(32, R(reg_value), Imm8(16)); + else + SHR(32, R(reg_value), Imm8(16)); + } else if (signExtend) { + // TODO: bake 8-bit into the original load. + MOVSX(32, accessSize, reg_value, R(reg_value)); + } +} + +void Jit64IL::SafeLoadRegToEAX(X64Reg reg, int accessSize, s32 offset, bool signExtend) +{ + if (offset) + ADD(32, R(reg), Imm32((u32)offset)); + TEST(32, R(reg), Imm32(0x0C000000)); + FixupBranch argh = J_CC(CC_Z); + switch (accessSize) + { + case 32: ABI_CallFunctionR(thunks.ProtectFunction((void *)&Memory::Read_U32, 1), reg); break; + case 16: ABI_CallFunctionR(thunks.ProtectFunction((void *)&Memory::Read_U16, 1), reg); break; + case 8: ABI_CallFunctionR(thunks.ProtectFunction((void *)&Memory::Read_U8, 1), reg); break; + } + if (signExtend && accessSize < 32) { + // Need to sign extend values coming from the Read_U* functions. + MOVSX(32, accessSize, EAX, R(EAX)); + } + FixupBranch arg2 = J(); + SetJumpTarget(argh); + UnsafeLoadRegToReg(reg, EAX, accessSize, 0, signExtend); + SetJumpTarget(arg2); +} + +void Jit64IL::UnsafeWriteRegToReg(X64Reg reg_value, X64Reg reg_addr, int accessSize, s32 offset) +{ + if (accessSize == 8 && reg_value >= 4) { + PanicAlert("WARNING: likely incorrect use of UnsafeWriteRegToReg!"); + } + BSWAP(accessSize, reg_value); +#ifdef _M_IX86 + AND(32, R(reg_addr), Imm32(Memory::MEMVIEW32_MASK)); + MOV(accessSize, MDisp(reg_addr, (u32)Memory::base + offset), R(reg_value)); +#else + MOV(accessSize, MComplex(RBX, reg_addr, SCALE_1, offset), R(reg_value)); +#endif +} + +// Destroys both arg registers +void Jit64IL::SafeWriteRegToReg(X64Reg reg_value, X64Reg reg_addr, int accessSize, s32 offset) +{ + if (offset) + ADD(32, R(reg_addr), Imm32(offset)); + TEST(32, R(reg_addr), Imm32(0x0C000000)); + FixupBranch argh = J_CC(CC_Z); + switch (accessSize) + { + case 32: ABI_CallFunctionRR(thunks.ProtectFunction((void *)&Memory::Write_U32, 2), reg_value, reg_addr); break; + case 16: ABI_CallFunctionRR(thunks.ProtectFunction((void *)&Memory::Write_U16, 2), reg_value, reg_addr); break; + case 8: ABI_CallFunctionRR(thunks.ProtectFunction((void *)&Memory::Write_U8, 2), reg_value, reg_addr); break; + } + FixupBranch arg2 = J(); + SetJumpTarget(argh); + UnsafeWriteRegToReg(reg_value, reg_addr, accessSize, 0); + SetJumpTarget(arg2); +} + +void Jit64IL::WriteToConstRamAddress(int accessSize, const Gen::OpArg& arg, u32 address) +{ +#ifdef _M_X64 + MOV(accessSize, MDisp(RBX, address & 0x3FFFFFFF), arg); +#else + MOV(accessSize, M((void*)(Memory::base + (address & Memory::MEMVIEW32_MASK))), arg); +#endif +} + +void Jit64IL::WriteFloatToConstRamAddress(const Gen::X64Reg& xmm_reg, u32 address) +{ +#ifdef _M_X64 + MOV(32, R(RAX), Imm32(address)); + MOVSS(MComplex(RBX, RAX, 1, 0), xmm_reg); +#else + MOVSS(M((void*)((u32)Memory::base + (address & Memory::MEMVIEW32_MASK))), xmm_reg); +#endif +} + +void Jit64IL::ForceSinglePrecisionS(X64Reg xmm) { + // Most games don't need these. Zelda requires it though - some platforms get stuck without them. + if (jo.accurateSinglePrecision) + { + CVTSD2SS(xmm, R(xmm)); + CVTSS2SD(xmm, R(xmm)); + } +} + +void Jit64IL::ForceSinglePrecisionP(X64Reg xmm) { + // Most games don't need these. Zelda requires it though - some platforms get stuck without them. + if (jo.accurateSinglePrecision) + { + CVTPD2PS(xmm, R(xmm)); + CVTPS2PD(xmm, R(xmm)); + } +} diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitBackpatch.cpp b/Source/Core/Core/Src/PowerPC/JitCommon/JitBackpatch.cpp index 6ba677e7f3..2343fa72a9 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/JitBackpatch.cpp +++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitBackpatch.cpp @@ -149,10 +149,10 @@ const u8 *TrampolineCache::GetWriteTrampoline(const InstructionInfo &info) // 1) It's really necessary. We don't know anything about the context. // 2) It doesn't really hurt. Only instructions that access I/O will get these, and there won't be // that many of them in a typical program/game. -const u8 *Jit64::BackPatch(u8 *codePtr, int accessType, u32 emAddress, CONTEXT *ctx) +const u8 *cCore::BackPatch(u8 *codePtr, int accessType, u32 emAddress, CONTEXT *ctx) { #ifdef _M_X64 - if (!jit.IsInCodeSpace(codePtr)) + if (!jit->IsInCodeSpace(codePtr)) return 0; // this will become a regular crash real soon after this InstructionInfo info; diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp index c2190b1991..c2c42c64df 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp +++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp @@ -337,7 +337,7 @@ void JitBlockCache::GetBlockNumbersFromAddress(u32 em_address, std::vector void JitBlockCache::InvalidateCodeRange(u32 address, u32 length) { - if (!jit.jo.enableBlocklink) + if (!jit->jo.enableBlocklink) return; return; //This is slow but should be safe (zelda needs it for block linking) diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/Jit_Tables.cpp b/Source/Core/Core/Src/PowerPC/JitCommon/Jit_Tables.cpp index 6e8d38aa78..19cfc06300 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/Jit_Tables.cpp +++ b/Source/Core/Core/Src/PowerPC/JitCommon/Jit_Tables.cpp @@ -16,9 +16,10 @@ // http://code.google.com/p/dolphin-emu/ #include "Jit_Tables.h" +#include "../CoreGeneralize.h" // Should be moved in to the Jit class -typedef void (Jit64::*_Instruction) (UGeckoInstruction instCode); +typedef void (cCore::*_Instruction) (UGeckoInstruction instCode); _Instruction dynaOpTable[64]; _Instruction dynaOpTable4[1024]; @@ -26,11 +27,11 @@ _Instruction dynaOpTable19[1024]; _Instruction dynaOpTable31[1024]; _Instruction dynaOpTable59[32]; _Instruction dynaOpTable63[1024]; -void Jit64::DynaRunTable4(UGeckoInstruction _inst) {(this->*dynaOpTable4 [_inst.SUBOP10])(_inst);} -void Jit64::DynaRunTable19(UGeckoInstruction _inst) {(this->*dynaOpTable19[_inst.SUBOP10])(_inst);} -void Jit64::DynaRunTable31(UGeckoInstruction _inst) {(this->*dynaOpTable31[_inst.SUBOP10])(_inst);} -void Jit64::DynaRunTable59(UGeckoInstruction _inst) {(this->*dynaOpTable59[_inst.SUBOP5 ])(_inst);} -void Jit64::DynaRunTable63(UGeckoInstruction _inst) {(this->*dynaOpTable63[_inst.SUBOP10])(_inst);} +void cCore::DynaRunTable4(UGeckoInstruction _inst) {(this->*dynaOpTable4 [_inst.SUBOP10])(_inst);} +void cCore::DynaRunTable19(UGeckoInstruction _inst) {(this->*dynaOpTable19[_inst.SUBOP10])(_inst);} +void cCore::DynaRunTable31(UGeckoInstruction _inst) {(this->*dynaOpTable31[_inst.SUBOP10])(_inst);} +void cCore::DynaRunTable59(UGeckoInstruction _inst) {(this->*dynaOpTable59[_inst.SUBOP5 ])(_inst);} +void cCore::DynaRunTable63(UGeckoInstruction _inst) {(this->*dynaOpTable63[_inst.SUBOP10])(_inst);} @@ -44,370 +45,342 @@ struct GekkoOPTemplate static GekkoOPTemplate primarytable[] = { - {4, &Jit64::DynaRunTable4}, //"RunTable4", OPTYPE_SUBTABLE | (4<<24), 0}}, - {19, &Jit64::DynaRunTable19}, //"RunTable19", OPTYPE_SUBTABLE | (19<<24), 0}}, - {31, &Jit64::DynaRunTable31}, //"RunTable31", OPTYPE_SUBTABLE | (31<<24), 0}}, - {59, &Jit64::DynaRunTable59}, //"RunTable59", OPTYPE_SUBTABLE | (59<<24), 0}}, - {63, &Jit64::DynaRunTable63}, //"RunTable63", OPTYPE_SUBTABLE | (63<<24), 0}}, + {4, &cCore::DynaRunTable4}, //"RunTable4", OPTYPE_SUBTABLE | (4<<24), 0}}, + {19, &cCore::DynaRunTable19}, //"RunTable19", OPTYPE_SUBTABLE | (19<<24), 0}}, + {31, &cCore::DynaRunTable31}, //"RunTable31", OPTYPE_SUBTABLE | (31<<24), 0}}, + {59, &cCore::DynaRunTable59}, //"RunTable59", OPTYPE_SUBTABLE | (59<<24), 0}}, + {63, &cCore::DynaRunTable63}, //"RunTable63", OPTYPE_SUBTABLE | (63<<24), 0}}, - {16, &Jit64::bcx}, //"bcx", OPTYPE_SYSTEM, FL_ENDBLOCK}}, - {18, &Jit64::bx}, //"bx", OPTYPE_SYSTEM, FL_ENDBLOCK}}, + {16, &cCore::bcx}, //"bcx", OPTYPE_SYSTEM, FL_ENDBLOCK}}, + {18, &cCore::bx}, //"bx", OPTYPE_SYSTEM, FL_ENDBLOCK}}, - {1, &Jit64::HLEFunction}, //"HLEFunction", OPTYPE_SYSTEM, FL_ENDBLOCK}}, - {2, &Jit64::Default}, //"DynaBlock", OPTYPE_SYSTEM, 0}}, - {3, &Jit64::Default}, //"twi", OPTYPE_SYSTEM, 0}}, - {17, &Jit64::sc}, //"sc", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}}, + {1, &cCore::HLEFunction}, //"HLEFunction", OPTYPE_SYSTEM, FL_ENDBLOCK}}, + {2, &cCore::Default}, //"DynaBlock", OPTYPE_SYSTEM, 0}}, + {3, &cCore::Default}, //"twi", OPTYPE_SYSTEM, 0}}, + {17, &cCore::sc}, //"sc", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}}, - {7, &Jit64::mulli}, //"mulli", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_RC_BIT, 2}}, - {8, &Jit64::subfic}, //"subfic", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CA}}, - {10, &Jit64::cmpXX}, //"cmpli", OPTYPE_INTEGER, FL_IN_A | FL_SET_CRn}}, - {11, &Jit64::cmpXX}, //"cmpi", OPTYPE_INTEGER, FL_IN_A | FL_SET_CRn}}, - {12, &Jit64::reg_imm}, //"addic", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CA}}, - {13, &Jit64::reg_imm}, //"addic_rc", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CR0}}, - {14, &Jit64::reg_imm}, //"addi", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A0}}, - {15, &Jit64::reg_imm}, //"addis", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A0}}, + {7, &cCore::mulli}, //"mulli", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_RC_BIT, 2}}, + {8, &cCore::subfic}, //"subfic", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CA}}, + {10, &cCore::cmpXX}, //"cmpli", OPTYPE_INTEGER, FL_IN_A | FL_SET_CRn}}, + {11, &cCore::cmpXX}, //"cmpi", OPTYPE_INTEGER, FL_IN_A | FL_SET_CRn}}, + {12, &cCore::reg_imm}, //"addic", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CA}}, + {13, &cCore::reg_imm}, //"addic_rc", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CR0}}, + {14, &cCore::reg_imm}, //"addi", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A0}}, + {15, &cCore::reg_imm}, //"addis", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A0}}, - {20, &Jit64::rlwimix}, //"rlwimix", OPTYPE_INTEGER, FL_OUT_A | FL_IN_A | FL_IN_S | FL_RC_BIT}}, - {21, &Jit64::rlwinmx}, //"rlwinmx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}}, - {23, &Jit64::rlwnmx}, //"rlwnmx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_IN_B | FL_RC_BIT}}, + {20, &cCore::rlwimix}, //"rlwimix", OPTYPE_INTEGER, FL_OUT_A | FL_IN_A | FL_IN_S | FL_RC_BIT}}, + {21, &cCore::rlwinmx}, //"rlwinmx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}}, + {23, &cCore::rlwnmx}, //"rlwnmx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_IN_B | FL_RC_BIT}}, - {24, &Jit64::reg_imm}, //"ori", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S}}, - {25, &Jit64::reg_imm}, //"oris", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S}}, - {26, &Jit64::reg_imm}, //"xori", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S}}, - {27, &Jit64::reg_imm}, //"xoris", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S}}, - {28, &Jit64::reg_imm}, //"andi_rc", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_SET_CR0}}, - {29, &Jit64::reg_imm}, //"andis_rc", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_SET_CR0}}, + {24, &cCore::reg_imm}, //"ori", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S}}, + {25, &cCore::reg_imm}, //"oris", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S}}, + {26, &cCore::reg_imm}, //"xori", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S}}, + {27, &cCore::reg_imm}, //"xoris", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S}}, + {28, &cCore::reg_imm}, //"andi_rc", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_SET_CR0}}, + {29, &cCore::reg_imm}, //"andis_rc", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_SET_CR0}}, -#if JITTEST - {32, &Jit64::lXz}, //"lwz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, - {33, &Jit64::lXz}, //"lwzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, - {34, &Jit64::lXz}, //"lbz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, - {35, &Jit64::lXz}, //"lbzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, - {40, &Jit64::lXz}, //"lhz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, - {41, &Jit64::lXz}, //"lhzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, -#else - {32, &Jit64::lXz}, //"lwz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, - {33, &Jit64::Default}, //"lwzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, - {34, &Jit64::lXz}, //"lbz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, - {35, &Jit64::Default}, //"lbzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, - {40, &Jit64::lXz}, //"lhz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, - {41, &Jit64::Default}, //"lhzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, -#endif - {42, &Jit64::lha}, //"lha", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, - {43, &Jit64::Default}, //"lhau", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, + {32, &cCore::lXz}, //"lwz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, + {33, &cCore::lXz}, //"lwzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, + {34, &cCore::lXz}, //"lbz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, + {35, &cCore::lXz}, //"lbzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, + {40, &cCore::lXz}, //"lhz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, + {41, &cCore::lXz}, //"lhzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, + + {42, &cCore::lha}, //"lha", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, + {43, &cCore::Default}, //"lhau", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, - {44, &Jit64::stX}, //"sth", OPTYPE_STORE, FL_IN_A | FL_IN_S}}, - {45, &Jit64::stX}, //"sthu", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_S}}, - {36, &Jit64::stX}, //"stw", OPTYPE_STORE, FL_IN_A | FL_IN_S}}, - {37, &Jit64::stX}, //"stwu", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_S}}, - {38, &Jit64::stX}, //"stb", OPTYPE_STORE, FL_IN_A | FL_IN_S}}, - {39, &Jit64::stX}, //"stbu", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_S}}, + {44, &cCore::stX}, //"sth", OPTYPE_STORE, FL_IN_A | FL_IN_S}}, + {45, &cCore::stX}, //"sthu", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_S}}, + {36, &cCore::stX}, //"stw", OPTYPE_STORE, FL_IN_A | FL_IN_S}}, + {37, &cCore::stX}, //"stwu", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_S}}, + {38, &cCore::stX}, //"stb", OPTYPE_STORE, FL_IN_A | FL_IN_S}}, + {39, &cCore::stX}, //"stbu", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_S}}, - {46, &Jit64::lmw}, //"lmw", OPTYPE_SYSTEM, FL_EVIL, 10}}, - {47, &Jit64::stmw}, //"stmw", OPTYPE_SYSTEM, FL_EVIL, 10}}, + {46, &cCore::lmw}, //"lmw", OPTYPE_SYSTEM, FL_EVIL, 10}}, + {47, &cCore::stmw}, //"stmw", OPTYPE_SYSTEM, FL_EVIL, 10}}, - {48, &Jit64::lfs}, //"lfs", OPTYPE_LOADFP, FL_IN_A}}, - {49, &Jit64::Default}, //"lfsu", OPTYPE_LOADFP, FL_OUT_A | FL_IN_A}}, - {50, &Jit64::lfd}, //"lfd", OPTYPE_LOADFP, FL_IN_A}}, - {51, &Jit64::Default}, //"lfdu", OPTYPE_LOADFP, FL_OUT_A | FL_IN_A}}, + {48, &cCore::lfs}, //"lfs", OPTYPE_LOADFP, FL_IN_A}}, + {49, &cCore::Default}, //"lfsu", OPTYPE_LOADFP, FL_OUT_A | FL_IN_A}}, + {50, &cCore::lfd}, //"lfd", OPTYPE_LOADFP, FL_IN_A}}, + {51, &cCore::Default}, //"lfdu", OPTYPE_LOADFP, FL_OUT_A | FL_IN_A}}, - {52, &Jit64::stfs}, //"stfs", OPTYPE_STOREFP, FL_IN_A}}, - {53, &Jit64::stfs}, //"stfsu", OPTYPE_STOREFP, FL_OUT_A | FL_IN_A}}, - {54, &Jit64::stfd}, //"stfd", OPTYPE_STOREFP, FL_IN_A}}, - {55, &Jit64::Default}, //"stfdu", OPTYPE_STOREFP, FL_OUT_A | FL_IN_A}}, + {52, &cCore::stfs}, //"stfs", OPTYPE_STOREFP, FL_IN_A}}, + {53, &cCore::stfs}, //"stfsu", OPTYPE_STOREFP, FL_OUT_A | FL_IN_A}}, + {54, &cCore::stfd}, //"stfd", OPTYPE_STOREFP, FL_IN_A}}, + {55, &cCore::Default}, //"stfdu", OPTYPE_STOREFP, FL_OUT_A | FL_IN_A}}, - {56, &Jit64::psq_l}, //"psq_l", OPTYPE_PS, FL_IN_A}}, - {57, &Jit64::psq_l}, //"psq_lu", OPTYPE_PS, FL_OUT_A | FL_IN_A}}, - {60, &Jit64::psq_st}, //"psq_st", OPTYPE_PS, FL_IN_A}}, - {61, &Jit64::psq_st}, //"psq_stu", OPTYPE_PS, FL_OUT_A | FL_IN_A}}, + {56, &cCore::psq_l}, //"psq_l", OPTYPE_PS, FL_IN_A}}, + {57, &cCore::psq_l}, //"psq_lu", OPTYPE_PS, FL_OUT_A | FL_IN_A}}, + {60, &cCore::psq_st}, //"psq_st", OPTYPE_PS, FL_IN_A}}, + {61, &cCore::psq_st}, //"psq_stu", OPTYPE_PS, FL_OUT_A | FL_IN_A}}, //missing: 0, 5, 6, 9, 22, 30, 62, 58 - {0, &Jit64::Default}, //"unknown_instruction", OPTYPE_UNKNOWN, 0}}, - {5, &Jit64::Default}, //"unknown_instruction", OPTYPE_UNKNOWN, 0}}, - {6, &Jit64::Default}, //"unknown_instruction", OPTYPE_UNKNOWN, 0}}, - {9, &Jit64::Default}, //"unknown_instruction", OPTYPE_UNKNOWN, 0}}, - {22, &Jit64::Default}, //"unknown_instruction", OPTYPE_UNKNOWN, 0}}, - {30, &Jit64::Default}, //"unknown_instruction", OPTYPE_UNKNOWN, 0}}, - {62, &Jit64::Default}, //"unknown_instruction", OPTYPE_UNKNOWN, 0}}, - {58, &Jit64::Default}, //"unknown_instruction", OPTYPE_UNKNOWN, 0}}, + {0, &cCore::Default}, //"unknown_instruction", OPTYPE_UNKNOWN, 0}}, + {5, &cCore::Default}, //"unknown_instruction", OPTYPE_UNKNOWN, 0}}, + {6, &cCore::Default}, //"unknown_instruction", OPTYPE_UNKNOWN, 0}}, + {9, &cCore::Default}, //"unknown_instruction", OPTYPE_UNKNOWN, 0}}, + {22, &cCore::Default}, //"unknown_instruction", OPTYPE_UNKNOWN, 0}}, + {30, &cCore::Default}, //"unknown_instruction", OPTYPE_UNKNOWN, 0}}, + {62, &cCore::Default}, //"unknown_instruction", OPTYPE_UNKNOWN, 0}}, + {58, &cCore::Default}, //"unknown_instruction", OPTYPE_UNKNOWN, 0}}, }; static GekkoOPTemplate table4[] = { //SUBOP10 - {0, &Jit64::Default}, //"ps_cmpu0", OPTYPE_PS, FL_SET_CRn}}, - {32, &Jit64::Default}, //"ps_cmpo0", OPTYPE_PS, FL_SET_CRn}}, - {40, &Jit64::ps_sign}, //"ps_neg", OPTYPE_PS, FL_RC_BIT}}, - {136, &Jit64::ps_sign}, //"ps_nabs", OPTYPE_PS, FL_RC_BIT}}, - {264, &Jit64::ps_sign}, //"ps_abs", OPTYPE_PS, FL_RC_BIT}}, - {64, &Jit64::Default}, //"ps_cmpu1", OPTYPE_PS, FL_RC_BIT}}, - {72, &Jit64::ps_mr}, //"ps_mr", OPTYPE_PS, FL_RC_BIT}}, - {96, &Jit64::Default}, //"ps_cmpo1", OPTYPE_PS, FL_RC_BIT}}, - {528, &Jit64::ps_mergeXX}, //"ps_merge00", OPTYPE_PS, FL_RC_BIT}}, - {560, &Jit64::ps_mergeXX}, //"ps_merge01", OPTYPE_PS, FL_RC_BIT}}, - {592, &Jit64::ps_mergeXX}, //"ps_merge10", OPTYPE_PS, FL_RC_BIT}}, - {624, &Jit64::ps_mergeXX}, //"ps_merge11", OPTYPE_PS, FL_RC_BIT}}, + {0, &cCore::Default}, //"ps_cmpu0", OPTYPE_PS, FL_SET_CRn}}, + {32, &cCore::Default}, //"ps_cmpo0", OPTYPE_PS, FL_SET_CRn}}, + {40, &cCore::ps_sign}, //"ps_neg", OPTYPE_PS, FL_RC_BIT}}, + {136, &cCore::ps_sign}, //"ps_nabs", OPTYPE_PS, FL_RC_BIT}}, + {264, &cCore::ps_sign}, //"ps_abs", OPTYPE_PS, FL_RC_BIT}}, + {64, &cCore::Default}, //"ps_cmpu1", OPTYPE_PS, FL_RC_BIT}}, + {72, &cCore::ps_mr}, //"ps_mr", OPTYPE_PS, FL_RC_BIT}}, + {96, &cCore::Default}, //"ps_cmpo1", OPTYPE_PS, FL_RC_BIT}}, + {528, &cCore::ps_mergeXX}, //"ps_merge00", OPTYPE_PS, FL_RC_BIT}}, + {560, &cCore::ps_mergeXX}, //"ps_merge01", OPTYPE_PS, FL_RC_BIT}}, + {592, &cCore::ps_mergeXX}, //"ps_merge10", OPTYPE_PS, FL_RC_BIT}}, + {624, &cCore::ps_mergeXX}, //"ps_merge11", OPTYPE_PS, FL_RC_BIT}}, - {1014, &Jit64::Default}, //"dcbz_l", OPTYPE_SYSTEM, 0}}, + {1014, &cCore::Default}, //"dcbz_l", OPTYPE_SYSTEM, 0}}, }; static GekkoOPTemplate table4_2[] = { - {10, &Jit64::ps_sum}, //"ps_sum0", OPTYPE_PS, 0}}, - {11, &Jit64::ps_sum}, //"ps_sum1", OPTYPE_PS, 0}}, - {12, &Jit64::ps_muls}, //"ps_muls0", OPTYPE_PS, 0}}, - {13, &Jit64::ps_muls}, //"ps_muls1", OPTYPE_PS, 0}}, - {14, &Jit64::ps_maddXX}, //"ps_madds0", OPTYPE_PS, 0}}, - {15, &Jit64::ps_maddXX}, //"ps_madds1", OPTYPE_PS, 0}}, - {18, &Jit64::ps_arith}, //"ps_div", OPTYPE_PS, 0, 16}}, - {20, &Jit64::ps_arith}, //"ps_sub", OPTYPE_PS, 0}}, - {21, &Jit64::ps_arith}, //"ps_add", OPTYPE_PS, 0}}, - {23, &Jit64::ps_sel}, //"ps_sel", OPTYPE_PS, 0}}, - {24, &Jit64::Default}, //"ps_res", OPTYPE_PS, 0}}, - {25, &Jit64::ps_arith}, //"ps_mul", OPTYPE_PS, 0}}, - {26, &Jit64::ps_rsqrte}, //"ps_rsqrte", OPTYPE_PS, 0, 1}}, - {28, &Jit64::ps_maddXX}, //"ps_msub", OPTYPE_PS, 0}}, - {29, &Jit64::ps_maddXX}, //"ps_madd", OPTYPE_PS, 0}}, - {30, &Jit64::ps_maddXX}, //"ps_nmsub", OPTYPE_PS, 0}}, - {31, &Jit64::ps_maddXX}, //"ps_nmadd", OPTYPE_PS, 0}}, + {10, &cCore::ps_sum}, //"ps_sum0", OPTYPE_PS, 0}}, + {11, &cCore::ps_sum}, //"ps_sum1", OPTYPE_PS, 0}}, + {12, &cCore::ps_muls}, //"ps_muls0", OPTYPE_PS, 0}}, + {13, &cCore::ps_muls}, //"ps_muls1", OPTYPE_PS, 0}}, + {14, &cCore::ps_maddXX}, //"ps_madds0", OPTYPE_PS, 0}}, + {15, &cCore::ps_maddXX}, //"ps_madds1", OPTYPE_PS, 0}}, + {18, &cCore::ps_arith}, //"ps_div", OPTYPE_PS, 0, 16}}, + {20, &cCore::ps_arith}, //"ps_sub", OPTYPE_PS, 0}}, + {21, &cCore::ps_arith}, //"ps_add", OPTYPE_PS, 0}}, + {23, &cCore::ps_sel}, //"ps_sel", OPTYPE_PS, 0}}, + {24, &cCore::Default}, //"ps_res", OPTYPE_PS, 0}}, + {25, &cCore::ps_arith}, //"ps_mul", OPTYPE_PS, 0}}, + {26, &cCore::ps_rsqrte}, //"ps_rsqrte", OPTYPE_PS, 0, 1}}, + {28, &cCore::ps_maddXX}, //"ps_msub", OPTYPE_PS, 0}}, + {29, &cCore::ps_maddXX}, //"ps_madd", OPTYPE_PS, 0}}, + {30, &cCore::ps_maddXX}, //"ps_nmsub", OPTYPE_PS, 0}}, + {31, &cCore::ps_maddXX}, //"ps_nmadd", OPTYPE_PS, 0}}, }; static GekkoOPTemplate table4_3[] = { - {6, &Jit64::Default}, //"psq_lx", OPTYPE_PS, 0}}, - {7, &Jit64::Default}, //"psq_stx", OPTYPE_PS, 0}}, - {38, &Jit64::Default}, //"psq_lux", OPTYPE_PS, 0}}, - {39, &Jit64::Default}, //"psq_stux", OPTYPE_PS, 0}}, + {6, &cCore::Default}, //"psq_lx", OPTYPE_PS, 0}}, + {7, &cCore::Default}, //"psq_stx", OPTYPE_PS, 0}}, + {38, &cCore::Default}, //"psq_lux", OPTYPE_PS, 0}}, + {39, &cCore::Default}, //"psq_stux", OPTYPE_PS, 0}}, }; static GekkoOPTemplate table19[] = { - {528, &Jit64::bcctrx}, //"bcctrx", OPTYPE_BRANCH, FL_ENDBLOCK}}, - {16, &Jit64::bclrx}, //"bclrx", OPTYPE_BRANCH, FL_ENDBLOCK}}, - {257, &Jit64::Default}, //"crand", OPTYPE_CR, FL_EVIL}}, - {129, &Jit64::Default}, //"crandc", OPTYPE_CR, FL_EVIL}}, - {289, &Jit64::Default}, //"creqv", OPTYPE_CR, FL_EVIL}}, - {225, &Jit64::Default}, //"crnand", OPTYPE_CR, FL_EVIL}}, - {33, &Jit64::Default}, //"crnor", OPTYPE_CR, FL_EVIL}}, - {449, &Jit64::Default}, //"cror", OPTYPE_CR, FL_EVIL}}, - {417, &Jit64::Default}, //"crorc", OPTYPE_CR, FL_EVIL}}, - {193, &Jit64::Default}, //"crxor", OPTYPE_CR, FL_EVIL}}, + {528, &cCore::bcctrx}, //"bcctrx", OPTYPE_BRANCH, FL_ENDBLOCK}}, + {16, &cCore::bclrx}, //"bclrx", OPTYPE_BRANCH, FL_ENDBLOCK}}, + {257, &cCore::Default}, //"crand", OPTYPE_CR, FL_EVIL}}, + {129, &cCore::Default}, //"crandc", OPTYPE_CR, FL_EVIL}}, + {289, &cCore::Default}, //"creqv", OPTYPE_CR, FL_EVIL}}, + {225, &cCore::Default}, //"crnand", OPTYPE_CR, FL_EVIL}}, + {33, &cCore::Default}, //"crnor", OPTYPE_CR, FL_EVIL}}, + {449, &cCore::Default}, //"cror", OPTYPE_CR, FL_EVIL}}, + {417, &cCore::Default}, //"crorc", OPTYPE_CR, FL_EVIL}}, + {193, &cCore::Default}, //"crxor", OPTYPE_CR, FL_EVIL}}, - {150, &Jit64::DoNothing}, //"isync", OPTYPE_ICACHE, FL_EVIL}}, - {0, &Jit64::Default}, //"mcrf", OPTYPE_SYSTEM, FL_EVIL}}, + {150, &cCore::DoNothing}, //"isync", OPTYPE_ICACHE, FL_EVIL}}, + {0, &cCore::Default}, //"mcrf", OPTYPE_SYSTEM, FL_EVIL}}, - {50, &Jit64::rfi}, //"rfi", OPTYPE_SYSTEM, FL_ENDBLOCK | FL_CHECKEXCEPTIONS, 1}}, - {18, &Jit64::Default}, //"rfid", OPTYPE_SYSTEM, FL_ENDBLOCK | FL_CHECKEXCEPTIONS}} + {50, &cCore::rfi}, //"rfi", OPTYPE_SYSTEM, FL_ENDBLOCK | FL_CHECKEXCEPTIONS, 1}}, + {18, &cCore::Default}, //"rfid", OPTYPE_SYSTEM, FL_ENDBLOCK | FL_CHECKEXCEPTIONS}} }; static GekkoOPTemplate table31[] = { - {28, &Jit64::andx}, //"andx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, - {60, &Jit64::Default}, //"andcx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, - {444, &Jit64::orx}, //"orx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, - {124, &Jit64::Default}, //"norx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, - {316, &Jit64::xorx}, //"xorx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, - {412, &Jit64::Default}, //"orcx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, - {476, &Jit64::Default}, //"nandx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, - {284, &Jit64::Default}, //"eqvx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, - {0, &Jit64::cmpXX}, //"cmp", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}}, - {32, &Jit64::cmpXX}, //"cmpl", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}}, - {26, &Jit64::cntlzwx}, //"cntlzwx",OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}}, - {922, &Jit64::extshx}, //"extshx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}}, - {954, &Jit64::extsbx}, //"extsbx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}}, - {536, &Jit64::srwx}, //"srwx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}}, - {792, &Jit64::srawx}, //"srawx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}}, - {824, &Jit64::srawix}, //"srawix", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}}, - {24, &Jit64::slwx}, //"slwx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}}, + {28, &cCore::andx}, //"andx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, + {60, &cCore::Default}, //"andcx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, + {444, &cCore::orx}, //"orx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, + {124, &cCore::Default}, //"norx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, + {316, &cCore::xorx}, //"xorx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, + {412, &cCore::Default}, //"orcx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, + {476, &cCore::Default}, //"nandx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, + {284, &cCore::Default}, //"eqvx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, + {0, &cCore::cmpXX}, //"cmp", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}}, + {32, &cCore::cmpXX}, //"cmpl", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}}, + {26, &cCore::cntlzwx}, //"cntlzwx",OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}}, + {922, &cCore::extshx}, //"extshx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}}, + {954, &cCore::extsbx}, //"extsbx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}}, + {536, &cCore::srwx}, //"srwx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}}, + {792, &cCore::srawx}, //"srawx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}}, + {824, &cCore::srawix}, //"srawix", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}}, + {24, &cCore::slwx}, //"slwx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}}, + + {54, &cCore::Default}, //"dcbst", OPTYPE_DCACHE, 0, 4}}, + {86, &cCore::DoNothing}, //"dcbf", OPTYPE_DCACHE, 0, 4}}, + {246, &cCore::Default}, //"dcbtst", OPTYPE_DCACHE, 0, 1}}, + {278, &cCore::Default}, //"dcbt", OPTYPE_DCACHE, 0, 1}}, + {470, &cCore::Default}, //"dcbi", OPTYPE_DCACHE, 0, 4}}, + {758, &cCore::Default}, //"dcba", OPTYPE_DCACHE, 0, 4}}, + {1014, &cCore::dcbz}, //"dcbz", OPTYPE_DCACHE, 0, 4}}, - {54, &Jit64::Default}, //"dcbst", OPTYPE_DCACHE, 0, 4}}, - {86, &Jit64::DoNothing}, //"dcbf", OPTYPE_DCACHE, 0, 4}}, - {246, &Jit64::Default}, //"dcbtst", OPTYPE_DCACHE, 0, 1}}, - {278, &Jit64::Default}, //"dcbt", OPTYPE_DCACHE, 0, 1}}, - {470, &Jit64::Default}, //"dcbi", OPTYPE_DCACHE, 0, 4}}, - {758, &Jit64::Default}, //"dcba", OPTYPE_DCACHE, 0, 4}}, - {1014, &Jit64::dcbz}, //"dcbz", OPTYPE_DCACHE, 0, 4}}, -#if JITTEST //load word - {23, &Jit64::lXzx}, //"lwzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, - {55, &Jit64::lXzx}, //"lwzux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}}, + {23, &cCore::lXzx}, //"lwzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, + {55, &cCore::lXzx}, //"lwzux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}}, //load halfword - {279, &Jit64::lXzx}, //"lhzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, - {311, &Jit64::lXzx}, //"lhzux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}}, + {279, &cCore::lXzx}, //"lhzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, + {311, &cCore::lXzx}, //"lhzux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}}, //load halfword signextend - {343, &Jit64::lhax}, //"lhax", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, - {375, &Jit64::Default}, //"lhaux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}}, + {343, &cCore::lhax}, //"lhax", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, + {375, &cCore::Default}, //"lhaux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}}, //load byte - {87, &Jit64::lXzx}, //"lbzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, - {119, &Jit64::lXzx}, //"lbzux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}}, -#else - //load word - {23, &Jit64::lwzx}, //"lwzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, - {55, &Jit64::lwzux}, //"lwzux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}}, - - //load halfword - {279, &Jit64::Default}, //"lhzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, - {311, &Jit64::Default}, //"lhzux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}}, - - //load halfword signextend - {343, &Jit64::lhax}, //"lhax", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, - {375, &Jit64::Default}, //"lhaux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}}, - - //load byte - {87, &Jit64::lbzx}, //"lbzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, - {119, &Jit64::Default}, //"lbzux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}}, -#endif + {87, &cCore::lXzx}, //"lbzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, + {119, &cCore::lXzx}, //"lbzux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}}, + //load byte reverse - {534, &Jit64::Default}, //"lwbrx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, - {790, &Jit64::Default}, //"lhbrx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, + {534, &cCore::Default}, //"lwbrx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, + {790, &cCore::Default}, //"lhbrx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, // Conditional load/store (Wii SMP) - {150, &Jit64::Default}, //"stwcxd", OPTYPE_STORE, FL_EVIL | FL_SET_CR0}}, - {20, &Jit64::Default}, //"lwarx", OPTYPE_LOAD, FL_EVIL | FL_OUT_D | FL_IN_A0B | FL_SET_CR0}}, + {150, &cCore::Default}, //"stwcxd", OPTYPE_STORE, FL_EVIL | FL_SET_CR0}}, + {20, &cCore::Default}, //"lwarx", OPTYPE_LOAD, FL_EVIL | FL_OUT_D | FL_IN_A0B | FL_SET_CR0}}, //load string (interpret these) - {533, &Jit64::Default}, //"lswx", OPTYPE_LOAD, FL_EVIL | FL_IN_A | FL_OUT_D}}, - {597, &Jit64::Default}, //"lswi", OPTYPE_LOAD, FL_EVIL | FL_IN_AB | FL_OUT_D}}, + {533, &cCore::Default}, //"lswx", OPTYPE_LOAD, FL_EVIL | FL_IN_A | FL_OUT_D}}, + {597, &cCore::Default}, //"lswi", OPTYPE_LOAD, FL_EVIL | FL_IN_AB | FL_OUT_D}}, //store word - {151, &Jit64::stXx}, //"stwx", OPTYPE_STORE, FL_IN_A0 | FL_IN_B}}, - {183, &Jit64::stXx}, //"stwux", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_B}}, + {151, &cCore::stXx}, //"stwx", OPTYPE_STORE, FL_IN_A0 | FL_IN_B}}, + {183, &cCore::stXx}, //"stwux", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_B}}, //store halfword - {407, &Jit64::stXx}, //"sthx", OPTYPE_STORE, FL_IN_A0 | FL_IN_B}}, - {439, &Jit64::stXx}, //"sthux", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_B}}, + {407, &cCore::stXx}, //"sthx", OPTYPE_STORE, FL_IN_A0 | FL_IN_B}}, + {439, &cCore::stXx}, //"sthux", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_B}}, //store byte - {215, &Jit64::stXx}, //"stbx", OPTYPE_STORE, FL_IN_A0 | FL_IN_B}}, - {247, &Jit64::stXx}, //"stbux", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_B}}, + {215, &cCore::stXx}, //"stbx", OPTYPE_STORE, FL_IN_A0 | FL_IN_B}}, + {247, &cCore::stXx}, //"stbux", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_B}}, //store bytereverse - {662, &Jit64::Default}, //"stwbrx", OPTYPE_STORE, FL_IN_A0 | FL_IN_B}}, - {918, &Jit64::Default}, //"sthbrx", OPTYPE_STORE, FL_IN_A | FL_IN_B}}, + {662, &cCore::Default}, //"stwbrx", OPTYPE_STORE, FL_IN_A0 | FL_IN_B}}, + {918, &cCore::Default}, //"sthbrx", OPTYPE_STORE, FL_IN_A | FL_IN_B}}, - {661, &Jit64::Default}, //"stswx", OPTYPE_STORE, FL_EVIL}}, - {725, &Jit64::Default}, //"stswi", OPTYPE_STORE, FL_EVIL}}, + {661, &cCore::Default}, //"stswx", OPTYPE_STORE, FL_EVIL}}, + {725, &cCore::Default}, //"stswi", OPTYPE_STORE, FL_EVIL}}, // fp load/store - {535, &Jit64::lfsx}, //"lfsx", OPTYPE_LOADFP, FL_IN_A0 | FL_IN_B}}, - {567, &Jit64::Default}, //"lfsux", OPTYPE_LOADFP, FL_IN_A | FL_IN_B}}, - {599, &Jit64::Default}, //"lfdx", OPTYPE_LOADFP, FL_IN_A0 | FL_IN_B}}, - {631, &Jit64::Default}, //"lfdux", OPTYPE_LOADFP, FL_IN_A | FL_IN_B}}, + {535, &cCore::lfsx}, //"lfsx", OPTYPE_LOADFP, FL_IN_A0 | FL_IN_B}}, + {567, &cCore::Default}, //"lfsux", OPTYPE_LOADFP, FL_IN_A | FL_IN_B}}, + {599, &cCore::Default}, //"lfdx", OPTYPE_LOADFP, FL_IN_A0 | FL_IN_B}}, + {631, &cCore::Default}, //"lfdux", OPTYPE_LOADFP, FL_IN_A | FL_IN_B}}, - {663, &Jit64::stfsx}, //"stfsx", OPTYPE_STOREFP, FL_IN_A0 | FL_IN_B}}, - {695, &Jit64::Default}, //"stfsux", OPTYPE_STOREFP, FL_IN_A | FL_IN_B}}, - {727, &Jit64::Default}, //"stfdx", OPTYPE_STOREFP, FL_IN_A0 | FL_IN_B}}, - {759, &Jit64::Default}, //"stfdux", OPTYPE_STOREFP, FL_IN_A | FL_IN_B}}, - {983, &Jit64::Default}, //"stfiwx", OPTYPE_STOREFP, FL_IN_A0 | FL_IN_B}}, + {663, &cCore::stfsx}, //"stfsx", OPTYPE_STOREFP, FL_IN_A0 | FL_IN_B}}, + {695, &cCore::Default}, //"stfsux", OPTYPE_STOREFP, FL_IN_A | FL_IN_B}}, + {727, &cCore::Default}, //"stfdx", OPTYPE_STOREFP, FL_IN_A0 | FL_IN_B}}, + {759, &cCore::Default}, //"stfdux", OPTYPE_STOREFP, FL_IN_A | FL_IN_B}}, + {983, &cCore::Default}, //"stfiwx", OPTYPE_STOREFP, FL_IN_A0 | FL_IN_B}}, - {19, &Jit64::mfcr}, //"mfcr", OPTYPE_SYSTEM, FL_OUT_D}}, - {83, &Jit64::mfmsr}, //"mfmsr", OPTYPE_SYSTEM, FL_OUT_D}}, - {144, &Jit64::mtcrf}, //"mtcrf", OPTYPE_SYSTEM, 0}}, - {146, &Jit64::mtmsr}, //"mtmsr", OPTYPE_SYSTEM, FL_ENDBLOCK}}, - {210, &Jit64::Default}, //"mtsr", OPTYPE_SYSTEM, 0}}, - {242, &Jit64::Default}, //"mtsrin", OPTYPE_SYSTEM, 0}}, - {339, &Jit64::mfspr}, //"mfspr", OPTYPE_SPR, FL_OUT_D}}, - {467, &Jit64::mtspr}, //"mtspr", OPTYPE_SPR, 0, 2}}, - {371, &Jit64::mftb}, //"mftb", OPTYPE_SYSTEM, FL_OUT_D | FL_TIMER}}, - {512, &Jit64::Default}, //"mcrxr", OPTYPE_SYSTEM, 0}}, - {595, &Jit64::Default}, //"mfsr", OPTYPE_SYSTEM, FL_OUT_D, 2}}, - {659, &Jit64::Default}, //"mfsrin", OPTYPE_SYSTEM, FL_OUT_D, 2}}, + {19, &cCore::mfcr}, //"mfcr", OPTYPE_SYSTEM, FL_OUT_D}}, + {83, &cCore::mfmsr}, //"mfmsr", OPTYPE_SYSTEM, FL_OUT_D}}, + {144, &cCore::mtcrf}, //"mtcrf", OPTYPE_SYSTEM, 0}}, + {146, &cCore::mtmsr}, //"mtmsr", OPTYPE_SYSTEM, FL_ENDBLOCK}}, + {210, &cCore::Default}, //"mtsr", OPTYPE_SYSTEM, 0}}, + {242, &cCore::Default}, //"mtsrin", OPTYPE_SYSTEM, 0}}, + {339, &cCore::mfspr}, //"mfspr", OPTYPE_SPR, FL_OUT_D}}, + {467, &cCore::mtspr}, //"mtspr", OPTYPE_SPR, 0, 2}}, + {371, &cCore::mftb}, //"mftb", OPTYPE_SYSTEM, FL_OUT_D | FL_TIMER}}, + {512, &cCore::Default}, //"mcrxr", OPTYPE_SYSTEM, 0}}, + {595, &cCore::Default}, //"mfsr", OPTYPE_SYSTEM, FL_OUT_D, 2}}, + {659, &cCore::Default}, //"mfsrin", OPTYPE_SYSTEM, FL_OUT_D, 2}}, - {4, &Jit64::Default}, //"tw", OPTYPE_SYSTEM, 0, 1}}, - {598, &Jit64::DoNothing}, //"sync", OPTYPE_SYSTEM, 0, 2}}, - {982, &Jit64::Default}, //"icbi", OPTYPE_SYSTEM, 0, 3}}, + {4, &cCore::Default}, //"tw", OPTYPE_SYSTEM, 0, 1}}, + {598, &cCore::DoNothing}, //"sync", OPTYPE_SYSTEM, 0, 2}}, + {982, &cCore::Default}, //"icbi", OPTYPE_SYSTEM, 0, 3}}, // Unused instructions on GC - {310, &Jit64::Default}, //"eciwx", OPTYPE_INTEGER, FL_RC_BIT}}, - {438, &Jit64::Default}, //"ecowx", OPTYPE_INTEGER, FL_RC_BIT}}, - {854, &Jit64::Default}, //"eieio", OPTYPE_INTEGER, FL_RC_BIT}}, - {306, &Jit64::Default}, //"tlbie", OPTYPE_SYSTEM, 0}}, - {370, &Jit64::Default}, //"tlbia", OPTYPE_SYSTEM, 0}}, - {566, &Jit64::Default}, //"tlbsync", OPTYPE_SYSTEM, 0}}, + {310, &cCore::Default}, //"eciwx", OPTYPE_INTEGER, FL_RC_BIT}}, + {438, &cCore::Default}, //"ecowx", OPTYPE_INTEGER, FL_RC_BIT}}, + {854, &cCore::Default}, //"eieio", OPTYPE_INTEGER, FL_RC_BIT}}, + {306, &cCore::Default}, //"tlbie", OPTYPE_SYSTEM, 0}}, + {370, &cCore::Default}, //"tlbia", OPTYPE_SYSTEM, 0}}, + {566, &cCore::Default}, //"tlbsync", OPTYPE_SYSTEM, 0}}, }; static GekkoOPTemplate table31_2[] = { - {266, &Jit64::addx}, //"addx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}}, - {10, &Jit64::Default}, //"addcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}}, - {138, &Jit64::addex}, //"addex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, - {234, &Jit64::Default}, //"addmex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, -#if JITTEST - {202, &Jit64::addzex}, //"addzex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, -#else - {202, &Jit64::Default}, //"addzex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, -#endif - {491, &Jit64::Default}, //"divwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 39}}, - {459, &Jit64::divwux}, //"divwux", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 39}}, - {75, &Jit64::Default}, //"mulhwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}}, - {11, &Jit64::mulhwux}, //"mulhwux", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}}, - {235, &Jit64::mullwx}, //"mullwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}}, - {104, &Jit64::negx}, //"negx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}}, - {40, &Jit64::subfx}, //"subfx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}}, - {8, &Jit64::subfcx}, //"subfcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}}, - {136, &Jit64::subfex}, //"subfex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, - {232, &Jit64::Default}, //"subfmex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, - {200, &Jit64::Default}, //"subfzex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, + {266, &cCore::addx}, //"addx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}}, + {10, &cCore::Default}, //"addcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}}, + {138, &cCore::addex}, //"addex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, + {234, &cCore::Default}, //"addmex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, + {202, &cCore::addzex}, //"addzex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, + {491, &cCore::Default}, //"divwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 39}}, + {459, &cCore::divwux}, //"divwux", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 39}}, + {75, &cCore::Default}, //"mulhwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}}, + {11, &cCore::mulhwux}, //"mulhwux", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}}, + {235, &cCore::mullwx}, //"mullwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}}, + {104, &cCore::negx}, //"negx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}}, + {40, &cCore::subfx}, //"subfx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}}, + {8, &cCore::subfcx}, //"subfcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}}, + {136, &cCore::subfex}, //"subfex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, + {232, &cCore::Default}, //"subfmex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, + {200, &cCore::Default}, //"subfzex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, }; static GekkoOPTemplate table59[] = { - {18, &Jit64::Default}, //{"fdivsx", OPTYPE_FPU, FL_RC_BIT_F, 16}}, - {20, &Jit64::fp_arith_s}, //"fsubsx", OPTYPE_FPU, FL_RC_BIT_F}}, - {21, &Jit64::fp_arith_s}, //"faddsx", OPTYPE_FPU, FL_RC_BIT_F}}, -// {22, &Jit64::Default}, //"fsqrtsx", OPTYPE_FPU, FL_RC_BIT_F}}, // Not implemented on gekko - {24, &Jit64::Default}, //"fresx", OPTYPE_FPU, FL_RC_BIT_F}}, - {25, &Jit64::fp_arith_s}, //"fmulsx", OPTYPE_FPU, FL_RC_BIT_F}}, - {28, &Jit64::fmaddXX}, //"fmsubsx", OPTYPE_FPU, FL_RC_BIT_F}}, - {29, &Jit64::fmaddXX}, //"fmaddsx", OPTYPE_FPU, FL_RC_BIT_F}}, - {30, &Jit64::fmaddXX}, //"fnmsubsx", OPTYPE_FPU, FL_RC_BIT_F}}, - {31, &Jit64::fmaddXX}, //"fnmaddsx", OPTYPE_FPU, FL_RC_BIT_F}}, + {18, &cCore::Default}, //{"fdivsx", OPTYPE_FPU, FL_RC_BIT_F, 16}}, + {20, &cCore::fp_arith_s}, //"fsubsx", OPTYPE_FPU, FL_RC_BIT_F}}, + {21, &cCore::fp_arith_s}, //"faddsx", OPTYPE_FPU, FL_RC_BIT_F}}, +// {22, &cCore::Default}, //"fsqrtsx", OPTYPE_FPU, FL_RC_BIT_F}}, // Not implemented on gekko + {24, &cCore::Default}, //"fresx", OPTYPE_FPU, FL_RC_BIT_F}}, + {25, &cCore::fp_arith_s}, //"fmulsx", OPTYPE_FPU, FL_RC_BIT_F}}, + {28, &cCore::fmaddXX}, //"fmsubsx", OPTYPE_FPU, FL_RC_BIT_F}}, + {29, &cCore::fmaddXX}, //"fmaddsx", OPTYPE_FPU, FL_RC_BIT_F}}, + {30, &cCore::fmaddXX}, //"fnmsubsx", OPTYPE_FPU, FL_RC_BIT_F}}, + {31, &cCore::fmaddXX}, //"fnmaddsx", OPTYPE_FPU, FL_RC_BIT_F}}, }; static GekkoOPTemplate table63[] = { - {264, &Jit64::Default}, //"fabsx", OPTYPE_FPU, FL_RC_BIT_F}}, - {32, &Jit64::fcmpx}, //"fcmpo", OPTYPE_FPU, FL_RC_BIT_F}}, - {0, &Jit64::fcmpx}, //"fcmpu", OPTYPE_FPU, FL_RC_BIT_F}}, - {14, &Jit64::Default}, //"fctiwx", OPTYPE_FPU, FL_RC_BIT_F}}, - {15, &Jit64::Default}, //"fctiwzx", OPTYPE_FPU, FL_RC_BIT_F}}, - {72, &Jit64::fmrx}, //"fmrx", OPTYPE_FPU, FL_RC_BIT_F}}, - {136, &Jit64::Default}, //"fnabsx", OPTYPE_FPU, FL_RC_BIT_F}}, - {40, &Jit64::Default}, //"fnegx", OPTYPE_FPU, FL_RC_BIT_F}}, - {12, &Jit64::Default}, //"frspx", OPTYPE_FPU, FL_RC_BIT_F}}, + {264, &cCore::Default}, //"fabsx", OPTYPE_FPU, FL_RC_BIT_F}}, + {32, &cCore::fcmpx}, //"fcmpo", OPTYPE_FPU, FL_RC_BIT_F}}, + {0, &cCore::fcmpx}, //"fcmpu", OPTYPE_FPU, FL_RC_BIT_F}}, + {14, &cCore::Default}, //"fctiwx", OPTYPE_FPU, FL_RC_BIT_F}}, + {15, &cCore::Default}, //"fctiwzx", OPTYPE_FPU, FL_RC_BIT_F}}, + {72, &cCore::fmrx}, //"fmrx", OPTYPE_FPU, FL_RC_BIT_F}}, + {136, &cCore::Default}, //"fnabsx", OPTYPE_FPU, FL_RC_BIT_F}}, + {40, &cCore::Default}, //"fnegx", OPTYPE_FPU, FL_RC_BIT_F}}, + {12, &cCore::Default}, //"frspx", OPTYPE_FPU, FL_RC_BIT_F}}, - {64, &Jit64::Default}, //"mcrfs", OPTYPE_SYSTEMFP, 0}}, - {583, &Jit64::Default}, //"mffsx", OPTYPE_SYSTEMFP, 0}}, - {70, &Jit64::Default}, //"mtfsb0x", OPTYPE_SYSTEMFP, 0, 2}}, - {38, &Jit64::Default}, //"mtfsb1x", OPTYPE_SYSTEMFP, 0, 2}}, - {134, &Jit64::Default}, //"mtfsfix", OPTYPE_SYSTEMFP, 0, 2}}, - {711, &Jit64::Default}, //"mtfsfx", OPTYPE_SYSTEMFP, 0, 2}}, + {64, &cCore::Default}, //"mcrfs", OPTYPE_SYSTEMFP, 0}}, + {583, &cCore::Default}, //"mffsx", OPTYPE_SYSTEMFP, 0}}, + {70, &cCore::Default}, //"mtfsb0x", OPTYPE_SYSTEMFP, 0, 2}}, + {38, &cCore::Default}, //"mtfsb1x", OPTYPE_SYSTEMFP, 0, 2}}, + {134, &cCore::Default}, //"mtfsfix", OPTYPE_SYSTEMFP, 0, 2}}, + {711, &cCore::Default}, //"mtfsfx", OPTYPE_SYSTEMFP, 0, 2}}, }; static GekkoOPTemplate table63_2[] = { - {18, &Jit64::Default}, //"fdivx", OPTYPE_FPU, FL_RC_BIT_F, 30}}, - {20, &Jit64::Default}, //"fsubx", OPTYPE_FPU, FL_RC_BIT_F}}, - {21, &Jit64::Default}, //"faddx", OPTYPE_FPU, FL_RC_BIT_F}}, - {22, &Jit64::Default}, //"fsqrtx", OPTYPE_FPU, FL_RC_BIT_F}}, - {23, &Jit64::Default}, //"fselx", OPTYPE_FPU, FL_RC_BIT_F}}, - {25, &Jit64::fp_arith_s}, //"fmulx", OPTYPE_FPU, FL_RC_BIT_F}}, - {26, &Jit64::fp_arith_s}, //"frsqrtex", OPTYPE_FPU, FL_RC_BIT_F}}, - {28, &Jit64::fmaddXX}, //"fmsubx", OPTYPE_FPU, FL_RC_BIT_F}}, - {29, &Jit64::fmaddXX}, //"fmaddx", OPTYPE_FPU, FL_RC_BIT_F}}, - {30, &Jit64::fmaddXX}, //"fnmsubx", OPTYPE_FPU, FL_RC_BIT_F}}, - {31, &Jit64::fmaddXX}, //"fnmaddx", OPTYPE_FPU, FL_RC_BIT_F}}, + {18, &cCore::Default}, //"fdivx", OPTYPE_FPU, FL_RC_BIT_F, 30}}, + {20, &cCore::Default}, //"fsubx", OPTYPE_FPU, FL_RC_BIT_F}}, + {21, &cCore::Default}, //"faddx", OPTYPE_FPU, FL_RC_BIT_F}}, + {22, &cCore::Default}, //"fsqrtx", OPTYPE_FPU, FL_RC_BIT_F}}, + {23, &cCore::Default}, //"fselx", OPTYPE_FPU, FL_RC_BIT_F}}, + {25, &cCore::fp_arith_s}, //"fmulx", OPTYPE_FPU, FL_RC_BIT_F}}, + {26, &cCore::fp_arith_s}, //"frsqrtex", OPTYPE_FPU, FL_RC_BIT_F}}, + {28, &cCore::fmaddXX}, //"fmsubx", OPTYPE_FPU, FL_RC_BIT_F}}, + {29, &cCore::fmaddXX}, //"fmaddx", OPTYPE_FPU, FL_RC_BIT_F}}, + {30, &cCore::fmaddXX}, //"fnmsubx", OPTYPE_FPU, FL_RC_BIT_F}}, + {31, &cCore::fmaddXX}, //"fnmaddx", OPTYPE_FPU, FL_RC_BIT_F}}, }; namespace JitTables { void CompileInstruction(UGeckoInstruction _inst) { - (jit.*dynaOpTable[_inst.OPCD])(_inst); + (jit->*dynaOpTable[_inst.OPCD])(_inst); GekkoOPInfo *info = GetOpInfo(_inst); if (info) { #ifdef OPLOG @@ -416,9 +389,9 @@ void CompileInstruction(UGeckoInstruction _inst) } #endif info->compileCount++; - info->lastUse = jit.js.compilerPC; + info->lastUse = jit->js.compilerPC; } else { - PanicAlert("Tried to compile illegal (or unknown) instruction %08x, at %08x", _inst.hex, jit.js.compilerPC); + PanicAlert("Tried to compile illegal (or unknown) instruction %08x, at %08x", _inst.hex, jit->js.compilerPC); } } void InitTables() @@ -426,15 +399,15 @@ void InitTables() //clear for (int i = 0; i < 32; i++) { - dynaOpTable59[i] = &Jit64::unknown_instruction; + dynaOpTable59[i] = &cCore::unknown_instruction; } for (int i = 0; i < 1024; i++) { - dynaOpTable4 [i] = &Jit64::unknown_instruction; - dynaOpTable19[i] = &Jit64::unknown_instruction; - dynaOpTable31[i] = &Jit64::unknown_instruction; - dynaOpTable63[i] = &Jit64::unknown_instruction; + dynaOpTable4 [i] = &cCore::unknown_instruction; + dynaOpTable19[i] = &cCore::unknown_instruction; + dynaOpTable31[i] = &cCore::unknown_instruction; + dynaOpTable63[i] = &cCore::unknown_instruction; } for (int i = 0; i < (int)(sizeof(primarytable) / sizeof(GekkoOPTemplate)); i++) diff --git a/Source/Core/Core/Src/PowerPC/PPCTables.cpp b/Source/Core/Core/Src/PowerPC/PPCTables.cpp index 95f26d3c4a..36acced58a 100644 --- a/Source/Core/Core/Src/PowerPC/PPCTables.cpp +++ b/Source/Core/Core/Src/PowerPC/PPCTables.cpp @@ -32,6 +32,8 @@ #error Unknown architecture! #endif #endif +#include "CoreGeneralize.h" +cCore *jit = NULL; // Should be put elsewhere struct op_inf { diff --git a/Source/Core/Core/Src/PowerPC/PowerPC.cpp b/Source/Core/Core/Src/PowerPC/PowerPC.cpp index d3ec9a9432..1b6c1a45fa 100644 --- a/Source/Core/Core/Src/PowerPC/PowerPC.cpp +++ b/Source/Core/Core/Src/PowerPC/PowerPC.cpp @@ -119,11 +119,16 @@ void Init() #endif ResetRegisters(); + #if defined JITTEST && JITTEST + jit = new Jit64IL(); + #else + jit = new Jit64(); + #endif PPCTables::InitTables(); // Initialize both execution engines ... Interpreter::Init(); - jit.Init(); + jit->Init(); // ... but start as interpreter by default. mode = MODE_INTERPRETER; state = CPU_STEPPING; @@ -132,7 +137,7 @@ void Init() void Shutdown() { // Shutdown both execution engines. Doesn't matter which one is active. - jit.Shutdown(); + jit->Shutdown(); Interpreter::Shutdown(); } @@ -145,7 +150,7 @@ void SetMode(CoreMode new_mode) switch (mode) { case MODE_INTERPRETER: // Switching from JIT to interpreter - jit.ClearCache(); // Remove all those nasty JIT patches. + jit->ClearCache(); // Remove all those nasty JIT patches. break; case MODE_JIT: // Switching from interpreter to JIT. @@ -162,7 +167,7 @@ void SingleStep() Interpreter::SingleStep(); break; case MODE_JIT: - jit.SingleStep(); + jit->SingleStep(); break; } } @@ -176,7 +181,7 @@ void RunLoop() Interpreter::Run(); break; case MODE_JIT: - jit.Run(); + jit->Run(); break; } Host_UpdateDisasmDialog(); diff --git a/Source/Core/Core/Src/PowerPC/Profiler.cpp b/Source/Core/Core/Src/PowerPC/Profiler.cpp index 96958e1927..52a5d3b02b 100644 --- a/Source/Core/Core/Src/PowerPC/Profiler.cpp +++ b/Source/Core/Core/Src/PowerPC/Profiler.cpp @@ -41,16 +41,16 @@ struct BlockStat void WriteProfileResults(const char *filename) { std::vector stats; - stats.reserve(jit.GetBlockCache()->GetNumBlocks()); + stats.reserve(jit->GetBlockCache()->GetNumBlocks()); u64 cost_sum = 0; #ifdef _WIN32 u64 timecost_sum = 0; LARGE_INTEGER countsPerSec; QueryPerformanceFrequency(&countsPerSec); #endif - for (int i = 0; i < jit.GetBlockCache()->GetNumBlocks(); i++) + for (int i = 0; i < jit->GetBlockCache()->GetNumBlocks(); i++) { - const JitBlock *block = jit.GetBlockCache()->GetBlock(i); + const JitBlock *block = jit->GetBlockCache()->GetBlock(i); u64 cost = (block->originalSize / 4) * block->runCount; // rough heuristic. mem instructions should cost more. #ifdef _WIN32 u64 timecost = block->ticCounter.QuadPart; // Indeed ;) @@ -73,7 +73,7 @@ void WriteProfileResults(const char *filename) { fprintf(f, "origAddr\tblkName\tcost\ttimeCost\tpercent\ttimePercent\tOvAllinBlkTime(ms)\tblkCodeSize\n"); for (unsigned int i = 0; i < stats.size(); i++) { - const JitBlock *block = jit.GetBlockCache()->GetBlock(stats[i].blockNum); + const JitBlock *block = jit->GetBlockCache()->GetBlock(stats[i].blockNum); if (block) { std::string name = g_symbolDB.GetDescription(block->originalAddress); diff --git a/Source/Core/Core/Src/SConscript b/Source/Core/Core/Src/SConscript index edd5049634..ee18e04853 100644 --- a/Source/Core/Core/Src/SConscript +++ b/Source/Core/Core/Src/SConscript @@ -68,6 +68,7 @@ files = ["ActionReplay.cpp", "IPC_HLE/WII_IPC_HLE_Device_usb.cpp", "IPC_HLE/WII_IPC_HLE_Usb_Kbd.cpp", "IPC_HLE/WiiMote_HID_Attr.cpp", + "PowerPC/CoreGeneralize.cpp", "PowerPC/PowerPC.cpp", "PowerPC/PPCAnalyst.cpp", "PowerPC/PPCTables.cpp", @@ -85,7 +86,6 @@ files = ["ActionReplay.cpp", "PowerPC/Interpreter/Interpreter_Tables.cpp", "PowerPC/JitCommon/JitCache.cpp", "PowerPC/JitCommon/JitBackpatch.cpp", - "PowerPC/JitCommon/Jit_Util.cpp", "HLE/HLE.cpp", "HLE/HLE_Misc.cpp", "HLE/HLE_OS.cpp", @@ -104,6 +104,7 @@ if not env['NOJIT']: "PowerPC/Jit64IL/Jit_SystemRegisters.cpp", "PowerPC/Jit64IL/IR.cpp", "PowerPC/Jit64IL/IR_X86.cpp", + "PowerPC/Jit64IL/Jit_Util.cpp", "PowerPC/JitCommon//Jit_Tables.cpp", ] else: @@ -118,6 +119,7 @@ if not env['NOJIT']: "PowerPC/Jit64/Jit_LoadStore.cpp", "PowerPC/Jit64/Jit_LoadStoreFloating.cpp", "PowerPC/Jit64/Jit_SystemRegisters.cpp", + "PowerPC/Jit64/Jit_Util.cpp", "PowerPC/JitCommon/Jit_Tables.cpp", ] diff --git a/Source/Core/Core/Src/State.cpp b/Source/Core/Core/Src/State.cpp index 04a12d255a..f95456a0dd 100644 --- a/Source/Core/Core/Src/State.cpp +++ b/Source/Core/Core/Src/State.cpp @@ -96,7 +96,7 @@ void LoadBufferStateCallback(u64 userdata, int cyclesLate) return; } - jit.ClearCache(); + jit->ClearCache(); u8 *ptr = *cur_buffer; PointerWrap p(&ptr, PointerWrap::MODE_READ); @@ -116,7 +116,7 @@ void SaveBufferStateCallback(u64 userdata, int cyclesLate) return; } - jit.ClearCache(); + jit->ClearCache(); u8 *ptr = NULL; @@ -211,7 +211,7 @@ void SaveStateCallback(u64 userdata, int cyclesLate) saveThread = NULL; } - jit.ClearCache(); + jit->ClearCache(); u8 *ptr = 0; PointerWrap p(&ptr, PointerWrap::MODE_MEASURE); DoState(p); @@ -315,7 +315,7 @@ void LoadStateCallback(u64 userdata, int cyclesLate) fclose(f); - jit.ClearCache(); + jit->ClearCache(); u8 *ptr = buffer; PointerWrap p(&ptr, PointerWrap::MODE_READ); diff --git a/Source/Core/DebuggerWX/Src/CodeWindow.cpp b/Source/Core/DebuggerWX/Src/CodeWindow.cpp index d12fe22cad..b0b931a75e 100644 --- a/Source/Core/DebuggerWX/Src/CodeWindow.cpp +++ b/Source/Core/DebuggerWX/Src/CodeWindow.cpp @@ -639,7 +639,7 @@ void CCodeWindow::OnCPUMode(wxCommandEvent& event) } // Clear the JIT cache to enable these changes - jit.ClearCache(); + jit->ClearCache(); } void CCodeWindow::OnJitMenu(wxCommandEvent& event) @@ -650,7 +650,7 @@ void CCodeWindow::OnJitMenu(wxCommandEvent& event) PPCTables::LogCompiledInstructions(); break; case IDM_CLEARCODECACHE: - jit.ClearCache(); break; + jit->ClearCache(); break; case IDM_SEARCHINSTRUCTION: { diff --git a/Source/Core/DebuggerWX/Src/CodeWindowSJP.cpp b/Source/Core/DebuggerWX/Src/CodeWindowSJP.cpp index 8eb31000be..79aa717b96 100644 --- a/Source/Core/DebuggerWX/Src/CodeWindowSJP.cpp +++ b/Source/Core/DebuggerWX/Src/CodeWindowSJP.cpp @@ -132,7 +132,7 @@ void CCodeWindow::OnProfilerMenu(wxCommandEvent& event) switch (event.GetId()) { case IDM_PROFILEBLOCKS: - jit.ClearCache(); + jit->ClearCache(); Profiler::g_ProfileBlocks = GetMenuBar()->IsChecked(IDM_PROFILEBLOCKS); break; case IDM_WRITEPROFILE: diff --git a/Source/Core/DebuggerWX/Src/JitWindow.cpp b/Source/Core/DebuggerWX/Src/JitWindow.cpp index 1c9824550e..3c9e5cff59 100644 --- a/Source/Core/DebuggerWX/Src/JitWindow.cpp +++ b/Source/Core/DebuggerWX/Src/JitWindow.cpp @@ -149,16 +149,16 @@ void CJitWindow::Compare(u32 em_address) disassembler x64disasm; x64disasm.set_syntax_intel(); - int block_num = jit.GetBlockCache()->GetBlockNumberFromStartAddress(em_address); + int block_num = jit->GetBlockCache()->GetBlockNumberFromStartAddress(em_address); if (block_num < 0) { for (int i = 0; i < 500; i++) { - block_num = jit.GetBlockCache()->GetBlockNumberFromStartAddress(em_address - 4 * i); + block_num = jit->GetBlockCache()->GetBlockNumberFromStartAddress(em_address - 4 * i); if (block_num >= 0) break; } if (block_num >= 0) { - JitBlock *block = jit.GetBlockCache()->GetBlock(block_num); + JitBlock *block = jit->GetBlockCache()->GetBlock(block_num); if (!(block->originalAddress <= em_address && block->originalSize + block->originalAddress >= em_address)) block_num = -1; } @@ -169,12 +169,12 @@ void CJitWindow::Compare(u32 em_address) return; } } - JitBlock *block = jit.GetBlockCache()->GetBlock(block_num); + JitBlock *block = jit->GetBlockCache()->GetBlock(block_num); // 800031f0 // == Fill in x86 box - const u8 *code = (const u8 *)jit.GetBlockCache()->GetCompiledCodeFromBlock(block_num); + const u8 *code = (const u8 *)jit->GetBlockCache()->GetCompiledCodeFromBlock(block_num); u64 disasmPtr = (u64)code; int size = block->codeSize; const u8 *end = code + size; diff --git a/Source/Core/DolphinWX/Src/MainNoGUI.cpp b/Source/Core/DolphinWX/Src/MainNoGUI.cpp index dc4b6c39c2..980a3c50f7 100644 --- a/Source/Core/DolphinWX/Src/MainNoGUI.cpp +++ b/Source/Core/DolphinWX/Src/MainNoGUI.cpp @@ -44,6 +44,7 @@ #include "Thread.h" #include "PowerPC/PowerPC.h" #include "PluginManager.h" +#include "LogManager.h" #include "BootManager.h" @@ -60,6 +61,7 @@ void Host_UpdateLogDisplay(){} void Host_UpdateDisasmDialog(){} +void Host_ShowJitResults(unsigned int){} Common::Event updateMainFrameEvent; diff --git a/Source/Core/InputCommon/Src/EventHandler.h b/Source/Core/InputCommon/Src/EventHandler.h index 688f229340..f8a6a06cf3 100644 --- a/Source/Core/InputCommon/Src/EventHandler.h +++ b/Source/Core/InputCommon/Src/EventHandler.h @@ -2,6 +2,7 @@ #define EVENTHANDER_H 1 #include "Common.h" #include +#include #include "Event.hpp" #define NUMKEYS 300