mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 12:00:17 +02:00
Merge pull request #5800 from Sonicadvance1/195
#5795 but with clang_format
This commit is contained in:
5 files changed
+126
-9
No files matched your search
@@ -525,16 +525,18 @@ int main(int argc, char** argv, char** const envp) {
|
||||
FEXCore::Profiler::Init(Program.ProgramName, Program.ProgramPath);
|
||||
|
||||
bool SupportsAVX {};
|
||||
bool SupportsSVE256 {};
|
||||
fextl::unique_ptr<FEXCore::Context::Context> CTX;
|
||||
{
|
||||
auto HostFeatures = FEX::FetchHostFeatures();
|
||||
CTX = FEXCore::Context::Context::CreateNewContext(HostFeatures);
|
||||
SupportsAVX = HostFeatures.SupportsAVX;
|
||||
SupportsSVE256 = HostFeatures.SupportsSVE256;
|
||||
}
|
||||
|
||||
FEX::Kernel::Init(Loader.Is64BitMode(), CTX.get());
|
||||
|
||||
auto SignalDelegation = FEX::HLE::CreateSignalDelegator(CTX.get(), Program.ProgramName, SupportsAVX);
|
||||
auto SignalDelegation = FEX::HLE::CreateSignalDelegator(CTX.get(), Program.ProgramName, SupportsAVX, SupportsSVE256);
|
||||
auto ThunkHandler = FEX::HLE::CreateThunkHandler();
|
||||
|
||||
auto SyscallHandler = Loader.Is64BitMode() ?
|
||||
|
||||
@@ -116,7 +116,7 @@ void SignalDelegator::SpillSRA(FEXCore::Core::InternalThreadState* Thread, void*
|
||||
Thread->CurrentFrame->State.gregs[i] = ArchHelpers::Context::GetArmReg(ucontext, SRAIdxMap);
|
||||
}
|
||||
|
||||
if (SupportsAVX) {
|
||||
if (SupportsAVX && SupportsSVE256) {
|
||||
// TODO: This doesn't save the upper 128-bits of the 256-bit registers.
|
||||
// This needs to be implemented still.
|
||||
for (size_t i = 0; i < Config.SRAFPRCount; i++) {
|
||||
@@ -872,10 +872,11 @@ void SignalDelegator::QueueSignal(pid_t tgid, pid_t tid, int Signal, siginfo_t*
|
||||
}
|
||||
}
|
||||
|
||||
SignalDelegator::SignalDelegator(FEXCore::Context::Context* _CTX, const std::string_view ApplicationName, bool SupportsAVX)
|
||||
SignalDelegator::SignalDelegator(FEXCore::Context::Context* _CTX, const std::string_view ApplicationName, bool SupportsAVX, bool SupportsSVE256)
|
||||
: CTX {_CTX}
|
||||
, ApplicationName {ApplicationName}
|
||||
, SupportsAVX {SupportsAVX} {
|
||||
, SupportsAVX {SupportsAVX}
|
||||
, SupportsSVE256 {SupportsSVE256} {
|
||||
// Signal zero isn't real
|
||||
HostHandlers[0].Installed = true;
|
||||
|
||||
@@ -1345,7 +1346,7 @@ uint64_t SignalDelegator::GuestSignalFD(int fd, const uint64_t* set, size_t sigs
|
||||
}
|
||||
|
||||
fextl::unique_ptr<FEX::HLE::SignalDelegator>
|
||||
CreateSignalDelegator(FEXCore::Context::Context* CTX, const std::string_view ApplicationName, bool SupportsAVX) {
|
||||
return fextl::make_unique<FEX::HLE::SignalDelegator>(CTX, ApplicationName, SupportsAVX);
|
||||
CreateSignalDelegator(FEXCore::Context::Context* CTX, const std::string_view ApplicationName, bool SupportsAVX, bool SupportsSVE256) {
|
||||
return fextl::make_unique<FEX::HLE::SignalDelegator>(CTX, ApplicationName, SupportsAVX, SupportsSVE256);
|
||||
}
|
||||
} // namespace FEX::HLE
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
|
||||
// Returns true if the host handled the signal
|
||||
// Arguments are the same as sigaction handler
|
||||
SignalDelegator(FEXCore::Context::Context* _CTX, const std::string_view ApplicationName, bool SupportsAVX);
|
||||
SignalDelegator(FEXCore::Context::Context* _CTX, const std::string_view ApplicationName, bool SupportsAVX, bool SupportsSVE256);
|
||||
~SignalDelegator() override;
|
||||
|
||||
// Called from the signal trampoline function.
|
||||
@@ -196,6 +196,7 @@ private:
|
||||
std::mutex HostDelegatorMutex;
|
||||
std::mutex GuestDelegatorMutex;
|
||||
bool SupportsAVX;
|
||||
bool SupportsSVE256;
|
||||
|
||||
// Called from the thunk handler to handle the signal
|
||||
void HandleGuestSignal(FEX::HLE::ThreadStateObject* ThreadObject, int Signal, void* Info, void* UContext);
|
||||
@@ -294,5 +295,5 @@ private:
|
||||
};
|
||||
|
||||
fextl::unique_ptr<FEX::HLE::SignalDelegator>
|
||||
CreateSignalDelegator(FEXCore::Context::Context* CTX, const std::string_view ApplicationName, bool SupportsAVX);
|
||||
CreateSignalDelegator(FEXCore::Context::Context* CTX, const std::string_view ApplicationName, bool SupportsAVX, bool SupportsSVE256);
|
||||
} // namespace FEX::HLE
|
||||
@@ -249,7 +249,7 @@ int main(int argc, char** argv, char** const envp) {
|
||||
auto CTX = FEXCore::Context::Context::CreateNewContext(HostFeatures);
|
||||
|
||||
#ifndef _WIN32
|
||||
auto SignalDelegation = FEX::HLE::CreateSignalDelegator(CTX.get(), {}, HostFeatures.SupportsAVX);
|
||||
auto SignalDelegation = FEX::HLE::CreateSignalDelegator(CTX.get(), {}, HostFeatures.SupportsAVX, HostFeatures.SupportsSVE256);
|
||||
#else
|
||||
// Enable exit on HLT while Wine's longjump is broken.
|
||||
//
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wattributes"
|
||||
|
||||
constexpr static uint32_t xmm_values[8][4] = {
|
||||
{0x00000001, 0x00000002, 0x00000003, 0x00000004}, {0x00000011, 0x00000012, 0x00000013, 0x00000014},
|
||||
{0x00000021, 0x00000022, 0x00000023, 0x00000024}, {0x00000031, 0x00000032, 0x00000033, 0x00000034},
|
||||
{0x00000041, 0x00000042, 0x00000043, 0x00000044}, {0x00000051, 0x00000052, 0x00000053, 0x00000054},
|
||||
{0x00000061, 0x00000062, 0x00000063, 0x00000064}, {0x00000071, 0x00000072, 0x00000073, 0x00000074},
|
||||
};
|
||||
|
||||
// 4 GPR slots (2 used + 2 pad for 16-byte alignment) + 32 XMM slots
|
||||
static uint32_t results[4 + 32] __attribute__((aligned(16)));
|
||||
static volatile int alarm_fired = 0;
|
||||
|
||||
extern "C" void ContinueAfterSignal();
|
||||
|
||||
static void SignalHandler(int signal, siginfo_t* siginfo, void* context) {
|
||||
ucontext_t* _context = (ucontext_t*)context;
|
||||
alarm_fired = 1;
|
||||
|
||||
#ifdef REG_RIP
|
||||
#define FEX_IP_REG REG_RIP
|
||||
#else
|
||||
#define FEX_IP_REG REG_EIP
|
||||
#endif
|
||||
_context->uc_mcontext.gregs[FEX_IP_REG] = reinterpret_cast<greg_t>(ContinueAfterSignal);
|
||||
#undef FEX_IP_REG
|
||||
}
|
||||
|
||||
// Load GPRs (ECX, EDX) and XMM0-XMM7 with known values, keep them
|
||||
// live in SRA with a reload loop. SIGALRM fires asynchronously, the
|
||||
// handler modifies EIP, forcing FEX to spill and reload all register
|
||||
// state via SpillSRA. After returning, store all registers for comparison.
|
||||
__attribute__((nocf_check)) static void LoadRegsLoopAndStore() {
|
||||
__asm volatile(R"(
|
||||
movaps xmm0, [%[v]]
|
||||
movaps xmm1, [%[v]+16]
|
||||
movaps xmm2, [%[v]+32]
|
||||
movaps xmm3, [%[v]+48]
|
||||
movaps xmm4, [%[v]+64]
|
||||
movaps xmm5, [%[v]+80]
|
||||
movaps xmm6, [%[v]+96]
|
||||
movaps xmm7, [%[v]+112]
|
||||
|
||||
.Lloop:
|
||||
mov ecx, 0x89ABCDEF
|
||||
mov edx, 0xFEDCBA98
|
||||
|
||||
movaps xmm0, [%[v]]
|
||||
movaps xmm1, [%[v]+16]
|
||||
movaps xmm2, [%[v]+32]
|
||||
movaps xmm3, [%[v]+48]
|
||||
movaps xmm4, [%[v]+64]
|
||||
movaps xmm5, [%[v]+80]
|
||||
movaps xmm6, [%[v]+96]
|
||||
movaps xmm7, [%[v]+112]
|
||||
|
||||
mov eax, %[alarm]
|
||||
test eax, eax
|
||||
jz .Lloop
|
||||
|
||||
.global ContinueAfterSignal
|
||||
ContinueAfterSignal:
|
||||
mov [%[res]], ecx
|
||||
mov [%[res]+4], edx
|
||||
|
||||
movaps [%[res]+16], xmm0
|
||||
movaps [%[res]+32], xmm1
|
||||
movaps [%[res]+48], xmm2
|
||||
movaps [%[res]+64], xmm3
|
||||
movaps [%[res]+80], xmm4
|
||||
movaps [%[res]+96], xmm5
|
||||
movaps [%[res]+112], xmm6
|
||||
movaps [%[res]+128], xmm7
|
||||
)" ::[v] "r"(xmm_values),
|
||||
[alarm] "m"(alarm_fired), [res] "r"(results)
|
||||
: "memory", "cc", "eax", "ecx", "edx");
|
||||
}
|
||||
|
||||
TEST_CASE("Signals: Register state preserved across async signal with SRA") {
|
||||
struct sigaction act {};
|
||||
act.sa_sigaction = SignalHandler;
|
||||
act.sa_flags = SA_SIGINFO;
|
||||
sigaction(SIGALRM, &act, nullptr);
|
||||
|
||||
alarm_fired = 0;
|
||||
memset(results, 0, sizeof(results));
|
||||
|
||||
alarm(1);
|
||||
LoadRegsLoopAndStore();
|
||||
|
||||
REQUIRE(alarm_fired == 1);
|
||||
|
||||
CHECK(results[0] == 0x89ABCDEF);
|
||||
CHECK(results[1] == 0xFEDCBA98);
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
uint32_t val = results[4 + i * 4 + j];
|
||||
if (val != xmm_values[i][j]) {
|
||||
printf("XMM%d[%d] = 0x%08x, expected 0x%08x\n", i, j, val, xmm_values[i][j]);
|
||||
}
|
||||
CHECK(val == xmm_values[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user