Optimization: Make SVC use RSB

This commit is contained in:
MerryMage 2016-08-15 15:02:08 +01:00
parent 6c45619aa1
commit 7d7ac0af71
8 changed files with 30 additions and 7 deletions

View file

@ -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();

View file

@ -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

View file

@ -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.
} }

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;
} }

View file

@ -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;