backend_x64: Simplify dispatcher

This commit is contained in:
MerryMage 2017-04-07 10:52:44 +01:00
parent 523ae542f4
commit 1b37420459
4 changed files with 90 additions and 31 deletions

View file

@ -18,9 +18,14 @@
namespace Dynarmic {
namespace BackendX64 {
BlockOfCode::BlockOfCode(UserCallbacks cb) : Xbyak::CodeGenerator(128 * 1024 * 1024), cb(cb), constant_pool(this, 256) {
BlockOfCode::BlockOfCode(UserCallbacks cb, LookupBlockCallback lookup_block, void* lookup_block_arg)
: Xbyak::CodeGenerator(128 * 1024 * 1024)
, cb(cb)
, lookup_block(lookup_block)
, lookup_block_arg(lookup_block_arg)
, constant_pool(this, 256)
{
GenRunCode();
GenReturnFromRunCode();
GenMemoryAccessors();
unwind_handler.Register(this);
user_code_begin = getCurr<CodePtr>();
@ -30,20 +35,32 @@ void BlockOfCode::ClearCache() {
SetCodePtr(user_code_begin);
}
size_t BlockOfCode::RunCode(JitState* jit_state, CodePtr basic_block, size_t cycles_to_run) const {
size_t BlockOfCode::RunCode(JitState* jit_state, size_t cycles_to_run) const {
constexpr size_t max_cycles_to_run = static_cast<size_t>(std::numeric_limits<decltype(jit_state->cycles_remaining)>::max());
ASSERT(cycles_to_run <= max_cycles_to_run);
jit_state->cycles_remaining = cycles_to_run;
run_code(jit_state, basic_block);
run_code(jit_state);
return cycles_to_run - jit_state->cycles_remaining; // Return number of cycles actually run.
}
void BlockOfCode::ReturnFromRunCode(bool MXCSR_switch) {
jmp(MXCSR_switch ? return_from_run_code : return_from_run_code_without_mxcsr_switch);
size_t index = 0;
if (!MXCSR_switch)
index |= NO_SWITCH_MXCSR;
jmp(return_from_run_code[index]);
}
void BlockOfCode::ForceReturnFromRunCode(bool MXCSR_switch) {
size_t index = FORCE_RETURN;
if (!MXCSR_switch)
index |= NO_SWITCH_MXCSR;
jmp(return_from_run_code[index]);
}
void BlockOfCode::GenRunCode() {
Xbyak::Label loop;
align();
run_code = getCurr<RunCodeFuncType>();
@ -54,19 +71,44 @@ void BlockOfCode::GenRunCode() {
ABI_PushCalleeSaveRegistersAndAdjustStack(this);
mov(r15, ABI_PARAM1);
L(loop);
mov(ABI_PARAM1, u64(lookup_block_arg));
CallFunction(lookup_block);
SwitchMxcsrOnEntry();
jmp(ABI_PARAM2);
}
jmp(ABI_RETURN);
void BlockOfCode::GenReturnFromRunCode() {
return_from_run_code = getCurr<const void*>();
// Return from run code variants
const auto emit_return_from_run_code = [this, &loop](bool no_mxcsr_switch, bool force_return){
if (!no_mxcsr_switch) {
SwitchMxcsrOnExit();
}
SwitchMxcsrOnExit();
if (!force_return) {
cmp(qword[r15 + offsetof(JitState, cycles_remaining)], 0);
jg(loop);
}
return_from_run_code_without_mxcsr_switch = getCurr<const void*>();
ABI_PopCalleeSaveRegistersAndAdjustStack(this);
ret();
};
ABI_PopCalleeSaveRegistersAndAdjustStack(this);
ret();
align();
return_from_run_code[0] = getCurr<const void*>();
emit_return_from_run_code(false, false);
align();
return_from_run_code[NO_SWITCH_MXCSR] = getCurr<const void*>();
emit_return_from_run_code(true, false);
align();
return_from_run_code[FORCE_RETURN] = getCurr<const void*>();
emit_return_from_run_code(false, true);
align();
return_from_run_code[NO_SWITCH_MXCSR | FORCE_RETURN] = getCurr<const void*>();
emit_return_from_run_code(true, true);
}
void BlockOfCode::GenMemoryAccessors() {