Skip to content

Commit

Permalink
Merge pull request #3906 from bylaws/ec-sysbi
Browse files Browse the repository at this point in the history
FEXCore: Add a generic spill/fill-all syscall ABI and use for Windows
  • Loading branch information
Sonicadvance1 authored Aug 1, 2024
2 parents 069e2ce + 2c4fd79 commit 10ee963
Show file tree
Hide file tree
Showing 4 changed files with 6 additions and 27 deletions.
25 changes: 3 additions & 22 deletions FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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");
}
Expand Down Expand Up @@ -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);
}

Expand Down
4 changes: 1 addition & 3 deletions FEXCore/include/FEXCore/HLE/SyscallHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion Source/Windows/ARM64EC/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion Source/Windows/WOW64/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit 10ee963

Please sign in to comment.