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:
|
||||
EmitTerminalIf(boost::get<IR::Term::If>(terminal), initial_location);
|
||||
return;
|
||||
case 7:
|
||||
EmitTerminalCheckHalt(boost::get<IR::Term::CheckHalt>(terminal), initial_location);
|
||||
return;
|
||||
default:
|
||||
ASSERT_MSG(0, "Invalid Terminal. Bad programmer.");
|
||||
return;
|
||||
|
@ -1776,6 +1779,12 @@ void EmitX64::EmitTerminalIf(IR::Term::If terminal, Arm::LocationDescriptor init
|
|||
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) {
|
||||
u8* const save_code_ptr = code->GetWritableCodePtr();
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ private:
|
|||
void EmitTerminalLinkBlockFast(IR::Term::LinkBlockFast 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 EmitTerminalCheckHalt(IR::Term::CheckHalt terminal, Arm::LocationDescriptor initial_location);
|
||||
void Patch(Arm::LocationDescriptor desc, CodePtr bb);
|
||||
|
||||
// Per-block state
|
||||
|
|
|
@ -112,10 +112,10 @@ size_t Jit::Run(size_t cycle_count) {
|
|||
is_executing = true;
|
||||
SCOPE_EXIT({ this->is_executing = false; });
|
||||
|
||||
halt_requested = false;
|
||||
impl->jit_state.halt_requested = false;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -136,7 +136,7 @@ void Jit::Reset() {
|
|||
|
||||
void Jit::HaltExecution() {
|
||||
ASSERT(is_executing);
|
||||
halt_requested = true;
|
||||
impl->jit_state.halt_requested = true;
|
||||
|
||||
// TODO: Uh do other stuff to JitState pls.
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ struct JitState {
|
|||
u32 guest_MXCSR = 0x00001f80;
|
||||
u32 save_host_MXCSR = 0;
|
||||
s64 cycles_remaining = 0;
|
||||
bool halt_requested = false;
|
||||
|
||||
// Exclusive state
|
||||
static constexpr u32 RESERVATION_GRANULE_MASK = 0xFFFFFFF8;
|
||||
|
|
|
@ -166,6 +166,7 @@ struct LinkBlockFast {
|
|||
struct PopRSBHint {};
|
||||
|
||||
struct If;
|
||||
struct CheckHalt;
|
||||
/// A Terminal is the terminal instruction in a MicroBlock.
|
||||
using Terminal = boost::variant<
|
||||
Invalid,
|
||||
|
@ -174,7 +175,8 @@ using Terminal = boost::variant<
|
|||
LinkBlock,
|
||||
LinkBlockFast,
|
||||
PopRSBHint,
|
||||
boost::recursive_wrapper<If>
|
||||
boost::recursive_wrapper<If>,
|
||||
boost::recursive_wrapper<CheckHalt>
|
||||
>;
|
||||
|
||||
/**
|
||||
|
@ -188,6 +190,15 @@ struct If {
|
|||
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
|
||||
|
||||
using Term::Terminal;
|
||||
|
|
|
@ -17,9 +17,10 @@ bool ArmTranslatorVisitor::arm_SVC(Cond cond, Imm24 imm24) {
|
|||
u32 imm32 = imm24;
|
||||
// SVC<c> #<imm24>
|
||||
if (ConditionPassed(cond)) {
|
||||
ir.PushRSB(ir.current_location.AdvancePC(4));
|
||||
ir.BranchWritePC(ir.Imm32(ir.current_location.PC() + 4));
|
||||
ir.CallSupervisor(ir.Imm32(imm32));
|
||||
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
||||
ir.SetTerm(IR::Term::CheckHalt{IR::Term::PopRSBHint{}});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -773,8 +773,9 @@ struct ThumbTranslatorVisitor final {
|
|||
u32 imm32 = imm8;
|
||||
// SVC #<imm8>
|
||||
ir.BranchWritePC(ir.Imm32(ir.current_location.PC() + 2));
|
||||
ir.PushRSB(ir.current_location.AdvancePC(2));
|
||||
ir.CallSupervisor(ir.Imm32(imm32));
|
||||
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
||||
ir.SetTerm(IR::Term::CheckHalt{IR::Term::PopRSBHint{}});
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -99,7 +99,6 @@ public:
|
|||
std::string Disassemble(const Arm::LocationDescriptor& descriptor);
|
||||
|
||||
private:
|
||||
bool halt_requested = false;
|
||||
bool is_executing = false;
|
||||
|
||||
struct Impl;
|
||||
|
|
Loading…
Reference in a new issue