block_of_code: Implement farcode
This commit is contained in:
parent
1c21ae6bcd
commit
0d47f50f57
2 changed files with 38 additions and 4 deletions
|
@ -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:
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue