block_of_code: Fix running under Rosetta

Rosetta doesn't have accurate emulation of the sahf instruction
This commit is contained in:
Merry 2022-08-05 23:43:01 +01:00
parent a38966a874
commit c60fd3f0ac

View file

@ -12,6 +12,12 @@
# include <sys/mman.h>
#endif
#ifdef __APPLE__
# include <errno.h>
# include <fmt/format.h>
# include <sys/sysctl.h>
#endif
#include <array>
#include <cstring>
@ -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<void(BlockOfCode&)> 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;