FEXCore: Add a generic spill/fill-all syscall ABI and use for Windows

Also drop the legacy hangover ABI as it has no users.
This commit is contained in:
Billy Laws 2024-07-23 16:21:08 +00:00
parent 069e2ce62a
commit 2c4fd79304
4 changed files with 6 additions and 27 deletions

View File

@ -51,15 +51,6 @@ void OpDispatchBuilder::SyscallOp(OpcodeArgs, bool IsSyscallInst) {
FEXCore::X86State::REG_RSI, FEXCore::X86State::REG_RDI, FEXCore::X86State::REG_RBP,
};
static constexpr SyscallArray GPRIndexes_Hangover = {
FEXCore::X86State::REG_RCX,
};
static constexpr SyscallArray GPRIndexes_Win64 = {
FEXCore::X86State::REG_RAX, FEXCore::X86State::REG_R10, FEXCore::X86State::REG_RDX,
FEXCore::X86State::REG_R8, FEXCore::X86State::REG_R9, FEXCore::X86State::REG_RSP,
};
SyscallFlags DefaultSyscallFlags = FEXCore::IR::SyscallFlags::DEFAULT;
const auto OSABI = CTX->SyscallHandler->GetOSABI();
@ -69,18 +60,11 @@ void OpDispatchBuilder::SyscallOp(OpcodeArgs, bool IsSyscallInst) {
} else if (OSABI == FEXCore::HLE::SyscallOSABI::OS_LINUX32) {
NumArguments = GPRIndexes_32.size();
GPRIndexes = &GPRIndexes_32;
} else if (OSABI == FEXCore::HLE::SyscallOSABI::OS_WIN64) {
NumArguments = 6;
GPRIndexes = &GPRIndexes_Win64;
DefaultSyscallFlags = FEXCore::IR::SyscallFlags::NORETURNEDRESULT;
} else if (OSABI == FEXCore::HLE::SyscallOSABI::OS_WIN32) {
// Since the whole context is going to be saved at entry anyway, theres no need to do additional work to pass in args
} else if (OSABI == FEXCore::HLE::SyscallOSABI::OS_GENERIC) {
// All registers will be spilled before the syscall and filled afterwards so no JIT-side argument handling is necessary.
NumArguments = 0;
GPRIndexes = nullptr;
DefaultSyscallFlags = FEXCore::IR::SyscallFlags::NORETURNEDRESULT;
} else if (OSABI == FEXCore::HLE::SyscallOSABI::OS_HANGOVER) {
NumArguments = 1;
GPRIndexes = &GPRIndexes_Hangover;
} else {
LogMan::Msg::DFmt("Unhandled OSABI syscall");
}
@ -116,10 +100,7 @@ void OpDispatchBuilder::SyscallOp(OpcodeArgs, bool IsSyscallInst) {
FlushRegisterCache();
auto SyscallOp = _Syscall(Arguments[0], Arguments[1], Arguments[2], Arguments[3], Arguments[4], Arguments[5], Arguments[6], DefaultSyscallFlags);
if (OSABI != FEXCore::HLE::SyscallOSABI::OS_HANGOVER &&
(DefaultSyscallFlags & FEXCore::IR::SyscallFlags::NORETURNEDRESULT) != FEXCore::IR::SyscallFlags::NORETURNEDRESULT) {
// Hangover doesn't want us returning a result here
// syscall is being abused as a thunk for now.
if ((DefaultSyscallFlags & FEXCore::IR::SyscallFlags::NORETURNEDRESULT) != FEXCore::IR::SyscallFlags::NORETURNEDRESULT) {
StoreGPRRegister(X86State::REG_RAX, SyscallOp);
}

View File

@ -39,9 +39,7 @@ enum class SyscallOSABI {
OS_UNKNOWN,
OS_LINUX64,
OS_LINUX32,
OS_WIN64,
OS_WIN32,
OS_HANGOVER,
OS_GENERIC, // No JIT-side argument handling, spill/fill all regs.
};
class SyscallHandler;

View File

@ -398,7 +398,7 @@ static void Init() {
class ECSyscallHandler : public FEXCore::HLE::SyscallHandler, public FEXCore::Allocator::FEXAllocOperators {
public:
ECSyscallHandler() {
OSABI = FEXCore::HLE::SyscallOSABI::OS_WIN32;
OSABI = FEXCore::HLE::SyscallOSABI::OS_GENERIC;
}
uint64_t HandleSyscall(FEXCore::Core::CpuStateFrame* Frame, FEXCore::HLE::SyscallArguments* Args) override {

View File

@ -363,7 +363,7 @@ __attribute__((naked)) extern "C" uint64_t SEHFrameTrampoline2Args(void* Arg0, v
class WowSyscallHandler : public FEXCore::HLE::SyscallHandler, public FEXCore::Allocator::FEXAllocOperators {
public:
WowSyscallHandler() {
OSABI = FEXCore::HLE::SyscallOSABI::OS_WIN32;
OSABI = FEXCore::HLE::SyscallOSABI::OS_GENERIC;
}
static uint64_t HandleSyscallImpl(FEXCore::Core::CpuStateFrame* Frame, FEXCore::HLE::SyscallArguments* Args) {