From 6802f885b1190914cf74c273d17d6a6955b5d60f Mon Sep 17 00:00:00 2001 From: Sonicadvance1 Date: Wed, 15 Jul 2009 16:59:53 +0000 Subject: [PATCH] Tons of reworking of the cores to make them more...generalized, not quite there yet, but great progress. Near impossible to break this up in to smaller chunks, and may break Windows building. Can not yet switch between JitIL and JIT during runtime, but it is on my list to do. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3801 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Common/Src/MathUtil.h | 1 + .../Core/Src/Debugger/PPCDebugInterface.cpp | 4 +- Source/Core/Core/Src/HW/Memmap.cpp | 2 +- Source/Core/Core/Src/MemTools.cpp | 8 +- .../Core/Core/Src/PowerPC/CoreGeneralize.cpp | 2 + Source/Core/Core/Src/PowerPC/CoreGeneralize.h | 273 +++++++++ .../Interpreter/Interpreter_FloatingPoint.cpp | 2 +- Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp | 4 +- Source/Core/Core/Src/PowerPC/Jit64/Jit.h | 35 +- Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp | 2 +- .../Core/Src/PowerPC/Jit64/Jit_Integer.cpp | 6 +- .../Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp | 118 ++-- .../PowerPC/{JitCommon => Jit64}/Jit_Util.cpp | 7 +- .../Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp | 64 +- Source/Core/Core/Src/PowerPC/Jit64IL/Jit.cpp | 40 +- Source/Core/Core/Src/PowerPC/Jit64IL/Jit.h | 35 +- .../Core/Core/Src/PowerPC/Jit64IL/JitAsm.cpp | 2 +- .../Core/Src/PowerPC/Jit64IL/Jit_Branch.cpp | 12 +- .../Src/PowerPC/Jit64IL/Jit_FloatingPoint.cpp | 8 +- .../Core/Src/PowerPC/Jit64IL/Jit_Integer.cpp | 54 +- .../Src/PowerPC/Jit64IL/Jit_LoadStore.cpp | 18 +- .../PowerPC/Jit64IL/Jit_LoadStoreFloating.cpp | 12 +- .../PowerPC/Jit64IL/Jit_LoadStorePaired.cpp | 4 +- .../Core/Src/PowerPC/Jit64IL/Jit_Paired.cpp | 18 +- .../PowerPC/Jit64IL/Jit_SystemRegisters.cpp | 14 +- .../Core/Src/PowerPC/Jit64IL/Jit_Util.cpp | 184 ++++++ .../Src/PowerPC/JitCommon/JitBackpatch.cpp | 4 +- .../Core/Src/PowerPC/JitCommon/JitCache.cpp | 2 +- .../Core/Src/PowerPC/JitCommon/Jit_Tables.cpp | 547 +++++++++--------- Source/Core/Core/Src/PowerPC/PPCTables.cpp | 2 + Source/Core/Core/Src/PowerPC/PowerPC.cpp | 15 +- Source/Core/Core/Src/PowerPC/Profiler.cpp | 8 +- Source/Core/Core/Src/SConscript | 4 +- Source/Core/Core/Src/State.cpp | 8 +- Source/Core/DebuggerWX/Src/CodeWindow.cpp | 4 +- Source/Core/DebuggerWX/Src/CodeWindowSJP.cpp | 2 +- Source/Core/DebuggerWX/Src/JitWindow.cpp | 10 +- Source/Core/DolphinWX/Src/MainNoGUI.cpp | 2 + Source/Core/InputCommon/Src/EventHandler.h | 1 + 39 files changed, 982 insertions(+), 556 deletions(-) create mode 100644 Source/Core/Core/Src/PowerPC/CoreGeneralize.cpp create mode 100644 Source/Core/Core/Src/PowerPC/CoreGeneralize.h rename Source/Core/Core/Src/PowerPC/{JitCommon => Jit64}/Jit_Util.cpp (97%) create mode 100644 Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Util.cpp 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