mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 11:00:19 +02:00
Whole-tree reformat with clang-format-19
This commit is contained in:
1 parent
3c7ece2ef3
commit
5267cde60e
31 files changed
+260
-273
No files matched your search
@@ -985,21 +985,21 @@ void ContextImpl::AddThunkTrampolineIRHandler(uintptr_t Entrypoint, uintptr_t Gu
|
||||
auto Result = AddCustomIREntrypoint(
|
||||
Entrypoint,
|
||||
[this, GuestThunkEntrypoint](uintptr_t Entrypoint, FEXCore::IR::IREmitter* emit) {
|
||||
auto IRHeader = emit->_IRHeader(emit->Invalid(), Entrypoint, 0, 0, 0, 0);
|
||||
auto Block = emit->CreateCodeNode(true, 0);
|
||||
IRHeader.first->Blocks = emit->WrapNode(Block);
|
||||
emit->SetCurrentCodeBlock(Block);
|
||||
auto IRHeader = emit->_IRHeader(emit->Invalid(), Entrypoint, 0, 0, 0, 0);
|
||||
auto Block = emit->CreateCodeNode(true, 0);
|
||||
IRHeader.first->Blocks = emit->WrapNode(Block);
|
||||
emit->SetCurrentCodeBlock(Block);
|
||||
|
||||
const auto GPRSize = GetGPROpSize();
|
||||
const auto GPRSize = GetGPROpSize();
|
||||
|
||||
if (GPRSize == IR::OpSize::i64Bit) {
|
||||
IR::Ref R = emit->_StoreRegister(emit->_Constant(Entrypoint), GPRSize);
|
||||
R->Reg = IR::PhysicalRegister(IR::GPRFixedClass, X86State::REG_R11).Raw;
|
||||
} else {
|
||||
emit->_StoreContext(GPRSize, IR::FPRClass, emit->_VCastFromGPR(IR::OpSize::i64Bit, IR::OpSize::i64Bit, emit->_Constant(Entrypoint)),
|
||||
offsetof(Core::CPUState, mm[0][0]));
|
||||
}
|
||||
emit->_ExitFunction(IR::OpSize::i64Bit, emit->_Constant(GuestThunkEntrypoint));
|
||||
if (GPRSize == IR::OpSize::i64Bit) {
|
||||
IR::Ref R = emit->_StoreRegister(emit->_Constant(Entrypoint), GPRSize);
|
||||
R->Reg = IR::PhysicalRegister(IR::GPRFixedClass, X86State::REG_R11).Raw;
|
||||
} else {
|
||||
emit->_StoreContext(GPRSize, IR::FPRClass, emit->_VCastFromGPR(IR::OpSize::i64Bit, IR::OpSize::i64Bit, emit->_Constant(Entrypoint)),
|
||||
offsetof(Core::CPUState, mm[0][0]));
|
||||
}
|
||||
emit->_ExitFunction(IR::OpSize::i64Bit, emit->_Constant(GuestThunkEntrypoint));
|
||||
},
|
||||
ThunkHandler, (void*)GuestThunkEntrypoint);
|
||||
|
||||
|
||||
@@ -1331,7 +1331,8 @@ void Decoder::DecodeInstructionsAtEntry(const uint8_t* _InstStream, uint64_t PC,
|
||||
InstStream -= PCOffset;
|
||||
EraseBlock = true;
|
||||
} else {
|
||||
LogMan::Msg::EFmt("{} instruction in entry block: {:X}", BlockIt->BlockStatus == DecodedBlockStatus::INVALID_INST ? "Invalid" : "NoExec", OpAddress);
|
||||
LogMan::Msg::EFmt("{} instruction in entry block: {:X}",
|
||||
BlockIt->BlockStatus == DecodedBlockStatus::INVALID_INST ? "Invalid" : "NoExec", OpAddress);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -193,29 +193,29 @@ namespace FEXCore::CPU {
|
||||
VFScalarOperation(IROp->Size, ElementSize, Op->ZeroUpperBits, ScalarEmit, Dst, Vector1, Vector2); \
|
||||
}
|
||||
|
||||
#define DEF_FMAOP_SCALAR_INSERT(FEXOp, ARMOp) \
|
||||
DEF_OP(FEXOp) { \
|
||||
const auto Op = IROp->C<IR::IROp_##FEXOp>(); \
|
||||
const auto ElementSize = Op->Header.ElementSize; \
|
||||
\
|
||||
auto ScalarEmit = \
|
||||
[this, ElementSize](ARMEmitter::VRegister Dst, ARMEmitter::VRegister Src1, ARMEmitter::VRegister Src2, ARMEmitter::VRegister Src3) { \
|
||||
if (ElementSize == IR::OpSize::i16Bit) { \
|
||||
ARMOp(Dst.H(), Src1.H(), Src2.H(), Src3.H()); \
|
||||
} else if (ElementSize == IR::OpSize::i32Bit) { \
|
||||
ARMOp(Dst.S(), Src1.S(), Src2.S(), Src3.S()); \
|
||||
} else if (ElementSize == IR::OpSize::i64Bit) { \
|
||||
ARMOp(Dst.D(), Src1.D(), Src2.D(), Src3.D()); \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
const auto Dst = GetVReg(Node); \
|
||||
const auto Upper = GetVReg(Op->Upper); \
|
||||
const auto Vector1 = GetVReg(Op->Vector1); \
|
||||
const auto Vector2 = GetVReg(Op->Vector2); \
|
||||
const auto Addend = GetVReg(Op->Addend); \
|
||||
\
|
||||
VFScalarFMAOperation(IROp->Size, ElementSize, ScalarEmit, Dst, Upper, Vector1, Vector2, Addend); \
|
||||
#define DEF_FMAOP_SCALAR_INSERT(FEXOp, ARMOp) \
|
||||
DEF_OP(FEXOp) { \
|
||||
const auto Op = IROp->C<IR::IROp_##FEXOp>(); \
|
||||
const auto ElementSize = Op->Header.ElementSize; \
|
||||
\
|
||||
auto ScalarEmit = [this, ElementSize](ARMEmitter::VRegister Dst, ARMEmitter::VRegister Src1, ARMEmitter::VRegister Src2, \
|
||||
ARMEmitter::VRegister Src3) { \
|
||||
if (ElementSize == IR::OpSize::i16Bit) { \
|
||||
ARMOp(Dst.H(), Src1.H(), Src2.H(), Src3.H()); \
|
||||
} else if (ElementSize == IR::OpSize::i32Bit) { \
|
||||
ARMOp(Dst.S(), Src1.S(), Src2.S(), Src3.S()); \
|
||||
} else if (ElementSize == IR::OpSize::i64Bit) { \
|
||||
ARMOp(Dst.D(), Src1.D(), Src2.D(), Src3.D()); \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
const auto Dst = GetVReg(Node); \
|
||||
const auto Upper = GetVReg(Op->Upper); \
|
||||
const auto Vector1 = GetVReg(Op->Vector1); \
|
||||
const auto Vector2 = GetVReg(Op->Vector2); \
|
||||
const auto Addend = GetVReg(Op->Addend); \
|
||||
\
|
||||
VFScalarFMAOperation(IROp->Size, ElementSize, ScalarEmit, Dst, Upper, Vector1, Vector2, Addend); \
|
||||
}
|
||||
|
||||
DEF_UNOP(VAbs, abs, true)
|
||||
@@ -803,8 +803,8 @@ DEF_OP(VFCMPScalarInsert) {
|
||||
default: break;
|
||||
}
|
||||
};
|
||||
auto ScalarEmitUNO =
|
||||
[this, SubRegSize, ZeroUpperBits, Is256Bit](ARMEmitter::VRegister Dst, ARMEmitter::VRegister Src1, ARMEmitter::VRegister Src2) {
|
||||
auto ScalarEmitUNO = [this, SubRegSize, ZeroUpperBits, Is256Bit](ARMEmitter::VRegister Dst, ARMEmitter::VRegister Src1,
|
||||
ARMEmitter::VRegister Src2) {
|
||||
switch (SubRegSize.Scalar) {
|
||||
case ARMEmitter::ScalarRegSize::i16Bit: {
|
||||
fcmge(VTMP1.H(), Src1.H(), Src2.H());
|
||||
@@ -838,8 +838,8 @@ DEF_OP(VFCMPScalarInsert) {
|
||||
}
|
||||
}
|
||||
};
|
||||
auto ScalarEmitNEQ =
|
||||
[this, SubRegSize, ZeroUpperBits, Is256Bit](ARMEmitter::VRegister Dst, ARMEmitter::VRegister Src1, ARMEmitter::VRegister Src2) {
|
||||
auto ScalarEmitNEQ = [this, SubRegSize, ZeroUpperBits, Is256Bit](ARMEmitter::VRegister Dst, ARMEmitter::VRegister Src1,
|
||||
ARMEmitter::VRegister Src2) {
|
||||
switch (SubRegSize.Scalar) {
|
||||
case ARMEmitter::ScalarRegSize::i16Bit: {
|
||||
fcmeq(VTMP1.H(), Src2.H(), Src1.H());
|
||||
@@ -868,8 +868,8 @@ DEF_OP(VFCMPScalarInsert) {
|
||||
}
|
||||
}
|
||||
};
|
||||
auto ScalarEmitORD =
|
||||
[this, SubRegSize, ZeroUpperBits, Is256Bit](ARMEmitter::VRegister Dst, ARMEmitter::VRegister Src1, ARMEmitter::VRegister Src2) {
|
||||
auto ScalarEmitORD = [this, SubRegSize, ZeroUpperBits, Is256Bit](ARMEmitter::VRegister Dst, ARMEmitter::VRegister Src1,
|
||||
ARMEmitter::VRegister Src2) {
|
||||
switch (SubRegSize.Scalar) {
|
||||
case ARMEmitter::ScalarRegSize::i16Bit: {
|
||||
fcmge(VTMP1.H(), Src1.H(), Src2.H());
|
||||
|
||||
@@ -2024,41 +2024,41 @@ void OpDispatchBuilder::RCROp(OpcodeArgs) {
|
||||
Calculate_ShiftVariable(
|
||||
Op, SrcMasked,
|
||||
[this, Op, Size, OpSize]() {
|
||||
// Rematerialize loads to avoid crossblock liveness
|
||||
Ref Src = LoadSource(GPRClass, Op, Op->Src[1], Op->Flags, {.AllowUpperGarbage = true});
|
||||
Ref Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.AllowUpperGarbage = true});
|
||||
// Rematerialize loads to avoid crossblock liveness
|
||||
Ref Src = LoadSource(GPRClass, Op, Op->Src[1], Op->Flags, {.AllowUpperGarbage = true});
|
||||
Ref Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.AllowUpperGarbage = true});
|
||||
|
||||
// Res = Src >> Shift
|
||||
Ref Res = _Lshr(OpSize, Dest, Src);
|
||||
auto CF = GetRFLAG(FEXCore::X86State::RFLAG_CF_RAW_LOC);
|
||||
// Res = Src >> Shift
|
||||
Ref Res = _Lshr(OpSize, Dest, Src);
|
||||
auto CF = GetRFLAG(FEXCore::X86State::RFLAG_CF_RAW_LOC);
|
||||
|
||||
auto One = _Constant(OpSizeFromSrc(Op), 1);
|
||||
auto One = _Constant(OpSizeFromSrc(Op), 1);
|
||||
|
||||
// Res |= (Dest << (Size - Shift + 1));
|
||||
// Expressed as Res | ((Src << (Size - Shift)) << 1) to get correct
|
||||
// behaviour for Shift without clobbering NZCV. Then observe that modulo
|
||||
// Size, Size - Shift = -Shift so we can use a simple Neg.
|
||||
//
|
||||
// The masking of Lshl means we don't need mask the source, since:
|
||||
//
|
||||
// -(x & Mask) & Mask = (-x) & Mask
|
||||
Ref NegSrc = _Neg(OpSize, Src);
|
||||
Res = _Orlshl(OpSize, Res, _Lshl(OpSize, Dest, NegSrc), 1);
|
||||
// Res |= (Dest << (Size - Shift + 1));
|
||||
// Expressed as Res | ((Src << (Size - Shift)) << 1) to get correct
|
||||
// behaviour for Shift without clobbering NZCV. Then observe that modulo
|
||||
// Size, Size - Shift = -Shift so we can use a simple Neg.
|
||||
//
|
||||
// The masking of Lshl means we don't need mask the source, since:
|
||||
//
|
||||
// -(x & Mask) & Mask = (-x) & Mask
|
||||
Ref NegSrc = _Neg(OpSize, Src);
|
||||
Res = _Orlshl(OpSize, Res, _Lshl(OpSize, Dest, NegSrc), 1);
|
||||
|
||||
// Our new CF will be bit (Shift - 1) of the source. this is hoisted up to
|
||||
// avoid the need to copy the source. Again, the Lshr absorbs the masking.
|
||||
auto NewCF = _Lshr(OpSize, Dest, _Sub(OpSize, Src, One));
|
||||
SetCFDirect(NewCF, 0, true);
|
||||
// Our new CF will be bit (Shift - 1) of the source. this is hoisted up to
|
||||
// avoid the need to copy the source. Again, the Lshr absorbs the masking.
|
||||
auto NewCF = _Lshr(OpSize, Dest, _Sub(OpSize, Src, One));
|
||||
SetCFDirect(NewCF, 0, true);
|
||||
|
||||
// Since shift != 0 we can inject the CF
|
||||
Res = _Or(OpSize, Res, _Lshl(OpSize, CF, NegSrc));
|
||||
// Since shift != 0 we can inject the CF
|
||||
Res = _Or(OpSize, Res, _Lshl(OpSize, CF, NegSrc));
|
||||
|
||||
// OF is the top two MSBs XOR'd together
|
||||
// Only when Shift == 1, it is undefined otherwise
|
||||
auto Xor = _XorShift(OpSize, Res, Res, ShiftType::LSR, 1);
|
||||
SetRFLAG<FEXCore::X86State::RFLAG_OF_RAW_LOC>(Xor, Size - 2, true);
|
||||
// OF is the top two MSBs XOR'd together
|
||||
// Only when Shift == 1, it is undefined otherwise
|
||||
auto Xor = _XorShift(OpSize, Res, Res, ShiftType::LSR, 1);
|
||||
SetRFLAG<FEXCore::X86State::RFLAG_OF_RAW_LOC>(Xor, Size - 2, true);
|
||||
|
||||
StoreResult(GPRClass, Op, Res, OpSize::iInvalid);
|
||||
StoreResult(GPRClass, Op, Res, OpSize::iInvalid);
|
||||
},
|
||||
OpSizeFromSrc(Op) == OpSize::i32Bit ? std::make_optional(&OpDispatchBuilder::ZeroShiftResult) : std::nullopt);
|
||||
}
|
||||
@@ -2243,38 +2243,38 @@ void OpDispatchBuilder::RCLOp(OpcodeArgs) {
|
||||
Calculate_ShiftVariable(
|
||||
Op, SrcMasked,
|
||||
[this, Op, Size, OpSize]() {
|
||||
// Rematerialized to avoid crossblock liveness
|
||||
Ref Src = LoadSource(GPRClass, Op, Op->Src[1], Op->Flags, {.AllowUpperGarbage = true});
|
||||
// Rematerialized to avoid crossblock liveness
|
||||
Ref Src = LoadSource(GPRClass, Op, Op->Src[1], Op->Flags, {.AllowUpperGarbage = true});
|
||||
|
||||
// Res = Src << Shift
|
||||
Ref Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.AllowUpperGarbage = true});
|
||||
Ref Res = _Lshl(OpSize, Dest, Src);
|
||||
auto CF = GetRFLAG(FEXCore::X86State::RFLAG_CF_RAW_LOC);
|
||||
// Res = Src << Shift
|
||||
Ref Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.AllowUpperGarbage = true});
|
||||
Ref Res = _Lshl(OpSize, Dest, Src);
|
||||
auto CF = GetRFLAG(FEXCore::X86State::RFLAG_CF_RAW_LOC);
|
||||
|
||||
// Res |= (Dest >> (Size - Shift + 1)), expressed as
|
||||
// Res | ((Dest >> (-Shift)) >> 1), since Size - Shift = -Shift mod
|
||||
// Size. The shift aborbs the masking.
|
||||
auto NegSrc = _Neg(OpSize, Src);
|
||||
Res = _Orlshr(OpSize, Res, _Lshr(OpSize, Dest, NegSrc), 1);
|
||||
// Res |= (Dest >> (Size - Shift + 1)), expressed as
|
||||
// Res | ((Dest >> (-Shift)) >> 1), since Size - Shift = -Shift mod
|
||||
// Size. The shift aborbs the masking.
|
||||
auto NegSrc = _Neg(OpSize, Src);
|
||||
Res = _Orlshr(OpSize, Res, _Lshr(OpSize, Dest, NegSrc), 1);
|
||||
|
||||
// Our new CF will be bit (Shift - 1) of the source
|
||||
auto NewCF = _Lshr(OpSize, Dest, NegSrc);
|
||||
SetCFDirect(NewCF, 0, true);
|
||||
// Our new CF will be bit (Shift - 1) of the source
|
||||
auto NewCF = _Lshr(OpSize, Dest, NegSrc);
|
||||
SetCFDirect(NewCF, 0, true);
|
||||
|
||||
// Since Shift != 0 we can inject the CF. Shift absorbs the masking.
|
||||
Ref CFShl = _Sub(OpSize, Src, _InlineConstant(1));
|
||||
auto TmpCF = _Lshl(OpSize, CF, CFShl);
|
||||
Res = _Or(OpSize, Res, TmpCF);
|
||||
// Since Shift != 0 we can inject the CF. Shift absorbs the masking.
|
||||
Ref CFShl = _Sub(OpSize, Src, _InlineConstant(1));
|
||||
auto TmpCF = _Lshl(OpSize, CF, CFShl);
|
||||
Res = _Or(OpSize, Res, TmpCF);
|
||||
|
||||
// OF is the top two MSBs XOR'd together
|
||||
// Only when Shift == 1, it is undefined otherwise
|
||||
//
|
||||
// Note that NewCF has garbage in the upper bits, but we ignore them here
|
||||
// and mask as part of the set after.
|
||||
auto NewOF = _XorShift(OpSize, Res, NewCF, ShiftType::LSL, Size - 1);
|
||||
SetRFLAG<FEXCore::X86State::RFLAG_OF_RAW_LOC>(NewOF, Size - 1, true);
|
||||
// OF is the top two MSBs XOR'd together
|
||||
// Only when Shift == 1, it is undefined otherwise
|
||||
//
|
||||
// Note that NewCF has garbage in the upper bits, but we ignore them here
|
||||
// and mask as part of the set after.
|
||||
auto NewOF = _XorShift(OpSize, Res, NewCF, ShiftType::LSL, Size - 1);
|
||||
SetRFLAG<FEXCore::X86State::RFLAG_OF_RAW_LOC>(NewOF, Size - 1, true);
|
||||
|
||||
StoreResult(GPRClass, Op, Res, OpSize::iInvalid);
|
||||
StoreResult(GPRClass, Op, Res, OpSize::iInvalid);
|
||||
},
|
||||
OpSizeFromSrc(Op) == OpSize::i32Bit ? std::make_optional(&OpDispatchBuilder::ZeroShiftResult) : std::nullopt);
|
||||
}
|
||||
@@ -4664,8 +4664,7 @@ void OpDispatchBuilder::CLWBOrTPause(OpcodeArgs) {
|
||||
if (DestIsMem(Op)) {
|
||||
Ref DestMem = MakeSegmentAddress(Op, Op->Dest);
|
||||
_CacheLineClean(DestMem);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (!CTX->HostFeatures.SupportsWFXT) {
|
||||
UnimplementedOp(Op);
|
||||
} else {
|
||||
@@ -4721,8 +4720,7 @@ void OpDispatchBuilder::UMonitorOrCLRSSBSY(OpcodeArgs) {
|
||||
if (DestIsMem(Op) || !CTX->HostFeatures.SupportsWFXT) {
|
||||
// CLRSSBSY
|
||||
UnimplementedOp(Op);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Explicit NOP implementation of umonitor.
|
||||
}
|
||||
}
|
||||
@@ -4730,8 +4728,7 @@ void OpDispatchBuilder::UMonitorOrCLRSSBSY(OpcodeArgs) {
|
||||
void OpDispatchBuilder::UMWaitOp(OpcodeArgs) {
|
||||
if (DestIsMem(Op) || !CTX->HostFeatures.SupportsWFXT) {
|
||||
UnimplementedOp(Op);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Explicit NOP implementation of umwait.
|
||||
// Still zero flags.
|
||||
//
|
||||
|
||||
@@ -42,8 +42,8 @@ constexpr auto OpDispatchTableGenH0F3A = []() consteval {
|
||||
|
||||
auto REX0 = OpDispatchTableGenH0F3AREX.template operator()<0>();
|
||||
auto REX1 = OpDispatchTableGenH0F3AREX.template operator()<1>();
|
||||
auto concat = []<typename T, size_t N1, size_t N2>(std::array<T, N1> const& lhs,
|
||||
std::array<T, N2> const& rhs) consteval -> std::array<T, N1 + N2> {
|
||||
auto concat = []<typename T, size_t N1, size_t N2>(const std::array<T, N1>& lhs,
|
||||
const std::array<T, N2>& rhs) consteval -> std::array<T, N1 + N2> {
|
||||
std::array<T, N1 + N2> Table {};
|
||||
for (size_t i = 0; i < N1; ++i) {
|
||||
Table[i] = lhs[i];
|
||||
|
||||
@@ -2539,8 +2539,7 @@ void OpDispatchBuilder::XSaveOpImpl(OpcodeArgs) {
|
||||
|
||||
// We need to save MXCSR and MXCSR_MASK if either SSE or AVX are requested to be saved
|
||||
{
|
||||
StoreIfFlagSet(
|
||||
1, [this, Op] { SaveMXCSRState(XSaveBase(Op)); }, 2);
|
||||
StoreIfFlagSet(1, [this, Op] { SaveMXCSRState(XSaveBase(Op)); }, 2);
|
||||
}
|
||||
|
||||
// Update XSTATE_BV region of the XSAVE header
|
||||
@@ -2715,13 +2714,11 @@ void OpDispatchBuilder::XRstorOpImpl(OpcodeArgs) {
|
||||
|
||||
// x87
|
||||
{
|
||||
RestoreIfFlagSetOrDefault(
|
||||
0, [this, Op] { RestoreX87State(XSaveBase(Op)); }, [this, Op] { DefaultX87State(Op); });
|
||||
RestoreIfFlagSetOrDefault(0, [this, Op] { RestoreX87State(XSaveBase(Op)); }, [this, Op] { DefaultX87State(Op); });
|
||||
}
|
||||
// SSE
|
||||
{
|
||||
RestoreIfFlagSetOrDefault(
|
||||
1, [this, Op] { RestoreSSEState(XSaveBase(Op)); }, [this] { DefaultSSEState(); });
|
||||
RestoreIfFlagSetOrDefault(1, [this, Op] { RestoreSSEState(XSaveBase(Op)); }, [this] { DefaultSSEState(); });
|
||||
}
|
||||
// AVX
|
||||
if (CTX->HostFeatures.SupportsAVX) {
|
||||
@@ -2734,9 +2731,9 @@ void OpDispatchBuilder::XRstorOpImpl(OpcodeArgs) {
|
||||
RestoreIfFlagSetOrDefault(
|
||||
1,
|
||||
[this, Op] {
|
||||
Ref Base = XSaveBase(Op);
|
||||
Ref MXCSR = _LoadMem(GPRClass, OpSize::i32Bit, Base, _Constant(24), OpSize::i32Bit, MEM_OFFSET_SXTX, 1);
|
||||
RestoreMXCSRState(MXCSR);
|
||||
Ref Base = XSaveBase(Op);
|
||||
Ref MXCSR = _LoadMem(GPRClass, OpSize::i32Bit, Base, _Constant(24), OpSize::i32Bit, MEM_OFFSET_SXTX, 1);
|
||||
RestoreMXCSRState(MXCSR);
|
||||
},
|
||||
[] { /* Intentionally do nothing*/ }, 2);
|
||||
}
|
||||
|
||||
@@ -54,23 +54,19 @@ struct NodeID final {
|
||||
[[nodiscard]] friend constexpr bool operator==(NodeID, NodeID) noexcept = default;
|
||||
|
||||
[[nodiscard]]
|
||||
friend constexpr bool
|
||||
operator<(NodeID lhs, NodeID rhs) noexcept {
|
||||
friend constexpr bool operator<(NodeID lhs, NodeID rhs) noexcept {
|
||||
return lhs.Value < rhs.Value;
|
||||
}
|
||||
[[nodiscard]]
|
||||
friend constexpr bool
|
||||
operator>(NodeID lhs, NodeID rhs) noexcept {
|
||||
friend constexpr bool operator>(NodeID lhs, NodeID rhs) noexcept {
|
||||
return operator<(rhs, lhs);
|
||||
}
|
||||
[[nodiscard]]
|
||||
friend constexpr bool
|
||||
operator<=(NodeID lhs, NodeID rhs) noexcept {
|
||||
friend constexpr bool operator<=(NodeID lhs, NodeID rhs) noexcept {
|
||||
return !operator>(lhs, rhs);
|
||||
}
|
||||
[[nodiscard]]
|
||||
friend constexpr bool
|
||||
operator>=(NodeID lhs, NodeID rhs) noexcept {
|
||||
friend constexpr bool operator>=(NodeID lhs, NodeID rhs) noexcept {
|
||||
return !operator<(lhs, rhs);
|
||||
}
|
||||
|
||||
@@ -183,8 +179,7 @@ struct FEX_PACKED NodeWrapperBase final {
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
friend constexpr bool
|
||||
operator==(const NodeWrapperBase<Type>&, const NodeWrapperBase<Type>&) = default;
|
||||
friend constexpr bool operator==(const NodeWrapperBase<Type>&, const NodeWrapperBase<Type>&) = default;
|
||||
|
||||
[[nodiscard]]
|
||||
static NodeWrapperBase<Type> FromImmediate(uint32_t Immediate) {
|
||||
@@ -423,8 +418,7 @@ struct FEX_PACKED RegisterClassType final {
|
||||
return Val;
|
||||
}
|
||||
[[nodiscard]]
|
||||
friend constexpr bool
|
||||
operator==(const RegisterClassType&, const RegisterClassType&) = default;
|
||||
friend constexpr bool operator==(const RegisterClassType&, const RegisterClassType&) = default;
|
||||
};
|
||||
|
||||
struct FEX_PACKED CondClassType final {
|
||||
@@ -433,8 +427,7 @@ struct FEX_PACKED CondClassType final {
|
||||
return Val;
|
||||
}
|
||||
[[nodiscard]]
|
||||
friend constexpr bool
|
||||
operator==(const CondClassType&, const CondClassType&) = default;
|
||||
friend constexpr bool operator==(const CondClassType&, const CondClassType&) = default;
|
||||
};
|
||||
|
||||
struct FEX_PACKED MemOffsetType final {
|
||||
@@ -443,8 +436,7 @@ struct FEX_PACKED MemOffsetType final {
|
||||
return Val;
|
||||
}
|
||||
[[nodiscard]]
|
||||
friend constexpr bool
|
||||
operator==(const MemOffsetType&, const MemOffsetType&) = default;
|
||||
friend constexpr bool operator==(const MemOffsetType&, const MemOffsetType&) = default;
|
||||
};
|
||||
|
||||
struct FEX_PACKED TypeDefinition final {
|
||||
@@ -479,8 +471,7 @@ struct FEX_PACKED TypeDefinition final {
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
friend constexpr bool
|
||||
operator==(const TypeDefinition&, const TypeDefinition&) = default;
|
||||
friend constexpr bool operator==(const TypeDefinition&, const TypeDefinition&) = default;
|
||||
};
|
||||
|
||||
static_assert(std::is_trivially_copyable_v<TypeDefinition>);
|
||||
@@ -493,8 +484,7 @@ struct FEX_PACKED FenceType final {
|
||||
return Val;
|
||||
}
|
||||
[[nodiscard]]
|
||||
friend constexpr bool
|
||||
operator==(const FenceType&, const FenceType&) = default;
|
||||
friend constexpr bool operator==(const FenceType&, const FenceType&) = default;
|
||||
};
|
||||
|
||||
struct FEX_PACKED RoundType final {
|
||||
@@ -503,8 +493,7 @@ struct FEX_PACKED RoundType final {
|
||||
return Val;
|
||||
}
|
||||
[[nodiscard]]
|
||||
friend constexpr bool
|
||||
operator==(const RoundType&, const RoundType&) = default;
|
||||
friend constexpr bool operator==(const RoundType&, const RoundType&) = default;
|
||||
};
|
||||
|
||||
class NodeIterator;
|
||||
@@ -537,14 +526,12 @@ public:
|
||||
, Node {Ptr} {}
|
||||
|
||||
[[nodiscard]]
|
||||
bool
|
||||
operator==(const NodeIterator& rhs) const {
|
||||
bool operator==(const NodeIterator& rhs) const {
|
||||
return Node.NodeOffset == rhs.Node.NodeOffset;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
bool
|
||||
operator!=(const NodeIterator& rhs) const {
|
||||
bool operator!=(const NodeIterator& rhs) const {
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
@@ -561,15 +548,13 @@ public:
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
value_type
|
||||
operator*() {
|
||||
value_type operator*() {
|
||||
OrderedNode* RealNode = Node.GetNode(BaseList);
|
||||
return {RealNode, RealNode->Op(IRList)};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
value_type
|
||||
operator()() {
|
||||
value_type operator()() {
|
||||
OrderedNode* RealNode = Node.GetNode(BaseList);
|
||||
return {RealNode, RealNode->Op(IRList)};
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ static inline uint64_t GetTime() {
|
||||
#endif
|
||||
|
||||
namespace FEXCore::Profiler {
|
||||
ProfilerBlock::ProfilerBlock(std::string_view const Format)
|
||||
ProfilerBlock::ProfilerBlock(const std::string_view Format)
|
||||
: DurationBegin {GetTime()}
|
||||
, Format {Format} {}
|
||||
|
||||
@@ -92,7 +92,7 @@ void Shutdown() {
|
||||
}
|
||||
}
|
||||
|
||||
void TraceObject(std::string_view const Format, uint64_t Duration) {
|
||||
void TraceObject(const std::string_view Format, uint64_t Duration) {
|
||||
if (TraceFD != -1) {
|
||||
// Print the duration as something that began negative duration ago
|
||||
const auto StringSize = Format.size() + strlen(" (lduration=-)\n") + 22;
|
||||
@@ -102,7 +102,7 @@ void TraceObject(std::string_view const Format, uint64_t Duration) {
|
||||
}
|
||||
}
|
||||
|
||||
void TraceObject(std::string_view const Format) {
|
||||
void TraceObject(const std::string_view Format) {
|
||||
if (TraceFD != -1) {
|
||||
const auto StringSize = Format.size() + 1;
|
||||
auto Event = reinterpret_cast<char*>(alloca(StringSize));
|
||||
@@ -164,9 +164,9 @@ void Shutdown() {
|
||||
}
|
||||
}
|
||||
|
||||
void TraceObject(std::string_view const Format, uint64_t Duration) {}
|
||||
void TraceObject(const std::string_view Format, uint64_t Duration) {}
|
||||
|
||||
void TraceObject(std::string_view const Format) {
|
||||
void TraceObject(const std::string_view Format) {
|
||||
if (Tracy::Enable) {
|
||||
TracyMessage(Format.data(), Format.size());
|
||||
}
|
||||
@@ -212,7 +212,7 @@ void Shutdown() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void TraceObject(std::string_view const Format, uint64_t Duration) {
|
||||
void TraceObject(const std::string_view Format, uint64_t Duration) {
|
||||
#if FEXCORE_PROFILER_BACKEND == FEXCORE_PROFILER_BACKEND_GPUVIS
|
||||
GPUVis::TraceObject(Format, Duration);
|
||||
#elif FEXCORE_PROFILER_BACKEND == FEXCORE_PROFILER_BACKEND_TRACY
|
||||
@@ -220,7 +220,7 @@ void TraceObject(std::string_view const Format, uint64_t Duration) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void TraceObject(std::string_view const Format) {
|
||||
void TraceObject(const std::string_view Format) {
|
||||
#if FEXCORE_PROFILER_BACKEND == FEXCORE_PROFILER_BACKEND_GPUVIS
|
||||
GPUVis::TraceObject(Format);
|
||||
#elif FEXCORE_PROFILER_BACKEND == FEXCORE_PROFILER_BACKEND_TRACY
|
||||
|
||||
@@ -75,7 +75,7 @@ enum class LayerType {
|
||||
};
|
||||
|
||||
template<typename PairTypes, typename ArrayPairType>
|
||||
static inline std::optional<fextl::string> EnumParser(const ArrayPairType& EnumPairs, std::string_view const View) {
|
||||
static inline std::optional<fextl::string> EnumParser(const ArrayPairType& EnumPairs, const std::string_view View) {
|
||||
uint64_t EnumMask {};
|
||||
auto Results = std::from_chars(View.data(), View.data() + View.size(), EnumMask);
|
||||
if (Results.ec == std::errc()) {
|
||||
|
||||
@@ -107,14 +107,12 @@ enum IndexNamedVectorConstant : uint8_t {
|
||||
struct SHA256Sum final {
|
||||
uint8_t data[32];
|
||||
[[nodiscard]]
|
||||
bool
|
||||
operator<(const SHA256Sum& rhs) const {
|
||||
bool operator<(const SHA256Sum& rhs) const {
|
||||
return memcmp(data, rhs.data, sizeof(data)) < 0;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
bool
|
||||
operator==(const SHA256Sum& rhs) const {
|
||||
bool operator==(const SHA256Sum& rhs) const {
|
||||
return memcmp(data, rhs.data, sizeof(data)) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -12,20 +12,17 @@ namespace FEXCore {
|
||||
// boilerplate.
|
||||
#define FEX_DECLARE_ENUM_FLAG_OPERATORS(type) \
|
||||
[[nodiscard]] \
|
||||
constexpr type \
|
||||
operator|(type a, type b) noexcept { \
|
||||
constexpr type operator|(type a, type b) noexcept { \
|
||||
using T = std::underlying_type_t<type>; \
|
||||
return static_cast<type>(static_cast<T>(a) | static_cast<T>(b)); \
|
||||
} \
|
||||
[[nodiscard]] \
|
||||
constexpr type \
|
||||
operator&(type a, type b) noexcept { \
|
||||
constexpr type operator&(type a, type b) noexcept { \
|
||||
using T = std::underlying_type_t<type>; \
|
||||
return static_cast<type>(static_cast<T>(a) & static_cast<T>(b)); \
|
||||
} \
|
||||
[[nodiscard]] \
|
||||
constexpr type \
|
||||
operator^(type a, type b) noexcept { \
|
||||
constexpr type operator^(type a, type b) noexcept { \
|
||||
using T = std::underlying_type_t<type>; \
|
||||
return static_cast<type>(static_cast<T>(a) ^ static_cast<T>(b)); \
|
||||
} \
|
||||
@@ -42,8 +39,7 @@ namespace FEXCore {
|
||||
return a; \
|
||||
} \
|
||||
[[nodiscard]] \
|
||||
constexpr type \
|
||||
operator~(type key) noexcept { \
|
||||
constexpr type operator~(type key) noexcept { \
|
||||
using T = std::underlying_type_t<type>; \
|
||||
return static_cast<type>(~static_cast<T>(key)); \
|
||||
} \
|
||||
|
||||
@@ -82,7 +82,7 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
ssize_t Write(std::string_view const Data) {
|
||||
ssize_t Write(const std::string_view Data) {
|
||||
return Write(Data.data(), Data.size());
|
||||
}
|
||||
|
||||
|
||||
@@ -141,10 +141,10 @@ namespace Msg {
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#define ERROR_AND_DIE_FMT(...) \
|
||||
do { \
|
||||
#define ERROR_AND_DIE_FMT(...) \
|
||||
do { \
|
||||
LogMan::Msg::MFmt(LogMan::ASSERT, __VA_ARGS__); \
|
||||
FEX_TRAP_EXECUTION; \
|
||||
FEX_TRAP_EXECUTION; \
|
||||
} while (0)
|
||||
|
||||
} // namespace Msg
|
||||
|
||||
@@ -81,8 +81,8 @@ FEX_DEFAULT_VISIBILITY void Init(std::string_view ProgramName, std::string_view
|
||||
FEX_DEFAULT_VISIBILITY void PostForkAction(bool IsChild);
|
||||
FEX_DEFAULT_VISIBILITY bool IsActive();
|
||||
FEX_DEFAULT_VISIBILITY void Shutdown();
|
||||
FEX_DEFAULT_VISIBILITY void TraceObject(std::string_view const Format);
|
||||
FEX_DEFAULT_VISIBILITY void TraceObject(std::string_view const Format, uint64_t Duration);
|
||||
FEX_DEFAULT_VISIBILITY void TraceObject(const std::string_view Format);
|
||||
FEX_DEFAULT_VISIBILITY void TraceObject(const std::string_view Format, uint64_t Duration);
|
||||
|
||||
#define UniqueScopeName2(name, line) name##line
|
||||
#define UniqueScopeName(name, line) UniqueScopeName2(name, line)
|
||||
@@ -97,13 +97,13 @@ FEX_DEFAULT_VISIBILITY void TraceObject(std::string_view const Format, uint64_t
|
||||
// A class that follows scoping rules to generate a profile duration block
|
||||
class ProfilerBlock final {
|
||||
public:
|
||||
ProfilerBlock(std::string_view const Format);
|
||||
ProfilerBlock(const std::string_view Format);
|
||||
|
||||
~ProfilerBlock();
|
||||
|
||||
private:
|
||||
uint64_t DurationBegin;
|
||||
std::string_view const Format;
|
||||
const std::string_view Format;
|
||||
};
|
||||
|
||||
// Declare a scoped profile block variable with a fixed name.
|
||||
@@ -148,9 +148,9 @@ static void PostForkAction(bool IsChild) {}
|
||||
[[maybe_unused]]
|
||||
static void Shutdown() {}
|
||||
[[maybe_unused]]
|
||||
static void TraceObject(std::string_view const Format) {}
|
||||
static void TraceObject(const std::string_view Format) {}
|
||||
[[maybe_unused]]
|
||||
static void TraceObject(std::string_view const, uint64_t) {}
|
||||
static void TraceObject(const std::string_view, uint64_t) {}
|
||||
|
||||
#define FEXCORE_PROFILE_INSTANT(...) \
|
||||
do { \
|
||||
|
||||
+13
-13
@@ -257,21 +257,21 @@ struct tcp_acceptor {
|
||||
.revents = 0,
|
||||
},
|
||||
[ServerFD = FD, &Reactor = Reactor, OnAccept = std::move(OnAccept)](error ec) mutable {
|
||||
if (ec != error::success) {
|
||||
return post_callback::drop;
|
||||
}
|
||||
if (ec != error::success) {
|
||||
return post_callback::drop;
|
||||
}
|
||||
|
||||
sockaddr_storage Addr {};
|
||||
socklen_t AddrSize {};
|
||||
int NewFD;
|
||||
do {
|
||||
NewFD = ::accept(ServerFD, reinterpret_cast<sockaddr*>(&Addr), &AddrSize);
|
||||
} while (NewFD < 0 && (errno == EINTR || errno == EAGAIN));
|
||||
if (NewFD < 0) {
|
||||
return OnAccept(error::generic_errno, std::nullopt);
|
||||
}
|
||||
sockaddr_storage Addr {};
|
||||
socklen_t AddrSize {};
|
||||
int NewFD;
|
||||
do {
|
||||
NewFD = ::accept(ServerFD, reinterpret_cast<sockaddr*>(&Addr), &AddrSize);
|
||||
} while (NewFD < 0 && (errno == EINTR || errno == EAGAIN));
|
||||
if (NewFD < 0) {
|
||||
return OnAccept(error::generic_errno, std::nullopt);
|
||||
}
|
||||
|
||||
return OnAccept(error::success, tcp_socket {Reactor, NewFD});
|
||||
return OnAccept(error::success, tcp_socket {Reactor, NewFD});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
|
||||
// Add macros which are missing in some versions of <elf.h>
|
||||
#ifndef ELF32_ST_VISIBILITY
|
||||
#define ELF32_ST_VISIBILITY(o) ((o)&0x3)
|
||||
#define ELF32_ST_VISIBILITY(o) ((o) & 0x3)
|
||||
#endif
|
||||
|
||||
#ifndef ELF64_ST_VISIBILITY
|
||||
#define ELF64_ST_VISIBILITY(o) ((o)&0x3)
|
||||
#define ELF64_ST_VISIBILITY(o) ((o) & 0x3)
|
||||
#endif
|
||||
|
||||
namespace ELFLoader {
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include <sys/random.h>
|
||||
|
||||
#define PAGE_START(x) ((x) & ~(uintptr_t)(4095))
|
||||
#define PAGE_OFFSET(x) ((x)&4095)
|
||||
#define PAGE_OFFSET(x) ((x) & 4095)
|
||||
#define PAGE_ALIGN(x) (((x) + 4095) & ~(uintptr_t)(4095))
|
||||
|
||||
class ELFCodeLoader final : public FEX::CodeLoader {
|
||||
|
||||
@@ -271,7 +271,7 @@ void SetupCompatInput(bool enable) {
|
||||
} // namespace FEX::CompatInput
|
||||
|
||||
namespace FEX::GCS {
|
||||
void CheckForGCS() {
|
||||
void CheckForGCS() {
|
||||
#ifndef PR_GET_SHADOW_STACK_STATUS
|
||||
#define PR_GET_SHADOW_STACK_STATUS 74
|
||||
#endif
|
||||
@@ -281,21 +281,21 @@ namespace FEX::GCS {
|
||||
#ifndef PR_SHADOW_STACK_ENABLE
|
||||
#define PR_SHADOW_STACK_ENABLE (1ULL << 0)
|
||||
#endif
|
||||
uint64_t ShadowStackWord {};
|
||||
if (prctl(PR_GET_SHADOW_STACK_STATUS, &ShadowStackWord, 0, 0, 0) == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Kernel supports shadow stack.
|
||||
if (ShadowStackWord & PR_SHADOW_STACK_ENABLE) {
|
||||
// Welp.
|
||||
ERROR_AND_DIE_FMT("Shadow stack is enabled which FEX is incompatible with!");
|
||||
}
|
||||
|
||||
// Disable if we've gotten this far, to ensure guest can't try.
|
||||
prctl(PR_LOCK_SHADOW_STACK_STATUS, ~0ULL, 0, 0, 0);
|
||||
uint64_t ShadowStackWord {};
|
||||
if (prctl(PR_GET_SHADOW_STACK_STATUS, &ShadowStackWord, 0, 0, 0) == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Kernel supports shadow stack.
|
||||
if (ShadowStackWord & PR_SHADOW_STACK_ENABLE) {
|
||||
// Welp.
|
||||
ERROR_AND_DIE_FMT("Shadow stack is enabled which FEX is incompatible with!");
|
||||
}
|
||||
|
||||
// Disable if we've gotten this far, to ensure guest can't try.
|
||||
prctl(PR_LOCK_SHADOW_STACK_STATUS, ~0ULL, 0, 0, 0);
|
||||
}
|
||||
} // namespace FEX::GCS
|
||||
|
||||
/**
|
||||
* @brief Get an FD from an environment variable and then unset the environment variable.
|
||||
|
||||
@@ -219,14 +219,14 @@ bool InitializeServerSocket(bool abstract) {
|
||||
.revents = 0,
|
||||
},
|
||||
[Socket = std::move(Socket).value()](fasio::error ec) mutable {
|
||||
if (ec != fasio::error::success) {
|
||||
close(Socket.FD);
|
||||
--NumClients;
|
||||
return fasio::post_callback::drop;
|
||||
}
|
||||
HandleSocketData(Socket);
|
||||
// Wait for next data
|
||||
return fasio::post_callback::repeat;
|
||||
if (ec != fasio::error::success) {
|
||||
close(Socket.FD);
|
||||
--NumClients;
|
||||
return fasio::post_callback::drop;
|
||||
}
|
||||
HandleSocketData(Socket);
|
||||
// Wait for next data
|
||||
return fasio::post_callback::repeat;
|
||||
});
|
||||
|
||||
// Wait for next connection
|
||||
|
||||
@@ -99,28 +99,28 @@ GdbServer::GdbServer(FEXCore::Context::Context* ctx, FEX::HLE::SignalDelegator*
|
||||
SignalDelegation->RegisterHostSignalHandler(
|
||||
Signal,
|
||||
[this](FEXCore::Core::InternalThreadState* Thread, int Signal, void* info, void* ucontext) {
|
||||
if (PassSignals[Signal]) {
|
||||
// Pass signal to the guest
|
||||
return false;
|
||||
}
|
||||
if (PassSignals[Signal]) {
|
||||
// Pass signal to the guest
|
||||
return false;
|
||||
}
|
||||
|
||||
auto ThreadObject = FEX::HLE::ThreadManager::GetStateObjectFromFEXCoreThread(Thread);
|
||||
ThreadObject->GdbInfo = {};
|
||||
ThreadObject->GdbInfo->Signal = Signal;
|
||||
auto ThreadObject = FEX::HLE::ThreadManager::GetStateObjectFromFEXCoreThread(Thread);
|
||||
ThreadObject->GdbInfo = {};
|
||||
ThreadObject->GdbInfo->Signal = Signal;
|
||||
|
||||
ThreadObject->GdbInfo->SignalPC = ArchHelpers::Context::GetPc(ucontext);
|
||||
this->SignalDelegation->SpillSRA(Thread, ucontext, Thread->CurrentFrame->InSyscallInfo);
|
||||
ThreadObject->GdbInfo->SignalPC = ArchHelpers::Context::GetPc(ucontext);
|
||||
this->SignalDelegation->SpillSRA(Thread, ucontext, Thread->CurrentFrame->InSyscallInfo);
|
||||
|
||||
memcpy(ThreadObject->GdbInfo->GPRs, ArchHelpers::Context::GetArmGPRs(ucontext), sizeof(ThreadObject->GdbInfo->GPRs));
|
||||
ThreadObject->GdbInfo->PState = ArchHelpers::Context::GetArmPState(ucontext);
|
||||
memcpy(ThreadObject->GdbInfo->GPRs, ArchHelpers::Context::GetArmGPRs(ucontext), sizeof(ThreadObject->GdbInfo->GPRs));
|
||||
ThreadObject->GdbInfo->PState = ArchHelpers::Context::GetArmPState(ucontext);
|
||||
|
||||
// Let GDB know that we have a signal
|
||||
this->Break(Thread, Signal);
|
||||
// Let GDB know that we have a signal
|
||||
this->Break(Thread, Signal);
|
||||
|
||||
WaitForThreadWakeup();
|
||||
ThreadObject->GdbInfo.reset();
|
||||
WaitForThreadWakeup();
|
||||
ThreadObject->GdbInfo.reset();
|
||||
|
||||
return true;
|
||||
return true;
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ void* MemAllocator32Bit::Mmap(void* addr, size_t length, int prot, int flags, in
|
||||
auto AllocateNoHint = [&]() -> void* {
|
||||
bool Wrapped = false;
|
||||
uint64_t BottomPage = Map32Bit && (LastScanLocation >= LastKeyLocation32Bit) ? LastKeyLocation32Bit : LastScanLocation;
|
||||
restart : {
|
||||
restart: {
|
||||
// Linear range scan
|
||||
uint64_t LowerPage = (this->*FindPageRangePtr)(BottomPage, PagesLength);
|
||||
if (LowerPage == 0) {
|
||||
@@ -452,7 +452,7 @@ uint64_t MemAllocator32Bit::Shmat(int shmid, const void* shmaddr, int shmflg, ui
|
||||
|
||||
bool Wrapped = false;
|
||||
uint64_t BottomPage = LastScanLocation;
|
||||
restart : {
|
||||
restart: {
|
||||
// Linear range scan
|
||||
uint64_t LowerPage = (this->*FindPageRangePtr)(BottomPage, PagesLength);
|
||||
if (LowerPage == 0) {
|
||||
|
||||
@@ -14,7 +14,7 @@ $end_info$
|
||||
namespace FEX::HLE {
|
||||
void SeccompEmulator::DumpProgram(const sock_fprog* prog) {
|
||||
auto Parse_Class_LD = [](uint32_t BPFIP, const sock_filter* Inst) {
|
||||
auto DestName = [](sock_filter const* Inst) {
|
||||
auto DestName = [](const sock_filter* Inst) {
|
||||
if (BPF_CLASS(Inst->code) == BPF_LD) {
|
||||
return "A";
|
||||
} else {
|
||||
@@ -22,7 +22,7 @@ void SeccompEmulator::DumpProgram(const sock_fprog* prog) {
|
||||
}
|
||||
};
|
||||
|
||||
auto AccessSize = [](sock_filter const* Inst) {
|
||||
auto AccessSize = [](const sock_filter* Inst) {
|
||||
switch (BPF_SIZE(Inst->code)) {
|
||||
case BPF_W: return 32;
|
||||
case BPF_H: return 16;
|
||||
@@ -32,7 +32,7 @@ void SeccompEmulator::DumpProgram(const sock_fprog* prog) {
|
||||
return 0;
|
||||
};
|
||||
|
||||
auto ModeType = [](sock_filter const* Inst) {
|
||||
auto ModeType = [](const sock_filter* Inst) {
|
||||
switch (BPF_MODE(Inst->code)) {
|
||||
case BPF_IMM: return "IMM";
|
||||
case BPF_ABS: return "ABS";
|
||||
@@ -44,7 +44,7 @@ void SeccompEmulator::DumpProgram(const sock_fprog* prog) {
|
||||
return "Unknown";
|
||||
};
|
||||
|
||||
auto LoadName = [](sock_filter const* Inst) {
|
||||
auto LoadName = [](const sock_filter* Inst) {
|
||||
using namespace std::string_view_literals;
|
||||
switch (BPF_MODE(Inst->code)) {
|
||||
case BPF_IMM: return fextl::fmt::format("#{}", Inst->k);
|
||||
@@ -61,7 +61,7 @@ void SeccompEmulator::DumpProgram(const sock_fprog* prog) {
|
||||
};
|
||||
|
||||
auto Parse_Class_ST = [](uint32_t BPFIP, const sock_filter* Inst) {
|
||||
auto DestName = [](sock_filter const* Inst) {
|
||||
auto DestName = [](const sock_filter* Inst) {
|
||||
if (BPF_CLASS(Inst->code) == BPF_ST) {
|
||||
return "A";
|
||||
} else {
|
||||
@@ -73,7 +73,7 @@ void SeccompEmulator::DumpProgram(const sock_fprog* prog) {
|
||||
};
|
||||
|
||||
auto Parse_Class_ALU = [](uint32_t BPFIP, const sock_filter* Inst) {
|
||||
auto GetOp = [](sock_filter const* Inst) {
|
||||
auto GetOp = [](const sock_filter* Inst) {
|
||||
const auto Op = BPF_OP(Inst->code);
|
||||
|
||||
switch (Op) {
|
||||
@@ -92,7 +92,7 @@ void SeccompEmulator::DumpProgram(const sock_fprog* prog) {
|
||||
}
|
||||
};
|
||||
|
||||
auto GetSrc = [](sock_filter const* Inst) {
|
||||
auto GetSrc = [](const sock_filter* Inst) {
|
||||
switch (BPF_SRC(Inst->code)) {
|
||||
case BPF_K: return fextl::fmt::format("0x{:x}", Inst->k);
|
||||
case BPF_X: return fextl::fmt::format("<X>");
|
||||
@@ -104,7 +104,7 @@ void SeccompEmulator::DumpProgram(const sock_fprog* prog) {
|
||||
};
|
||||
|
||||
auto Parse_Class_JMP = [](uint32_t BPFIP, const sock_filter* Inst) {
|
||||
auto GetOp = [](sock_filter const* Inst) {
|
||||
auto GetOp = [](const sock_filter* Inst) {
|
||||
switch (BPF_OP(Inst->code)) {
|
||||
case BPF_JA: return "a";
|
||||
case BPF_JEQ: return "eq";
|
||||
@@ -115,7 +115,7 @@ void SeccompEmulator::DumpProgram(const sock_fprog* prog) {
|
||||
return "Unknown";
|
||||
};
|
||||
|
||||
auto GetSrc = [](sock_filter const* Inst) {
|
||||
auto GetSrc = [](const sock_filter* Inst) {
|
||||
switch (BPF_SRC(Inst->code)) {
|
||||
case BPF_K: return fextl::fmt::format("0x{:x}", Inst->k);
|
||||
case BPF_X: return fextl::fmt::format("<X>");
|
||||
@@ -128,7 +128,7 @@ void SeccompEmulator::DumpProgram(const sock_fprog* prog) {
|
||||
};
|
||||
|
||||
auto Parse_Class_RET = [](uint32_t BPFIP, const sock_filter* Inst) {
|
||||
auto GetRetValue = [](sock_filter const* Inst) {
|
||||
auto GetRetValue = [](const sock_filter* Inst) {
|
||||
switch (BPF_RVAL(Inst->code)) {
|
||||
case BPF_K: {
|
||||
uint32_t RetData = Inst->k & SECCOMP_RET_DATA;
|
||||
|
||||
@@ -159,7 +159,7 @@ private:
|
||||
}
|
||||
|
||||
FEX_CONFIG_OPT(Is64BitMode, IS64BIT_MODE);
|
||||
fextl::string const ApplicationName;
|
||||
const fextl::string ApplicationName;
|
||||
FEX_CONFIG_OPT(ParanoidTSO, PARANOIDTSO);
|
||||
FEX_CONFIG_OPT(HalfBarrierTSOEnabled, HALFBARRIERTSOENABLED);
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace FEX::HLE::VMATracking {
|
||||
namespace SpecialDev {
|
||||
static constexpr uint64_t Anon = 0x1'0000'0000; // Anonymous shared mapping, id is incrementing allocation number
|
||||
static constexpr uint64_t SHM = 0x2'0000'0000; // sys-v shm, id is shmid
|
||||
}; // namespace SpecialDev
|
||||
}; // namespace SpecialDev
|
||||
|
||||
// Memory Resource ID
|
||||
// An id that can be used to identify when shared mappings actually have the same backing storage
|
||||
|
||||
@@ -121,14 +121,14 @@ void RegisterLongJumpHandler(FEX::HLE::SignalDelegator* Handler) {
|
||||
Handler->RegisterFrontendHostSignalHandler(
|
||||
SIGSEGV,
|
||||
[](FEXCore::Core::InternalThreadState* Thread, int Signal, void* info, void* ucontext) {
|
||||
constexpr uint8_t HLT = 0xF4;
|
||||
if (reinterpret_cast<uint8_t*>(Thread->CurrentFrame->State.rip)[0] != HLT) {
|
||||
DidFault = true;
|
||||
return false;
|
||||
}
|
||||
constexpr uint8_t HLT = 0xF4;
|
||||
if (reinterpret_cast<uint8_t*>(Thread->CurrentFrame->State.rip)[0] != HLT) {
|
||||
DidFault = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
longjmp(LongJumpHandler::LongJump, 1);
|
||||
return false;
|
||||
longjmp(LongJumpHandler::LongJump, 1);
|
||||
return false;
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ size_t wcrtomb(char* __restrict__ _Dest, wchar_t _Source, mbstate_t* __restrict_
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
DLLEXPORT_FUNC(errno_t, wcrtomb_s, (size_t * _Retval, char* _Dst, size_t _SizeInBytes, wchar_t _Ch, mbstate_t* _State)) {
|
||||
DLLEXPORT_FUNC(errno_t, wcrtomb_s, (size_t* _Retval, char* _Dst, size_t _SizeInBytes, wchar_t _Ch, mbstate_t* _State)) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
|
||||
@@ -178,7 +178,7 @@ typedef struct __PEB { /* win32/win64 */
|
||||
#ifdef _WIN64
|
||||
ULONG GdiHandleBuffer[60]; /* /140 */
|
||||
#else
|
||||
ULONG GdiHandleBuffer[34]; /* 0c4/ */
|
||||
ULONG GdiHandleBuffer[34]; /* 0c4/ */
|
||||
#endif
|
||||
PVOID PostProcessInitRoutine; /* 14c/230 */
|
||||
PRTL_BITMAP TlsExpansionBitmap; /* 150/238 */
|
||||
@@ -259,7 +259,7 @@ typedef struct __TEB { /* win32/win64 */
|
||||
#ifdef _WIN64
|
||||
PVOID SystemReserved1[30]; /* /0190 */
|
||||
#else
|
||||
PVOID SystemReserved1[26]; /* 10c/ used for krnl386 private data in Wine */
|
||||
PVOID SystemReserved1[26]; /* 10c/ used for krnl386 private data in Wine */
|
||||
#endif
|
||||
char PlaceholderCompatibilityMode; /* 174/0280 */
|
||||
BOOLEAN PlaceholderHydrationAlwaysExplicit; /* 175/0281 */
|
||||
@@ -309,7 +309,7 @@ typedef struct __TEB { /* win32/win64 */
|
||||
#ifdef _WIN64
|
||||
PVOID Instrumentation[11]; /* /16b8 */
|
||||
#else
|
||||
PVOID Instrumentation[9]; /* f2c/ */
|
||||
PVOID Instrumentation[9]; /* f2c/ */
|
||||
#endif
|
||||
GUID ActivityId; /* f50/1710 */
|
||||
PVOID SubProcessTag; /* f60/1720 */
|
||||
|
||||
@@ -199,8 +199,8 @@ struct __attribute__((packed)) PackedArguments<R, A0, A1, A2, A3, A4, A5, A6, A7
|
||||
template<typename R, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8,
|
||||
typename A9, typename A10, typename A11, typename A12, typename A13, typename A14, typename A15, typename A16, typename A17,
|
||||
typename A18, typename A19, typename A20, typename A21, typename A22>
|
||||
struct __attribute__((packed))
|
||||
PackedArguments<R, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22> {
|
||||
struct __attribute__((
|
||||
packed)) PackedArguments<R, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22> {
|
||||
A0 a0;
|
||||
A1 a1;
|
||||
A2 a2;
|
||||
@@ -230,8 +230,8 @@ PackedArguments<R, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A
|
||||
template<typename R, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8,
|
||||
typename A9, typename A10, typename A11, typename A12, typename A13, typename A14, typename A15, typename A16, typename A17,
|
||||
typename A18, typename A19, typename A20, typename A21, typename A22, typename A23>
|
||||
struct __attribute__((packed))
|
||||
PackedArguments<R, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23> {
|
||||
struct __attribute__((
|
||||
packed)) PackedArguments<R, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23> {
|
||||
A0 a0;
|
||||
A1 a1;
|
||||
A2 a2;
|
||||
|
||||
@@ -479,13 +479,13 @@ void fexfn_impl_libwayland_client_fex_wl_exchange_interface_pointer(guest_layout
|
||||
|
||||
// NOTE: These arrays are complements to global symbols in the guest, so we
|
||||
// never explicitly free this memory
|
||||
guest_interface.data.methods.data = (uintptr_t) new guest_layout<wl_message>[host_interface->method_count];
|
||||
guest_interface.data.methods.data = (uintptr_t)new guest_layout<wl_message>[host_interface->method_count];
|
||||
for (int i = 0; i < host_interface->method_count; ++i) {
|
||||
guest_interface.data.methods.get_pointer()[i] = to_guest(to_host_layout(host_interface->methods[i]));
|
||||
guest_interface.data.methods.get_pointer()[i].data.types = to_guest(to_host_layout(host_interface->methods[i].types));
|
||||
}
|
||||
|
||||
guest_interface.data.events.data = (uintptr_t) new guest_layout<wl_message>[host_interface->event_count];
|
||||
guest_interface.data.events.data = (uintptr_t)new guest_layout<wl_message>[host_interface->event_count];
|
||||
for (int i = 0; i < host_interface->event_count; ++i) {
|
||||
guest_interface.data.events.get_pointer()[i] = to_guest(to_host_layout(host_interface->events[i]));
|
||||
guest_interface.data.events.get_pointer()[i].data.types = to_guest(to_host_layout(host_interface->events[i].types));
|
||||
|
||||
@@ -34,7 +34,9 @@ TEST_CASE("ppoll") {
|
||||
|
||||
SECTION("invalid timespec") {
|
||||
struct pollfd valid_fds {
|
||||
.fd = STDOUT_FILENO, .events = 0, .revents = 0,
|
||||
.fd = STDOUT_FILENO,
|
||||
.events = 0,
|
||||
.revents = 0,
|
||||
};
|
||||
auto ret = ::syscall(SYS_ppoll, &valid_fds, 1, invalid_timespec, nullptr, sizeof(uint64_t));
|
||||
REQUIRE(ret == -1);
|
||||
@@ -43,7 +45,9 @@ TEST_CASE("ppoll") {
|
||||
|
||||
SECTION("invalid sigset") {
|
||||
struct pollfd valid_fds {
|
||||
.fd = STDOUT_FILENO, .events = 0, .revents = 0,
|
||||
.fd = STDOUT_FILENO,
|
||||
.events = 0,
|
||||
.revents = 0,
|
||||
};
|
||||
|
||||
struct timespec valid_ts {};
|
||||
@@ -54,7 +58,9 @@ TEST_CASE("ppoll") {
|
||||
|
||||
SECTION("valid configuration") {
|
||||
struct pollfd valid_fds {
|
||||
.fd = STDOUT_FILENO, .events = 0, .revents = 0,
|
||||
.fd = STDOUT_FILENO,
|
||||
.events = 0,
|
||||
.revents = 0,
|
||||
};
|
||||
|
||||
struct timespec valid_ts {};
|
||||
@@ -66,7 +72,9 @@ TEST_CASE("ppoll") {
|
||||
|
||||
SECTION("invalid timespec write-back") {
|
||||
struct pollfd valid_fds {
|
||||
.fd = STDOUT_FILENO, .events = 0, .revents = 0,
|
||||
.fd = STDOUT_FILENO,
|
||||
.events = 0,
|
||||
.revents = 0,
|
||||
};
|
||||
|
||||
// Kernel will read timespec, but it then can't write the result back.
|
||||
@@ -112,7 +120,9 @@ TEST_CASE("ppoll_64") {
|
||||
|
||||
SECTION("invalid timespec") {
|
||||
struct pollfd valid_fds {
|
||||
.fd = STDOUT_FILENO, .events = 0, .revents = 0,
|
||||
.fd = STDOUT_FILENO,
|
||||
.events = 0,
|
||||
.revents = 0,
|
||||
};
|
||||
auto ret = ::syscall(SYS_ppoll_time64, &valid_fds, 1, invalid_timespec, nullptr, sizeof(uint64_t));
|
||||
REQUIRE(ret == -1);
|
||||
@@ -121,7 +131,9 @@ TEST_CASE("ppoll_64") {
|
||||
|
||||
SECTION("invalid sigset") {
|
||||
struct pollfd valid_fds {
|
||||
.fd = STDOUT_FILENO, .events = 0, .revents = 0,
|
||||
.fd = STDOUT_FILENO,
|
||||
.events = 0,
|
||||
.revents = 0,
|
||||
};
|
||||
|
||||
timespec64 valid_ts {};
|
||||
@@ -132,7 +144,9 @@ TEST_CASE("ppoll_64") {
|
||||
|
||||
SECTION("valid configuration") {
|
||||
struct pollfd valid_fds {
|
||||
.fd = STDOUT_FILENO, .events = 0, .revents = 0,
|
||||
.fd = STDOUT_FILENO,
|
||||
.events = 0,
|
||||
.revents = 0,
|
||||
};
|
||||
|
||||
timespec64 valid_ts {};
|
||||
@@ -144,7 +158,9 @@ TEST_CASE("ppoll_64") {
|
||||
|
||||
SECTION("invalid timespec write-back") {
|
||||
struct pollfd valid_fds {
|
||||
.fd = STDOUT_FILENO, .events = 0, .revents = 0,
|
||||
.fd = STDOUT_FILENO,
|
||||
.events = 0,
|
||||
.revents = 0,
|
||||
};
|
||||
|
||||
// Kernel will read timespec, but it then can't write the result back.
|
||||
|
||||
@@ -434,12 +434,10 @@ TEST_CASE_METHOD(Fixture, "VersionedLibrary") {
|
||||
|
||||
#if CLANG_VERSION_MAJOR >= 17
|
||||
CHECK_THAT(output, matches(callExpr(callee(functionDecl(hasName("dlopen"))), hasArgument(0, stringLiteral().bind("libname"))))
|
||||
.check_binding(
|
||||
"libname", +[](const clang::StringLiteral* lit) { return lit->getString().ends_with(".so.123"); }));
|
||||
.check_binding("libname", +[](const clang::StringLiteral* lit) { return lit->getString().ends_with(".so.123"); }));
|
||||
#else
|
||||
CHECK_THAT(output, matches(callExpr(callee(functionDecl(hasName("dlopen"))), hasArgument(0, stringLiteral().bind("libname"))))
|
||||
.check_binding(
|
||||
"libname", +[](const clang::StringLiteral* lit) { return lit->getString().endswith(".so.123"); }));
|
||||
.check_binding("libname", +[](const clang::StringLiteral* lit) { return lit->getString().endswith(".so.123"); }));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -577,8 +575,7 @@ TEST_CASE_METHOD(Fixture, "LayoutWrappers") {
|
||||
has(fieldDecl(hasName("data"), hasType(hasCanonicalType(asString("struct A")))))));
|
||||
const auto layout_undefined = [](const char* type) {
|
||||
return matches(classTemplateSpecializationDecl(hasName(type), hasAnyTemplateArgument(refersToType(asString("struct A")))).bind("layout"))
|
||||
.check_binding(
|
||||
"layout", +[](const clang::ClassTemplateSpecializationDecl* decl) { return !decl->isCompleteDefinition(); });
|
||||
.check_binding("layout", +[](const clang::ClassTemplateSpecializationDecl* decl) { return !decl->isCompleteDefinition(); });
|
||||
};
|
||||
const auto guest_converter_defined = matches(functionDecl(
|
||||
hasName("to_guest"),
|
||||
|
||||
Reference in new issue
Block a user