|
@@ -8,6 +8,10 @@
|
|
|
#include "core/core.h"
|
|
#include "core/core.h"
|
|
|
#include "core/core_timing.h"
|
|
#include "core/core_timing.h"
|
|
|
|
|
|
|
|
|
|
+#ifdef _MSC_VER
|
|
|
|
|
+#include <intrin.h>
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
using Callback = Dynarmic::A32::Coprocessor::Callback;
|
|
using Callback = Dynarmic::A32::Coprocessor::Callback;
|
|
|
using CallbackOrAccessOneWord = Dynarmic::A32::Coprocessor::CallbackOrAccessOneWord;
|
|
using CallbackOrAccessOneWord = Dynarmic::A32::Coprocessor::CallbackOrAccessOneWord;
|
|
|
using CallbackOrAccessTwoWords = Dynarmic::A32::Coprocessor::CallbackOrAccessTwoWords;
|
|
using CallbackOrAccessTwoWords = Dynarmic::A32::Coprocessor::CallbackOrAccessTwoWords;
|
|
@@ -47,12 +51,31 @@ CallbackOrAccessOneWord DynarmicCP15::CompileSendOneWord(bool two, unsigned opc1
|
|
|
switch (opc2) {
|
|
switch (opc2) {
|
|
|
case 4:
|
|
case 4:
|
|
|
// CP15_DATA_SYNC_BARRIER
|
|
// CP15_DATA_SYNC_BARRIER
|
|
|
- // This is a dummy write, we ignore the value written here.
|
|
|
|
|
- return &dummy_value;
|
|
|
|
|
|
|
+ return Callback{
|
|
|
|
|
+ [](Dynarmic::A32::Jit*, void*, std::uint32_t, std::uint32_t) -> std::uint64_t {
|
|
|
|
|
+#ifdef _MSC_VER
|
|
|
|
|
+ _mm_mfence();
|
|
|
|
|
+ _mm_lfence();
|
|
|
|
|
+#else
|
|
|
|
|
+ asm volatile("mfence\n\tlfence\n\t" : : : "memory");
|
|
|
|
|
+#endif
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ },
|
|
|
|
|
+ std::nullopt,
|
|
|
|
|
+ };
|
|
|
case 5:
|
|
case 5:
|
|
|
// CP15_DATA_MEMORY_BARRIER
|
|
// CP15_DATA_MEMORY_BARRIER
|
|
|
- // This is a dummy write, we ignore the value written here.
|
|
|
|
|
- return &dummy_value;
|
|
|
|
|
|
|
+ return Callback{
|
|
|
|
|
+ [](Dynarmic::A32::Jit*, void*, std::uint32_t, std::uint32_t) -> std::uint64_t {
|
|
|
|
|
+#ifdef _MSC_VER
|
|
|
|
|
+ _mm_mfence();
|
|
|
|
|
+#else
|
|
|
|
|
+ asm volatile("mfence\n\t" : : : "memory");
|
|
|
|
|
+#endif
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ },
|
|
|
|
|
+ std::nullopt,
|
|
|
|
|
+ };
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|