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 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<CodePtr>();
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:

View file

@ -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;