mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-24 03:00:48 +02:00
Merge pull request #579 from Sonicadvance1/remove_shm
Removes SHM and non-unified memory!
This commit is contained in:
commit
00a2560905
46 files changed
+274
-1527
No files matched your search
-2
@@ -190,8 +190,6 @@ set (SRCS
|
||||
Interface/HLE/Syscalls/NotImplemented.cpp
|
||||
Interface/HLE/Syscalls/Stubs.cpp
|
||||
Interface/HLE/Thunks/Thunks.cpp
|
||||
Interface/Memory/MemMapper.cpp
|
||||
Interface/Memory/SharedMem.cpp
|
||||
Interface/IR/IR.cpp
|
||||
Interface/IR/IREmitter.cpp
|
||||
Interface/IR/PassManager.cpp
|
||||
|
||||
@@ -26,9 +26,6 @@ namespace FEXCore::Config {
|
||||
case FEXCore::Config::CONFIG_GDBSERVER:
|
||||
Config != 0 ? CTX->StartGdbServer() : CTX->StopGdbServer();
|
||||
break;
|
||||
case FEXCore::Config::CONFIG_UNIFIED_MEMORY:
|
||||
CTX->Config.UnifiedMemory = Config != 0;
|
||||
break;
|
||||
case FEXCore::Config::CONFIG_IS64BIT_MODE:
|
||||
CTX->Config.Is64BitMode = Config != 0;
|
||||
break;
|
||||
@@ -85,9 +82,6 @@ namespace FEXCore::Config {
|
||||
case FEXCore::Config::CONFIG_GDBSERVER:
|
||||
return CTX->GetGdbServerStatus();
|
||||
break;
|
||||
case FEXCore::Config::CONFIG_UNIFIED_MEMORY:
|
||||
return CTX->Config.UnifiedMemory;
|
||||
break;
|
||||
case FEXCore::Config::CONFIG_IS64BIT_MODE:
|
||||
return CTX->Config.Is64BitMode;
|
||||
break;
|
||||
|
||||
@@ -26,11 +26,6 @@ namespace FEXCore::Context {
|
||||
delete CTX;
|
||||
}
|
||||
|
||||
bool AddGuestMemoryRegion(FEXCore::Context::Context *CTX, FEXCore::SHM::SHMObject *SHM) {
|
||||
CTX->MemoryMapper.SetBaseRegion(SHM);
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetApplicationFile(FEXCore::Context::Context *CTX, std::string const &File) {
|
||||
CTX->SyscallHandler->SetFilename(File);
|
||||
// XXX: This isn't good for debugging
|
||||
@@ -134,10 +129,6 @@ namespace Debug {
|
||||
return CTX->GetCPUState();
|
||||
}
|
||||
|
||||
void GetMemoryRegions(FEXCore::Context::Context *CTX, std::vector<FEXCore::Memory::MemRegion> *Regions) {
|
||||
return CTX->GetMemoryRegions(Regions);
|
||||
}
|
||||
|
||||
bool GetDebugDataForRIP(FEXCore::Context::Context *CTX, uint64_t RIP, FEXCore::Core::DebugData *Data) {
|
||||
return CTX->GetDebugDataForRIP(RIP, Data);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "Interface/Core/SignalDelegator.h"
|
||||
#include "Interface/Core/X86HelperGen.h"
|
||||
#include "Interface/HLE/Syscalls.h"
|
||||
#include "Interface/Memory/MemMapper.h"
|
||||
#include "Interface/IR/PassManager.h"
|
||||
#include <FEXCore/Config/Config.h>
|
||||
#include <FEXCore/Core/CPUBackend.h>
|
||||
@@ -54,7 +53,6 @@ namespace FEXCore::Context {
|
||||
CoreRunningMode RunningMode {CoreRunningMode::MODE_RUN};
|
||||
FEXCore::Config::ConfigCore Core {FEXCore::Config::CONFIG_INTERPRETER};
|
||||
bool GdbServer {false};
|
||||
bool UnifiedMemory {true};
|
||||
std::string RootFSPath;
|
||||
std::string ThunkLibsPath;
|
||||
|
||||
@@ -69,7 +67,6 @@ namespace FEXCore::Context {
|
||||
|
||||
} Config;
|
||||
|
||||
FEXCore::Memory::MemMapper MemoryMapper;
|
||||
FEXCore::HostFeatures HostFeatures;
|
||||
|
||||
std::mutex ThreadCreationMutex;
|
||||
@@ -129,7 +126,6 @@ namespace FEXCore::Context {
|
||||
uint64_t GetThreadCount() const;
|
||||
FEXCore::Core::RuntimeStats *GetRuntimeStatsForThread(uint64_t Thread);
|
||||
FEXCore::Core::CPUState GetCPUState();
|
||||
void GetMemoryRegions(std::vector<FEXCore::Memory::MemRegion> *Regions);
|
||||
bool GetDebugDataForRIP(uint64_t RIP, FEXCore::Core::DebugData *Data);
|
||||
bool FindHostCodeForRIP(uint64_t RIP, uint8_t **Code);
|
||||
|
||||
@@ -161,9 +157,6 @@ namespace FEXCore::Context {
|
||||
private:
|
||||
void WaitForIdleWithTimeout();
|
||||
|
||||
void *MapRegion(FEXCore::Core::InternalThreadState *Thread, uint64_t Offset, uint64_t Size, bool Fixed = false, bool RelativeToBase = true);
|
||||
void *ShmBase();
|
||||
void MirrorRegion(FEXCore::Core::InternalThreadState *Thread, void *HostPtr, uint64_t Offset, uint64_t Size);
|
||||
void ExecutionThread(FEXCore::Core::InternalThreadState *Thread);
|
||||
void NotifyPause();
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ BlockCache::BlockCache(FEXCore::Context::Context *CTX)
|
||||
PageMemory = reinterpret_cast<uintptr_t>(mmap(nullptr, CODE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
|
||||
LogMan::Throw::A(PageMemory != -1ULL, "Failed to allocate page memory");
|
||||
|
||||
MemoryBase = ctx->MemoryMapper.GetBaseOffset<uintptr_t>(0);
|
||||
VirtualMemSize = ctx->Config.VirtualMemSize;
|
||||
}
|
||||
|
||||
|
||||
@@ -123,8 +123,6 @@ private:
|
||||
size_t AllocateOffset {};
|
||||
|
||||
FEXCore::Context::Context *ctx;
|
||||
uintptr_t MemoryBase{};
|
||||
uint64_t VirtualMemSize{};
|
||||
|
||||
};
|
||||
}
|
||||
+3
-65
@@ -26,8 +26,6 @@
|
||||
|
||||
#include "Interface/Core/GdbServer.h"
|
||||
|
||||
constexpr uint64_t STACK_OFFSET = 0xc000'0000;
|
||||
|
||||
namespace FEXCore::CPU {
|
||||
bool CreateCPUCore(FEXCore::Context::Context *CTX) {
|
||||
// This should be used for generating things that are shared between threads
|
||||
@@ -259,31 +257,11 @@ namespace FEXCore::Context {
|
||||
// We are the parent thread
|
||||
ParentThread = Thread;
|
||||
|
||||
uintptr_t MemoryBase = MemoryMapper.GetBaseOffset<uintptr_t>(0);
|
||||
Loader->SetMemoryBase(MemoryBase, Config.UnifiedMemory);
|
||||
Loader->MapMemoryRegion();
|
||||
|
||||
auto MemoryMapperFunction = [&](uint64_t Base, uint64_t Size, bool Fixed, bool RelativeToBase) -> void* {
|
||||
Thread->BlockCache->HintUsedRange(Base, Base);
|
||||
return MapRegion(Thread, Base, Size, Fixed, RelativeToBase);
|
||||
};
|
||||
Thread->State.State.gregs[X86State::REG_RSP] = Loader->SetupStack();
|
||||
|
||||
Loader->MapMemoryRegion(MemoryMapperFunction);
|
||||
|
||||
void *StackPointer = MapRegion(Thread, STACK_OFFSET, Loader->StackSize(), true, false);
|
||||
|
||||
uint64_t GuestStack = STACK_OFFSET;
|
||||
if (Config.UnifiedMemory) {
|
||||
GuestStack = reinterpret_cast<uint64_t>(StackPointer);
|
||||
}
|
||||
Thread->State.State.gregs[X86State::REG_RSP] = Loader->SetupStack(StackPointer, GuestStack);
|
||||
|
||||
// Now let the code loader setup memory
|
||||
auto MemoryWriterFunction = [&](void const *Data, uint64_t Addr, uint64_t Size) -> void {
|
||||
// Writes the machine code to be emulated in to memory
|
||||
memcpy(reinterpret_cast<void*>(Addr), Data, Size);
|
||||
};
|
||||
|
||||
Loader->LoadMemory(MemoryWriterFunction);
|
||||
Loader->LoadMemory();
|
||||
Loader->GetInitLocations(&InitLocations);
|
||||
|
||||
Thread->State.State.rip = StartingRIP = Loader->DefaultRIP();
|
||||
@@ -612,12 +590,7 @@ namespace FEXCore::Context {
|
||||
|
||||
std::tuple<void *, FEXCore::Core::DebugData *> Context::CompileCode(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP) {
|
||||
uint8_t const *GuestCode{};
|
||||
if (Config.UnifiedMemory) {
|
||||
GuestCode = reinterpret_cast<uint8_t const*>(GuestRIP);
|
||||
}
|
||||
else {
|
||||
GuestCode = MemoryMapper.GetPointer<uint8_t const*>(GuestRIP);
|
||||
}
|
||||
|
||||
// Do we already have this in the IR cache?
|
||||
auto IR = Thread->IRLists.find(GuestRIP);
|
||||
@@ -666,12 +639,7 @@ namespace FEXCore::Context {
|
||||
|
||||
uintptr_t ExistingCodePtr{};
|
||||
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
ExistingCodePtr = reinterpret_cast<uintptr_t>(Block.Entry + BlockInstructionsLength);
|
||||
}
|
||||
else {
|
||||
ExistingCodePtr = MemoryMapper.GetPointer<uintptr_t>(Block.Entry + BlockInstructionsLength);
|
||||
}
|
||||
|
||||
memcpy(&existing, (void*)(ExistingCodePtr), DecodedInfo->InstSize);
|
||||
auto CodeChanged = Thread->OpDispatcher->_ValidateCode(existing, ExistingCodePtr, DecodedInfo->InstSize);
|
||||
@@ -951,30 +919,6 @@ namespace FEXCore::Context {
|
||||
Thread->State.State.rip = RIPBackup;
|
||||
}
|
||||
|
||||
void *Context::MapRegion(FEXCore::Core::InternalThreadState *Thread, uint64_t Offset, uint64_t Size, bool Fixed, bool RelativeToBase) {
|
||||
void *Ptr = MemoryMapper.MapRegion(Offset, Size, Fixed, RelativeToBase);
|
||||
Thread->CPUBackend->MapRegion(Ptr, Offset, Size);
|
||||
Thread->FallbackBackend->MapRegion(Ptr, Offset, Size);
|
||||
return Ptr;
|
||||
}
|
||||
|
||||
void Context::MirrorRegion(FEXCore::Core::InternalThreadState *Thread, void *HostPtr, uint64_t Offset, uint64_t Size) {
|
||||
Thread->CPUBackend->MapRegion(HostPtr, Offset, Size);
|
||||
Thread->FallbackBackend->MapRegion(HostPtr, Offset, Size);
|
||||
}
|
||||
|
||||
void *Context::ShmBase() {
|
||||
return MemoryMapper.GetMemoryBase();
|
||||
}
|
||||
|
||||
void Context::CopyMemoryMapping([[maybe_unused]] FEXCore::Core::InternalThreadState*, FEXCore::Core::InternalThreadState *ChildThread) {
|
||||
auto Regions = MemoryMapper.MappedRegions;
|
||||
for (auto const& Region : Regions) {
|
||||
ChildThread->CPUBackend->MapRegion(Region.Ptr, Region.Offset, Region.Size);
|
||||
ChildThread->FallbackBackend->MapRegion(Region.Ptr, Region.Offset, Region.Size);
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t Context::GetThreadCount() const {
|
||||
return Threads.size();
|
||||
}
|
||||
@@ -987,12 +931,6 @@ namespace FEXCore::Context {
|
||||
return ParentThread->State.State;
|
||||
}
|
||||
|
||||
void Context::GetMemoryRegions(std::vector<FEXCore::Memory::MemRegion> *Regions) {
|
||||
Regions->clear();
|
||||
Regions->resize(MemoryMapper.MappedRegions.size());
|
||||
memcpy(&Regions->at(0), &MemoryMapper.MappedRegions.at(0), sizeof(FEXCore::Memory::MemRegion) * MemoryMapper.MappedRegions.size());
|
||||
}
|
||||
|
||||
bool Context::GetDebugDataForRIP(uint64_t RIP, FEXCore::Core::DebugData *Data) {
|
||||
auto it = ParentThread->DebugData.find(RIP);
|
||||
if (it == ParentThread->DebugData.end()) {
|
||||
|
||||
@@ -615,9 +615,6 @@ GdbServer::HandledPacketType GdbServer::handleMemory(std::string &packet) {
|
||||
// TODO: check we are in a valid memory range
|
||||
// Also, clamp length
|
||||
void* ptr = reinterpret_cast<void*>(addr);
|
||||
if (!CTX->Config.UnifiedMemory) {
|
||||
ptr = CTX->MemoryMapper.GetPointer(addr);
|
||||
}
|
||||
|
||||
if (write) {
|
||||
std::memcpy(ptr, data.data(), data.length());
|
||||
|
||||
@@ -841,14 +841,7 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
|
||||
// Size is the size of each pair element
|
||||
switch (Size) {
|
||||
case 4: {
|
||||
std::atomic<uint64_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint64_t> **>(SSAData, Op->Header.Args[2]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint64_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[2]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[2]));
|
||||
}
|
||||
std::atomic<uint64_t> *Data = *GetSrc<std::atomic<uint64_t> **>(SSAData, Op->Header.Args[2]);
|
||||
|
||||
uint64_t Src1 = *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]);
|
||||
uint64_t Src2 = *GetSrc<uint64_t*>(SSAData, Op->Header.Args[1]);
|
||||
@@ -859,14 +852,7 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
std::atomic<__uint128_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<__uint128_t> **>(SSAData, Op->Header.Args[2]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<__uint128_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[2]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[2]));
|
||||
}
|
||||
std::atomic<__uint128_t> *Data = *GetSrc<std::atomic<__uint128_t> **>(SSAData, Op->Header.Args[2]);
|
||||
|
||||
__uint128_t Src1 = *GetSrc<__uint128_t*>(SSAData, Op->Header.Args[0]);
|
||||
__uint128_t Src2 = *GetSrc<__uint128_t*>(SSAData, Op->Header.Args[1]);
|
||||
@@ -920,14 +906,7 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
|
||||
case IR::OP_LOADMEM:
|
||||
case IR::OP_LOADMEMTSO: {
|
||||
auto Op = IROp->C<IR::IROp_LoadMem>();
|
||||
uint8_t const *Data{};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<uint8_t const**>(SSAData, Op->Addr);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<uint8_t const*>(*GetSrc<uint64_t*>(SSAData, Op->Addr));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Addr));
|
||||
}
|
||||
uint8_t const *Data = *GetSrc<uint8_t const**>(SSAData, Op->Addr);
|
||||
|
||||
if (!Op->Offset.IsInvalid()) {
|
||||
auto Offset = *GetSrc<uintptr_t const*>(SSAData, Op->Offset) * Op->OffsetScale;
|
||||
@@ -938,20 +917,12 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
|
||||
case MEM_OFFSET_SXTW.Val: Data += (int32_t)Offset; break;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(GDP, Data, OpSize);
|
||||
break;
|
||||
}
|
||||
case IR::OP_VLOADMEMELEMENT: {
|
||||
auto Op = IROp->C<IR::IROp_VLoadMemElement>();
|
||||
void const *Data{};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<void const**>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<void const*>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
void const *Data = *GetSrc<void const**>(SSAData, Op->Header.Args[0]);
|
||||
|
||||
memcpy(GDP, GetSrc<void*>(SSAData, Op->Header.Args[1]), 16);
|
||||
memcpy(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(GDP) + (Op->Header.ElementSize * Op->Index)),
|
||||
@@ -962,14 +933,7 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
|
||||
case IR::OP_STOREMEMTSO: {
|
||||
#define STORE_DATA(x, y) \
|
||||
case x: { \
|
||||
uint8_t *Data{}; \
|
||||
if (Thread->CTX->Config.UnifiedMemory) { \
|
||||
Data = *GetSrc<uint8_t**>(SSAData, Op->Addr); \
|
||||
} \
|
||||
else { \
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<uint8_t*>(*GetSrc<uint64_t*>(SSAData, Op->Addr)); \
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Addr)); \
|
||||
} \
|
||||
uint8_t *Data = *GetSrc<uint8_t**>(SSAData, Op->Addr); \
|
||||
if (!Op->Offset.IsInvalid()) {\
|
||||
auto Offset = *GetSrc<uintptr_t const*>(SSAData, Op->Offset) * Op->OffsetScale;\
|
||||
\
|
||||
@@ -991,14 +955,7 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
|
||||
STORE_DATA(4, uint32_t)
|
||||
STORE_DATA(8, uint64_t)
|
||||
case 16: {
|
||||
void *Data{};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<void**>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<void*>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
void *Data = *GetSrc<void**>(SSAData, Op->Header.Args[0]);
|
||||
|
||||
void *Src = GetSrc<void*>(SSAData, Op->Header.Args[1]);
|
||||
memcpy(Data, Src, 16);
|
||||
@@ -1012,14 +969,7 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
|
||||
case IR::OP_VSTOREMEMELEMENT: {
|
||||
#define STORE_DATA(x, y) \
|
||||
case x: { \
|
||||
y *Data{}; \
|
||||
if (Thread->CTX->Config.UnifiedMemory) { \
|
||||
Data = *GetSrc<y**>(SSAData, Op->Header.Args[0]); \
|
||||
} \
|
||||
else { \
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<y*>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0])); \
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0])); \
|
||||
} \
|
||||
y *Data = *GetSrc<y**>(SSAData, Op->Header.Args[0]); \
|
||||
memcpy(Data, &GetSrc<y*>(SSAData, Op->Header.Args[1])[Op->Index], sizeof(y)); \
|
||||
break; \
|
||||
}
|
||||
@@ -1606,14 +1556,7 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
|
||||
auto Size = OpSize;
|
||||
switch (Size) {
|
||||
case 1: {
|
||||
std::atomic<uint8_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint8_t> **>(SSAData, Op->Header.Args[2]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint8_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[2]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[2]));
|
||||
}
|
||||
std::atomic<uint8_t> *Data = *GetSrc<std::atomic<uint8_t> **>(SSAData, Op->Header.Args[2]);
|
||||
|
||||
uint8_t Src1 = *GetSrc<uint8_t*>(SSAData, Op->Header.Args[0]);
|
||||
uint8_t Src2 = *GetSrc<uint8_t*>(SSAData, Op->Header.Args[1]);
|
||||
@@ -1624,15 +1567,7 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
std::atomic<uint16_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint16_t> **>(SSAData, Op->Header.Args[2]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint16_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[2]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[2]));
|
||||
}
|
||||
|
||||
std::atomic<uint16_t> *Data = *GetSrc<std::atomic<uint16_t> **>(SSAData, Op->Header.Args[2]);
|
||||
uint16_t Src1 = *GetSrc<uint16_t*>(SSAData, Op->Header.Args[0]);
|
||||
uint16_t Src2 = *GetSrc<uint16_t*>(SSAData, Op->Header.Args[1]);
|
||||
|
||||
@@ -1642,14 +1577,7 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
std::atomic<uint32_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint32_t> **>(SSAData, Op->Header.Args[2]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint32_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[2]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[2]));
|
||||
}
|
||||
std::atomic<uint32_t> *Data = *GetSrc<std::atomic<uint32_t> **>(SSAData, Op->Header.Args[2]);
|
||||
|
||||
uint32_t Src1 = *GetSrc<uint32_t*>(SSAData, Op->Header.Args[0]);
|
||||
uint32_t Src2 = *GetSrc<uint32_t*>(SSAData, Op->Header.Args[1]);
|
||||
@@ -1660,14 +1588,7 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
std::atomic<uint64_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint64_t> **>(SSAData, Op->Header.Args[2]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint64_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[2]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[2]));
|
||||
}
|
||||
std::atomic<uint64_t> *Data = *GetSrc<std::atomic<uint64_t> **>(SSAData, Op->Header.Args[2]);
|
||||
|
||||
uint64_t Src1 = *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]);
|
||||
uint64_t Src2 = *GetSrc<uint64_t*>(SSAData, Op->Header.Args[1]);
|
||||
@@ -1685,55 +1606,25 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicAdd>();
|
||||
switch (Op->Size) {
|
||||
case 1: {
|
||||
std::atomic<uint8_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint8_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint8_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
|
||||
std::atomic<uint8_t> *Data = *GetSrc<std::atomic<uint8_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint8_t Src = *GetSrc<uint8_t*>(SSAData, Op->Header.Args[1]);
|
||||
*Data += Src;
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
std::atomic<uint16_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint16_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint16_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint16_t*>(SSAData, Op->Header.Args[0]));
|
||||
std::atomic<uint16_t> *Data = *GetSrc<std::atomic<uint16_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint16_t Src = *GetSrc<uint16_t*>(SSAData, Op->Header.Args[1]);
|
||||
*Data += Src;
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
std::atomic<uint32_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint32_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint32_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint32_t> *Data = *GetSrc<std::atomic<uint32_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint32_t Src = *GetSrc<uint32_t*>(SSAData, Op->Header.Args[1]);
|
||||
*Data += Src;
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
std::atomic<uint64_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint64_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint64_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint64_t> *Data = *GetSrc<std::atomic<uint64_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint64_t Src = *GetSrc<uint64_t*>(SSAData, Op->Header.Args[1]);
|
||||
*Data += Src;
|
||||
break;
|
||||
@@ -1746,53 +1637,25 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicSub>();
|
||||
switch (Op->Size) {
|
||||
case 1: {
|
||||
std::atomic<uint8_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint8_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint8_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint8_t> *Data = *GetSrc<std::atomic<uint8_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint8_t Src = *GetSrc<uint8_t*>(SSAData, Op->Header.Args[1]);
|
||||
*Data -= Src;
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
std::atomic<uint16_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint16_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint16_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint16_t> *Data = *GetSrc<std::atomic<uint16_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint16_t Src = *GetSrc<uint16_t*>(SSAData, Op->Header.Args[1]);
|
||||
*Data -= Src;
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
std::atomic<uint32_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint32_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint32_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint32_t> *Data = *GetSrc<std::atomic<uint32_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint32_t Src = *GetSrc<uint32_t*>(SSAData, Op->Header.Args[1]);
|
||||
*Data -= Src;
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
std::atomic<uint64_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint64_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint64_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint64_t> *Data = *GetSrc<std::atomic<uint64_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint64_t Src = *GetSrc<uint64_t*>(SSAData, Op->Header.Args[1]);
|
||||
*Data -= Src;
|
||||
break;
|
||||
@@ -1805,53 +1668,25 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicAnd>();
|
||||
switch (Op->Size) {
|
||||
case 1: {
|
||||
std::atomic<uint8_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint8_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint8_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint8_t> *Data = *GetSrc<std::atomic<uint8_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint8_t Src = *GetSrc<uint8_t*>(SSAData, Op->Header.Args[1]);
|
||||
*Data &= Src;
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
std::atomic<uint16_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint16_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint16_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint16_t> *Data = *GetSrc<std::atomic<uint16_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint16_t Src = *GetSrc<uint16_t*>(SSAData, Op->Header.Args[1]);
|
||||
*Data &= Src;
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
std::atomic<uint32_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint32_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint32_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint32_t> *Data = *GetSrc<std::atomic<uint32_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint32_t Src = *GetSrc<uint32_t*>(SSAData, Op->Header.Args[1]);
|
||||
*Data &= Src;
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
std::atomic<uint64_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint64_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint64_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint64_t> *Data = *GetSrc<std::atomic<uint64_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint64_t Src = *GetSrc<uint64_t*>(SSAData, Op->Header.Args[1]);
|
||||
*Data &= Src;
|
||||
break;
|
||||
@@ -1864,55 +1699,25 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicOr>();
|
||||
switch (Op->Size) {
|
||||
case 1: {
|
||||
std::atomic<uint8_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint8_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint8_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint8_t*>(SSAData, Op->Header.Args[0]));
|
||||
std::atomic<uint8_t> *Data = *GetSrc<std::atomic<uint8_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint8_t Src = *GetSrc<uint8_t*>(SSAData, Op->Header.Args[1]);
|
||||
*Data |= Src;
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
std::atomic<uint16_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint16_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint16_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint16_t*>(SSAData, Op->Header.Args[0]));
|
||||
std::atomic<uint16_t> *Data = *GetSrc<std::atomic<uint16_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint16_t Src = *GetSrc<uint16_t*>(SSAData, Op->Header.Args[1]);
|
||||
*Data |= Src;
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
std::atomic<uint32_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint32_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint32_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint32_t> *Data = *GetSrc<std::atomic<uint32_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint32_t Src = *GetSrc<uint32_t*>(SSAData, Op->Header.Args[1]);
|
||||
*Data |= Src;
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
std::atomic<uint64_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint64_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint64_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint64_t> *Data = *GetSrc<std::atomic<uint64_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint64_t Src = *GetSrc<uint64_t*>(SSAData, Op->Header.Args[1]);
|
||||
*Data |= Src;
|
||||
break;
|
||||
@@ -1925,54 +1730,25 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicXor>();
|
||||
switch (Op->Size) {
|
||||
case 1: {
|
||||
std::atomic<uint8_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint8_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint8_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint8_t> *Data = *GetSrc<std::atomic<uint8_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint8_t Src = *GetSrc<uint8_t*>(SSAData, Op->Header.Args[1]);
|
||||
*Data ^= Src;
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
std::atomic<uint16_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint16_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint16_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint16_t*>(SSAData, Op->Header.Args[0]));
|
||||
std::atomic<uint16_t> *Data = *GetSrc<std::atomic<uint16_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint16_t Src = *GetSrc<uint16_t*>(SSAData, Op->Header.Args[1]);
|
||||
*Data ^= Src;
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
std::atomic<uint32_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint32_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint32_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint32_t> *Data = *GetSrc<std::atomic<uint32_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint32_t Src = *GetSrc<uint32_t*>(SSAData, Op->Header.Args[1]);
|
||||
*Data ^= Src;
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
std::atomic<uint64_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint64_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint64_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint64_t> *Data = *GetSrc<std::atomic<uint64_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint64_t Src = *GetSrc<uint64_t*>(SSAData, Op->Header.Args[1]);
|
||||
*Data ^= Src;
|
||||
break;
|
||||
@@ -1985,56 +1761,28 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicSwap>();
|
||||
switch (Op->Size) {
|
||||
case 1: {
|
||||
std::atomic<uint8_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint8_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint8_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint8_t> *Data = *GetSrc<std::atomic<uint8_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint8_t Src = *GetSrc<uint8_t*>(SSAData, Op->Header.Args[1]);
|
||||
uint8_t Previous = Data->exchange(Src);
|
||||
GD = Previous;
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
std::atomic<uint16_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint16_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint16_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint16_t> *Data = *GetSrc<std::atomic<uint16_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint16_t Src = *GetSrc<uint16_t*>(SSAData, Op->Header.Args[1]);
|
||||
uint16_t Previous = Data->exchange(Src);
|
||||
GD = Previous;
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
std::atomic<uint32_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint32_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint32_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint32_t> *Data = *GetSrc<std::atomic<uint32_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint32_t Src = *GetSrc<uint32_t*>(SSAData, Op->Header.Args[1]);
|
||||
uint32_t Previous = Data->exchange(Src);
|
||||
GD = Previous;
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
std::atomic<uint64_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint64_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint64_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint64_t> *Data = *GetSrc<std::atomic<uint64_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint64_t Src = *GetSrc<uint64_t*>(SSAData, Op->Header.Args[1]);
|
||||
uint64_t Previous = Data->exchange(Src);
|
||||
GD = Previous;
|
||||
@@ -2048,56 +1796,28 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicFetchAdd>();
|
||||
switch (Op->Size) {
|
||||
case 1: {
|
||||
std::atomic<uint8_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint8_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint8_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint8_t> *Data = *GetSrc<std::atomic<uint8_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint8_t Src = *GetSrc<uint8_t*>(SSAData, Op->Header.Args[1]);
|
||||
uint8_t Previous = Data->fetch_add(Src);
|
||||
GD = Previous;
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
std::atomic<uint16_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint16_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint16_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint16_t> *Data = *GetSrc<std::atomic<uint16_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint16_t Src = *GetSrc<uint16_t*>(SSAData, Op->Header.Args[1]);
|
||||
uint16_t Previous = Data->fetch_add(Src);
|
||||
GD = Previous;
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
std::atomic<uint32_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint32_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint32_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint32_t> *Data = *GetSrc<std::atomic<uint32_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint32_t Src = *GetSrc<uint32_t*>(SSAData, Op->Header.Args[1]);
|
||||
uint32_t Previous = Data->fetch_add(Src);
|
||||
GD = Previous;
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
std::atomic<uint64_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint64_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint64_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint64_t> *Data = *GetSrc<std::atomic<uint64_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint64_t Src = *GetSrc<uint64_t*>(SSAData, Op->Header.Args[1]);
|
||||
uint64_t Previous = Data->fetch_add(Src);
|
||||
GD = Previous;
|
||||
@@ -2111,56 +1831,28 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicFetchSub>();
|
||||
switch (Op->Size) {
|
||||
case 1: {
|
||||
std::atomic<uint8_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint8_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint8_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint8_t> *Data = *GetSrc<std::atomic<uint8_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint8_t Src = *GetSrc<uint8_t*>(SSAData, Op->Header.Args[1]);
|
||||
uint8_t Previous = Data->fetch_sub(Src);
|
||||
GD = Previous;
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
std::atomic<uint16_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint16_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint16_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint16_t> *Data = *GetSrc<std::atomic<uint16_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint16_t Src = *GetSrc<uint16_t*>(SSAData, Op->Header.Args[1]);
|
||||
uint16_t Previous = Data->fetch_sub(Src);
|
||||
GD = Previous;
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
std::atomic<uint32_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint32_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint32_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint32_t> *Data = *GetSrc<std::atomic<uint32_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint32_t Src = *GetSrc<uint32_t*>(SSAData, Op->Header.Args[1]);
|
||||
uint32_t Previous = Data->fetch_sub(Src);
|
||||
GD = Previous;
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
std::atomic<uint64_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint64_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint64_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint64_t> *Data = *GetSrc<std::atomic<uint64_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint64_t Src = *GetSrc<uint64_t*>(SSAData, Op->Header.Args[1]);
|
||||
uint64_t Previous = Data->fetch_sub(Src);
|
||||
GD = Previous;
|
||||
@@ -2174,56 +1866,28 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicFetchAnd>();
|
||||
switch (Op->Size) {
|
||||
case 1: {
|
||||
std::atomic<uint8_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint8_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint8_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint8_t> *Data = *GetSrc<std::atomic<uint8_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint8_t Src = *GetSrc<uint8_t*>(SSAData, Op->Header.Args[1]);
|
||||
uint8_t Previous = Data->fetch_and(Src);
|
||||
GD = Previous;
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
std::atomic<uint16_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint16_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint16_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint16_t> *Data = *GetSrc<std::atomic<uint16_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint16_t Src = *GetSrc<uint16_t*>(SSAData, Op->Header.Args[1]);
|
||||
uint16_t Previous = Data->fetch_and(Src);
|
||||
GD = Previous;
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
std::atomic<uint32_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint32_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint32_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint32_t> *Data = *GetSrc<std::atomic<uint32_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint32_t Src = *GetSrc<uint32_t*>(SSAData, Op->Header.Args[1]);
|
||||
uint32_t Previous = Data->fetch_and(Src);
|
||||
GD = Previous;
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
std::atomic<uint64_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint64_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint64_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint64_t> *Data = *GetSrc<std::atomic<uint64_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint64_t Src = *GetSrc<uint64_t*>(SSAData, Op->Header.Args[1]);
|
||||
uint64_t Previous = Data->fetch_and(Src);
|
||||
GD = Previous;
|
||||
@@ -2237,56 +1901,28 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicFetchOr>();
|
||||
switch (Op->Size) {
|
||||
case 1: {
|
||||
std::atomic<uint8_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint8_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint8_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint8_t> *Data = *GetSrc<std::atomic<uint8_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint8_t Src = *GetSrc<uint8_t*>(SSAData, Op->Header.Args[1]);
|
||||
uint8_t Previous = Data->fetch_or(Src);
|
||||
GD = Previous;
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
std::atomic<uint16_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint16_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint16_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint16_t> *Data = *GetSrc<std::atomic<uint16_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint16_t Src = *GetSrc<uint16_t*>(SSAData, Op->Header.Args[1]);
|
||||
uint16_t Previous = Data->fetch_or(Src);
|
||||
GD = Previous;
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
std::atomic<uint32_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint32_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint32_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint32_t> *Data = *GetSrc<std::atomic<uint32_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint32_t Src = *GetSrc<uint32_t*>(SSAData, Op->Header.Args[1]);
|
||||
uint32_t Previous = Data->fetch_or(Src);
|
||||
GD = Previous;
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
std::atomic<uint64_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint64_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint64_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint64_t> *Data = *GetSrc<std::atomic<uint64_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint64_t Src = *GetSrc<uint64_t*>(SSAData, Op->Header.Args[1]);
|
||||
uint64_t Previous = Data->fetch_or(Src);
|
||||
GD = Previous;
|
||||
@@ -2300,56 +1936,28 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicFetchXor>();
|
||||
switch (Op->Size) {
|
||||
case 1: {
|
||||
std::atomic<uint8_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint8_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint8_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint8_t> *Data = *GetSrc<std::atomic<uint8_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint8_t Src = *GetSrc<uint8_t*>(SSAData, Op->Header.Args[1]);
|
||||
uint8_t Previous = Data->fetch_xor(Src);
|
||||
GD = Previous;
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
std::atomic<uint16_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint16_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint16_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint16_t> *Data = *GetSrc<std::atomic<uint16_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint16_t Src = *GetSrc<uint16_t*>(SSAData, Op->Header.Args[1]);
|
||||
uint16_t Previous = Data->fetch_xor(Src);
|
||||
GD = Previous;
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
std::atomic<uint32_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint32_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint32_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint32_t> *Data = *GetSrc<std::atomic<uint32_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint32_t Src = *GetSrc<uint32_t*>(SSAData, Op->Header.Args[1]);
|
||||
uint32_t Previous = Data->fetch_xor(Src);
|
||||
GD = Previous;
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
std::atomic<uint64_t> *Data = {};
|
||||
if (Thread->CTX->Config.UnifiedMemory) {
|
||||
Data = *GetSrc<std::atomic<uint64_t> **>(SSAData, Op->Header.Args[0]);
|
||||
}
|
||||
else {
|
||||
Data = Thread->CTX->MemoryMapper.GetPointer<std::atomic<uint64_t> *>(*GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
LogMan::Throw::A(Data != nullptr, "Couldn't Map pointer to 0x%lx\n", *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]));
|
||||
}
|
||||
std::atomic<uint64_t> *Data = *GetSrc<std::atomic<uint64_t> **>(SSAData, Op->Header.Args[0]);
|
||||
uint64_t Src = *GetSrc<uint64_t*>(SSAData, Op->Header.Args[1]);
|
||||
uint64_t Previous = Data->fetch_xor(Src);
|
||||
GD = Previous;
|
||||
|
||||
@@ -13,12 +13,6 @@ DEF_OP(CASPair) {
|
||||
auto Desired = GetSrcPair<RA_64>(Op->Header.Args[1].ID());
|
||||
auto MemSrc = GetReg<RA_64>(Op->Header.Args[2].ID());
|
||||
|
||||
if (!CTX->Config.UnifiedMemory) {
|
||||
LoadConstant(TMP1, (uint64_t)CTX->MemoryMapper.GetMemoryBase());
|
||||
add(TMP1, TMP1, MemSrc);
|
||||
MemSrc = TMP1;
|
||||
}
|
||||
|
||||
if (SupportsAtomics) {
|
||||
mov(TMP3, Expected.first);
|
||||
mov(TMP4, Expected.second);
|
||||
@@ -108,12 +102,6 @@ DEF_OP(CAS) {
|
||||
auto Desired = GetReg<RA_64>(Op->Header.Args[1].ID());
|
||||
auto MemSrc = GetReg<RA_64>(Op->Header.Args[2].ID());
|
||||
|
||||
if (!CTX->Config.UnifiedMemory) {
|
||||
LoadConstant(TMP1, (uint64_t)CTX->MemoryMapper.GetMemoryBase());
|
||||
add(TMP1, TMP1, MemSrc);
|
||||
MemSrc = TMP1;
|
||||
}
|
||||
|
||||
if (SupportsAtomics) {
|
||||
mov(TMP2, Expected);
|
||||
switch (OpSize) {
|
||||
@@ -221,11 +209,6 @@ DEF_OP(AtomicAdd) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicAdd>();
|
||||
|
||||
auto MemSrc = GetReg<RA_64>(Op->Header.Args[0].ID());
|
||||
if (!CTX->Config.UnifiedMemory) {
|
||||
LoadConstant(TMP1, (uint64_t)CTX->MemoryMapper.GetMemoryBase());
|
||||
add(TMP1, TMP1, MemSrc);
|
||||
MemSrc = TMP1;
|
||||
}
|
||||
|
||||
if (SupportsAtomics) {
|
||||
switch (Op->Size) {
|
||||
@@ -284,11 +267,6 @@ DEF_OP(AtomicSub) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicSub>();
|
||||
|
||||
auto MemSrc = GetReg<RA_64>(Op->Header.Args[0].ID());
|
||||
if (!CTX->Config.UnifiedMemory) {
|
||||
LoadConstant(TMP1, (uint64_t)CTX->MemoryMapper.GetMemoryBase());
|
||||
add(TMP1, TMP1, MemSrc);
|
||||
MemSrc = TMP1;
|
||||
}
|
||||
|
||||
if (SupportsAtomics) {
|
||||
neg(TMP2, GetReg<RA_64>(Op->Header.Args[1].ID()));
|
||||
@@ -348,11 +326,6 @@ DEF_OP(AtomicAnd) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicAnd>();
|
||||
|
||||
auto MemSrc = GetReg<RA_64>(Op->Header.Args[0].ID());
|
||||
if (!CTX->Config.UnifiedMemory) {
|
||||
LoadConstant(TMP1, (uint64_t)CTX->MemoryMapper.GetMemoryBase());
|
||||
add(TMP1, TMP1, MemSrc);
|
||||
MemSrc = TMP1;
|
||||
}
|
||||
|
||||
if (SupportsAtomics) {
|
||||
mvn(TMP2, GetReg<RA_64>(Op->Header.Args[1].ID()));
|
||||
@@ -412,11 +385,6 @@ DEF_OP(AtomicOr) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicOr>();
|
||||
|
||||
auto MemSrc = GetReg<RA_64>(Op->Header.Args[0].ID());
|
||||
if (!CTX->Config.UnifiedMemory) {
|
||||
LoadConstant(TMP1, (uint64_t)CTX->MemoryMapper.GetMemoryBase());
|
||||
add(TMP1, TMP1, MemSrc);
|
||||
MemSrc = TMP1;
|
||||
}
|
||||
|
||||
if (SupportsAtomics) {
|
||||
switch (Op->Size) {
|
||||
@@ -475,11 +443,6 @@ DEF_OP(AtomicXor) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicXor>();
|
||||
|
||||
auto MemSrc = GetReg<RA_64>(Op->Header.Args[0].ID());
|
||||
if (!CTX->Config.UnifiedMemory) {
|
||||
LoadConstant(TMP1, (uint64_t)CTX->MemoryMapper.GetMemoryBase());
|
||||
add(TMP1, TMP1, MemSrc);
|
||||
MemSrc = TMP1;
|
||||
}
|
||||
|
||||
if (SupportsAtomics) {
|
||||
switch (Op->Size) {
|
||||
@@ -538,11 +501,6 @@ DEF_OP(AtomicSwap) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicSwap>();
|
||||
|
||||
auto MemSrc = GetReg<RA_64>(Op->Header.Args[0].ID());
|
||||
if (!CTX->Config.UnifiedMemory) {
|
||||
LoadConstant(TMP1, (uint64_t)CTX->MemoryMapper.GetMemoryBase());
|
||||
add(TMP1, TMP1, MemSrc);
|
||||
MemSrc = TMP1;
|
||||
}
|
||||
|
||||
if (SupportsAtomics) {
|
||||
mov(TMP2, GetReg<RA_64>(Op->Header.Args[1].ID()));
|
||||
@@ -602,11 +560,6 @@ DEF_OP(AtomicSwap) {
|
||||
DEF_OP(AtomicFetchAdd) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicFetchAdd>();
|
||||
auto MemSrc = GetReg<RA_64>(Op->Header.Args[0].ID());
|
||||
if (!CTX->Config.UnifiedMemory) {
|
||||
LoadConstant(TMP1, (uint64_t)CTX->MemoryMapper.GetMemoryBase());
|
||||
add(TMP1, TMP1, MemSrc);
|
||||
MemSrc = TMP1;
|
||||
}
|
||||
|
||||
if (SupportsAtomics) {
|
||||
switch (Op->Size) {
|
||||
@@ -668,11 +621,6 @@ DEF_OP(AtomicFetchAdd) {
|
||||
DEF_OP(AtomicFetchSub) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicFetchSub>();
|
||||
auto MemSrc = GetReg<RA_64>(Op->Header.Args[0].ID());
|
||||
if (!CTX->Config.UnifiedMemory) {
|
||||
LoadConstant(TMP1, (uint64_t)CTX->MemoryMapper.GetMemoryBase());
|
||||
add(TMP1, TMP1, MemSrc);
|
||||
MemSrc = TMP1;
|
||||
}
|
||||
|
||||
if (SupportsAtomics) {
|
||||
neg(TMP2, GetReg<RA_64>(Op->Header.Args[1].ID()));
|
||||
@@ -735,11 +683,6 @@ DEF_OP(AtomicFetchSub) {
|
||||
DEF_OP(AtomicFetchAnd) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicFetchAnd>();
|
||||
auto MemSrc = GetReg<RA_64>(Op->Header.Args[0].ID());
|
||||
if (!CTX->Config.UnifiedMemory) {
|
||||
LoadConstant(TMP1, (uint64_t)CTX->MemoryMapper.GetMemoryBase());
|
||||
add(TMP1, TMP1, MemSrc);
|
||||
MemSrc = TMP1;
|
||||
}
|
||||
|
||||
if (SupportsAtomics) {
|
||||
mvn(TMP2, GetReg<RA_64>(Op->Header.Args[1].ID()));
|
||||
@@ -802,11 +745,6 @@ DEF_OP(AtomicFetchAnd) {
|
||||
DEF_OP(AtomicFetchOr) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicFetchOr>();
|
||||
auto MemSrc = GetReg<RA_64>(Op->Header.Args[0].ID());
|
||||
if (!CTX->Config.UnifiedMemory) {
|
||||
LoadConstant(TMP1, (uint64_t)CTX->MemoryMapper.GetMemoryBase());
|
||||
add(TMP1, TMP1, MemSrc);
|
||||
MemSrc = TMP1;
|
||||
}
|
||||
|
||||
if (SupportsAtomics) {
|
||||
switch (Op->Size) {
|
||||
@@ -868,11 +806,6 @@ DEF_OP(AtomicFetchOr) {
|
||||
DEF_OP(AtomicFetchXor) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicFetchXor>();
|
||||
auto MemSrc = GetReg<RA_64>(Op->Header.Args[0].ID());
|
||||
if (!CTX->Config.UnifiedMemory) {
|
||||
LoadConstant(TMP1, (uint64_t)CTX->MemoryMapper.GetMemoryBase());
|
||||
add(TMP1, TMP1, MemSrc);
|
||||
MemSrc = TMP1;
|
||||
}
|
||||
|
||||
if (SupportsAtomics) {
|
||||
switch (Op->Size) {
|
||||
|
||||
@@ -426,13 +426,6 @@ DEF_OP(LoadMem) {
|
||||
auto Op = IROp->C<IR::IROp_LoadMem>();
|
||||
|
||||
auto MemReg = GetReg<RA_64>(Op->Header.Args[0].ID());
|
||||
|
||||
if (!CTX->Config.UnifiedMemory) {
|
||||
MemReg = TMP1;
|
||||
LoadConstant(MemReg, (uint64_t)CTX->MemoryMapper.GetMemoryBase());
|
||||
add(MemReg, MemReg, GetReg<RA_64>(Op->Header.Args[0].ID()));
|
||||
}
|
||||
|
||||
auto MemSrc = GenerateMemOperand(Op->Size, MemReg, Op->Offset, Op->OffsetType, Op->OffsetScale);
|
||||
|
||||
if (Op->Class == FEXCore::IR::GPRClass) {
|
||||
@@ -480,11 +473,6 @@ DEF_OP(LoadMemTSO) {
|
||||
auto Op = IROp->C<IR::IROp_LoadMemTSO>();
|
||||
|
||||
auto MemSrc = MemOperand(GetReg<RA_64>(Op->Header.Args[0].ID()));
|
||||
if (!CTX->Config.UnifiedMemory) {
|
||||
LoadConstant(TMP1, (uint64_t)CTX->MemoryMapper.GetMemoryBase());
|
||||
add(TMP1, TMP1, GetReg<RA_64>(Op->Header.Args[0].ID()));
|
||||
MemSrc = MemOperand(TMP1);
|
||||
}
|
||||
|
||||
if (!Op->Offset.IsInvalid()) {
|
||||
LogMan::Msg::A("LoadMemTSO: No offset allowed");
|
||||
@@ -564,14 +552,8 @@ DEF_OP(LoadMemTSO) {
|
||||
|
||||
DEF_OP(StoreMem) {
|
||||
auto Op = IROp->C<IR::IROp_StoreMem>();
|
||||
|
||||
auto MemReg = GetReg<RA_64>(Op->Header.Args[0].ID());
|
||||
|
||||
if (!CTX->Config.UnifiedMemory) {
|
||||
MemReg = TMP1;
|
||||
LoadConstant(MemReg, (uint64_t)CTX->MemoryMapper.GetMemoryBase());
|
||||
add(MemReg, MemReg, GetReg<RA_64>(Op->Header.Args[0].ID()));
|
||||
}
|
||||
auto MemReg = GetReg<RA_64>(Op->Header.Args[0].ID());
|
||||
|
||||
auto MemSrc = GenerateMemOperand(Op->Size, MemReg, Op->Offset, Op->OffsetType, Op->OffsetScale);
|
||||
|
||||
@@ -618,11 +600,6 @@ DEF_OP(StoreMem) {
|
||||
DEF_OP(StoreMemTSO) {
|
||||
auto Op = IROp->C<IR::IROp_StoreMemTSO>();
|
||||
auto MemSrc = MemOperand(GetReg<RA_64>(Op->Header.Args[0].ID()));
|
||||
if (!CTX->Config.UnifiedMemory) {
|
||||
LoadConstant(TMP1, (uint64_t)CTX->MemoryMapper.GetMemoryBase());
|
||||
add(TMP1, TMP1, GetReg<RA_64>(Op->Header.Args[0].ID()));
|
||||
MemSrc = MemOperand(TMP1);
|
||||
}
|
||||
|
||||
if (!Op->Offset.IsInvalid()) {
|
||||
LogMan::Msg::A("StoreMemTSO: No offset allowed");
|
||||
|
||||
+14
-116
@@ -15,20 +15,12 @@ DEF_OP(CASPair) {
|
||||
// This will write to memory! Careful!
|
||||
// Third operand must be a calculated guest memory address
|
||||
//OrderedNode *CASResult = _CAS(Src3, Src2, Src1);
|
||||
uint64_t Memory = CTX->MemoryMapper.GetBaseOffset<uint64_t>(0);
|
||||
auto Dst = GetSrcPair<RA_64>(Node);
|
||||
auto Expected = GetSrcPair<RA_64>(Op->Header.Args[0].ID());
|
||||
auto Desired = GetSrcPair<RA_64>(Op->Header.Args[1].ID());
|
||||
auto MemSrc = GetSrc<RA_64>(Op->Header.Args[2].ID());
|
||||
|
||||
Xbyak::Reg MemReg = rdi;
|
||||
if (CTX->Config.UnifiedMemory) {
|
||||
MemReg = MemSrc;
|
||||
}
|
||||
else {
|
||||
mov(MemReg, Memory);
|
||||
add(MemReg, MemSrc);
|
||||
}
|
||||
Xbyak::Reg MemReg = MemSrc;
|
||||
|
||||
mov(rax, Expected.first);
|
||||
mov(rdx, Expected.second);
|
||||
@@ -73,16 +65,8 @@ DEF_OP(CAS) {
|
||||
// This will write to memory! Careful!
|
||||
// Third operand must be a calculated guest memory address
|
||||
//OrderedNode *CASResult = _CAS(Src3, Src2, Src1);
|
||||
uint64_t Memory = CTX->MemoryMapper.GetBaseOffset<uint64_t>(0);
|
||||
|
||||
Xbyak::Reg MemReg = rcx;
|
||||
if (CTX->Config.UnifiedMemory) {
|
||||
MemReg = GetSrc<RA_64>(Op->Header.Args[2].ID());
|
||||
}
|
||||
else {
|
||||
mov(MemReg, Memory);
|
||||
add(MemReg, GetSrc<RA_64>(Op->Header.Args[2].ID()));
|
||||
}
|
||||
Xbyak::Reg MemReg = GetSrc<RA_64>(Op->Header.Args[2].ID());
|
||||
|
||||
mov(rdx, GetSrc<RA_64>(Op->Header.Args[1].ID()));
|
||||
mov(rax, GetSrc<RA_64>(Op->Header.Args[0].ID()));
|
||||
@@ -121,16 +105,8 @@ DEF_OP(CAS) {
|
||||
|
||||
DEF_OP(AtomicAdd) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicAdd>();
|
||||
uint64_t Memory = CTX->MemoryMapper.GetBaseOffset<uint64_t>(0);
|
||||
|
||||
Xbyak::Reg MemReg = rax;
|
||||
if (CTX->Config.UnifiedMemory) {
|
||||
MemReg = GetSrc<RA_64>(Op->Header.Args[0].ID());
|
||||
}
|
||||
else {
|
||||
mov(MemReg, Memory);
|
||||
add(MemReg, GetSrc<RA_64>(Op->Header.Args[0].ID()));
|
||||
}
|
||||
Xbyak::Reg MemReg = GetSrc<RA_64>(Op->Header.Args[0].ID());
|
||||
|
||||
lock();
|
||||
switch (Op->Size) {
|
||||
@@ -152,16 +128,8 @@ DEF_OP(AtomicAdd) {
|
||||
|
||||
DEF_OP(AtomicSub) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicSub>();
|
||||
uint64_t Memory = CTX->MemoryMapper.GetBaseOffset<uint64_t>(0);
|
||||
|
||||
Xbyak::Reg MemReg = rax;
|
||||
if (CTX->Config.UnifiedMemory) {
|
||||
MemReg = GetSrc<RA_64>(Op->Header.Args[0].ID());
|
||||
}
|
||||
else {
|
||||
mov(MemReg, Memory);
|
||||
add(MemReg, GetSrc<RA_64>(Op->Header.Args[0].ID()));
|
||||
}
|
||||
Xbyak::Reg MemReg = GetSrc<RA_64>(Op->Header.Args[0].ID());
|
||||
lock();
|
||||
switch (Op->Size) {
|
||||
case 1:
|
||||
@@ -182,16 +150,8 @@ DEF_OP(AtomicSub) {
|
||||
|
||||
DEF_OP(AtomicAnd) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicAnd>();
|
||||
uint64_t Memory = CTX->MemoryMapper.GetBaseOffset<uint64_t>(0);
|
||||
|
||||
Xbyak::Reg MemReg = rax;
|
||||
if (CTX->Config.UnifiedMemory) {
|
||||
MemReg = GetSrc<RA_64>(Op->Header.Args[0].ID());
|
||||
}
|
||||
else {
|
||||
mov(MemReg, Memory);
|
||||
add(MemReg, GetSrc<RA_64>(Op->Header.Args[0].ID()));
|
||||
}
|
||||
Xbyak::Reg MemReg = GetSrc<RA_64>(Op->Header.Args[0].ID());
|
||||
lock();
|
||||
switch (Op->Size) {
|
||||
case 1:
|
||||
@@ -212,16 +172,8 @@ DEF_OP(AtomicAnd) {
|
||||
|
||||
DEF_OP(AtomicOr) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicOr>();
|
||||
uint64_t Memory = CTX->MemoryMapper.GetBaseOffset<uint64_t>(0);
|
||||
|
||||
Xbyak::Reg MemReg = rax;
|
||||
if (CTX->Config.UnifiedMemory) {
|
||||
MemReg = GetSrc<RA_64>(Op->Header.Args[0].ID());
|
||||
}
|
||||
else {
|
||||
mov(MemReg, Memory);
|
||||
add(MemReg, GetSrc<RA_64>(Op->Header.Args[0].ID()));
|
||||
}
|
||||
Xbyak::Reg MemReg = GetSrc<RA_64>(Op->Header.Args[0].ID());
|
||||
lock();
|
||||
switch (Op->Size) {
|
||||
case 1:
|
||||
@@ -242,16 +194,8 @@ DEF_OP(AtomicOr) {
|
||||
|
||||
DEF_OP(AtomicXor) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicXor>();
|
||||
uint64_t Memory = CTX->MemoryMapper.GetBaseOffset<uint64_t>(0);
|
||||
|
||||
Xbyak::Reg MemReg = rax;
|
||||
if (CTX->Config.UnifiedMemory) {
|
||||
MemReg = GetSrc<RA_64>(Op->Header.Args[0].ID());
|
||||
}
|
||||
else {
|
||||
mov(MemReg, Memory);
|
||||
add(MemReg, GetSrc<RA_64>(Op->Header.Args[0].ID()));
|
||||
}
|
||||
Xbyak::Reg MemReg = GetSrc<RA_64>(Op->Header.Args[0].ID());
|
||||
lock();
|
||||
switch (Op->Size) {
|
||||
case 1:
|
||||
@@ -272,16 +216,10 @@ DEF_OP(AtomicXor) {
|
||||
|
||||
DEF_OP(AtomicSwap) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicSwap>();
|
||||
uint64_t Memory = CTX->MemoryMapper.GetBaseOffset<uint64_t>(0);
|
||||
|
||||
Xbyak::Reg MemReg = rax;
|
||||
if (CTX->Config.UnifiedMemory) {
|
||||
mov(MemReg, GetSrc<RA_64>(Op->Header.Args[0].ID()));
|
||||
}
|
||||
else {
|
||||
mov(MemReg, Memory);
|
||||
add(MemReg, GetSrc<RA_64>(Op->Header.Args[0].ID()));
|
||||
}
|
||||
mov(MemReg, GetSrc<RA_64>(Op->Header.Args[0].ID()));
|
||||
|
||||
switch (Op->Size) {
|
||||
case 1:
|
||||
mov(GetDst<RA_8>(Node), GetSrc<RA_8>(Op->Header.Args[1].ID()));
|
||||
@@ -309,16 +247,8 @@ DEF_OP(AtomicSwap) {
|
||||
|
||||
DEF_OP(AtomicFetchAdd) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicFetchAdd>();
|
||||
uint64_t Memory = CTX->MemoryMapper.GetBaseOffset<uint64_t>(0);
|
||||
|
||||
Xbyak::Reg MemReg = rax;
|
||||
if (CTX->Config.UnifiedMemory) {
|
||||
MemReg = GetSrc<RA_64>(Op->Header.Args[0].ID());
|
||||
}
|
||||
else {
|
||||
mov(MemReg, Memory);
|
||||
add(MemReg, GetSrc<RA_64>(Op->Header.Args[0].ID()));
|
||||
}
|
||||
Xbyak::Reg MemReg = GetSrc<RA_64>(Op->Header.Args[0].ID());
|
||||
switch (Op->Size) {
|
||||
case 1:
|
||||
mov(cl, GetSrc<RA_8>(Op->Header.Args[1].ID()));
|
||||
@@ -350,16 +280,8 @@ DEF_OP(AtomicFetchAdd) {
|
||||
|
||||
DEF_OP(AtomicFetchSub) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicFetchSub>();
|
||||
uint64_t Memory = CTX->MemoryMapper.GetBaseOffset<uint64_t>(0);
|
||||
|
||||
Xbyak::Reg MemReg = rax;
|
||||
if (CTX->Config.UnifiedMemory) {
|
||||
MemReg = GetSrc<RA_64>(Op->Header.Args[0].ID());
|
||||
}
|
||||
else {
|
||||
mov(MemReg, Memory);
|
||||
add(MemReg, GetSrc<RA_64>(Op->Header.Args[0].ID()));
|
||||
}
|
||||
Xbyak::Reg MemReg = GetSrc<RA_64>(Op->Header.Args[0].ID());
|
||||
switch (Op->Size) {
|
||||
case 1:
|
||||
mov(cl, GetSrc<RA_8>(Op->Header.Args[1].ID()));
|
||||
@@ -395,17 +317,9 @@ DEF_OP(AtomicFetchSub) {
|
||||
|
||||
DEF_OP(AtomicFetchAnd) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicFetchAnd>();
|
||||
uint64_t Memory = CTX->MemoryMapper.GetBaseOffset<uint64_t>(0);
|
||||
|
||||
// TMP1 = rax
|
||||
Xbyak::Reg MemReg = TMP4;
|
||||
if (CTX->Config.UnifiedMemory) {
|
||||
MemReg = GetSrc<RA_64>(Op->Header.Args[0].ID());
|
||||
}
|
||||
else {
|
||||
mov(MemReg, Memory);
|
||||
add(MemReg, GetSrc<RA_64>(Op->Header.Args[0].ID()));
|
||||
}
|
||||
Xbyak::Reg MemReg = GetSrc<RA_64>(Op->Header.Args[0].ID());
|
||||
|
||||
switch (Op->Size) {
|
||||
case 1: {
|
||||
@@ -481,17 +395,9 @@ DEF_OP(AtomicFetchAnd) {
|
||||
|
||||
DEF_OP(AtomicFetchOr) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicFetchOr>();
|
||||
uint64_t Memory = CTX->MemoryMapper.GetBaseOffset<uint64_t>(0);
|
||||
|
||||
// TMP1 = rax
|
||||
Xbyak::Reg MemReg = TMP4;
|
||||
if (CTX->Config.UnifiedMemory) {
|
||||
MemReg = GetSrc<RA_64>(Op->Header.Args[0].ID());
|
||||
}
|
||||
else {
|
||||
mov(MemReg, Memory);
|
||||
add(MemReg, GetSrc<RA_64>(Op->Header.Args[0].ID()));
|
||||
}
|
||||
Xbyak::Reg MemReg = GetSrc<RA_64>(Op->Header.Args[0].ID());
|
||||
switch (Op->Size) {
|
||||
case 1: {
|
||||
mov(TMP1.cvt8(), byte [MemReg]);
|
||||
@@ -566,17 +472,9 @@ DEF_OP(AtomicFetchOr) {
|
||||
|
||||
DEF_OP(AtomicFetchXor) {
|
||||
auto Op = IROp->C<IR::IROp_AtomicFetchXor>();
|
||||
uint64_t Memory = CTX->MemoryMapper.GetBaseOffset<uint64_t>(0);
|
||||
|
||||
// TMP1 = rax
|
||||
Xbyak::Reg MemReg = TMP4;
|
||||
if (CTX->Config.UnifiedMemory) {
|
||||
MemReg = GetSrc<RA_64>(Op->Header.Args[0].ID());
|
||||
}
|
||||
else {
|
||||
mov(MemReg, Memory);
|
||||
add(MemReg, GetSrc<RA_64>(Op->Header.Args[0].ID()));
|
||||
}
|
||||
Xbyak::Reg MemReg = GetSrc<RA_64>(Op->Header.Args[0].ID());
|
||||
switch (Op->Size) {
|
||||
case 1: {
|
||||
mov(TMP1.cvt8(), byte [MemReg]);
|
||||
|
||||
@@ -480,16 +480,8 @@ Xbyak::RegExp JITCore::GenerateModRM(Xbyak::Reg Base, IR::OrderedNodeWrapper Off
|
||||
|
||||
DEF_OP(LoadMem) {
|
||||
auto Op = IROp->C<IR::IROp_LoadMem>();
|
||||
uint64_t Memory = CTX->MemoryMapper.GetBaseOffset<uint64_t>(0);
|
||||
|
||||
Xbyak::Reg MemReg = rax;
|
||||
if (CTX->Config.UnifiedMemory) {
|
||||
MemReg = GetSrc<RA_64>(Op->Addr.ID());
|
||||
}
|
||||
else {
|
||||
mov(MemReg, Memory);
|
||||
add(MemReg, GetSrc<RA_64>(Op->Addr.ID()));
|
||||
}
|
||||
Xbyak::Reg MemReg = GetSrc<RA_64>(Op->Addr.ID());
|
||||
|
||||
auto MemPtr = GenerateModRM(MemReg, Op->Offset, Op->OffsetType, Op->OffsetScale);
|
||||
|
||||
@@ -556,16 +548,8 @@ DEF_OP(LoadMem) {
|
||||
|
||||
DEF_OP(StoreMem) {
|
||||
auto Op = IROp->C<IR::IROp_StoreMem>();
|
||||
uint64_t Memory = CTX->MemoryMapper.GetBaseOffset<uint64_t>(0);
|
||||
|
||||
Xbyak::Reg MemReg = rax;
|
||||
if (CTX->Config.UnifiedMemory) {
|
||||
MemReg = GetSrc<RA_64>(Op->Addr.ID());
|
||||
}
|
||||
else {
|
||||
mov(MemReg, Memory);
|
||||
add(MemReg, GetSrc<RA_64>(Op->Addr.ID()));
|
||||
}
|
||||
Xbyak::Reg MemReg = GetSrc<RA_64>(Op->Addr.ID());
|
||||
|
||||
auto MemPtr = GenerateModRM(MemReg, Op->Offset, Op->OffsetType, Op->OffsetScale);
|
||||
|
||||
|
||||
@@ -91,11 +91,7 @@ void OpDispatchBuilder::ThunkOp(OpcodeArgs) {
|
||||
uint8_t GPRSize = CTX->Config.Is64BitMode ? 8 : 4;
|
||||
const char *name;
|
||||
|
||||
if (CTX->Config.UnifiedMemory) {
|
||||
name = (const char*)(Op->PC + 2);
|
||||
} else {
|
||||
name = CTX->MemoryMapper.GetPointer<const char*>(Op->PC + 2);
|
||||
}
|
||||
name = (const char*)(Op->PC + 2);
|
||||
|
||||
_Thunk(
|
||||
_LoadContext(GPRSize, offsetof(FEXCore::Core::CPUState, gregs[FEXCore::X86State::REG_RDI]), GPRClass),
|
||||
|
||||
+4
-87
@@ -24,7 +24,6 @@
|
||||
|
||||
constexpr uint64_t PAGE_SIZE = 4096;
|
||||
|
||||
#define BRK_BASE 0xd000'0000
|
||||
#define BRK_SIZE 0x1000'0000
|
||||
|
||||
namespace FEXCore {
|
||||
@@ -33,8 +32,7 @@ uint64_t SyscallHandler::HandleBRK(FEXCore::Core::InternalThreadState *Thread, v
|
||||
uint64_t Result;
|
||||
|
||||
if (DataSpace == 0) {
|
||||
// XXX: We need to setup our default BRK space first
|
||||
DefaultProgramBreak(Thread, BRK_BASE);
|
||||
DefaultProgramBreak(Thread);
|
||||
}
|
||||
|
||||
if (Addr == nullptr) { // Just wants to get the location of the program break atm
|
||||
@@ -50,7 +48,7 @@ uint64_t SyscallHandler::HandleBRK(FEXCore::Core::InternalThreadState *Thread, v
|
||||
}
|
||||
else {
|
||||
uint64_t NewSize = NewEnd - DataSpace;
|
||||
|
||||
|
||||
// make sure we don't overflow to TLS storage
|
||||
if (NewSize >= BRK_SIZE)
|
||||
return -ENOMEM;
|
||||
@@ -62,90 +60,9 @@ uint64_t SyscallHandler::HandleBRK(FEXCore::Core::InternalThreadState *Thread, v
|
||||
return Result;
|
||||
}
|
||||
|
||||
uint64_t SyscallHandler::HandleMMAP(FEXCore::Core::InternalThreadState *Thread, void *addr, size_t length, int prot, int flags, int fd, off_t offset) {
|
||||
std::lock_guard<std::mutex> lk(MMapMutex);
|
||||
|
||||
uint64_t Base = AlignDown(LastMMAP, PAGE_SIZE);
|
||||
uint64_t Size = AlignUp(length, PAGE_SIZE);
|
||||
if (length == 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if ((LastMMAP + length) >= ENDMMAP) {
|
||||
LogMan::Msg::D("uhoh, mmap failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (flags & MAP_FIXED) {
|
||||
Base = reinterpret_cast<uint64_t>(addr);
|
||||
if (fd != -1) {
|
||||
auto Name = FM.FindFDName(fd);
|
||||
if (Name) {
|
||||
LogMan::Msg::D("Mapping File to [0x%lx, 0x%lx) -> '%s' -> %p", Base, Base + Size, Name->c_str(), Base);
|
||||
}
|
||||
}
|
||||
|
||||
void *Res{};
|
||||
if (fd != -1) {
|
||||
Res = mmap(addr, length, prot, flags, fd, offset);
|
||||
if (Res == MAP_FAILED) {
|
||||
LogMan::Msg::A("Couldn't map file to %p\n", addr);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Res = mmap(addr, length, prot, flags, fd, offset);
|
||||
}
|
||||
|
||||
if (Res == MAP_FAILED) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return Base;
|
||||
}
|
||||
else {
|
||||
// If we are running unified memory then we want to be after our base
|
||||
// This makes code page loading less of a burden
|
||||
Base = CTX->MemoryMapper.GetBaseOffset<uint64_t>(LastMMAP);
|
||||
|
||||
void *HostPtr = reinterpret_cast<void*>(Base);
|
||||
if (fd != -1) {
|
||||
auto Name = FM.FindFDName(fd);
|
||||
if (Name) {
|
||||
LogMan::Msg::D("Mapping File to [0x%lx, 0x%lx) -> '%s' -> %p", Base, Base + Size, Name->c_str(), HostPtr);
|
||||
}
|
||||
}
|
||||
|
||||
void *Res{};
|
||||
if (fd != -1) {
|
||||
Res = mmap(HostPtr, length, prot, flags | MAP_FIXED, fd, offset);
|
||||
if (Res == MAP_FAILED) {
|
||||
perror(nullptr);
|
||||
LogMan::Msg::A("Couldn't map file to %p. error %d(%s)\n", HostPtr, errno, strerror(errno));
|
||||
}
|
||||
else {
|
||||
}
|
||||
}
|
||||
else {
|
||||
Res = mmap(HostPtr, length, prot, flags | MAP_FIXED, fd, offset);
|
||||
}
|
||||
|
||||
if (Res == MAP_FAILED) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
LastMMAP += Size;
|
||||
return Base;
|
||||
}
|
||||
}
|
||||
|
||||
void SyscallHandler::DefaultProgramBreak(FEXCore::Core::InternalThreadState *Thread, uint64_t Addr) {
|
||||
void SyscallHandler::DefaultProgramBreak(FEXCore::Core::InternalThreadState *Thread) {
|
||||
DataSpaceSize = 0;
|
||||
// Just allocate 16MB of data memory past the default program break location at this point
|
||||
CTX->MapRegion(Thread, Addr, BRK_SIZE, true);
|
||||
|
||||
Addr += CTX->MemoryMapper.GetBaseOffset<uint64_t>(0);
|
||||
|
||||
DataSpace = Addr;
|
||||
DefaultProgramBreakAddress = Addr;
|
||||
DataSpace = (uint64_t)mmap(nullptr, BRK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
}
|
||||
|
||||
SyscallHandler::SyscallHandler(FEXCore::Context::Context *ctx)
|
||||
|
||||
+1
-7
@@ -25,7 +25,7 @@ public:
|
||||
|
||||
virtual uint64_t HandleSyscall(FEXCore::Core::InternalThreadState *Thread, FEXCore::HLE::SyscallArguments *Args) = 0;
|
||||
|
||||
void DefaultProgramBreak(FEXCore::Core::InternalThreadState *Thread, uint64_t Addr);
|
||||
void DefaultProgramBreak(FEXCore::Core::InternalThreadState *Thread);
|
||||
|
||||
void SetFilename(std::string const &File) { FM.SetFilename(File); }
|
||||
std::string const & GetFilename() const { return FM.GetFilename(); }
|
||||
@@ -60,7 +60,6 @@ public:
|
||||
}
|
||||
|
||||
uint64_t HandleBRK(FEXCore::Core::InternalThreadState *Thread, void *Addr);
|
||||
uint64_t HandleMMAP(FEXCore::Core::InternalThreadState *Thread, void *addr, size_t length, int prot, int flags, int fd, off_t offset);
|
||||
|
||||
FileManager FM;
|
||||
|
||||
@@ -78,11 +77,6 @@ protected:
|
||||
// BRK management
|
||||
uint64_t DataSpace {};
|
||||
uint64_t DataSpaceSize {};
|
||||
uint64_t DefaultProgramBreakAddress {};
|
||||
|
||||
// MMap management
|
||||
uint64_t LastMMAP = 0x1'0000'0000;
|
||||
uint64_t ENDMMAP = 0x2'0000'0000;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -45,8 +45,6 @@ namespace FEXCore::HLE {
|
||||
bool Is64Bit = Thread->CTX->Config.Is64BitMode;
|
||||
|
||||
auto NewThread = Thread->CTX->CreateThread(&NewThreadState, reinterpret_cast<uint64_t>(parent_tid));
|
||||
Thread->CTX->CopyMemoryMapping(Thread, NewThread);
|
||||
|
||||
Thread->CTX->InitializeThread(NewThread);
|
||||
|
||||
if (Is64Bit) {
|
||||
|
||||
@@ -49,18 +49,9 @@ namespace FEXCore {
|
||||
|
||||
auto CTX = Thread->CTX;
|
||||
|
||||
if (!CTX->Config.UnifiedMemory) {
|
||||
Args = CTX->MemoryMapper.GetPointer<LoadlibArgs*>((uintptr_t)Args);
|
||||
}
|
||||
|
||||
auto Name = Args->Name;
|
||||
auto CallbackThunks = Args->CallbackThunks;
|
||||
|
||||
if (!CTX->Config.UnifiedMemory) {
|
||||
Name = CTX->MemoryMapper.GetPointer<const char*>((uintptr_t)Name);
|
||||
CallbackThunks = CTX->MemoryMapper.GetPointer<uintptr_t>(CallbackThunks);
|
||||
}
|
||||
|
||||
auto SOName = CTX->Config.ThunkLibsPath + "/" + (const char*)Name + "-host.so";
|
||||
|
||||
LogMan::Msg::D("Load lib: %s -> %s", Name, SOName.c_str());
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <sys/mman.h>
|
||||
#include <sys/shm.h>
|
||||
|
||||
#define MEM_PASSTHROUGH
|
||||
namespace FEXCore::HLE::x64 {
|
||||
void RegisterMemory() {
|
||||
REGISTER_SYSCALL_IMPL_X64(munmap, [](FEXCore::Core::InternalThreadState *Thread, void *addr, size_t length) -> uint64_t {
|
||||
@@ -14,12 +13,8 @@ namespace FEXCore::HLE::x64 {
|
||||
});
|
||||
|
||||
REGISTER_SYSCALL_IMPL_X64(mmap, [](FEXCore::Core::InternalThreadState *Thread, void *addr, size_t length, int prot, int flags, int fd, off_t offset) -> uint64_t {
|
||||
#ifdef MEM_PASSTHROUGH
|
||||
uint64_t Result = reinterpret_cast<uint64_t>(::mmap(addr, length, prot, flags, fd, offset));
|
||||
SYSCALL_ERRNO();
|
||||
#else
|
||||
return Thread->CTX->SyscallHandler->HandleMMAP(Thread, addr, length, prot, flags, fd, offset);
|
||||
#endif
|
||||
});
|
||||
|
||||
REGISTER_SYSCALL_IMPL_X64(mremap, [](FEXCore::Core::InternalThreadState *Thread, void *old_address, size_t old_size, size_t new_size, int flags, void *new_address) -> uint64_t {
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
#include <FEXCore/Utils/LogManager.h>
|
||||
#include "Interface/Memory/MemMapper.h"
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace FEXCore::Memory {
|
||||
|
||||
void *MemMapper::MapRegion(uint64_t Offset, size_t Size, bool Fixed, bool RelativeToBase) {
|
||||
return MapRegion(Offset, Size, PROT_READ | PROT_WRITE, Fixed, RelativeToBase);
|
||||
}
|
||||
|
||||
void *MemMapper::ChangeMappedRegion(uint64_t Offset, size_t Size, uint32_t Flags, bool Fixed, bool RelativeToBase) {
|
||||
uintptr_t PtrOffset = Offset;
|
||||
|
||||
if (RelativeToBase) {
|
||||
PtrOffset = reinterpret_cast<uintptr_t>(SHM->Object.Ptr) + Offset;
|
||||
}
|
||||
|
||||
void *Ptr = mmap(reinterpret_cast<void*>(PtrOffset), Size, Flags,
|
||||
MAP_POPULATE | MAP_PRIVATE | (Fixed ? MAP_FIXED : 0), SHM->SHMFD, Offset);
|
||||
|
||||
if (Ptr == MAP_FAILED) {
|
||||
LogMan::Msg::A("Failed to map memory region [0x%lx, 0x%lx)", Offset, Offset + Size);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return Ptr;
|
||||
}
|
||||
|
||||
void *MemMapper::MapRegion(uint64_t Offset, size_t Size, uint32_t Flags, bool Fixed, bool RelativeToBase) {
|
||||
uintptr_t PtrOffset = Offset;
|
||||
|
||||
if (RelativeToBase) {
|
||||
PtrOffset = reinterpret_cast<uintptr_t>(SHM->Object.Ptr) + Offset;
|
||||
}
|
||||
|
||||
void *Ptr = mmap(reinterpret_cast<void*>(PtrOffset), Size, Flags,
|
||||
MAP_PRIVATE | (Fixed ? MAP_FIXED : 0), SHM->SHMFD, Offset);
|
||||
|
||||
if (Ptr == MAP_FAILED) {
|
||||
LogMan::Msg::A("Failed to map memory region [0x%lx, 0x%lx)", Offset, Offset + Size);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MappedRegions.emplace_back(MemRegion{Ptr, Offset, Size});
|
||||
|
||||
return Ptr;
|
||||
}
|
||||
|
||||
void MemMapper::UnmapRegion(void *Ptr, size_t Size) {
|
||||
auto it = std::find(MappedRegions.begin(), MappedRegions.end(), Ptr);
|
||||
if (it != MappedRegions.end()) {
|
||||
munmap(Ptr, Size);
|
||||
MappedRegions.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void *MemMapper::GetPointer(uint64_t Offset) {
|
||||
for (auto const &Region : MappedRegions) {
|
||||
if (Region.contains(Offset)) {
|
||||
return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(Region.Ptr) + (Offset - Region.Offset));
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void *MemMapper::GetPointerSizeCheck(uint64_t Offset, uint64_t Size) {
|
||||
for (auto const &Region : MappedRegions) {
|
||||
if (Region.contains(Offset)) {
|
||||
LogMan::Throw::A((Region.Offset + Region.Size) >= (Offset + Size), "Pointer in region but region isn't large enough. Needs 0x%lx more", Offset - Region.Offset + Size - Region.Size);
|
||||
if ((Region.Offset + Region.Size) >= (Offset + Size)) {
|
||||
return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(Region.Ptr) + (Offset - Region.Offset));
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
#pragma once
|
||||
#include "Interface/Memory/SharedMem.h"
|
||||
#include <FEXCore/Memory/MemMapper.h>
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
namespace FEXCore::Context {
|
||||
struct Context;
|
||||
}
|
||||
|
||||
namespace FEXCore::Memory {
|
||||
|
||||
class MemMapper final {
|
||||
friend struct FEXCore::Context::Context;
|
||||
public:
|
||||
void SetBaseRegion(FEXCore::SHM::SHMObject *NewSHM) {
|
||||
SHM = reinterpret_cast<FEXCore::SHM::InternalSHMObject*>(NewSHM);
|
||||
}
|
||||
size_t GetSHMSize() const {
|
||||
return SHM->Size;
|
||||
}
|
||||
|
||||
void *MapRegion(uint64_t Offset, size_t Size, bool Fixed = true, bool RelativeToBase = true);
|
||||
void *MapRegion(uint64_t Offset, size_t Size, uint32_t Flags, bool Fixed = true, bool RelativeToBase = true);
|
||||
void *ChangeMappedRegion(uint64_t Offset, size_t Size, uint32_t Flags, bool Fixed = true, bool RelativeToBase = true);
|
||||
|
||||
void UnmapRegion(void *Ptr, size_t Size);
|
||||
|
||||
void *GetMemoryBase() { return SHM->Object.Ptr; }
|
||||
|
||||
void *GetPointer(uint64_t Offset);
|
||||
#ifndef NDEBUG
|
||||
void *GetPointerSizeCheck(uint64_t Offset, uint64_t Size);
|
||||
#else
|
||||
void *GetPointerSizeCheck(uint64_t Offset, uint64_t Size) { return GetPointer(Offset); }
|
||||
#endif
|
||||
template<typename T>
|
||||
T GetPointer(uint64_t Offset) {
|
||||
return reinterpret_cast<T>(GetPointer(Offset));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T GetBaseOffset(uint64_t Offset) {
|
||||
return reinterpret_cast<T>((reinterpret_cast<uintptr_t>(GetMemoryBase()) + Offset));
|
||||
}
|
||||
|
||||
private:
|
||||
FEXCore::SHM::InternalSHMObject *SHM;
|
||||
std::vector<FEXCore::Memory::MemRegion> MappedRegions{};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
#include <FEXCore/Utils/LogManager.h>
|
||||
#include "Interface/Memory/SharedMem.h"
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <fcntl.h>
|
||||
#include <string>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace FEXCore::SHM {
|
||||
void *MapRegionFlags(InternalSHMObject *SHM, size_t Offset, size_t Size, uint32_t flags, bool Fixed) {
|
||||
uintptr_t PtrOffset = reinterpret_cast<uintptr_t>(SHM->Object.Ptr) + Offset;
|
||||
|
||||
void *Ptr = mmap(reinterpret_cast<void*>(PtrOffset), Size, flags,
|
||||
MAP_NORESERVE | MAP_PRIVATE | (Fixed ? MAP_FIXED : 0), SHM->SHMFD, Offset);
|
||||
if (Ptr == MAP_FAILED) {
|
||||
LogMan::Msg::A("Failed to map memory region [0x%lx, 0x%lx)", Offset, Offset + Size);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return Ptr;
|
||||
}
|
||||
|
||||
SHMObject *AllocateSHMRegion(size_t Size) {
|
||||
InternalSHMObject *SHM = new InternalSHMObject{};
|
||||
const std::string SHMName = "FEXCore" + std::to_string(getpid());
|
||||
|
||||
SHM->SHMFD = shm_open(SHMName.c_str(), O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||
if (SHM->SHMFD == -1) {
|
||||
LogMan::Msg::E("Couldn't open SHM");
|
||||
goto err;
|
||||
}
|
||||
|
||||
// Unlink the SHM file immediately so it doesn't get left around
|
||||
shm_unlink(SHMName.c_str());
|
||||
|
||||
// Extend the SHM to the size we requested
|
||||
if (ftruncate(SHM->SHMFD, Size) != 0) {
|
||||
LogMan::Msg::E("Couldn't set SHM size");
|
||||
goto err;
|
||||
}
|
||||
|
||||
SHM->Object.Ptr = MapRegionFlags(SHM, 0, Size, PROT_READ | PROT_WRITE, false);
|
||||
SHM->Size = Size;
|
||||
if (SHM->Object.Ptr == nullptr) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
return &SHM->Object;
|
||||
err:
|
||||
delete SHM;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void DestroyRegion(SHMObject *SHM) {
|
||||
InternalSHMObject *Obj = reinterpret_cast<InternalSHMObject*>(SHM);
|
||||
close(Obj->SHMFD);
|
||||
delete Obj;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <FEXCore/Memory/SharedMem.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace FEXCore::SHM {
|
||||
struct InternalSHMObject {
|
||||
SHMObject Object;
|
||||
int SHMFD;
|
||||
size_t Size;
|
||||
};
|
||||
}
|
||||
+2
-2
@@ -229,12 +229,12 @@ void ELFSymbolDatabase::FillSymbols() {
|
||||
|
||||
}
|
||||
|
||||
void ELFSymbolDatabase::MapMemoryRegions(std::function<void*(uint64_t, uint64_t, bool, bool)> Mapper) {
|
||||
void ELFSymbolDatabase::MapMemoryRegions(std::function<void*(uint64_t, uint64_t)> Mapper) {
|
||||
auto Map = [&](ELFInfo& ELF) {
|
||||
uint64_t ELFBase = std::get<0>(ELF.CustomLayout);
|
||||
uint64_t ELFSize = std::get<2>(ELF.CustomLayout);
|
||||
uint64_t OffsetFromBase = ELFBase - ELF.GuestBase;
|
||||
ELF.ELFBase = static_cast<uint8_t*>(Mapper(ELFBase, ELFSize, true, false)) - OffsetFromBase;
|
||||
ELF.ELFBase = static_cast<uint8_t*>(Mapper(ELFBase, ELFSize)) - OffsetFromBase;
|
||||
};
|
||||
|
||||
Map(LocalInfo);
|
||||
|
||||
@@ -15,7 +15,6 @@ namespace FEXCore::Config {
|
||||
CONFIG_GDBSERVER,
|
||||
CONFIG_ROOTFSPATH,
|
||||
CONFIG_THUNKLIBSPATH,
|
||||
CONFIG_UNIFIED_MEMORY,
|
||||
CONFIG_IS64BIT_MODE,
|
||||
CONFIG_EMULATED_CPU_CORES,
|
||||
CONFIG_TSO_ENABLED,
|
||||
|
||||
+3
-10
@@ -32,7 +32,7 @@ public:
|
||||
*
|
||||
* Probably will be GuestPtr + StackSize() - <Some amount>
|
||||
*/
|
||||
virtual uint64_t SetupStack(void *HostPtr, uint64_t GuestPtr) const = 0;
|
||||
virtual uint64_t SetupStack() const = 0;
|
||||
|
||||
/**
|
||||
* @brief Function to return the guest RIP that the code should start out at
|
||||
@@ -41,12 +41,6 @@ public:
|
||||
|
||||
virtual void GetInitLocations(std::vector<uint64_t> *Locations) {}
|
||||
|
||||
/**
|
||||
* @brief Lets the core tell the CodeLoader where the virtual memory region starts and if we are running in an environment
|
||||
* where host and guest code is unified in a single address space
|
||||
*/
|
||||
virtual void SetMemoryBase(uint64_t Base, bool Unified) {}
|
||||
|
||||
/**
|
||||
* @brief Allows the loader to map memory regions that it needs
|
||||
*
|
||||
@@ -54,7 +48,7 @@ public:
|
||||
*
|
||||
* @param Mapper Returns the host facing pointer for memory setup if the codfe loader needs to do things to it
|
||||
*/
|
||||
virtual void MapMemoryRegion(std::function<void*(uint64_t, uint64_t, bool, bool)> Mapper) {}
|
||||
virtual void MapMemoryRegion() {}
|
||||
|
||||
/**
|
||||
* @brief Memory writer function for loading code in to guest memory
|
||||
@@ -63,8 +57,7 @@ public:
|
||||
* Second argument = Guest memory data location
|
||||
* Third argument = Guest memory size
|
||||
*/
|
||||
using MemoryWriter = std::function<void(void const*, uint64_t, uint64_t)>;
|
||||
virtual void LoadMemory(MemoryWriter Writer) = 0;
|
||||
virtual void LoadMemory() = 0;
|
||||
|
||||
/**
|
||||
* @brief Get the final RIP we are supposed to end up on in a debugger
|
||||
|
||||
-12
@@ -22,9 +22,6 @@ namespace FEXCore::HLE {
|
||||
struct SyscallArguments;
|
||||
class SyscallVisitor;
|
||||
}
|
||||
namespace FEXCore::SHM {
|
||||
struct SHMObject;
|
||||
}
|
||||
|
||||
namespace FEXCore::Context {
|
||||
struct Context;
|
||||
@@ -74,15 +71,6 @@ namespace FEXCore::Context {
|
||||
*/
|
||||
void DestroyContext(FEXCore::Context::Context *CTX);
|
||||
|
||||
/**
|
||||
* @brief Adds a base pointer that the VM can use for "physical" memory backing
|
||||
*
|
||||
* Will be the guests physical memory location of zero
|
||||
*
|
||||
* @return true on added. false when we had already added a guest memory region
|
||||
*/
|
||||
bool AddGuestMemoryRegion(FEXCore::Context::Context *CTX, FEXCore::SHM::SHMObject *SHM);
|
||||
|
||||
/**
|
||||
* @brief Allows setting up in memory code and other things prior to launchign code execution
|
||||
*
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
#include <FEXCore/Core/CoreState.h>
|
||||
#include <FEXCore/Memory/MemMapper.h>
|
||||
#include <FEXCore/Debug/InternalThreadState.h>
|
||||
|
||||
#include <stdint.h>
|
||||
@@ -21,8 +20,6 @@ namespace Debug {
|
||||
FEXCore::Core::RuntimeStats *GetRuntimeStatsForThread(FEXCore::Context::Context *CTX, uint64_t Thread);
|
||||
FEXCore::Core::CPUState GetCPUState(FEXCore::Context::Context *CTX);
|
||||
|
||||
void GetMemoryRegions(FEXCore::Context::Context *CTX, std::vector<FEXCore::Memory::MemRegion> *Regions);
|
||||
|
||||
bool GetDebugDataForRIP(FEXCore::Context::Context *CTX, uint64_t RIP, FEXCore::Core::DebugData *Data);
|
||||
bool FindHostCodeForRIP(FEXCore::Context::Context *CTX, uint64_t RIP, uint8_t **Code);
|
||||
// XXX:
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
#include <cstddef>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace FEXCore::Memory {
|
||||
struct MemRegion {
|
||||
void *Ptr;
|
||||
size_t Offset;
|
||||
size_t Size;
|
||||
|
||||
bool operator==(void *rhs) const { return Ptr == rhs; }
|
||||
bool contains(uint64_t Addr) const { return Addr >= Offset && Addr < (Offset + Size); }
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
#pragma once
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace FEXCore::SHM {
|
||||
|
||||
struct SHMObject {
|
||||
void *Ptr;
|
||||
uint8_t InternalState[0];
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Allocate a shared memory region that will be the base of our VM's memory
|
||||
*
|
||||
* @param Size The size of the SHM region
|
||||
*
|
||||
* @return An object representing our internal SHM state
|
||||
*/
|
||||
SHMObject *AllocateSHMRegion(size_t Size);
|
||||
|
||||
/**
|
||||
* @brief Destroy the SHM region
|
||||
*
|
||||
* @param SHM The region previously created with AllocateSHMRegion
|
||||
*/
|
||||
void DestroyRegion(SHMObject *SHM);
|
||||
}
|
||||
@@ -11,7 +11,7 @@ public:
|
||||
|
||||
uint64_t GetElfBase() const;
|
||||
|
||||
void MapMemoryRegions(std::function<void*(uint64_t, uint64_t, bool, bool)> Mapper);
|
||||
void MapMemoryRegions(std::function<void*(uint64_t, uint64_t)> Mapper);
|
||||
void WriteLoadableSections(::ELFLoader::ELFContainer::MemoryWriter Writer);
|
||||
|
||||
uint64_t DefaultRIP() const;
|
||||
|
||||
@@ -104,11 +104,6 @@ namespace FEX::ArgLoader {
|
||||
.dest("ThunkLibs")
|
||||
.help("Folder to find the host-side thunking libs");
|
||||
|
||||
EmulationGroup.add_option("-U", "--unified-memory")
|
||||
.dest("UnifiedMemory")
|
||||
.action("store_true")
|
||||
.help("Enable unified memory for the emulator");
|
||||
|
||||
EmulationGroup.add_option("-E", "--env")
|
||||
.dest("Env")
|
||||
.help("Adds an environment variable")
|
||||
@@ -241,11 +236,6 @@ namespace FEX::ArgLoader {
|
||||
Set(FEXCore::Config::ConfigOption::CONFIG_THUNKLIBSPATH, Option);
|
||||
}
|
||||
|
||||
if (Options.is_set_by_user("UnifiedMemory")) {
|
||||
bool Option = Options.get("UnifiedMemory");
|
||||
Set(FEXCore::Config::ConfigOption::CONFIG_UNIFIED_MEMORY, std::to_string(Option));
|
||||
}
|
||||
|
||||
if (Options.is_set_by_user("Env")) {
|
||||
for (auto iter = Options.all("Env").begin(); iter != Options.all("Env").end(); ++iter) {
|
||||
Set(FEXCore::Config::ConfigOption::CONFIG_ENVIRONMENT, *iter);
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <FEXCore/Core/X86Enums.h>
|
||||
#include <FEXCore/HLE/SyscallHandler.h>
|
||||
#include <FEXCore/Debug/InternalThreadState.h>
|
||||
#include <FEXCore/Memory/SharedMem.h>
|
||||
|
||||
#include <ucontext.h>
|
||||
#include <cassert>
|
||||
|
||||
@@ -87,14 +87,6 @@ target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Source/)
|
||||
|
||||
target_link_libraries(${NAME} ${LIBS})
|
||||
|
||||
set(NAME PTrace)
|
||||
set(SRCS TestSingleStepHardware.cpp)
|
||||
|
||||
add_executable(${NAME} ${SRCS})
|
||||
target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Source/)
|
||||
|
||||
target_link_libraries(${NAME} ${LIBS})
|
||||
|
||||
set(NAME IRLoader)
|
||||
set(SRCS
|
||||
IRLoader.cpp
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <FEXCore/Config/Config.h>
|
||||
#include <FEXCore/Core/CodeLoader.h>
|
||||
#include <FEXCore/Core/Context.h>
|
||||
#include <FEXCore/Memory/SharedMem.h>
|
||||
#include <FEXCore/Utils/ELFLoader.h>
|
||||
#include <FEXCore/Utils/LogManager.h>
|
||||
|
||||
@@ -230,12 +229,6 @@ int main(int argc, char **argv, char **const envp) {
|
||||
FEX::HarnessHelper::ELFCodeLoader Loader{Program, LDPath(), Args, ParsedArgs, envp, &Environment};
|
||||
|
||||
FEXCore::Context::InitializeStaticTables(Loader.Is64BitMode() ? FEXCore::Context::MODE_64BIT : FEXCore::Context::MODE_32BIT);
|
||||
uint64_t VMemSize = 1ULL << 36;
|
||||
if (!Loader.Is64BitMode()) {
|
||||
VMemSize = 1ULL << 32;
|
||||
}
|
||||
|
||||
auto SHM = FEXCore::SHM::AllocateSHMRegion(VMemSize);
|
||||
auto CTX = FEXCore::Context::CreateNewContext();
|
||||
FEXCore::Context::InitializeContext(CTX);
|
||||
|
||||
@@ -246,7 +239,6 @@ int main(int argc, char **argv, char **const envp) {
|
||||
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_GDBSERVER, GdbServerConfig());
|
||||
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_ROOTFSPATH, LDPath());
|
||||
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_THUNKLIBSPATH, ThunkLibsPath());
|
||||
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_UNIFIED_MEMORY, true);
|
||||
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_IS64BIT_MODE, Loader.Is64BitMode());
|
||||
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_EMULATED_CPU_CORES, ThreadsConfig());
|
||||
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_TSO_ENABLED, TSOEnabledConfig());
|
||||
@@ -255,7 +247,6 @@ int main(int argc, char **argv, char **const envp) {
|
||||
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_ABI_NO_PF, AbiNoPF());
|
||||
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_DUMPIR, DumpIR());
|
||||
|
||||
FEXCore::Context::AddGuestMemoryRegion(CTX, SHM);
|
||||
FEXCore::Context::InitCore(CTX, &Loader);
|
||||
FEXCore::Context::SetApplicationFile(CTX, std::filesystem::canonical(Program));
|
||||
|
||||
@@ -276,7 +267,6 @@ int main(int argc, char **argv, char **const envp) {
|
||||
auto ProgramStatus = FEXCore::Context::GetProgramStatus(CTX);
|
||||
|
||||
FEXCore::Context::DestroyContext(CTX);
|
||||
FEXCore::SHM::DestroyRegion(SHM);
|
||||
|
||||
FEXCore::Config::Shutdown();
|
||||
|
||||
|
||||
@@ -276,13 +276,11 @@ namespace FEX::HarnessHelper {
|
||||
return regions;
|
||||
}
|
||||
|
||||
void LoadMemory(uint64_t MemoryBase, FEXCore::CodeLoader::MemoryWriter Writer) {
|
||||
void LoadMemory() {
|
||||
uintptr_t DataOffset = BaseConfig.OptionMemDataOffset;
|
||||
for (unsigned i = 0; i < BaseConfig.OptionMemDataCount; ++i) {
|
||||
MemDataStructBase *MemData = reinterpret_cast<MemDataStructBase*>(RawConfigFile.data() + DataOffset);
|
||||
|
||||
Writer(&MemData->data, MemoryBase + MemData->address, MemData->length);
|
||||
|
||||
memcpy(reinterpret_cast<void*>(MemData->address), &MemData->data, MemData->length);
|
||||
DataOffset += sizeof(MemDataStructBase) + MemData->length;
|
||||
}
|
||||
}
|
||||
@@ -345,66 +343,74 @@ namespace FEX::HarnessHelper {
|
||||
return STACK_SIZE;
|
||||
}
|
||||
|
||||
void SetMemoryBase(uint64_t Base, bool Unified) override {
|
||||
MemoryBase = Base;
|
||||
}
|
||||
|
||||
uint64_t SetupStack([[maybe_unused]] void *HostPtr, uint64_t GuestPtr) const override {
|
||||
return GuestPtr + STACK_SIZE - 16;
|
||||
uint64_t SetupStack() const override {
|
||||
if (Config.Is64BitMode()) {
|
||||
return reinterpret_cast<uint64_t>(mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) + STACK_SIZE;
|
||||
}
|
||||
else {
|
||||
uint64_t Result = reinterpret_cast<uint64_t>(mmap(reinterpret_cast<void*>(STACK_OFFSET), STACK_SIZE, PROT_READ | PROT_WRITE, MAP_FIXED_NOREPLACE | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
|
||||
LogMan::Throw::A(Result != ~0ULL, "mmap failed");
|
||||
return Result + STACK_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t DefaultRIP() const override {
|
||||
return RIP;
|
||||
}
|
||||
|
||||
void MapMemoryRegion(std::function<void*(uint64_t, uint64_t, bool, bool)> Mapper) override {
|
||||
void MapMemoryRegion() override {
|
||||
bool LimitedSize = true;
|
||||
auto DoMMap = [](uint64_t Address, size_t Size) -> void* {
|
||||
void *Result = mmap(reinterpret_cast<void*>(Address), Size, PROT_READ | PROT_WRITE, MAP_FIXED_NOREPLACE | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
LogMan::Throw::A(Result != (void*)~0ULL, "mmap failed");
|
||||
return Result;
|
||||
};
|
||||
|
||||
if (LimitedSize) {
|
||||
Mapper(0xe000'0000, PAGE_SIZE * 10, true, false);
|
||||
DoMMap(0xe000'0000, PAGE_SIZE * 10);
|
||||
|
||||
// SIB8
|
||||
// We test [-128, -126] (Bottom)
|
||||
// We test [-8, 8] (Middle)
|
||||
// We test [120, 127] (Top)
|
||||
// Can fit in two pages
|
||||
Mapper(0xe800'0000 - PAGE_SIZE, PAGE_SIZE * 2, true, false);
|
||||
DoMMap(0xe800'0000 - PAGE_SIZE, PAGE_SIZE * 2);
|
||||
|
||||
// SIB32 Bottom
|
||||
// We test INT_MIN, INT_MIN + 8
|
||||
Mapper(0x2'0000'0000, PAGE_SIZE, true, false);
|
||||
DoMMap(0x2'0000'0000, PAGE_SIZE);
|
||||
// SIB32 Middle
|
||||
// We test -8 + 8
|
||||
Mapper(0x2'8000'0000 - PAGE_SIZE, PAGE_SIZE * 2, true, false);
|
||||
DoMMap(0x2'8000'0000 - PAGE_SIZE, PAGE_SIZE * 2);
|
||||
|
||||
// SIB32 Top
|
||||
// We Test INT_MAX - 8, INT_MAX
|
||||
Mapper(0x3'0000'0000 - PAGE_SIZE, PAGE_SIZE * 2, true, false);
|
||||
DoMMap(0x3'0000'0000 - PAGE_SIZE, PAGE_SIZE * 2);
|
||||
}
|
||||
else {
|
||||
// This is scratch memory location and SIB8 location
|
||||
Mapper(0xe000'0000, 0x1000'0000, true, false);
|
||||
DoMMap(0xe000'0000, 0x1000'0000);
|
||||
// This is for large SIB 32bit displacement testing
|
||||
Mapper(0x2'0000'0000, 0x1'0000'1000, true, false);
|
||||
DoMMap(0x2'0000'0000, 0x1'0000'1000);
|
||||
}
|
||||
|
||||
// Map in the memory region for the test file
|
||||
size_t Length = AlignUp(RawFile.size(), PAGE_SIZE);
|
||||
Code_start_page = reinterpret_cast<uint64_t>(Mapper(Code_start_page, Length, true, false));
|
||||
Code_start_page = reinterpret_cast<uint64_t>(DoMMap(Code_start_page, Length));
|
||||
mprotect(reinterpret_cast<void*>(Code_start_page), Length, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
RIP = Code_start_page;
|
||||
|
||||
// Map the memory regions the test file asks for
|
||||
for (auto& [region, size] : Config.GetMemoryRegions()) {
|
||||
Mapper(region, size, true, false);
|
||||
DoMMap(region, size);
|
||||
}
|
||||
}
|
||||
|
||||
void LoadMemory(MemoryWriter Writer) override {
|
||||
void LoadMemory() override {
|
||||
// Memory base here starts at the start location we passed back with GetLayout()
|
||||
// This will write at [CODE_START_RANGE + 0, RawFile.size() )
|
||||
Writer(&RawFile.at(0), RIP, RawFile.size());
|
||||
|
||||
Config.LoadMemory(0, Writer);
|
||||
memcpy(reinterpret_cast<void*>(RIP), &RawFile.at(0), RawFile.size());
|
||||
Config.LoadMemory();
|
||||
}
|
||||
|
||||
uint64_t GetFinalRIP() override { return RIP + RawFile.size(); }
|
||||
@@ -417,10 +423,10 @@ namespace FEX::HarnessHelper {
|
||||
|
||||
private:
|
||||
constexpr static uint64_t STACK_SIZE = PAGE_SIZE;
|
||||
constexpr static uint64_t STACK_OFFSET = 0xc000'0000;
|
||||
// Zero is special case to know when we are done
|
||||
uint64_t Code_start_page = 0x1'0000;
|
||||
uint64_t RIP {};
|
||||
uint64_t MemoryBase{};
|
||||
|
||||
std::vector<char> RawFile;
|
||||
ConfigLoader Config;
|
||||
@@ -498,6 +504,11 @@ public:
|
||||
AuxVariables.emplace_back(auxv_t{33, 0ULL}); // sysinfo (vDSO)
|
||||
}
|
||||
|
||||
AuxVariables.emplace_back(auxv_t{3, DB.GetElfBase()}); // Program header
|
||||
AuxVariables.emplace_back(auxv_t{7, DB.GetElfBase()}); // Interpreter address
|
||||
AuxVariables.emplace_back(auxv_t{9, DB.DefaultRIP()}); // AT_ENTRY
|
||||
AuxVariables.emplace_back(auxv_t{0, 0}); // Null ender
|
||||
|
||||
for (auto &Arg : ParsedArgs) {
|
||||
LoaderArgs.emplace_back(Arg.c_str());
|
||||
}
|
||||
@@ -507,24 +518,9 @@ public:
|
||||
return STACK_SIZE;
|
||||
}
|
||||
|
||||
virtual void SetMemoryBase(uint64_t Base, bool Unified) override {
|
||||
if (File.WasDynamic() && Unified) {
|
||||
MemoryBase = Base;
|
||||
}
|
||||
else {
|
||||
MemoryBase = 0;
|
||||
}
|
||||
// Set up our aux values here
|
||||
AuxVariables.emplace_back(auxv_t{3, DB.GetElfBase()}); // Program header
|
||||
AuxVariables.emplace_back(auxv_t{7, DB.GetElfBase()}); // Interpreter address
|
||||
AuxVariables.emplace_back(auxv_t{9, DB.DefaultRIP()}); // AT_ENTRY
|
||||
AuxVariables.emplace_back(auxv_t{0, 0}); // Null ender
|
||||
}
|
||||
|
||||
template <typename PointerType, typename AuxType, size_t PointerSize>
|
||||
static void SetupPointers(
|
||||
uintptr_t StackPointer,
|
||||
uint64_t rsp,
|
||||
uint64_t AuxVOffset,
|
||||
uint64_t ArgumentOffset,
|
||||
uint64_t EnvpOffset,
|
||||
@@ -544,8 +540,8 @@ public:
|
||||
// Arguments memory lives after everything else
|
||||
uint8_t *ArgumentBackingBase = reinterpret_cast<uint8_t*>(StackPointer + ArgumentOffset);
|
||||
uint8_t *EnvpBackingBase = reinterpret_cast<uint8_t*>(StackPointer + EnvpOffset);
|
||||
PointerType ArgumentBackingBaseGuest = rsp + ArgumentOffset;
|
||||
PointerType EnvpBackingBaseGuest = rsp + EnvpOffset;
|
||||
PointerType ArgumentBackingBaseGuest = StackPointer + ArgumentOffset;
|
||||
PointerType EnvpBackingBaseGuest = StackPointer + EnvpOffset;
|
||||
|
||||
*reinterpret_cast<PointerType *>(StackPointer + 0) = Args.size();
|
||||
PadPointers[0] = 0;
|
||||
@@ -588,7 +584,7 @@ public:
|
||||
for (size_t i = 0; i < AuxVariables.size(); ++i) {
|
||||
if (AuxVariables[i].key == 25) {
|
||||
// Random value is always 128bits
|
||||
AuxType Random{25, static_cast<PointerType>(rsp + RandomNumberOffset)};
|
||||
AuxType Random{25, static_cast<PointerType>(StackPointer + RandomNumberOffset)};
|
||||
uint64_t *RandomLoc = reinterpret_cast<uint64_t*>(StackPointer + RandomNumberOffset);
|
||||
RandomLoc[0] = 0xDEAD;
|
||||
RandomLoc[1] = 0xDEAD2;
|
||||
@@ -605,10 +601,18 @@ public:
|
||||
*(PointerType*)(&AuxTabSize) = sizeof(AuxType) * AuxVariables.size();
|
||||
}
|
||||
|
||||
uint64_t SetupStack(void *HostPtr, uint64_t GuestPtr) const override {
|
||||
uintptr_t StackPointer = reinterpret_cast<uintptr_t>(HostPtr) + StackSize();
|
||||
uint64_t SetupStack() const override {
|
||||
uintptr_t StackPointer{};
|
||||
if (File.GetMode() == ::ELFLoader::ELFContainer::MODE_64BIT) {
|
||||
StackPointer = reinterpret_cast<uintptr_t>(mmap(nullptr, StackSize(), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
|
||||
}
|
||||
else {
|
||||
StackPointer = reinterpret_cast<uintptr_t>(mmap(reinterpret_cast<void*>(STACK_OFFSET), StackSize(), PROT_READ | PROT_WRITE, MAP_FIXED_NOREPLACE | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
|
||||
LogMan::Throw::A(StackPointer != ~0ULL, "mmap failed");
|
||||
}
|
||||
|
||||
StackPointer += StackSize();
|
||||
// Set up our initial CPU state
|
||||
uint64_t rsp = GuestPtr + StackSize();
|
||||
uint64_t SizeOfPointer = File.GetMode() == ELFLoader::ELFContainer::MODE_64BIT ? 8 : 4;
|
||||
|
||||
uint64_t TotalArgumentMemSize{};
|
||||
@@ -638,7 +642,6 @@ public:
|
||||
TotalArgumentMemSize += 16;
|
||||
|
||||
// Offset the stack by how much memory we need
|
||||
rsp -= TotalArgumentMemSize;
|
||||
StackPointer -= TotalArgumentMemSize;
|
||||
|
||||
// Stack setup
|
||||
@@ -658,7 +661,6 @@ public:
|
||||
if (SizeOfPointer == 8) {
|
||||
SetupPointers<uint64_t, auxv_t, 8>(
|
||||
StackPointer,
|
||||
rsp,
|
||||
AuxVOffset,
|
||||
ArgumentOffset,
|
||||
EnvpOffset,
|
||||
@@ -673,7 +675,6 @@ public:
|
||||
else {
|
||||
SetupPointers<uint32_t, auxv32_t, 4>(
|
||||
StackPointer,
|
||||
rsp,
|
||||
AuxVOffset,
|
||||
ArgumentOffset,
|
||||
EnvpOffset,
|
||||
@@ -686,20 +687,26 @@ public:
|
||||
);
|
||||
}
|
||||
|
||||
return rsp;
|
||||
return StackPointer;
|
||||
}
|
||||
|
||||
uint64_t DefaultRIP() const override {
|
||||
return DB.DefaultRIP();
|
||||
}
|
||||
|
||||
void MapMemoryRegion(std::function<void*(uint64_t, uint64_t, bool, bool)> Mapper) override {
|
||||
DB.MapMemoryRegions(Mapper);
|
||||
void MapMemoryRegion() override {
|
||||
auto DoMMap = [](uint64_t Address, size_t Size) -> void* {
|
||||
void *Result = mmap(reinterpret_cast<void*>(Address), Size, PROT_READ | PROT_WRITE, MAP_FIXED_NOREPLACE | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
LogMan::Throw::A(Result != (void*)~0ULL, "Couldn't mmap");
|
||||
return Result;
|
||||
};
|
||||
|
||||
DB.MapMemoryRegions(DoMMap);
|
||||
}
|
||||
|
||||
void LoadMemory(MemoryWriter Writer) override {
|
||||
void LoadMemory() override {
|
||||
auto ELFLoaderWrapper = [&](void const *Data, uint64_t Addr, uint64_t Size) -> void {
|
||||
Writer(Data, Addr, Size);
|
||||
memcpy(reinterpret_cast<void*>(Addr), Data, Size);
|
||||
};
|
||||
DB.WriteLoadableSections(ELFLoaderWrapper);
|
||||
}
|
||||
@@ -740,9 +747,9 @@ private:
|
||||
uint64_t AuxTabBase, AuxTabSize;
|
||||
uint64_t ArgumentBackingSize{};
|
||||
uint64_t EnvironmentBackingSize{};
|
||||
uint64_t MemoryBase{};
|
||||
|
||||
constexpr static uint64_t STACK_SIZE = 8 * 1024 * 1024;
|
||||
constexpr static uint64_t STACK_OFFSET = 0xc000'0000;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <FEXCore/Config/Config.h>
|
||||
#include <FEXCore/Core/CodeLoader.h>
|
||||
#include <FEXCore/Core/Context.h>
|
||||
#include <FEXCore/Memory/SharedMem.h>
|
||||
#include <FEXCore/Utils/LogManager.h>
|
||||
|
||||
void MsgHandler(LogMan::DebugLevels Level, char const *Message) {
|
||||
@@ -60,25 +59,21 @@ class IRCodeLoader final : public FEXCore::CodeLoader {
|
||||
return STACK_SIZE;
|
||||
}
|
||||
|
||||
void SetMemoryBase(uint64_t Base, bool Unified) override {
|
||||
MemoryBase = Base;
|
||||
}
|
||||
|
||||
uint64_t SetupStack([[maybe_unused]] void *HostPtr, uint64_t GuestPtr) const override {
|
||||
return GuestPtr + STACK_SIZE - 16;
|
||||
uint64_t SetupStack() const override {
|
||||
return reinterpret_cast<uint64_t>(mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
|
||||
}
|
||||
|
||||
uint64_t DefaultRIP() const override {
|
||||
return IR->GetEntryRIP();
|
||||
}
|
||||
|
||||
void MapMemoryRegion(std::function<void*(uint64_t, uint64_t, bool, bool)> Mapper) override {
|
||||
void MapMemoryRegion() override {
|
||||
// Map the memory regions the test file asks for
|
||||
IR->MapRegions(Mapper);
|
||||
IR->MapRegions();
|
||||
}
|
||||
|
||||
void LoadMemory(MemoryWriter Writer) override {
|
||||
IR->LoadMemory(MemoryBase, Writer);
|
||||
void LoadMemory() override {
|
||||
IR->LoadMemory();
|
||||
}
|
||||
|
||||
uint64_t GetFinalRIP() override { return 0; }
|
||||
@@ -90,7 +85,6 @@ class IRCodeLoader final : public FEXCore::CodeLoader {
|
||||
private:
|
||||
FEX::IRLoader::Loader *IR;
|
||||
constexpr static uint64_t STACK_SIZE = 8 * 1024 * 1024;
|
||||
uint64_t MemoryBase = 0;
|
||||
};
|
||||
|
||||
int main(int argc, char **argv, char **const envp) {
|
||||
@@ -108,7 +102,6 @@ int main(int argc, char **argv, char **const envp) {
|
||||
FEXCore::Config::Value<bool> MultiblockConfig{FEXCore::Config::CONFIG_MULTIBLOCK, false};
|
||||
FEXCore::Config::Value<bool> GdbServerConfig{FEXCore::Config::CONFIG_GDBSERVER, false};
|
||||
FEXCore::Config::Value<std::string> LDPath{FEXCore::Config::CONFIG_ROOTFSPATH, ""};
|
||||
FEXCore::Config::Value<bool> UnifiedMemory{FEXCore::Config::CONFIG_UNIFIED_MEMORY, false};
|
||||
|
||||
auto Args = FEX::ArgLoader::Get();
|
||||
auto ParsedArgs = FEX::ArgLoader::GetParsedArgs();
|
||||
@@ -116,7 +109,6 @@ int main(int argc, char **argv, char **const envp) {
|
||||
LogMan::Throw::A(Args.size() > 1, "Not enough arguments");
|
||||
|
||||
FEXCore::Context::InitializeStaticTables();
|
||||
auto SHM = FEXCore::SHM::AllocateSHMRegion(1ULL << 36);
|
||||
auto CTX = FEXCore::Context::CreateNewContext();
|
||||
FEXCore::Context::InitializeContext(CTX);
|
||||
|
||||
@@ -126,9 +118,6 @@ int main(int argc, char **argv, char **const envp) {
|
||||
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_MAXBLOCKINST, BlockSizeConfig());
|
||||
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_GDBSERVER, GdbServerConfig());
|
||||
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_ROOTFSPATH, LDPath());
|
||||
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_UNIFIED_MEMORY, UnifiedMemory());
|
||||
|
||||
FEXCore::Context::AddGuestMemoryRegion(CTX, SHM);
|
||||
|
||||
FEX::IRLoader::InitializeStaticTables();
|
||||
FEX::IRLoader::Loader Loader(Args[0], Args[1]);
|
||||
@@ -169,7 +158,6 @@ int main(int argc, char **argv, char **const envp) {
|
||||
}
|
||||
|
||||
FEXCore::Context::DestroyContext(CTX);
|
||||
FEXCore::SHM::DestroyRegion(SHM);
|
||||
|
||||
return Return;
|
||||
}
|
||||
@@ -40,13 +40,13 @@ namespace FEX::IRLoader {
|
||||
return Config.CompareStates(State, nullptr);
|
||||
}
|
||||
|
||||
void LoadMemory(uint64_t MemoryBase, FEXCore::CodeLoader::MemoryWriter Writer) {
|
||||
Config.LoadMemory(MemoryBase, Writer);
|
||||
void LoadMemory() {
|
||||
Config.LoadMemory();
|
||||
}
|
||||
|
||||
void MapRegions(std::function<void*(uint64_t, uint64_t, bool, bool)> Mapper) {
|
||||
void MapRegions() {
|
||||
for (auto& [region, size] : Config.GetMemoryRegions()) {
|
||||
Mapper(region, size, true, true);
|
||||
mmap(reinterpret_cast<void*>(region), size, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <FEXCore/Core/X86Enums.h>
|
||||
#include <FEXCore/HLE/SyscallHandler.h>
|
||||
#include <FEXCore/Debug/InternalThreadState.h>
|
||||
#include <FEXCore/Memory/SharedMem.h>
|
||||
#include <FEXCore/Utils/LogManager.h>
|
||||
|
||||
#include <cassert>
|
||||
@@ -60,24 +59,18 @@ int main(int argc, char **argv) {
|
||||
LogMan::Throw::A(Args.size() > 1, "Not enough arguments");
|
||||
|
||||
FEXCore::Context::InitializeStaticTables();
|
||||
auto SHM1 = FEXCore::SHM::AllocateSHMRegion(1ULL << 36);
|
||||
auto CTX1 = FEXCore::Context::CreateNewContext();
|
||||
|
||||
auto SHM2 = FEXCore::SHM::AllocateSHMRegion(1ULL << 36);
|
||||
auto CTX2 = FEXCore::Context::CreateNewContext();
|
||||
|
||||
FEXCore::Config::SetConfig(CTX1, FEXCore::Config::CONFIG_DEFAULTCORE, FEXCore::Config::CONFIG_CUSTOM);
|
||||
FEXCore::Config::SetConfig(CTX1, FEXCore::Config::CONFIG_SINGLESTEP, 1);
|
||||
FEXCore::Config::SetConfig(CTX1, FEXCore::Config::CONFIG_MAXBLOCKINST, 1);
|
||||
|
||||
FEXCore::Context::AddGuestMemoryRegion(CTX1, SHM1);
|
||||
|
||||
FEXCore::Config::SetConfig(CTX2, FEXCore::Config::CONFIG_DEFAULTCORE, FEXCore::Config::CONFIG_INTERPRETER);
|
||||
FEXCore::Config::SetConfig(CTX2, FEXCore::Config::CONFIG_SINGLESTEP, 1);
|
||||
FEXCore::Config::SetConfig(CTX2, FEXCore::Config::CONFIG_MAXBLOCKINST, 1);
|
||||
|
||||
FEXCore::Context::AddGuestMemoryRegion(CTX2, SHM2);
|
||||
|
||||
FEXCore::Context::InitializeContext(CTX1);
|
||||
FEXCore::Context::InitializeContext(CTX2);
|
||||
|
||||
@@ -102,9 +95,7 @@ int main(int argc, char **argv) {
|
||||
bool Passed = Loader.CompareStates(&State1, &State2);
|
||||
LogMan::Msg::I("Passed? %s\n", Passed ? "Yes" : "No");
|
||||
|
||||
FEXCore::SHM::DestroyRegion(SHM1);
|
||||
FEXCore::Context::DestroyContext(CTX1);
|
||||
FEXCore::SHM::DestroyRegion(SHM2);
|
||||
FEXCore::Context::DestroyContext(CTX2);
|
||||
|
||||
return Passed ? 0 : 1;
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include <FEXCore/Core/X86Enums.h>
|
||||
#include <FEXCore/HLE/SyscallHandler.h>
|
||||
#include <FEXCore/Debug/InternalThreadState.h>
|
||||
#include <FEXCore/Memory/SharedMem.h>
|
||||
#include <FEXCore/Utils/LogManager.h>
|
||||
|
||||
#include <cassert>
|
||||
@@ -81,10 +80,8 @@ int main(int argc, char **argv, char **const envp) {
|
||||
FEX::HarnessHelper::HarnessCodeLoader Loader{Args[0], Args[1].c_str()};
|
||||
|
||||
FEXCore::Context::InitializeStaticTables(Loader.Is64BitMode() ? FEXCore::Context::MODE_64BIT : FEXCore::Context::MODE_32BIT);
|
||||
auto SHM = FEXCore::SHM::AllocateSHMRegion(1ULL << 34);
|
||||
auto CTX = FEXCore::Context::CreateNewContext();
|
||||
|
||||
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_UNIFIED_MEMORY, true);
|
||||
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_DEFAULTCORE, CoreConfig());
|
||||
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_MULTIBLOCK, MultiblockConfig());
|
||||
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_SINGLESTEP, SingleStepConfig());
|
||||
@@ -96,8 +93,6 @@ int main(int argc, char **argv, char **const envp) {
|
||||
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_ABI_NO_PF, AbiNoPF());
|
||||
FEXCore::Context::SetCustomCPUBackendFactory(CTX, HostFactory::CPUCreationFactory);
|
||||
|
||||
FEXCore::Context::AddGuestMemoryRegion(CTX, SHM);
|
||||
|
||||
FEXCore::Context::InitializeContext(CTX);
|
||||
|
||||
bool Result1 = FEXCore::Context::InitCore(CTX, &Loader);
|
||||
@@ -114,7 +109,6 @@ int main(int argc, char **argv, char **const envp) {
|
||||
|
||||
LogMan::Msg::I("Passed? %s\n", Passed ? "Yes" : "No");
|
||||
|
||||
FEXCore::SHM::DestroyRegion(SHM);
|
||||
FEXCore::Context::DestroyContext(CTX);
|
||||
|
||||
return Passed ? 0 : -1;
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
#include "Common/ArgumentLoader.h"
|
||||
#include "Common/EnvironmentLoader.h"
|
||||
#include "Common/Config.h"
|
||||
#include "HarnessHelpers.h"
|
||||
|
||||
#include <FEXCore/Core/CodeLoader.h>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sys/mman.h>
|
||||
#include <FEXCore/Utils/ELFLoader.h>
|
||||
#include <FEXCore/Utils/LogManager.h>
|
||||
|
||||
namespace FEX {
|
||||
uint8_t data[] = {
|
||||
0xb8, 0x00, 0x00, 0x80, 0x3f, // mov eax, 0x3f800000
|
||||
0x0f, 0xc7, 0xf8, // rdseed eax
|
||||
0xba, 0x00, 0x00, 0x00, 0xe0, // mov edx, 0xe0000000
|
||||
0x89, 0x02, // mov dword [edx], eax
|
||||
0xC3, // RET
|
||||
};
|
||||
|
||||
class TestCodeLoader final : public FEXCore::CodeLoader {
|
||||
static constexpr uint32_t PAGE_SIZE = 4096;
|
||||
public:
|
||||
|
||||
TestCodeLoader() = default;
|
||||
|
||||
uint64_t StackSize() const override {
|
||||
return STACK_SIZE;
|
||||
}
|
||||
|
||||
uint64_t SetupStack([[maybe_unused]] void *HostPtr, uint64_t GuestPtr) const override {
|
||||
return GuestPtr + STACK_SIZE - 8;
|
||||
}
|
||||
|
||||
uint64_t DefaultRIP() const override {
|
||||
return RIP;
|
||||
}
|
||||
|
||||
void MapMemoryRegion(std::function<void*(uint64_t, uint64_t, bool, bool)> Mapper) override {
|
||||
// XXX: Pull this from the config
|
||||
Mapper(0xe000'0000, 0x1000'0000, true, true);
|
||||
Mapper(0x2'0000'0000, 0x1'0000'1000, true, true);
|
||||
}
|
||||
|
||||
void LoadMemory(MemoryWriter Writer) override {
|
||||
Writer(data, DefaultRIP(), sizeof(data));
|
||||
}
|
||||
|
||||
private:
|
||||
constexpr static uint64_t STACK_SIZE = PAGE_SIZE;
|
||||
// Zero is special case to know when we are done
|
||||
constexpr static uint64_t RIP = 0x1;
|
||||
};
|
||||
}
|
||||
|
||||
void MsgHandler(LogMan::DebugLevels Level, char const *Message) {
|
||||
const char *CharLevel{nullptr};
|
||||
|
||||
switch (Level) {
|
||||
case LogMan::NONE:
|
||||
CharLevel = "NONE";
|
||||
break;
|
||||
case LogMan::ASSERT:
|
||||
CharLevel = "ASSERT";
|
||||
break;
|
||||
case LogMan::ERROR:
|
||||
CharLevel = "ERROR";
|
||||
break;
|
||||
case LogMan::DEBUG:
|
||||
CharLevel = "DEBUG";
|
||||
break;
|
||||
case LogMan::INFO:
|
||||
CharLevel = "Info";
|
||||
break;
|
||||
default:
|
||||
CharLevel = "???";
|
||||
break;
|
||||
}
|
||||
printf("[%s] %s\n", CharLevel, Message);
|
||||
}
|
||||
|
||||
void AssertHandler(char const *Message) {
|
||||
printf("[ASSERT] %s\n", Message);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv, char **const envp) {
|
||||
LogMan::Throw::InstallHandler(AssertHandler);
|
||||
LogMan::Msg::InstallHandler(MsgHandler);
|
||||
FEXCore::Config::Initialize();
|
||||
FEXCore::Config::AddLayer(std::make_unique<FEX::Config::MainLoader>());
|
||||
FEXCore::Config::AddLayer(std::make_unique<FEX::ArgLoader::ArgLoader>(argc, argv));
|
||||
FEXCore::Config::AddLayer(std::make_unique<FEX::Config::EnvLoader>(envp));
|
||||
FEXCore::Config::Load();
|
||||
|
||||
FEXCore::Config::Value<uint8_t> CoreConfig{FEXCore::Config::CONFIG_DEFAULTCORE, 0};
|
||||
auto Args = FEX::ArgLoader::Get();
|
||||
|
||||
// FEX::Core localCore {static_cast<FEX::CPUCore::CPUCoreType>(CoreConfig())};
|
||||
// FEX::TestCodeLoader Loader{};
|
||||
// bool Result = localCore.Load(&Loader);
|
||||
//
|
||||
// auto Base = localCore.GetCPU()->MemoryMapper->GetPointer<void*>(0);
|
||||
// localCore.RunLoop(true);
|
||||
// printf("Managed to load? %s\n", Result ? "Yes" : "No");
|
||||
|
||||
return 0;
|
||||
}
|
||||
+108
-118
@@ -227,10 +227,6 @@ namespace CPUStats {
|
||||
}
|
||||
}
|
||||
|
||||
namespace MemoryViewer {
|
||||
std::vector<FEXCore::Memory::MemRegion> MappedRegions;
|
||||
}
|
||||
|
||||
// Logging Windows
|
||||
namespace Logging {
|
||||
bool ShowLogOutput = true;
|
||||
@@ -393,13 +389,6 @@ namespace Disasm {
|
||||
}
|
||||
|
||||
uint8_t *GetPointerFromRegions(uint64_t PC) {
|
||||
for (auto &Region : MemoryViewer::MappedRegions) {
|
||||
if (Region.contains(PC)) {
|
||||
uint64_t Offset = PC - Region.Offset;
|
||||
return reinterpret_cast<uint8_t*>(reinterpret_cast<uintptr_t>(Region.Ptr) + Offset);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -842,132 +831,133 @@ namespace MemoryViewer {
|
||||
uint64_t CurrentAddress {};
|
||||
char CurrentAddressString[32]{};
|
||||
bool MappedRegionGetter(void *data, int idx, const char** out_text) {
|
||||
auto &Region = MappedRegions[idx];
|
||||
static char Buf[512];
|
||||
snprintf(Buf, 512, "[0x%lx, 0x%lx) - 0x%lx", Region.Offset, Region.Offset + Region.Size, Region.Size);
|
||||
*out_text = Buf;
|
||||
return true;
|
||||
return false;
|
||||
//auto &Region = MappedRegions[idx];
|
||||
//static char Buf[512];
|
||||
//snprintf(Buf, 512, "[0x%lx, 0x%lx) - 0x%lx", Region.Offset, Region.Offset + Region.Size, Region.Size);
|
||||
//*out_text = Buf;
|
||||
//return true;
|
||||
}
|
||||
|
||||
bool MappedRegionMemoryGetter(void *data, int idx, const char** out_text) {
|
||||
if (MappedRegions.empty())
|
||||
return false;
|
||||
return false;
|
||||
//if (MappedRegions.empty())
|
||||
// return false;
|
||||
|
||||
auto &Region = MappedRegions[MappedRegionsCurrentItem];
|
||||
static char Buf[512]{};
|
||||
char BufChars[17]{};
|
||||
uint8_t *Ptr = static_cast<uint8_t*>(Region.Ptr);
|
||||
Ptr += idx * 16;
|
||||
//auto &Region = MappedRegions[MappedRegionsCurrentItem];
|
||||
//static char Buf[512]{};
|
||||
//char BufChars[17]{};
|
||||
//uint8_t *Ptr = static_cast<uint8_t*>(Region.Ptr);
|
||||
//Ptr += idx * 16;
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (isprint(Ptr[i]))
|
||||
BufChars[i] = Ptr[i];
|
||||
else
|
||||
BufChars[i] = '.';
|
||||
}
|
||||
//for (int i = 0; i < 16; i++) {
|
||||
// if (isprint(Ptr[i]))
|
||||
// BufChars[i] = Ptr[i];
|
||||
// else
|
||||
// BufChars[i] = '.';
|
||||
//}
|
||||
|
||||
snprintf(Buf, 512,
|
||||
"%4lX > %02x %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\t%s",
|
||||
Region.Offset + idx * 16,
|
||||
Ptr[0], Ptr[1], Ptr[2], Ptr[3], Ptr[4], Ptr[5], Ptr[6], Ptr[7],
|
||||
Ptr[8], Ptr[9], Ptr[10], Ptr[11], Ptr[12], Ptr[13], Ptr[14], Ptr[15],
|
||||
BufChars
|
||||
);
|
||||
*out_text = Buf;
|
||||
return true;
|
||||
//snprintf(Buf, 512,
|
||||
// "%4lX > %02x %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\t%s",
|
||||
// Region.Offset + idx * 16,
|
||||
// Ptr[0], Ptr[1], Ptr[2], Ptr[3], Ptr[4], Ptr[5], Ptr[6], Ptr[7],
|
||||
// Ptr[8], Ptr[9], Ptr[10], Ptr[11], Ptr[12], Ptr[13], Ptr[14], Ptr[15],
|
||||
// BufChars
|
||||
// );
|
||||
//*out_text = Buf;
|
||||
//return true;
|
||||
}
|
||||
|
||||
void Window() {
|
||||
auto DisplayAddress = [&](uint64_t RIP) {
|
||||
MappedRegionsCurrentItem = 0;
|
||||
// First we need to find the RIP in the mapped regions
|
||||
// Skip first entry because it is the full 64GB of vmem
|
||||
for (size_t i = 1; i < MappedRegions.size(); ++i) {
|
||||
if (MappedRegions[i].contains(RIP)) {
|
||||
MappedRegionsCurrentItem = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Now we need to set our hex view listbox to the correct line
|
||||
MappedRegionsMemoryCurrentItem = static_cast<int>(RIP - MappedRegions[MappedRegionsCurrentItem].Offset) / 16;
|
||||
//auto DisplayAddress = [&](uint64_t RIP) {
|
||||
// MappedRegionsCurrentItem = 0;
|
||||
// // First we need to find the RIP in the mapped regions
|
||||
// // Skip first entry because it is the full 64GB of vmem
|
||||
// for (size_t i = 1; i < MappedRegions.size(); ++i) {
|
||||
// if (MappedRegions[i].contains(RIP)) {
|
||||
// MappedRegionsCurrentItem = i;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// // Now we need to set our hex view listbox to the correct line
|
||||
// MappedRegionsMemoryCurrentItem = static_cast<int>(RIP - MappedRegions[MappedRegionsCurrentItem].Offset) / 16;
|
||||
|
||||
// Now set the Current Address textbox and string to the correct address
|
||||
LogMan::Msg::D("RIP is 0x%lx", RIP);
|
||||
CurrentAddress = RIP;
|
||||
std::ostringstream out{};
|
||||
out << "0x" << std::hex << CurrentAddress;
|
||||
strncpy(CurrentAddressString, out.str().c_str(), 32);
|
||||
};
|
||||
// // Now set the Current Address textbox and string to the correct address
|
||||
// LogMan::Msg::D("RIP is 0x%lx", RIP);
|
||||
// CurrentAddress = RIP;
|
||||
// std::ostringstream out{};
|
||||
// out << "0x" << std::hex << CurrentAddress;
|
||||
// strncpy(CurrentAddressString, out.str().c_str(), 32);
|
||||
//};
|
||||
|
||||
if (ImGui::Begin("#Memory Viewer", &ShowMemoryWindow)) {
|
||||
if (FEX::DebuggerState::ActiveCore() && !FEX::DebuggerState::IsCoreRunning()) {
|
||||
FEXCore::Context::Debug::GetMemoryRegions(FEX::DebuggerState::GetContext(), &MappedRegions);
|
||||
}
|
||||
//if (ImGui::Begin("#Memory Viewer", &ShowMemoryWindow)) {
|
||||
// if (FEX::DebuggerState::ActiveCore() && !FEX::DebuggerState::IsCoreRunning()) {
|
||||
// FEXCore::Context::Debug::GetMemoryRegions(FEX::DebuggerState::GetContext(), &MappedRegions);
|
||||
// }
|
||||
|
||||
if (!MappedRegions.empty()) {
|
||||
ImGui::PushItemWidth(-1.0);
|
||||
if (ImGui::ListBox("Mapped Regions", &MappedRegionsCurrentItem, MappedRegionGetter, nullptr, MappedRegions.size())) {
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
// if (!MappedRegions.empty()) {
|
||||
// ImGui::PushItemWidth(-1.0);
|
||||
// if (ImGui::ListBox("Mapped Regions", &MappedRegionsCurrentItem, MappedRegionGetter, nullptr, MappedRegions.size())) {
|
||||
// }
|
||||
// ImGui::PopItemWidth();
|
||||
|
||||
if (ImGui::InputText("RIP:", CurrentAddressString, 32, ImGuiInputTextFlags_EnterReturnsTrue)) {
|
||||
DisplayAddress(std::stoull(CurrentAddressString, nullptr, 0));
|
||||
}
|
||||
// if (ImGui::InputText("RIP:", CurrentAddressString, 32, ImGuiInputTextFlags_EnterReturnsTrue)) {
|
||||
// DisplayAddress(std::stoull(CurrentAddressString, nullptr, 0));
|
||||
// }
|
||||
|
||||
ImGui::DragInt("Size", &CodeSize, 1.0f, 1, 255);
|
||||
if (ImGui::Button("Disasm")) {
|
||||
CurrentAddress = std::stoull(CurrentAddressString, nullptr, 0);
|
||||
Disasm::DisasmGuest(CurrentAddress, CodeSize);
|
||||
}
|
||||
if (FEX::DebuggerState::IsCoreRunning()) {
|
||||
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
|
||||
}
|
||||
if (ImGui::Button("Compile RIP")) {
|
||||
FEXCore::Context::Debug::CompileRIP(FEX::DebuggerState::GetContext(), CurrentAddress);
|
||||
// ImGui::DragInt("Size", &CodeSize, 1.0f, 1, 255);
|
||||
// if (ImGui::Button("Disasm")) {
|
||||
// CurrentAddress = std::stoull(CurrentAddressString, nullptr, 0);
|
||||
// Disasm::DisasmGuest(CurrentAddress, CodeSize);
|
||||
// }
|
||||
// if (FEX::DebuggerState::IsCoreRunning()) {
|
||||
// ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
|
||||
// ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
|
||||
// }
|
||||
// if (ImGui::Button("Compile RIP")) {
|
||||
// FEXCore::Context::Debug::CompileRIP(FEX::DebuggerState::GetContext(), CurrentAddress);
|
||||
|
||||
std::stringstream out;
|
||||
FEX::DebuggerState::GetIR(&out, CurrentAddress);
|
||||
Disasm::Disasm(CurrentAddress);
|
||||
Logging::IRData = out.str();
|
||||
// std::stringstream out;
|
||||
// FEX::DebuggerState::GetIR(&out, CurrentAddress);
|
||||
// Disasm::Disasm(CurrentAddress);
|
||||
// Logging::IRData = out.str();
|
||||
|
||||
// FEXCore::IR::IntrusiveIRList *ir;
|
||||
// bool HadIR = FEXCore::Context::Debug::FindIRForRIP(FEX::DebuggerState::GetContext(), CurrentAddress, &ir);
|
||||
// if (HadIR) {
|
||||
// IR::CalculateCFGLines(ir);
|
||||
// }
|
||||
}
|
||||
if (FEX::DebuggerState::IsCoreRunning()) {
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::PopItemFlag();
|
||||
}
|
||||
// // FEXCore::IR::IntrusiveIRList *ir;
|
||||
// // bool HadIR = FEXCore::Context::Debug::FindIRForRIP(FEX::DebuggerState::GetContext(), CurrentAddress, &ir);
|
||||
// // if (HadIR) {
|
||||
// // IR::CalculateCFGLines(ir);
|
||||
// // }
|
||||
// }
|
||||
// if (FEX::DebuggerState::IsCoreRunning()) {
|
||||
// ImGui::PopStyleVar();
|
||||
// ImGui::PopItemFlag();
|
||||
// }
|
||||
|
||||
if (ImGui::Button("Go to current RIP")) {
|
||||
if (FEX::DebuggerState::ActiveCore()) {
|
||||
DisplayAddress(CPUState::CurrentState.rip);
|
||||
}
|
||||
}
|
||||
// if (ImGui::Button("Go to current RIP")) {
|
||||
// if (FEX::DebuggerState::ActiveCore()) {
|
||||
// DisplayAddress(CPUState::CurrentState.rip);
|
||||
// }
|
||||
// }
|
||||
|
||||
if (ImGui::BeginChildFrame(ImGui::GetID("Hex"), ImVec2(-1, -1))) {
|
||||
ImGui::PushItemWidth(-1.0);
|
||||
// if (ImGui::BeginChildFrame(ImGui::GetID("Hex"), ImVec2(-1, -1))) {
|
||||
// ImGui::PushItemWidth(-1.0);
|
||||
|
||||
if (FEXImGui::ListBox("##Memory Hex",
|
||||
&MappedRegionsMemoryCurrentItem,
|
||||
MappedRegionMemoryGetter,
|
||||
nullptr,
|
||||
static_cast<int>(MappedRegions[MappedRegionsCurrentItem].Size) / 16)) {
|
||||
CurrentAddress = MappedRegions[MappedRegionsCurrentItem].Offset + MappedRegionsMemoryCurrentItem * 16;
|
||||
std::ostringstream out{};
|
||||
out << "0x" << std::hex << CurrentAddress;
|
||||
strncpy(CurrentAddressString, out.str().c_str(), 32);
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
}
|
||||
ImGui::EndChildFrame();
|
||||
}
|
||||
|
||||
}
|
||||
ImGui::End();
|
||||
// if (FEXImGui::ListBox("##Memory Hex",
|
||||
// &MappedRegionsMemoryCurrentItem,
|
||||
// MappedRegionMemoryGetter,
|
||||
// nullptr,
|
||||
// static_cast<int>(MappedRegions[MappedRegionsCurrentItem].Size) / 16)) {
|
||||
// CurrentAddress = MappedRegions[MappedRegionsCurrentItem].Offset + MappedRegionsMemoryCurrentItem * 16;
|
||||
// std::ostringstream out{};
|
||||
// out << "0x" << std::hex << CurrentAddress;
|
||||
// strncpy(CurrentAddressString, out.str().c_str(), 32);
|
||||
// }
|
||||
// ImGui::PopItemWidth();
|
||||
// }
|
||||
// ImGui::EndChildFrame();
|
||||
// }
|
||||
//}
|
||||
//ImGui::End();
|
||||
}
|
||||
|
||||
void Menu() {
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include <FEXCore/Core/Context.h>
|
||||
#include <FEXCore/Core/CodeLoader.h>
|
||||
#include <FEXCore/Debug/ContextDebug.h>
|
||||
#include <FEXCore/Memory/SharedMem.h>
|
||||
#include <FEXCore/Utils/Event.h>
|
||||
#include <FEXCore/Utils/LogManager.h>
|
||||
|
||||
@@ -26,7 +25,6 @@
|
||||
|
||||
Event SteppingEvent;
|
||||
FEXCore::Context::Context *CTX{};
|
||||
FEXCore::SHM::SHMObject *SHM{};
|
||||
std::atomic_bool ShouldClose = false;
|
||||
std::thread CoreThread;
|
||||
|
||||
@@ -42,11 +40,8 @@ void StepCallback() {
|
||||
}
|
||||
|
||||
void CreateCoreCallback(char const *Filename, bool ELF) {
|
||||
SHM = FEXCore::SHM::AllocateSHMRegion(1ULL << 32);
|
||||
CTX = FEXCore::Context::CreateNewContext();
|
||||
|
||||
FEXCore::Context::AddGuestMemoryRegion(CTX, SHM);
|
||||
|
||||
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_DEFAULTCORE, FEX::DebuggerState::GetCoreType());
|
||||
|
||||
FEXCore::Context::InitializeContext(CTX);
|
||||
@@ -84,15 +79,10 @@ void CompileRIPCallback(uint64_t RIP) {
|
||||
void CloseCallback() {
|
||||
FEXCore::Context::Stop(CTX);
|
||||
|
||||
if (SHM) {
|
||||
FEXCore::SHM::DestroyRegion(SHM);
|
||||
}
|
||||
|
||||
if (CTX) {
|
||||
FEXCore::Context::DestroyContext(CTX);
|
||||
}
|
||||
|
||||
SHM = nullptr;
|
||||
CTX = nullptr;
|
||||
|
||||
ShouldClose = false;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Careful. Globbing can't see changes to the contents of files
|
||||
# Need to do a fresh clean to see changes
|
||||
file(GLOB_RECURSE POSIX_TESTS CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/External/fex-posixtest-bins/conformance/*.test)
|
||||
|
||||
|
||||
foreach(POSIX_TEST ${POSIX_TESTS})
|
||||
|
||||
string(REPLACE "/fex-posixtest-bins/" ";" TEST_NAME_LIST ${POSIX_TEST})
|
||||
@@ -16,9 +16,9 @@ foreach(POSIX_TEST ${POSIX_TESTS})
|
||||
"${CMAKE_SOURCE_DIR}/unittests/POSIX/Disabled_Tests"
|
||||
"${TEST_NAME}"
|
||||
"${CMAKE_BINARY_DIR}/Bin/FEXLoader"
|
||||
"-U" "-c" "irint" "-n" "500" "-R" $ENV{ROOTFS} "--"
|
||||
"-c" "irint" "-n" "500" "-R" $ENV{ROOTFS} "--"
|
||||
"${POSIX_TEST}")
|
||||
|
||||
|
||||
add_test(NAME "${TEST_NAME}.jit.posix"
|
||||
COMMAND "python3" "${CMAKE_SOURCE_DIR}/Scripts/posix_test_runner.py"
|
||||
"${CMAKE_SOURCE_DIR}/unittests/POSIX/Known_Failures"
|
||||
@@ -26,7 +26,7 @@ foreach(POSIX_TEST ${POSIX_TESTS})
|
||||
"${CMAKE_SOURCE_DIR}/unittests/POSIX/Disabled_Tests"
|
||||
"${TEST_NAME}"
|
||||
"${CMAKE_BINARY_DIR}/Bin/FEXLoader"
|
||||
"-U" "-c" "irjit" "-n" "500" "-R" $ENV{ROOTFS} "--"
|
||||
"-c" "irjit" "-n" "500" "-R" $ENV{ROOTFS} "--"
|
||||
"${POSIX_TEST}")
|
||||
|
||||
|
||||
|
||||
@@ -559,6 +559,9 @@ conformance-interfaces-nanosleep-7-1.test # uses sigabort
|
||||
conformance-interfaces-nanosleep-7-2.test # uses sigabort
|
||||
conformance-interfaces-sigprocmask-6-1.test
|
||||
|
||||
# unstable because of threaded unit test running
|
||||
conformance-interfaces-mlockall-8-1.test
|
||||
|
||||
# Race happy
|
||||
conformance-interfaces-nanosleep-1-3.test
|
||||
conformance-interfaces-clock_nanosleep-1-3.test
|
||||
|
||||
@@ -2,7 +2,6 @@ conformance-interfaces-clock-1-1.test
|
||||
conformance-interfaces-clock_getcpuclockid-2-1.test
|
||||
conformance-interfaces-clock_nanosleep-11-1.test
|
||||
conformance-interfaces-clock_nanosleep-13-1.test
|
||||
conformance-interfaces-mlockall-8-1.test
|
||||
conformance-interfaces-munmap-2-1.test
|
||||
conformance-interfaces-nanosleep-10000-1.test
|
||||
conformance-interfaces-nanosleep-5-1.test
|
||||
|
||||
Reference in new issue
Block a user