diff --git a/src/dynarmic/backend/A64/emitter/a64_emitter.cpp b/src/dynarmic/backend/A64/emitter/a64_emitter.cpp index 5b527f46..62a56000 100644 --- a/src/dynarmic/backend/A64/emitter/a64_emitter.cpp +++ b/src/dynarmic/backend/A64/emitter/a64_emitter.cpp @@ -8,10 +8,6 @@ #include #include -#if defined(__APPLE__) -#include -#endif - #include #include #include @@ -20,6 +16,13 @@ #include "a64_emitter.h" #include "dynarmic/common/math_util.h" +#ifdef _WIN32 +# include +#endif +#ifdef __APPLE__ +# include +#endif + namespace Dynarmic::BackendA64::Arm64Gen { namespace { @@ -37,6 +40,7 @@ int CountLeadingZeros(u64 value, int width) { return __builtin_clzll(value); } #endif + // TODO(jbramley): Optimize this for ARM64 hosts. int count = 0; uint64_t bit_test = 1ULL << (width - 1); @@ -367,10 +371,11 @@ void ARM64XEmitter::FlushIcacheSection(const u8* start, const u8* end) { if (start == end) return; -#if defined(__APPLE__) - // Header file says this is equivalent to: sys_icache_invalidate(start, end - - // start); +#if defined(IOS) || defined(__APPLE__) + // Header file says this is equivalent to: sys_icache_invalidate(start, end - start); sys_cache_control(kCacheFunctionPrepareForExecution, const_cast(start), end - start); +#elif defined(WIN32) + FlushInstructionCache(GetCurrentProcess(), start, end - start); #else // Don't rely on GCC's __clear_cache implementation, as it caches // icache/dcache cache line sizes, that can vary between cores on diff --git a/src/dynarmic/backend/A64/emitter/code_block.h b/src/dynarmic/backend/A64/emitter/code_block.h index 50b31729..665d0d4e 100644 --- a/src/dynarmic/backend/A64/emitter/code_block.h +++ b/src/dynarmic/backend/A64/emitter/code_block.h @@ -82,7 +82,13 @@ public: // it'll do the job. void FreeCodeSpace() { ASSERT(!m_is_child); - ASSERT(munmap(region, total_region_size) == 0); + if (region) { +#ifdef _WIN32 + ASSERT(VirtualFree(region, 0, MEM_RELEASE)); +#else + ASSERT(munmap(region, total_region_size) == 0); +#endif + } region = nullptr; region_size = 0; total_region_size = 0; @@ -96,12 +102,7 @@ public: bool IsInSpace(const u8* ptr) const { return ptr >= region && ptr < (region + region_size); } - // Cannot currently be undone. Will write protect the entire code region. - // Start over if you need to change the code (call FreeCodeSpace(), - // AllocCodeSpace()). - void WriteProtect() { - ASSERT(mprotect(region, region_size, PROT_READ | PROT_EXEC) != 0); - } + void ResetCodePtr() { T::SetCodePtr(region); }