block_of_code: Implement farcode

This commit is contained in:
MerryMage 2017-04-19 18:58:36 +01:00
parent 1c21ae6bcd
commit 0d47f50f57
2 changed files with 38 additions and 4 deletions

View file

@ -18,8 +18,11 @@
namespace Dynarmic { namespace Dynarmic {
namespace BackendX64 { 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) BlockOfCode::BlockOfCode(UserCallbacks cb, LookupBlockCallback lookup_block, void* lookup_block_arg)
: Xbyak::CodeGenerator(128 * 1024 * 1024) : Xbyak::CodeGenerator(TOTAL_CODE_SIZE)
, cb(cb) , cb(cb)
, lookup_block(lookup_block) , lookup_block(lookup_block)
, lookup_block_arg(lookup_block_arg) , lookup_block_arg(lookup_block_arg)
@ -28,11 +31,16 @@ BlockOfCode::BlockOfCode(UserCallbacks cb, LookupBlockCallback lookup_block, voi
GenRunCode(); GenRunCode();
GenMemoryAccessors(); GenMemoryAccessors();
unwind_handler.Register(this); unwind_handler.Register(this);
user_code_begin = getCurr<CodePtr>(); near_code_begin = getCurr();
far_code_begin = getCurr() + FAR_CODE_OFFSET;
ClearCache();
} }
void BlockOfCode::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 { 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); 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) { void BlockOfCode::nop(size_t size) {
switch (size) { switch (size) {
case 0: case 0:

View file

@ -59,6 +59,11 @@ public:
Xbyak::Address MConst(u64 constant); 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 { const void* GetReturnFromRunCodeAddress() const {
return return_from_run_code[0]; return return_from_run_code[0];
} }
@ -127,10 +132,15 @@ private:
LookupBlockCallback lookup_block; LookupBlockCallback lookup_block;
void* lookup_block_arg; void* lookup_block_arg;
CodePtr user_code_begin; CodePtr near_code_begin;
CodePtr far_code_begin;
ConstantPool constant_pool; ConstantPool constant_pool;
bool in_far_code = false;
CodePtr near_code_ptr;
CodePtr far_code_ptr;
using RunCodeFuncType = void(*)(JitState*); using RunCodeFuncType = void(*)(JitState*);
RunCodeFuncType run_code = nullptr; RunCodeFuncType run_code = nullptr;
static constexpr size_t NO_SWITCH_MXCSR = 1 << 0; static constexpr size_t NO_SWITCH_MXCSR = 1 << 0;