Merge pull request #3853 from neobrain/refactor_warn_fixes

Fix all the warnings
This commit is contained in:
Tony Wasserka 2024-07-11 10:12:41 +02:00 committed by GitHub
commit 9a8694c2f3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 151 additions and 93 deletions

View File

@ -99,7 +99,7 @@ DEF_OP(LoadRegister) {
} }
} }
} else if (Op->Class == IR::FPRClass) { } else if (Op->Class == IR::FPRClass) {
const auto regSize = HostSupportsAVX256 ? Core::CPUState::XMM_AVX_REG_SIZE : Core::CPUState::XMM_SSE_REG_SIZE; [[maybe_unused]] const auto regSize = HostSupportsAVX256 ? Core::CPUState::XMM_AVX_REG_SIZE : Core::CPUState::XMM_SSE_REG_SIZE;
LOGMAN_THROW_A_FMT(Op->Reg < StaticFPRegisters.size(), "out of range reg"); LOGMAN_THROW_A_FMT(Op->Reg < StaticFPRegisters.size(), "out of range reg");
LOGMAN_THROW_A_FMT(OpSize == regSize, "expected sized"); LOGMAN_THROW_A_FMT(OpSize == regSize, "expected sized");
@ -120,8 +120,6 @@ DEF_OP(LoadRegister) {
DEF_OP(StoreRegister) { DEF_OP(StoreRegister) {
const auto Op = IROp->C<IR::IROp_StoreRegister>(); const auto Op = IROp->C<IR::IROp_StoreRegister>();
const auto OpSize = IROp->Size;
if (Op->Class == IR::GPRClass) { if (Op->Class == IR::GPRClass) {
unsigned Reg = Op->Reg == Core::CPUState::PF_AS_GREG ? (StaticRegisters.size() - 2) : unsigned Reg = Op->Reg == Core::CPUState::PF_AS_GREG ? (StaticRegisters.size() - 2) :
@ -137,9 +135,9 @@ DEF_OP(StoreRegister) {
mov(ARMEmitter::Size::i64Bit, reg, Src); mov(ARMEmitter::Size::i64Bit, reg, Src);
} }
} else if (Op->Class == IR::FPRClass) { } else if (Op->Class == IR::FPRClass) {
const auto regSize = HostSupportsAVX256 ? Core::CPUState::XMM_AVX_REG_SIZE : Core::CPUState::XMM_SSE_REG_SIZE; [[maybe_unused]] const auto regSize = HostSupportsAVX256 ? Core::CPUState::XMM_AVX_REG_SIZE : Core::CPUState::XMM_SSE_REG_SIZE;
LOGMAN_THROW_A_FMT(Op->Reg < StaticFPRegisters.size(), "reg out of range"); LOGMAN_THROW_A_FMT(Op->Reg < StaticFPRegisters.size(), "reg out of range");
LOGMAN_THROW_A_FMT(OpSize == regSize, "expected sized"); LOGMAN_THROW_A_FMT(IROp->Size == regSize, "expected sized");
const auto guest = StaticFPRegisters[Op->Reg]; const auto guest = StaticFPRegisters[Op->Reg];
const auto host = GetVReg(Op->Value.ID()); const auto host = GetVReg(Op->Value.ID());
@ -2308,7 +2306,7 @@ DEF_OP(VStoreNonTemporalPair) {
const auto Op = IROp->C<IR::IROp_VStoreNonTemporalPair>(); const auto Op = IROp->C<IR::IROp_VStoreNonTemporalPair>();
const auto OpSize = IROp->Size; const auto OpSize = IROp->Size;
const auto Is128Bit = OpSize == Core::CPUState::XMM_SSE_REG_SIZE; [[maybe_unused]] const auto Is128Bit = OpSize == Core::CPUState::XMM_SSE_REG_SIZE;
LOGMAN_THROW_A_FMT(Is128Bit, "This IR operation only operates at 128-bit wide"); LOGMAN_THROW_A_FMT(Is128Bit, "This IR operation only operates at 128-bit wide");
const auto ValueLow = GetVReg(Op->ValueLow.ID()); const auto ValueLow = GetVReg(Op->ValueLow.ID());

View File

@ -53,7 +53,7 @@ DEF_OP(Copy) {
DEF_OP(Swap1) { DEF_OP(Swap1) {
auto Op = IROp->C<IR::IROp_Swap1>(); auto Op = IROp->C<IR::IROp_Swap1>();
auto A = GetReg(Op->A.ID()), B = GetReg(Op->B.ID()); auto A = GetReg(Op->A.ID()), B = GetReg(Op->B.ID());
LOGMAN_THROW_AA_FMT(B == GetReg(Node), "Invariant"); LOGMAN_THROW_A_FMT(B == GetReg(Node), "Invariant");
mov(ARMEmitter::Size::i64Bit, TMP1, A); mov(ARMEmitter::Size::i64Bit, TMP1, A);
mov(ARMEmitter::Size::i64Bit, A, B); mov(ARMEmitter::Size::i64Bit, A, B);

View File

@ -508,7 +508,7 @@ OpDispatchBuilder::RefPair OpDispatchBuilder::AVX128_LoadSource_WithOpSize(
OpDispatchBuilder::RefVSIB OpDispatchBuilder::RefVSIB
OpDispatchBuilder::AVX128_LoadVSIB(const X86Tables::DecodedOp& Op, const X86Tables::DecodedOperand& Operand, uint32_t Flags, bool NeedsHigh) { OpDispatchBuilder::AVX128_LoadVSIB(const X86Tables::DecodedOp& Op, const X86Tables::DecodedOperand& Operand, uint32_t Flags, bool NeedsHigh) {
const bool IsVSIB = (Op->Flags & X86Tables::DecodeFlags::FLAG_VSIB_BYTE) != 0; [[maybe_unused]] const bool IsVSIB = (Op->Flags & X86Tables::DecodeFlags::FLAG_VSIB_BYTE) != 0;
LOGMAN_THROW_A_FMT(Operand.IsSIB() && IsVSIB, "Trying to load VSIB for something that isn't the correct type!"); LOGMAN_THROW_A_FMT(Operand.IsSIB() && IsVSIB, "Trying to load VSIB for something that isn't the correct type!");
// VSIB is a very special case which has a ton of encoded data. // VSIB is a very special case which has a ton of encoded data.
@ -1012,7 +1012,6 @@ template<size_t DstElementSize>
void OpDispatchBuilder::AVX128_InsertCVTGPR_To_FPR(OpcodeArgs) { void OpDispatchBuilder::AVX128_InsertCVTGPR_To_FPR(OpcodeArgs) {
const auto SrcSize = GetSrcSize(Op); const auto SrcSize = GetSrcSize(Op);
const auto DstSize = GetDstSize(Op); const auto DstSize = GetDstSize(Op);
const auto Is128Bit = DstSize == Core::CPUState::XMM_SSE_REG_SIZE;
auto Src1 = AVX128_LoadSource_WithOpSize(Op, Op->Src[0], Op->Flags, false); auto Src1 = AVX128_LoadSource_WithOpSize(Op, Op->Src[0], Op->Flags, false);
@ -1036,8 +1035,9 @@ void OpDispatchBuilder::AVX128_InsertCVTGPR_To_FPR(OpcodeArgs) {
Result.Low = _VSToFVectorInsert(IR::SizeToOpSize(DstSize), DstElementSize, DstElementSize, Src1.Low, Src2.Low, false, false); Result.Low = _VSToFVectorInsert(IR::SizeToOpSize(DstSize), DstElementSize, DstElementSize, Src1.Low, Src2.Low, false, false);
} }
Result.High = LoadZeroVector(OpSize::i128Bit); [[maybe_unused]] const auto Is128Bit = DstSize == Core::CPUState::XMM_SSE_REG_SIZE;
LOGMAN_THROW_A_FMT(Is128Bit, "Programming Error: This should never occur!"); LOGMAN_THROW_A_FMT(Is128Bit, "Programming Error: This should never occur!");
Result.High = LoadZeroVector(OpSize::i128Bit);
AVX128_StoreResult_WithOpSize(Op, Op->Dest, Result); AVX128_StoreResult_WithOpSize(Op, Op->Dest, Result);
} }

View File

@ -5161,7 +5161,7 @@ template void OpDispatchBuilder::VFMSUBADD<2, 1, 3>(OpcodeArgs);
template void OpDispatchBuilder::VFMSUBADD<2, 3, 1>(OpcodeArgs); template void OpDispatchBuilder::VFMSUBADD<2, 3, 1>(OpcodeArgs);
OpDispatchBuilder::RefVSIB OpDispatchBuilder::LoadVSIB(const X86Tables::DecodedOp& Op, const X86Tables::DecodedOperand& Operand, uint32_t Flags) { OpDispatchBuilder::RefVSIB OpDispatchBuilder::LoadVSIB(const X86Tables::DecodedOp& Op, const X86Tables::DecodedOperand& Operand, uint32_t Flags) {
const bool IsVSIB = (Op->Flags & X86Tables::DecodeFlags::FLAG_VSIB_BYTE) != 0; [[maybe_unused]] const bool IsVSIB = (Op->Flags & X86Tables::DecodeFlags::FLAG_VSIB_BYTE) != 0;
LOGMAN_THROW_A_FMT(Operand.IsSIB() && IsVSIB, "Trying to load VSIB for something that isn't the correct type!"); LOGMAN_THROW_A_FMT(Operand.IsSIB() && IsVSIB, "Trying to load VSIB for something that isn't the correct type!");
// VSIB is a very special case which has a ton of encoded data. // VSIB is a very special case which has a ton of encoded data.

View File

@ -80,6 +80,45 @@ struct JITSymbolBuffer {
}; };
static_assert(sizeof(JITSymbolBuffer) == 4096, "Ensure this is one page in size"); static_assert(sizeof(JITSymbolBuffer) == 4096, "Ensure this is one page in size");
// Special-purpose replacement for std::unique_ptr to allow InternalThreadState to be standard layout.
// Since a NonMovableUniquePtr is neither copyable nor movable, its only function is to own and release the contained object.
template<typename T>
struct NonMovableUniquePtr {
NonMovableUniquePtr() noexcept = default;
NonMovableUniquePtr(const NonMovableUniquePtr&) = delete;
NonMovableUniquePtr& operator=(const NonMovableUniquePtr& UPtr) = delete;
NonMovableUniquePtr& operator=(fextl::unique_ptr<T> UPtr) noexcept {
Ptr = UPtr.release();
return *this;
}
~NonMovableUniquePtr() {
fextl::default_delete<T> {}(Ptr);
}
T* operator->() const noexcept {
return Ptr;
}
std::add_lvalue_reference_t<T> operator*() const noexcept {
return *Ptr;
}
T* get() const noexcept {
return Ptr;
}
operator bool() const noexcept {
return Ptr != nullptr;
}
private:
T* Ptr = nullptr;
};
static_assert(!std::is_move_constructible_v<NonMovableUniquePtr<int>>);
static_assert(!std::is_move_assignable_v<NonMovableUniquePtr<int>>);
struct InternalThreadState : public FEXCore::Allocator::FEXAllocOperators { struct InternalThreadState : public FEXCore::Allocator::FEXAllocOperators {
FEXCore::Core::CpuStateFrame* const CurrentFrame = &BaseFrameState; FEXCore::Core::CpuStateFrame* const CurrentFrame = &BaseFrameState;
@ -93,20 +132,20 @@ struct InternalThreadState : public FEXCore::Allocator::FEXAllocOperators {
FEXCore::Context::Context* CTX; FEXCore::Context::Context* CTX;
std::atomic<SignalEvent> SignalReason {SignalEvent::Nothing}; std::atomic<SignalEvent> SignalReason {SignalEvent::Nothing};
fextl::unique_ptr<FEXCore::Threads::Thread> ExecutionThread; NonMovableUniquePtr<FEXCore::Threads::Thread> ExecutionThread;
bool StartPaused {false}; bool StartPaused {false};
InterruptableConditionVariable StartRunning; InterruptableConditionVariable StartRunning;
Event ThreadWaiting; Event ThreadWaiting;
fextl::unique_ptr<FEXCore::IR::OpDispatchBuilder> OpDispatcher; NonMovableUniquePtr<FEXCore::IR::OpDispatchBuilder> OpDispatcher;
fextl::unique_ptr<FEXCore::CPU::CPUBackend> CPUBackend; NonMovableUniquePtr<FEXCore::CPU::CPUBackend> CPUBackend;
fextl::unique_ptr<FEXCore::LookupCache> LookupCache; NonMovableUniquePtr<FEXCore::LookupCache> LookupCache;
fextl::unique_ptr<FEXCore::Frontend::Decoder> FrontendDecoder; NonMovableUniquePtr<FEXCore::Frontend::Decoder> FrontendDecoder;
fextl::unique_ptr<FEXCore::IR::PassManager> PassManager; NonMovableUniquePtr<FEXCore::IR::PassManager> PassManager;
FEXCore::HLE::ThreadManagement ThreadManager; FEXCore::HLE::ThreadManagement ThreadManager;
fextl::unique_ptr<JITSymbolBuffer> SymbolBuffer; NonMovableUniquePtr<JITSymbolBuffer> SymbolBuffer;
int StatusCode {}; int StatusCode {};
FEXCore::Context::ExitReason ExitReason {FEXCore::Context::ExitReason::EXIT_WAITING}; FEXCore::Context::ExitReason ExitReason {FEXCore::Context::ExitReason::EXIT_WAITING};
@ -134,8 +173,9 @@ struct InternalThreadState : public FEXCore::Allocator::FEXAllocOperators {
// Can be reprotected as RO to trigger an interrupt at generated code block entrypoints // Can be reprotected as RO to trigger an interrupt at generated code block entrypoints
alignas(FEXCore::Utils::FEX_PAGE_SIZE) uint8_t InterruptFaultPage[FEXCore::Utils::FEX_PAGE_SIZE]; alignas(FEXCore::Utils::FEX_PAGE_SIZE) uint8_t InterruptFaultPage[FEXCore::Utils::FEX_PAGE_SIZE];
}; };
static_assert(std::is_standard_layout_v<FEXCore::Core::InternalThreadState>);
static_assert( static_assert(
(offsetof(FEXCore::Core::InternalThreadState, InterruptFaultPage) - offsetof(FEXCore::Core::InternalThreadState, BaseFrameState)) < 4096, (offsetof(FEXCore::Core::InternalThreadState, InterruptFaultPage) - offsetof(FEXCore::Core::InternalThreadState, BaseFrameState)) < 4096,
"Fault page is outside of immediate range from CPU state"); "Fault page is outside of immediate range from CPU state");
// static_assert(std::is_standard_layout<InternalThreadState>::value, "This needs to be standard layout");
} // namespace FEXCore::Core } // namespace FEXCore::Core

View File

@ -6,18 +6,18 @@ json_t* PoolInit(jsonPool_t* Pool);
json_t* PoolAlloc(jsonPool_t* Pool); json_t* PoolAlloc(jsonPool_t* Pool);
JsonAllocator::JsonAllocator() JsonAllocator::JsonAllocator()
: PoolObject { : jsonPool_t {
.init = FEX::JSON::PoolInit, .init = FEX::JSON::PoolInit,
.alloc = FEX::JSON::PoolAlloc, .alloc = FEX::JSON::PoolAlloc,
} {} } {}
json_t* PoolInit(jsonPool_t* Pool) { json_t* PoolInit(jsonPool_t* Pool) {
JsonAllocator* alloc = reinterpret_cast<JsonAllocator*>(Pool); JsonAllocator* alloc = static_cast<JsonAllocator*>(Pool);
return &*alloc->json_objects.emplace(alloc->json_objects.end()); return &*alloc->json_objects.emplace(alloc->json_objects.end());
} }
json_t* PoolAlloc(jsonPool_t* Pool) { json_t* PoolAlloc(jsonPool_t* Pool) {
JsonAllocator* alloc = reinterpret_cast<JsonAllocator*>(Pool); JsonAllocator* alloc = static_cast<JsonAllocator*>(Pool);
return &*alloc->json_objects.emplace(alloc->json_objects.end()); return &*alloc->json_objects.emplace(alloc->json_objects.end());
} }
} // namespace FEX::JSON } // namespace FEX::JSON

View File

@ -6,13 +6,11 @@
#include <tiny-json.h> #include <tiny-json.h>
namespace FEX::JSON { namespace FEX::JSON {
struct JsonAllocator { struct JsonAllocator : jsonPool_t {
jsonPool_t PoolObject;
fextl::list<json_t> json_objects; fextl::list<json_t> json_objects;
JsonAllocator(); JsonAllocator();
}; };
static_assert(offsetof(JsonAllocator, PoolObject) == 0, "This needs to be at offset zero");
template<typename T> template<typename T>
const json_t* CreateJSON(T& Container, JsonAllocator& Allocator) { const json_t* CreateJSON(T& Container, JsonAllocator& Allocator) {
@ -20,6 +18,6 @@ const json_t* CreateJSON(T& Container, JsonAllocator& Allocator) {
return nullptr; return nullptr;
} }
return json_createWithPool(&Container.at(0), &Allocator.PoolObject); return json_createWithPool(&Container.at(0), &Allocator);
} }
} // namespace FEX::JSON } // namespace FEX::JSON

View File

@ -60,18 +60,15 @@ namespace DRM {
} }
fex_drm_version(struct drm_version val) fex_drm_version(struct drm_version val)
: name {val.name} : name {auto_compat_ptr {val.name}}
, date {val.date} , date {auto_compat_ptr {val.date}}
, desc {val.desc} { , desc {auto_compat_ptr {val.desc}} {
version_major = val.version_major; version_major = val.version_major;
version_minor = val.version_minor; version_minor = val.version_minor;
version_patchlevel = val.version_patchlevel; version_patchlevel = val.version_patchlevel;
name_len = val.name_len; name_len = val.name_len;
name = val.name;
date_len = val.date_len; date_len = val.date_len;
date = val.date;
desc_len = val.desc_len; desc_len = val.desc_len;
desc = val.desc;
} }
}; };
@ -89,7 +86,7 @@ namespace DRM {
} }
fex_drm_unique(struct drm_unique val) fex_drm_unique(struct drm_unique val)
: unique {val.unique} { : unique {auto_compat_ptr {val.unique}} {
unique_len = val.unique_len; unique_len = val.unique_len;
} }
}; };
@ -116,7 +113,7 @@ namespace DRM {
} }
fex_drm_map(struct drm_map val) fex_drm_map(struct drm_map val)
: handle {val.handle} { : handle {auto_compat_ptr {val.handle}} {
CPYT(offset); CPYT(offset);
CPYT(size); CPYT(size);
CPYT(type); CPYT(type);
@ -227,7 +224,7 @@ namespace DRM {
} }
fex_drm_buf_info(struct drm_buf_info val) fex_drm_buf_info(struct drm_buf_info val)
: list {val.list} { : list {auto_compat_ptr {val.list}} {
CPYF(count); CPYF(count);
} }
}; };
@ -250,7 +247,7 @@ namespace DRM {
} }
fex_drm_buf_pub(struct drm_buf_pub val) fex_drm_buf_pub(struct drm_buf_pub val)
: address {val.address} { : address {auto_compat_ptr {val.address}} {
CPYF(idx); CPYF(idx);
CPYF(total); CPYF(total);
CPYF(used); CPYF(used);
@ -282,11 +279,11 @@ namespace DRM {
fex_drm_buf_map(struct drm_buf_map val) fex_drm_buf_map(struct drm_buf_map val)
#ifdef __cplusplus #ifdef __cplusplus
: virt {val.virt} : virt {auto_compat_ptr {val.virt}}
#else #else
: virtual {val.virtual} : virtual {auto_compat_ptr {val.virtual}}
#endif #endif
, list {val.list} { , list {auto_compat_ptr {val.list}} {
CPYF(count); CPYF(count);
} }
}; };
@ -305,7 +302,7 @@ namespace DRM {
} }
fex_drm_buf_free(struct drm_buf_free val) fex_drm_buf_free(struct drm_buf_free val)
: list {val.list} { : list {auto_compat_ptr {val.list}} {
CPYF(count); CPYF(count);
} }
}; };
@ -324,7 +321,7 @@ namespace DRM {
} }
fex_drm_ctx_priv_map(struct drm_ctx_priv_map val) fex_drm_ctx_priv_map(struct drm_ctx_priv_map val)
: handle {val.handle} { : handle {auto_compat_ptr {val.handle}} {
CPYF(ctx_id); CPYF(ctx_id);
} }
}; };
@ -342,7 +339,7 @@ namespace DRM {
} }
fex_drm_ctx_res(struct drm_ctx_res val) fex_drm_ctx_res(struct drm_ctx_res val)
: contexts {val.contexts} { : contexts {auto_compat_ptr {val.contexts}} {
CPYF(count); CPYF(count);
} }
}; };
@ -377,10 +374,10 @@ namespace DRM {
} }
fex_drm_dma(struct drm_dma val) fex_drm_dma(struct drm_dma val)
: send_indices {val.send_indices} : send_indices {auto_compat_ptr {val.send_indices}}
, send_sizes {val.send_sizes} , send_sizes {auto_compat_ptr {val.send_sizes}}
, request_indices {val.request_indices} , request_indices {auto_compat_ptr {val.request_indices}}
, request_sizes {val.request_sizes} { , request_sizes {auto_compat_ptr {val.request_sizes}} {
CPYF(context); CPYF(context);
CPYF(send_count); CPYF(send_count);
CPYF(flags); CPYF(flags);
@ -763,7 +760,7 @@ namespace RADEON {
} }
fex_drm_radeon_clear_t(drm_radeon_clear_t val) fex_drm_radeon_clear_t(drm_radeon_clear_t val)
: depth_boxes {val.depth_boxes} { : depth_boxes {auto_compat_ptr {val.depth_boxes}} {
flags = val.flags; flags = val.flags;
clear_color = val.clear_color; clear_color = val.clear_color;
clear_depth = val.clear_depth; clear_depth = val.clear_depth;
@ -784,7 +781,7 @@ namespace RADEON {
} }
fex_drm_radeon_stipple_t(drm_radeon_stipple_t val) fex_drm_radeon_stipple_t(drm_radeon_stipple_t val)
: mask {val.mask} {} : mask {auto_compat_ptr {val.mask}} {}
}; };
struct FEX_ANNOTATE("alias-x86_32-drm_radeon_texture") FEX_ANNOTATE("fex-match") fex_drm_radeon_texture_t { struct FEX_ANNOTATE("alias-x86_32-drm_radeon_texture") FEX_ANNOTATE("fex-match") fex_drm_radeon_texture_t {
@ -809,7 +806,7 @@ namespace RADEON {
} }
fex_drm_radeon_texture_t(drm_radeon_texture_t val) fex_drm_radeon_texture_t(drm_radeon_texture_t val)
: image {val.image} { : image {auto_compat_ptr {val.image}} {
offset = val.offset; offset = val.offset;
pitch = val.pitch; pitch = val.pitch;
format = val.format; format = val.format;
@ -840,8 +837,8 @@ namespace RADEON {
} }
fex_drm_radeon_vertex2_t(drm_radeon_vertex2_t val) fex_drm_radeon_vertex2_t(drm_radeon_vertex2_t val)
: state {val.state} : state {auto_compat_ptr {val.state}}
, prim {val.prim} { , prim {auto_compat_ptr {val.prim}} {
idx = val.idx; idx = val.idx;
discard = val.discard; discard = val.discard;
nr_states = val.nr_states; nr_states = val.nr_states;
@ -867,8 +864,8 @@ namespace RADEON {
} }
fex_drm_radeon_cmd_buffer_t(drm_radeon_cmd_buffer_t val) fex_drm_radeon_cmd_buffer_t(drm_radeon_cmd_buffer_t val)
: buf {val.buf} : buf {auto_compat_ptr {val.buf}}
, boxes {val.boxes} { , boxes {auto_compat_ptr {val.boxes}} {
val.bufsz = bufsz; val.bufsz = bufsz;
val.nbox = nbox; val.nbox = nbox;
} }
@ -888,7 +885,7 @@ namespace RADEON {
} }
fex_drm_radeon_getparam_t(drm_radeon_getparam_t val) fex_drm_radeon_getparam_t(drm_radeon_getparam_t val)
: value {val.value} { : value {auto_compat_ptr {val.value}} {
val.param = param; val.param = param;
} }
}; };
@ -911,7 +908,7 @@ namespace RADEON {
} }
fex_drm_radeon_mem_alloc_t(drm_radeon_mem_alloc_t val) fex_drm_radeon_mem_alloc_t(drm_radeon_mem_alloc_t val)
: region_offset {val.region_offset} { : region_offset {auto_compat_ptr {val.region_offset}} {
val.region = region; val.region = region;
val.alignment = alignment; val.alignment = alignment;
val.size = size; val.size = size;
@ -930,7 +927,7 @@ namespace RADEON {
} }
fex_drm_radeon_irq_emit_t(drm_radeon_irq_emit_t val) fex_drm_radeon_irq_emit_t(drm_radeon_irq_emit_t val)
: irq_seq {val.irq_seq} {} : irq_seq {auto_compat_ptr {val.irq_seq}} {}
}; };
struct FEX_ANNOTATE("alias-x86_32-drm_radeon_setparam") FEX_ANNOTATE("fex-match") FEX_PACKED fex_drm_radeon_setparam_t { struct FEX_ANNOTATE("alias-x86_32-drm_radeon_setparam") FEX_ANNOTATE("fex-match") FEX_PACKED fex_drm_radeon_setparam_t {
@ -959,7 +956,6 @@ namespace MSM {
compat_int64_t tv_sec; compat_int64_t tv_sec;
compat_int64_t tv_nsec; compat_int64_t tv_nsec;
fex_drm_msm_timespec() = delete;
operator drm_msm_timespec() const { operator drm_msm_timespec() const {
drm_msm_timespec val {}; drm_msm_timespec val {};
val.tv_sec = tv_sec; val.tv_sec = tv_sec;
@ -967,10 +963,15 @@ namespace MSM {
return val; return val;
} }
fex_drm_msm_timespec(struct drm_msm_timespec val) { static fex_drm_msm_timespec FromHost(struct drm_msm_timespec val) {
tv_sec = val.tv_sec; fex_drm_msm_timespec ret;
tv_nsec = val.tv_nsec; ret.tv_sec = val.tv_sec;
ret.tv_nsec = val.tv_nsec;
return ret;
} }
private:
fex_drm_msm_timespec() = default;
}; };
struct FEX_ANNOTATE("alias-x86_32-drm_msm_wait_fence") FEX_ANNOTATE("fex-match") FEX_PACKED fex_drm_msm_wait_fence { struct FEX_ANNOTATE("alias-x86_32-drm_msm_wait_fence") FEX_ANNOTATE("fex-match") FEX_PACKED fex_drm_msm_wait_fence {
@ -991,7 +992,7 @@ namespace MSM {
} }
fex_drm_msm_wait_fence(struct drm_msm_wait_fence val) fex_drm_msm_wait_fence(struct drm_msm_wait_fence val)
: timeout {val.timeout} { : timeout {fex_drm_msm_timespec::FromHost(val.timeout)} {
fence = val.fence; fence = val.fence;
flags = val.flags; flags = val.flags;
queueid = val.queueid; queueid = val.queueid;
@ -1024,7 +1025,7 @@ namespace I915 {
} }
fex_drm_i915_batchbuffer_t(drm_i915_batchbuffer_t val) fex_drm_i915_batchbuffer_t(drm_i915_batchbuffer_t val)
: cliprects {val.cliprects} { : cliprects {auto_compat_ptr {val.cliprects}} {
CPYF(start); CPYF(start);
CPYF(used); CPYF(used);
CPYF(DR1); CPYF(DR1);
@ -1045,7 +1046,7 @@ namespace I915 {
} }
fex_drm_i915_irq_emit_t(drm_i915_irq_emit_t val) fex_drm_i915_irq_emit_t(drm_i915_irq_emit_t val)
: irq_seq {val.irq_seq} {} : irq_seq {auto_compat_ptr {val.irq_seq}} {}
}; };
struct FEX_ANNOTATE("alias-x86_32-drm_i915_getparam") FEX_ANNOTATE("fex-match") fex_drm_i915_getparam_t { struct FEX_ANNOTATE("alias-x86_32-drm_i915_getparam") FEX_ANNOTATE("fex-match") fex_drm_i915_getparam_t {
@ -1061,7 +1062,7 @@ namespace I915 {
} }
fex_drm_i915_getparam_t(drm_i915_getparam_t val) fex_drm_i915_getparam_t(drm_i915_getparam_t val)
: value {val.value} { : value {auto_compat_ptr {val.value}} {
CPYF(param); CPYF(param);
} }
}; };
@ -1083,7 +1084,7 @@ namespace I915 {
} }
fex_drm_i915_mem_alloc_t(drm_i915_mem_alloc_t val) fex_drm_i915_mem_alloc_t(drm_i915_mem_alloc_t val)
: region_offset {val.region_offset} { : region_offset {auto_compat_ptr {val.region_offset}} {
CPYT(region); CPYT(region);
CPYT(alignment); CPYT(alignment);
CPYT(size); CPYT(size);
@ -1112,8 +1113,8 @@ namespace I915 {
} }
fex_drm_i915_cmdbuffer_t(drm_i915_cmdbuffer_t val) fex_drm_i915_cmdbuffer_t(drm_i915_cmdbuffer_t val)
: buf {val.buf} : buf {auto_compat_ptr {val.buf}}
, cliprects {val.cliprects} { , cliprects {auto_compat_ptr {val.cliprects}} {
CPYT(sz); CPYT(sz);
CPYT(DR1); CPYT(DR1);
CPYT(DR4); CPYT(DR4);

View File

@ -103,7 +103,7 @@ uint64_t _ipc(FEXCore::Core::CpuStateFrame* Frame, uint32_t call, uint32_t first
uint32_t semnum = second; uint32_t semnum = second;
// Upper 16bits used for a different flag? // Upper 16bits used for a different flag?
int32_t cmd = third & 0xFF; int32_t cmd = third & 0xFF;
compat_ptr<semun_32> semun(ptr); auto_compat_ptr<semun_32> semun(ptr);
bool IPC64 = third & 0x100; bool IPC64 = third & 0x100;
switch (cmd) { switch (cmd) {
case IPC_SET: { case IPC_SET: {

View File

@ -304,7 +304,7 @@ void ConvertHeaderToGuest(struct msghdr32* Guest, struct msghdr* Host) {
} }
} }
static uint64_t RecvMMsg(int sockfd, compat_ptr<mmsghdr_32> msgvec, uint32_t vlen, int flags, struct timespec* timeout_ts) { static uint64_t RecvMMsg(int sockfd, auto_compat_ptr<mmsghdr_32> msgvec, uint32_t vlen, int flags, struct timespec* timeout_ts) {
fextl::vector<iovec> Host_iovec; fextl::vector<iovec> Host_iovec;
fextl::vector<struct mmsghdr> HostMHeader(vlen); fextl::vector<struct mmsghdr> HostMHeader(vlen);
for (size_t i = 0; i < vlen; ++i) { for (size_t i = 0; i < vlen; ++i) {
@ -321,7 +321,7 @@ static uint64_t RecvMMsg(int sockfd, compat_ptr<mmsghdr_32> msgvec, uint32_t vle
SYSCALL_ERRNO(); SYSCALL_ERRNO();
} }
static uint64_t SendMMsg(int sockfd, compat_ptr<mmsghdr_32> msgvec, uint32_t vlen, int flags) { static uint64_t SendMMsg(int sockfd, auto_compat_ptr<mmsghdr_32> msgvec, uint32_t vlen, int flags) {
fextl::vector<iovec> Host_iovec; fextl::vector<iovec> Host_iovec;
fextl::vector<struct mmsghdr> HostMmsg(vlen); fextl::vector<struct mmsghdr> HostMmsg(vlen);
@ -407,7 +407,7 @@ static uint64_t SendMMsg(int sockfd, compat_ptr<mmsghdr_32> msgvec, uint32_t vle
SYSCALL_ERRNO(); SYSCALL_ERRNO();
} }
static uint64_t SetSockOpt(int sockfd, int level, int optname, compat_ptr<void> optval, int optlen) { static uint64_t SetSockOpt(int sockfd, int level, int optname, auto_compat_ptr<void> optval, int optlen) {
uint64_t Result {}; uint64_t Result {};
if (level == SOL_SOCKET) { if (level == SOL_SOCKET) {
@ -534,7 +534,7 @@ static uint64_t SetSockOpt(int sockfd, int level, int optname, compat_ptr<void>
SYSCALL_ERRNO(); SYSCALL_ERRNO();
} }
static uint64_t GetSockOpt(int sockfd, int level, int optname, compat_ptr<void> optval, compat_ptr<socklen_t> optlen) { static uint64_t GetSockOpt(int sockfd, int level, int optname, auto_compat_ptr<void> optval, auto_compat_ptr<socklen_t> optlen) {
uint64_t Result {}; uint64_t Result {};
if (level == SOL_SOCKET) { if (level == SOL_SOCKET) {
switch (optname) { switch (optname) {
@ -748,12 +748,12 @@ void RegisterSocket(FEX::HLE::SyscallHandler* Handler) {
}); });
REGISTER_SYSCALL_IMPL_X32(sendmmsg, REGISTER_SYSCALL_IMPL_X32(sendmmsg,
[](FEXCore::Core::CpuStateFrame* Frame, int sockfd, compat_ptr<mmsghdr_32> msgvec, uint32_t vlen, [](FEXCore::Core::CpuStateFrame* Frame, int sockfd, auto_compat_ptr<mmsghdr_32> msgvec, uint32_t vlen,
int flags) -> uint64_t { return SendMMsg(sockfd, msgvec, vlen, flags); }); int flags) -> uint64_t { return SendMMsg(sockfd, msgvec, vlen, flags); });
REGISTER_SYSCALL_IMPL_X32(recvmmsg, REGISTER_SYSCALL_IMPL_X32(recvmmsg,
[](FEXCore::Core::CpuStateFrame* Frame, int sockfd, compat_ptr<mmsghdr_32> msgvec, uint32_t vlen, int flags, [](FEXCore::Core::CpuStateFrame* Frame, int sockfd, auto_compat_ptr<mmsghdr_32> msgvec, uint32_t vlen,
timespec32* timeout_ts) -> uint64_t { int flags, timespec32* timeout_ts) -> uint64_t {
struct timespec tp64 {}; struct timespec tp64 {};
struct timespec* timed_ptr {}; struct timespec* timed_ptr {};
if (timeout_ts) { if (timeout_ts) {
@ -771,7 +771,7 @@ void RegisterSocket(FEX::HLE::SyscallHandler* Handler) {
}); });
REGISTER_SYSCALL_IMPL_X32(recvmmsg_time64, REGISTER_SYSCALL_IMPL_X32(recvmmsg_time64,
[](FEXCore::Core::CpuStateFrame* Frame, int sockfd, compat_ptr<mmsghdr_32> msgvec, uint32_t vlen, int flags, [](FEXCore::Core::CpuStateFrame* Frame, int sockfd, auto_compat_ptr<mmsghdr_32> msgvec, uint32_t vlen, int flags,
struct timespec* timeout_ts) -> uint64_t { return RecvMMsg(sockfd, msgvec, vlen, flags, timeout_ts); }); struct timespec* timeout_ts) -> uint64_t { return RecvMMsg(sockfd, msgvec, vlen, flags, timeout_ts); });
REGISTER_SYSCALL_IMPL_X32(recvmsg, [](FEXCore::Core::CpuStateFrame* Frame, int sockfd, struct msghdr32* msg, int flags) -> uint64_t { REGISTER_SYSCALL_IMPL_X32(recvmsg, [](FEXCore::Core::CpuStateFrame* Frame, int sockfd, struct msghdr32* msg, int flags) -> uint64_t {
@ -779,11 +779,11 @@ void RegisterSocket(FEX::HLE::SyscallHandler* Handler) {
}); });
REGISTER_SYSCALL_IMPL_X32(setsockopt, REGISTER_SYSCALL_IMPL_X32(setsockopt,
[](FEXCore::Core::CpuStateFrame* Frame, int sockfd, int level, int optname, compat_ptr<void> optval, [](FEXCore::Core::CpuStateFrame* Frame, int sockfd, int level, int optname, auto_compat_ptr<void> optval,
socklen_t optlen) -> uint64_t { return SetSockOpt(sockfd, level, optname, optval, optlen); }); socklen_t optlen) -> uint64_t { return SetSockOpt(sockfd, level, optname, optval, optlen); });
REGISTER_SYSCALL_IMPL_X32(getsockopt, REGISTER_SYSCALL_IMPL_X32(getsockopt,
[](FEXCore::Core::CpuStateFrame* Frame, int sockfd, int level, int optname, compat_ptr<void> optval, [](FEXCore::Core::CpuStateFrame* Frame, int sockfd, int level, int optname, auto_compat_ptr<void> optval,
compat_ptr<socklen_t> optlen) -> uint64_t { return GetSockOpt(sockfd, level, optname, optval, optlen); }); auto_compat_ptr<socklen_t> optlen) -> uint64_t { return GetSockOpt(sockfd, level, optname, optval, optlen); });
} }
} // namespace FEX::HLE::x32 } // namespace FEX::HLE::x32

View File

@ -62,13 +62,16 @@ typedef FEX_ALIGNED(4) int64_t compat_loff_t;
template<typename T> template<typename T>
class compat_ptr { class compat_ptr {
public: protected:
compat_ptr() = delete; static compat_ptr FromAddress(uint32_t In) {
compat_ptr(uint32_t In) compat_ptr<T> ret;
: Ptr {In} {} ret.Ptr = In;
compat_ptr(T* In) return ret;
: Ptr {static_cast<uint32_t>(reinterpret_cast<uintptr_t>(In))} {} }
compat_ptr() = default;
public:
template<typename T2 = T, typename = std::enable_if<!std::is_same<T2, void>::value, T2>> template<typename T2 = T, typename = std::enable_if<!std::is_same<T2, void>::value, T2>>
T2& operator*() const { T2& operator*() const {
return *Interpret(); return *Interpret();
@ -103,15 +106,33 @@ public:
} }
uint32_t Ptr; uint32_t Ptr;
private: private:
T* Interpret() const { T* Interpret() const {
return reinterpret_cast<T*>(Ptr); return reinterpret_cast<T*>(Ptr);
} }
}; };
static_assert(std::is_trivial<compat_ptr<void>>::value, "Needs to be trivial"); static_assert(std::is_trivial<compat_ptr<void>>::value, "Needs to be trivial");
static_assert(sizeof(compat_ptr<void>) == 4, "Incorrect size"); static_assert(sizeof(compat_ptr<void>) == 4, "Incorrect size");
/**
* Helper class to import a compat_ptr from a native pointer or raw address.
*
* Adding these custom constructors to compat_ptr itself would trigger clang's -Wpacked-non-pod warnings.
*/
template<typename T>
class auto_compat_ptr : public compat_ptr<T> {
public:
auto_compat_ptr(uint32_t In)
: compat_ptr<T> {compat_ptr<T>::FromAddress(In)} {}
auto_compat_ptr(T* In)
: compat_ptr<T> {compat_ptr<T>::FromAddress(static_cast<uint32_t>(reinterpret_cast<uintptr_t>(In)))} {}
};
template<typename T>
auto_compat_ptr(T*) -> auto_compat_ptr<T>;
/** /**
* @name timespec32 * @name timespec32
* *
@ -280,7 +301,7 @@ struct FEX_ANNOTATE("alias-x86_32-stack_t") FEX_ANNOTATE("fex-match") stack_t32
} }
stack_t32(stack_t ss) stack_t32(stack_t ss)
: ss_sp {ss.ss_sp} { : ss_sp {auto_compat_ptr {ss.ss_sp}} {
ss_flags = ss.ss_flags; ss_flags = ss.ss_flags;
ss_size = ss.ss_size; ss_size = ss.ss_size;
} }
@ -832,8 +853,8 @@ struct FEX_PACKED FEX_ANNOTATE("fex-match") OldGuestSigAction_32 {
} }
OldGuestSigAction_32(FEX::HLE::GuestSigAction action) OldGuestSigAction_32(FEX::HLE::GuestSigAction action)
: handler_32 {reinterpret_cast<void*>(action.sigaction_handler.handler)} : handler_32 {auto_compat_ptr {reinterpret_cast<void*>(action.sigaction_handler.handler)}}
, restorer_32 {reinterpret_cast<void*>(action.restorer)} { , restorer_32 {auto_compat_ptr {reinterpret_cast<void*>(action.restorer)}} {
sa_flags = action.sa_flags; sa_flags = action.sa_flags;
sa_mask = action.sa_mask.Val; sa_mask = action.sa_mask.Val;
} }
@ -865,8 +886,8 @@ struct FEX_PACKED FEX_ANNOTATE("fex-match") GuestSigAction_32 {
} }
GuestSigAction_32(FEX::HLE::GuestSigAction action) GuestSigAction_32(FEX::HLE::GuestSigAction action)
: handler_32 {reinterpret_cast<void*>(action.sigaction_handler.handler)} : handler_32 {auto_compat_ptr {reinterpret_cast<void*>(action.sigaction_handler.handler)}}
, restorer_32 {reinterpret_cast<void*>(action.restorer)} { , restorer_32 {auto_compat_ptr {reinterpret_cast<void*>(action.restorer)}} {
sa_flags = action.sa_flags; sa_flags = action.sa_flags;
sa_mask = action.sa_mask; sa_mask = action.sa_mask;
} }
@ -1087,7 +1108,7 @@ union FEX_ANNOTATE("alias-x86_32-sigval") FEX_ANNOTATE("fex-match") sigval32 {
} }
sigval32(sigval val) { sigval32(sigval val) {
sival_ptr = val.sival_ptr; sival_ptr = auto_compat_ptr {val.sival_ptr};
} }
}; };
@ -1198,7 +1219,7 @@ struct FEX_PACKED FEX_ANNOTATE("alias-x86_32-epoll_event") FEX_ANNOTATE("fex-mat
} }
epoll_event32(struct epoll_event event) epoll_event32(struct epoll_event event)
: data {event.data.u64} { : data {auto_compat_ptr<void> {static_cast<uint32_t>(event.data.u64)}} {
events = event.events; events = event.events;
} }
}; };