diff --git a/Utilities/JIT.cpp b/Utilities/JIT.cpp index 372cec0ba2..83a5df8953 100644 --- a/Utilities/JIT.cpp +++ b/Utilities/JIT.cpp @@ -1,3 +1,34 @@ +#include "JIT.h" + +asmjit::JitRuntime& asmjit::get_global_runtime() +{ + // Magic static + static asmjit::JitRuntime g_rt; + return g_rt; +} + +void asmjit::build_transaction_enter(asmjit::X86Assembler& c, asmjit::Label abort) +{ + Label fall = c.newLabel(); + Label begin = c.newLabel(); + c.jmp(begin); + c.bind(fall); + c.test(x86::eax, _XABORT_RETRY); + c.jz(abort); + c.align(kAlignCode, 16); + c.bind(begin); + c.xbegin(fall); +} + +void asmjit::build_transaction_abort(asmjit::X86Assembler& c, unsigned char code) +{ + c.db(0xc6); + c.db(0xf8); + c.db(code); + c.xor_(x86::eax, x86::eax); + c.ret(); +} + #ifdef LLVM_AVAILABLE #include @@ -34,8 +65,6 @@ #include #endif -#include "JIT.h" - // Memory manager mutex shared_mutex s_mutex; diff --git a/Utilities/JIT.h b/Utilities/JIT.h index 303e1356ff..39797d83b3 100644 --- a/Utilities/JIT.h +++ b/Utilities/JIT.h @@ -1,5 +1,61 @@ #pragma once +#define ASMJIT_STATIC +#define ASMJIT_DEBUG + +#include "asmjit.h" +#include + +namespace asmjit +{ + // Should only be used to build global functions + JitRuntime& get_global_runtime(); + + // Emit xbegin and adjacent loop + void build_transaction_enter(X86Assembler& c, Label abort); + + // Emit xabort and return zero + void build_transaction_abort(X86Assembler& c, unsigned char code); +} + +// Build runtime function with asmjit::X86Assembler +template +FT build_function_asm(F&& builder) +{ + using namespace asmjit; + + auto& rt = get_global_runtime(); + + CodeHolder code; + code.init(rt.getCodeInfo()); + code._globalHints = asmjit::CodeEmitter::kHintOptimizedAlign; + + std::array args; +#ifdef _WIN32 + args[0] = x86::rcx; + args[1] = x86::rdx; + args[2] = x86::r8; + args[3] = x86::r9; +#else + args[0] = x86::rdi; + args[1] = x86::rsi; + args[2] = x86::rdx; + args[3] = x86::rcx; +#endif + + X86Assembler compiler(&code); + builder(std::ref(compiler), args); + + FT result; + + if (rt.add(&result, &code)) + { + return nullptr; + } + + return result; +} + #ifdef LLVM_AVAILABLE #include diff --git a/rpcs3/Emu/Cell/SPUASMJITRecompiler.h b/rpcs3/Emu/Cell/SPUASMJITRecompiler.h index edac1675d0..a2c77a5e75 100644 --- a/rpcs3/Emu/Cell/SPUASMJITRecompiler.h +++ b/rpcs3/Emu/Cell/SPUASMJITRecompiler.h @@ -1,15 +1,11 @@ #pragma once +#include "Utilities/JIT.h" #include "Utilities/mutex.h" #include "SPURecompiler.h" #include -#define ASMJIT_STATIC -#define ASMJIT_DEBUG - -#include "asmjit.h" - // SPU ASMJIT Runtime object (global) class spu_runtime {