|
|
@ -75,14 +75,8 @@ public: |
|
|
HaltReason Run() { |
|
|
HaltReason Run() { |
|
|
ASSERT(!is_executing); |
|
|
ASSERT(!is_executing); |
|
|
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&jit_state.halt_reason))); |
|
|
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&jit_state.halt_reason))); |
|
|
|
|
|
|
|
|
is_executing = true; |
|
|
is_executing = true; |
|
|
SCOPE_EXIT { |
|
|
|
|
|
this->is_executing = false; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// TODO: Check code alignment
|
|
|
// TODO: Check code alignment
|
|
|
|
|
|
|
|
|
const CodePtr current_code_ptr = [this] { |
|
|
const CodePtr current_code_ptr = [this] { |
|
|
// RSB optimization
|
|
|
// RSB optimization
|
|
|
const u32 new_rsb_ptr = (jit_state.rsb_ptr - 1) & A64JitState::RSBPtrMask; |
|
|
const u32 new_rsb_ptr = (jit_state.rsb_ptr - 1) & A64JitState::RSBPtrMask; |
|
|
@ -94,37 +88,28 @@ public: |
|
|
}(); |
|
|
}(); |
|
|
|
|
|
|
|
|
const HaltReason hr = block_of_code.RunCode(&jit_state, current_code_ptr); |
|
|
const HaltReason hr = block_of_code.RunCode(&jit_state, current_code_ptr); |
|
|
|
|
|
|
|
|
PerformRequestedCacheInvalidation(hr); |
|
|
PerformRequestedCacheInvalidation(hr); |
|
|
|
|
|
|
|
|
|
|
|
is_executing = false; |
|
|
return hr; |
|
|
return hr; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
HaltReason Step() { |
|
|
HaltReason Step() { |
|
|
ASSERT(!is_executing); |
|
|
ASSERT(!is_executing); |
|
|
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&jit_state.halt_reason))); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PerformRequestedCacheInvalidation(HaltReason(Atomic::Load(&jit_state.halt_reason))); |
|
|
is_executing = true; |
|
|
is_executing = true; |
|
|
SCOPE_EXIT { |
|
|
|
|
|
this->is_executing = false; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const HaltReason hr = block_of_code.StepCode(&jit_state, GetCurrentSingleStep()); |
|
|
const HaltReason hr = block_of_code.StepCode(&jit_state, GetCurrentSingleStep()); |
|
|
|
|
|
|
|
|
PerformRequestedCacheInvalidation(hr); |
|
|
PerformRequestedCacheInvalidation(hr); |
|
|
|
|
|
|
|
|
|
|
|
is_executing = false; |
|
|
return hr; |
|
|
return hr; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void ClearCache() { |
|
|
void ClearCache() { |
|
|
std::unique_lock lock{invalidation_mutex}; |
|
|
|
|
|
invalidate_entire_cache = true; |
|
|
invalidate_entire_cache = true; |
|
|
HaltExecution(HaltReason::CacheInvalidation); |
|
|
HaltExecution(HaltReason::CacheInvalidation); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void InvalidateCacheRange(u64 start_address, size_t length) { |
|
|
void InvalidateCacheRange(u64 start_address, size_t length) { |
|
|
std::unique_lock lock{invalidation_mutex}; |
|
|
|
|
|
const auto end_address = static_cast<u64>(start_address + length - 1); |
|
|
|
|
|
|
|
|
const auto end_address = u64(start_address + length - 1); |
|
|
const auto range = boost::icl::discrete_interval<u64>::closed(start_address, end_address); |
|
|
const auto range = boost::icl::discrete_interval<u64>::closed(start_address, end_address); |
|
|
invalid_cache_ranges.add(range); |
|
|
invalid_cache_ranges.add(range); |
|
|
HaltExecution(HaltReason::CacheInvalidation); |
|
|
HaltExecution(HaltReason::CacheInvalidation); |
|
|
@ -136,11 +121,11 @@ public: |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void HaltExecution(HaltReason hr) { |
|
|
void HaltExecution(HaltReason hr) { |
|
|
Atomic::Or(&jit_state.halt_reason, static_cast<u32>(hr)); |
|
|
|
|
|
|
|
|
Atomic::Or(&jit_state.halt_reason, u32(hr)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void ClearHalt(HaltReason hr) { |
|
|
void ClearHalt(HaltReason hr) { |
|
|
Atomic::And(&jit_state.halt_reason, ~static_cast<u32>(hr)); |
|
|
|
|
|
|
|
|
Atomic::And(&jit_state.halt_reason, ~u32(hr)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
u64 GetSP() const { |
|
|
u64 GetSP() const { |
|
|
@ -228,10 +213,6 @@ public: |
|
|
jit_state.exclusive_state = 0; |
|
|
jit_state.exclusive_state = 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bool IsExecuting() const { |
|
|
|
|
|
return is_executing; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::string Disassemble() const { |
|
|
std::string Disassemble() const { |
|
|
const size_t size = reinterpret_cast<const char*>(block_of_code.getCurr()) - reinterpret_cast<const char*>(block_of_code.GetCodeBegin()); |
|
|
const size_t size = reinterpret_cast<const char*>(block_of_code.getCurr()) - reinterpret_cast<const char*>(block_of_code.GetCodeBegin()); |
|
|
auto const* p = reinterpret_cast<const char*>(block_of_code.GetCodeBegin()); |
|
|
auto const* p = reinterpret_cast<const char*>(block_of_code.GetCodeBegin()); |
|
|
@ -280,14 +261,10 @@ private: |
|
|
|
|
|
|
|
|
void PerformRequestedCacheInvalidation(HaltReason hr) { |
|
|
void PerformRequestedCacheInvalidation(HaltReason hr) { |
|
|
if (Has(hr, HaltReason::CacheInvalidation)) { |
|
|
if (Has(hr, HaltReason::CacheInvalidation)) { |
|
|
std::unique_lock lock{invalidation_mutex}; |
|
|
|
|
|
|
|
|
|
|
|
ClearHalt(HaltReason::CacheInvalidation); |
|
|
ClearHalt(HaltReason::CacheInvalidation); |
|
|
|
|
|
|
|
|
if (!invalidate_entire_cache && invalid_cache_ranges.empty()) { |
|
|
if (!invalidate_entire_cache && invalid_cache_ranges.empty()) { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
jit_state.ResetRSB(); |
|
|
jit_state.ResetRSB(); |
|
|
if (invalidate_entire_cache) { |
|
|
if (invalidate_entire_cache) { |
|
|
block_of_code.ClearCache(); |
|
|
block_of_code.ClearCache(); |
|
|
@ -306,10 +283,9 @@ private: |
|
|
BlockOfCode block_of_code; |
|
|
BlockOfCode block_of_code; |
|
|
A64EmitX64 emitter; |
|
|
A64EmitX64 emitter; |
|
|
Optimization::PolyfillOptions polyfill_options; |
|
|
Optimization::PolyfillOptions polyfill_options; |
|
|
bool is_executing = false; |
|
|
|
|
|
bool invalidate_entire_cache = false; |
|
|
|
|
|
boost::icl::interval_set<u64> invalid_cache_ranges; |
|
|
boost::icl::interval_set<u64> invalid_cache_ranges; |
|
|
std::mutex invalidation_mutex; |
|
|
|
|
|
|
|
|
bool invalidate_entire_cache = false; |
|
|
|
|
|
bool is_executing = false; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Jit::Jit(UserConfig conf) |
|
|
Jit::Jit(UserConfig conf) |
|
|
@ -421,10 +397,6 @@ void Jit::ClearExclusiveState() { |
|
|
impl->ClearExclusiveState(); |
|
|
impl->ClearExclusiveState(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bool Jit::IsExecuting() const { |
|
|
|
|
|
return impl->IsExecuting(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::string Jit::Disassemble() const { |
|
|
std::string Jit::Disassemble() const { |
|
|
return impl->Disassemble(); |
|
|
return impl->Disassemble(); |
|
|
} |
|
|
} |
|
|
|