block_of_code: Move MXCSR switching out of dispatch loop
Also clarify MXCSR entry/exit terminology
This commit is contained in:
parent
2a818f9d8e
commit
eb80aae9c0
3 changed files with 21 additions and 20 deletions
|
@ -85,22 +85,22 @@ void BlockOfCode::RunCode(JitState* jit_state, size_t cycles_to_run) const {
|
||||||
run_code(jit_state);
|
run_code(jit_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlockOfCode::ReturnFromRunCode(bool MXCSR_switch) {
|
void BlockOfCode::ReturnFromRunCode(bool mxcsr_already_exited) {
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
if (!MXCSR_switch)
|
if (mxcsr_already_exited)
|
||||||
index |= NO_SWITCH_MXCSR;
|
index |= MXCSR_ALREADY_EXITED;
|
||||||
jmp(return_from_run_code[index]);
|
jmp(return_from_run_code[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlockOfCode::ForceReturnFromRunCode(bool MXCSR_switch) {
|
void BlockOfCode::ForceReturnFromRunCode(bool mxcsr_already_exited) {
|
||||||
size_t index = FORCE_RETURN;
|
size_t index = FORCE_RETURN;
|
||||||
if (!MXCSR_switch)
|
if (mxcsr_already_exited)
|
||||||
index |= NO_SWITCH_MXCSR;
|
index |= MXCSR_ALREADY_EXITED;
|
||||||
jmp(return_from_run_code[index]);
|
jmp(return_from_run_code[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlockOfCode::GenRunCode() {
|
void BlockOfCode::GenRunCode() {
|
||||||
Xbyak::Label loop;
|
Xbyak::Label loop, enter_mxcsr_then_loop;
|
||||||
|
|
||||||
align();
|
align();
|
||||||
run_code = getCurr<RunCodeFuncType>();
|
run_code = getCurr<RunCodeFuncType>();
|
||||||
|
@ -119,22 +119,23 @@ void BlockOfCode::GenRunCode() {
|
||||||
|
|
||||||
mov(r15, ABI_PARAM1);
|
mov(r15, ABI_PARAM1);
|
||||||
|
|
||||||
|
L(enter_mxcsr_then_loop);
|
||||||
|
SwitchMxcsrOnEntry();
|
||||||
L(loop);
|
L(loop);
|
||||||
mov(ABI_PARAM1, u64(lookup_block_arg));
|
mov(ABI_PARAM1, u64(lookup_block_arg));
|
||||||
CallFunction(lookup_block);
|
CallFunction(lookup_block);
|
||||||
|
|
||||||
SwitchMxcsrOnEntry();
|
|
||||||
jmp(ABI_RETURN);
|
jmp(ABI_RETURN);
|
||||||
|
|
||||||
// Return from run code variants
|
// Return from run code variants
|
||||||
const auto emit_return_from_run_code = [this, &loop](bool no_mxcsr_switch, bool force_return){
|
const auto emit_return_from_run_code = [this, &loop, &enter_mxcsr_then_loop](bool mxcsr_already_exited, bool force_return){
|
||||||
if (!no_mxcsr_switch) {
|
|
||||||
SwitchMxcsrOnExit();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!force_return) {
|
if (!force_return) {
|
||||||
cmp(qword[r15 + offsetof(JitState, cycles_remaining)], 0);
|
cmp(qword[r15 + offsetof(JitState, cycles_remaining)], 0);
|
||||||
jg(loop);
|
jg(mxcsr_already_exited ? enter_mxcsr_then_loop : loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mxcsr_already_exited) {
|
||||||
|
SwitchMxcsrOnExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
mov(ABI_PARAM1, qword[r15 + offsetof(JitState, cycles_to_run)]);
|
mov(ABI_PARAM1, qword[r15 + offsetof(JitState, cycles_to_run)]);
|
||||||
|
@ -150,7 +151,7 @@ void BlockOfCode::GenRunCode() {
|
||||||
emit_return_from_run_code(false, false);
|
emit_return_from_run_code(false, false);
|
||||||
|
|
||||||
align();
|
align();
|
||||||
return_from_run_code[NO_SWITCH_MXCSR] = getCurr<const void*>();
|
return_from_run_code[MXCSR_ALREADY_EXITED] = getCurr<const void*>();
|
||||||
emit_return_from_run_code(true, false);
|
emit_return_from_run_code(true, false);
|
||||||
|
|
||||||
align();
|
align();
|
||||||
|
@ -158,7 +159,7 @@ void BlockOfCode::GenRunCode() {
|
||||||
emit_return_from_run_code(false, true);
|
emit_return_from_run_code(false, true);
|
||||||
|
|
||||||
align();
|
align();
|
||||||
return_from_run_code[NO_SWITCH_MXCSR | FORCE_RETURN] = getCurr<const void*>();
|
return_from_run_code[MXCSR_ALREADY_EXITED | FORCE_RETURN] = getCurr<const void*>();
|
||||||
emit_return_from_run_code(true, true);
|
emit_return_from_run_code(true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,9 +34,9 @@ public:
|
||||||
/// Runs emulated code for approximately `cycles_to_run` cycles.
|
/// Runs emulated code for approximately `cycles_to_run` cycles.
|
||||||
void RunCode(JitState* jit_state, size_t cycles_to_run) const;
|
void RunCode(JitState* jit_state, size_t cycles_to_run) const;
|
||||||
/// Code emitter: Returns to dispatcher
|
/// Code emitter: Returns to dispatcher
|
||||||
void ReturnFromRunCode(bool MXCSR_switch = true);
|
void ReturnFromRunCode(bool mxcsr_already_exited = false);
|
||||||
/// Code emitter: Returns to dispatcher, forces return to host
|
/// Code emitter: Returns to dispatcher, forces return to host
|
||||||
void ForceReturnFromRunCode(bool MXCSR_switch = true);
|
void ForceReturnFromRunCode(bool mxcsr_already_exited = false);
|
||||||
/// Code emitter: Makes guest MXCSR the current MXCSR
|
/// Code emitter: Makes guest MXCSR the current MXCSR
|
||||||
void SwitchMxcsrOnEntry();
|
void SwitchMxcsrOnEntry();
|
||||||
/// Code emitter: Makes saved host MXCSR the current MXCSR
|
/// Code emitter: Makes saved host MXCSR the current MXCSR
|
||||||
|
@ -145,7 +145,7 @@ private:
|
||||||
|
|
||||||
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 MXCSR_ALREADY_EXITED = 1 << 0;
|
||||||
static constexpr size_t FORCE_RETURN = 1 << 1;
|
static constexpr size_t FORCE_RETURN = 1 << 1;
|
||||||
std::array<const void*, 4> return_from_run_code;
|
std::array<const void*, 4> return_from_run_code;
|
||||||
void GenRunCode();
|
void GenRunCode();
|
||||||
|
|
|
@ -3371,7 +3371,7 @@ void EmitX64::EmitTerminal(IR::Term::Interpret terminal, IR::LocationDescriptor
|
||||||
code->mov(MJitStateReg(Arm::Reg::PC), code->ABI_PARAM1.cvt32());
|
code->mov(MJitStateReg(Arm::Reg::PC), code->ABI_PARAM1.cvt32());
|
||||||
code->SwitchMxcsrOnExit();
|
code->SwitchMxcsrOnExit();
|
||||||
code->CallFunction(cb.InterpreterFallback);
|
code->CallFunction(cb.InterpreterFallback);
|
||||||
code->ReturnFromRunCode(false); // TODO: Check cycles
|
code->ReturnFromRunCode(true); // TODO: Check cycles
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitX64::EmitTerminal(IR::Term::ReturnToDispatch, IR::LocationDescriptor) {
|
void EmitX64::EmitTerminal(IR::Term::ReturnToDispatch, IR::LocationDescriptor) {
|
||||||
|
|
Loading…
Reference in a new issue