diff --git a/src/dynarmic/backend/x64/block_of_code.cpp b/src/dynarmic/backend/x64/block_of_code.cpp index 6e42231b..cc2bcc9b 100644 --- a/src/dynarmic/backend/x64/block_of_code.cpp +++ b/src/dynarmic/backend/x64/block_of_code.cpp @@ -12,6 +12,12 @@ # include #endif +#ifdef __APPLE__ +# include +# include +# include +#endif + #include #include @@ -183,6 +189,19 @@ HostFeature GetHostFeatures() { return features; } +#ifdef __APPLE__ +bool IsUnderRosetta() { + int result = 0; + size_t result_size = sizeof(result); + if (sysctlbyname("sysctl.proc_translated", &result, &result_size, nullptr, 0) == -1) { + if (errno != ENOENT) + fmt::print("IsUnderRosetta: Failed to detect Rosetta state, assuming not under Rosetta"); + return false; + } + return result != 0; +} +#endif + } // anonymous namespace BlockOfCode::BlockOfCode(RunCodeCallbacks cb, JitStateInfo jsi, size_t total_code_size, std::function rcp) @@ -394,6 +413,10 @@ void BlockOfCode::LookupBlock() { } void BlockOfCode::LoadRequiredFlagsForCondFromRax(IR::Cond cond) { +#ifdef __APPLE__ + static const bool is_rosetta = IsUnderRosetta(); +#endif + // sahf restores SF, ZF, CF // add al, 0x7F restores OF @@ -419,6 +442,15 @@ void BlockOfCode::LoadRequiredFlagsForCondFromRax(IR::Cond cond) { case IR::Cond::LT: // n != v case IR::Cond::GT: // !z & (n == v) case IR::Cond::LE: // z | (n != v) +#ifdef __APPLE__ + if (is_rosetta) { + shl(al, 3); + xchg(al, ah); + push(rax); + popf(); + break; + } +#endif cmp(al, 0x81); sahf(); break;