Optimization: Make SVC use RSB
This commit is contained in:
parent
6c45619aa1
commit
7d7ac0af71
8 changed files with 30 additions and 7 deletions
|
@ -1674,6 +1674,9 @@ void EmitX64::EmitTerminal(IR::Terminal terminal, Arm::LocationDescriptor initia
|
||||||
case 6:
|
case 6:
|
||||||
EmitTerminalIf(boost::get<IR::Term::If>(terminal), initial_location);
|
EmitTerminalIf(boost::get<IR::Term::If>(terminal), initial_location);
|
||||||
return;
|
return;
|
||||||
|
case 7:
|
||||||
|
EmitTerminalCheckHalt(boost::get<IR::Term::CheckHalt>(terminal), initial_location);
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
ASSERT_MSG(0, "Invalid Terminal. Bad programmer.");
|
ASSERT_MSG(0, "Invalid Terminal. Bad programmer.");
|
||||||
return;
|
return;
|
||||||
|
@ -1776,6 +1779,12 @@ void EmitX64::EmitTerminalIf(IR::Term::If terminal, Arm::LocationDescriptor init
|
||||||
EmitTerminal(terminal.then_, initial_location);
|
EmitTerminal(terminal.then_, initial_location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmitX64::EmitTerminalCheckHalt(IR::Term::CheckHalt terminal, Arm::LocationDescriptor initial_location) {
|
||||||
|
code->CMP(8, MDisp(R15, offsetof(JitState, halt_requested)), Imm8(0));
|
||||||
|
code->J_CC(CC_NE, code->GetReturnFromRunCodeAddress(), true);
|
||||||
|
EmitTerminal(terminal.else_, initial_location);
|
||||||
|
}
|
||||||
|
|
||||||
void EmitX64::Patch(Arm::LocationDescriptor desc, CodePtr bb) {
|
void EmitX64::Patch(Arm::LocationDescriptor desc, CodePtr bb) {
|
||||||
u8* const save_code_ptr = code->GetWritableCodePtr();
|
u8* const save_code_ptr = code->GetWritableCodePtr();
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,7 @@ private:
|
||||||
void EmitTerminalLinkBlockFast(IR::Term::LinkBlockFast terminal, Arm::LocationDescriptor initial_location);
|
void EmitTerminalLinkBlockFast(IR::Term::LinkBlockFast terminal, Arm::LocationDescriptor initial_location);
|
||||||
void EmitTerminalPopRSBHint(IR::Term::PopRSBHint terminal, Arm::LocationDescriptor initial_location);
|
void EmitTerminalPopRSBHint(IR::Term::PopRSBHint terminal, Arm::LocationDescriptor initial_location);
|
||||||
void EmitTerminalIf(IR::Term::If terminal, Arm::LocationDescriptor initial_location);
|
void EmitTerminalIf(IR::Term::If terminal, Arm::LocationDescriptor initial_location);
|
||||||
|
void EmitTerminalCheckHalt(IR::Term::CheckHalt terminal, Arm::LocationDescriptor initial_location);
|
||||||
void Patch(Arm::LocationDescriptor desc, CodePtr bb);
|
void Patch(Arm::LocationDescriptor desc, CodePtr bb);
|
||||||
|
|
||||||
// Per-block state
|
// Per-block state
|
||||||
|
|
|
@ -112,10 +112,10 @@ size_t Jit::Run(size_t cycle_count) {
|
||||||
is_executing = true;
|
is_executing = true;
|
||||||
SCOPE_EXIT({ this->is_executing = false; });
|
SCOPE_EXIT({ this->is_executing = false; });
|
||||||
|
|
||||||
halt_requested = false;
|
impl->jit_state.halt_requested = false;
|
||||||
|
|
||||||
size_t cycles_executed = 0;
|
size_t cycles_executed = 0;
|
||||||
while (cycles_executed < cycle_count && !halt_requested) {
|
while (cycles_executed < cycle_count && !impl->jit_state.halt_requested) {
|
||||||
cycles_executed += impl->Execute(cycle_count - cycles_executed);
|
cycles_executed += impl->Execute(cycle_count - cycles_executed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ void Jit::Reset() {
|
||||||
|
|
||||||
void Jit::HaltExecution() {
|
void Jit::HaltExecution() {
|
||||||
ASSERT(is_executing);
|
ASSERT(is_executing);
|
||||||
halt_requested = true;
|
impl->jit_state.halt_requested = true;
|
||||||
|
|
||||||
// TODO: Uh do other stuff to JitState pls.
|
// TODO: Uh do other stuff to JitState pls.
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ struct JitState {
|
||||||
u32 guest_MXCSR = 0x00001f80;
|
u32 guest_MXCSR = 0x00001f80;
|
||||||
u32 save_host_MXCSR = 0;
|
u32 save_host_MXCSR = 0;
|
||||||
s64 cycles_remaining = 0;
|
s64 cycles_remaining = 0;
|
||||||
|
bool halt_requested = false;
|
||||||
|
|
||||||
// Exclusive state
|
// Exclusive state
|
||||||
static constexpr u32 RESERVATION_GRANULE_MASK = 0xFFFFFFF8;
|
static constexpr u32 RESERVATION_GRANULE_MASK = 0xFFFFFFF8;
|
||||||
|
|
|
@ -166,6 +166,7 @@ struct LinkBlockFast {
|
||||||
struct PopRSBHint {};
|
struct PopRSBHint {};
|
||||||
|
|
||||||
struct If;
|
struct If;
|
||||||
|
struct CheckHalt;
|
||||||
/// A Terminal is the terminal instruction in a MicroBlock.
|
/// A Terminal is the terminal instruction in a MicroBlock.
|
||||||
using Terminal = boost::variant<
|
using Terminal = boost::variant<
|
||||||
Invalid,
|
Invalid,
|
||||||
|
@ -174,7 +175,8 @@ using Terminal = boost::variant<
|
||||||
LinkBlock,
|
LinkBlock,
|
||||||
LinkBlockFast,
|
LinkBlockFast,
|
||||||
PopRSBHint,
|
PopRSBHint,
|
||||||
boost::recursive_wrapper<If>
|
boost::recursive_wrapper<If>,
|
||||||
|
boost::recursive_wrapper<CheckHalt>
|
||||||
>;
|
>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -188,6 +190,15 @@ struct If {
|
||||||
Terminal else_;
|
Terminal else_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This terminal instruction checks if a halt was requested. If it wasn't, else_ is
|
||||||
|
* executed.
|
||||||
|
*/
|
||||||
|
struct CheckHalt {
|
||||||
|
CheckHalt(Terminal else_) : else_(else_) {}
|
||||||
|
Terminal else_;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Term
|
} // namespace Term
|
||||||
|
|
||||||
using Term::Terminal;
|
using Term::Terminal;
|
||||||
|
|
|
@ -17,9 +17,10 @@ bool ArmTranslatorVisitor::arm_SVC(Cond cond, Imm24 imm24) {
|
||||||
u32 imm32 = imm24;
|
u32 imm32 = imm24;
|
||||||
// SVC<c> #<imm24>
|
// SVC<c> #<imm24>
|
||||||
if (ConditionPassed(cond)) {
|
if (ConditionPassed(cond)) {
|
||||||
|
ir.PushRSB(ir.current_location.AdvancePC(4));
|
||||||
ir.BranchWritePC(ir.Imm32(ir.current_location.PC() + 4));
|
ir.BranchWritePC(ir.Imm32(ir.current_location.PC() + 4));
|
||||||
ir.CallSupervisor(ir.Imm32(imm32));
|
ir.CallSupervisor(ir.Imm32(imm32));
|
||||||
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
ir.SetTerm(IR::Term::CheckHalt{IR::Term::PopRSBHint{}});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -773,8 +773,9 @@ struct ThumbTranslatorVisitor final {
|
||||||
u32 imm32 = imm8;
|
u32 imm32 = imm8;
|
||||||
// SVC #<imm8>
|
// SVC #<imm8>
|
||||||
ir.BranchWritePC(ir.Imm32(ir.current_location.PC() + 2));
|
ir.BranchWritePC(ir.Imm32(ir.current_location.PC() + 2));
|
||||||
|
ir.PushRSB(ir.current_location.AdvancePC(2));
|
||||||
ir.CallSupervisor(ir.Imm32(imm32));
|
ir.CallSupervisor(ir.Imm32(imm32));
|
||||||
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
ir.SetTerm(IR::Term::CheckHalt{IR::Term::PopRSBHint{}});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,6 @@ public:
|
||||||
std::string Disassemble(const Arm::LocationDescriptor& descriptor);
|
std::string Disassemble(const Arm::LocationDescriptor& descriptor);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool halt_requested = false;
|
|
||||||
bool is_executing = false;
|
bool is_executing = false;
|
||||||
|
|
||||||
struct Impl;
|
struct Impl;
|
||||||
|
|
Loading…
Reference in a new issue