From 0d47f50f572951450f80815277503d41363934cf Mon Sep 17 00:00:00 2001 From: MerryMage Date: Wed, 19 Apr 2017 18:58:36 +0100 Subject: [PATCH] block_of_code: Implement farcode --- src/backend_x64/block_of_code.cpp | 30 +++++++++++++++++++++++++++--- src/backend_x64/block_of_code.h | 12 +++++++++++- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/backend_x64/block_of_code.cpp b/src/backend_x64/block_of_code.cpp index 7148bd40..29791982 100644 --- a/src/backend_x64/block_of_code.cpp +++ b/src/backend_x64/block_of_code.cpp @@ -18,8 +18,11 @@ namespace Dynarmic { namespace BackendX64 { +constexpr size_t TOTAL_CODE_SIZE = 128 * 1024 * 1024; +constexpr size_t FAR_CODE_OFFSET = 100 * 1024 * 1024; + BlockOfCode::BlockOfCode(UserCallbacks cb, LookupBlockCallback lookup_block, void* lookup_block_arg) - : Xbyak::CodeGenerator(128 * 1024 * 1024) + : Xbyak::CodeGenerator(TOTAL_CODE_SIZE) , cb(cb) , lookup_block(lookup_block) , lookup_block_arg(lookup_block_arg) @@ -28,11 +31,16 @@ BlockOfCode::BlockOfCode(UserCallbacks cb, LookupBlockCallback lookup_block, voi GenRunCode(); GenMemoryAccessors(); unwind_handler.Register(this); - user_code_begin = getCurr(); + near_code_begin = getCurr(); + far_code_begin = getCurr() + FAR_CODE_OFFSET; + ClearCache(); } void BlockOfCode::ClearCache() { - SetCodePtr(user_code_begin); + in_far_code = false; + near_code_ptr = near_code_begin; + far_code_ptr = far_code_begin; + SetCodePtr(near_code_begin); } size_t BlockOfCode::RunCode(JitState* jit_state, size_t cycles_to_run) const { @@ -183,6 +191,22 @@ Xbyak::Address BlockOfCode::MConst(u64 constant) { return constant_pool.GetConstant(constant); } +void BlockOfCode::SwitchToFarCode() { + ASSERT(!in_far_code); + in_far_code = true; + near_code_ptr = getCurr(); + SetCodePtr(far_code_ptr); + + ASSERT_MSG(near_code_ptr < far_code_begin, "Near code has overwritten far code!"); +} + +void BlockOfCode::SwitchToNearCode() { + ASSERT(in_far_code); + in_far_code = false; + far_code_ptr = getCurr(); + SetCodePtr(near_code_ptr); +} + void BlockOfCode::nop(size_t size) { switch (size) { case 0: diff --git a/src/backend_x64/block_of_code.h b/src/backend_x64/block_of_code.h index ca1bce9d..4a9a1cbb 100644 --- a/src/backend_x64/block_of_code.h +++ b/src/backend_x64/block_of_code.h @@ -59,6 +59,11 @@ public: Xbyak::Address MConst(u64 constant); + /// Far code sits far away from the near code. Execution remains primarily in near code. + /// "Cold" / Rarely executed instructions sit in far code, so the CPU doesn't fetch them unless necessary. + void SwitchToFarCode(); + void SwitchToNearCode(); + const void* GetReturnFromRunCodeAddress() const { return return_from_run_code[0]; } @@ -127,10 +132,15 @@ private: LookupBlockCallback lookup_block; void* lookup_block_arg; - CodePtr user_code_begin; + CodePtr near_code_begin; + CodePtr far_code_begin; ConstantPool constant_pool; + bool in_far_code = false; + CodePtr near_code_ptr; + CodePtr far_code_ptr; + using RunCodeFuncType = void(*)(JitState*); RunCodeFuncType run_code = nullptr; static constexpr size_t NO_SWITCH_MXCSR = 1 << 0;