mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-26 19:11:00 +00:00
[cmake] enable clang-cl and WoA builds (#348)
Compilation and CMake fixes for both Windows on ARM and clang-cl, meaning Windows can now be built on both MSVC and clang on both amd64 and aarch64. Compiling on clang is *dramatically* faster so this should be useful for CI. Co-authored-by: crueter <crueter@eden-emu.dev> Co-authored-by: crueter <crueter@crueter.xyz> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/348 Reviewed-by: CamilleLaVey <camillelavey99@gmail.com> Reviewed-by: crueter <crueter@eden-emu.dev> Co-authored-by: lizzie <lizzie@eden-emu.dev> Co-committed-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
@@ -103,7 +103,7 @@ if (MSVC)
|
||||
/WX)
|
||||
endif()
|
||||
|
||||
if (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
|
||||
if (CXX_CLANG)
|
||||
list(APPEND DYNARMIC_CXX_FLAGS
|
||||
-Qunused-arguments
|
||||
-Wno-missing-braces)
|
||||
@@ -131,7 +131,7 @@ else()
|
||||
-Wfatal-errors)
|
||||
endif()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
if (CXX_GCC)
|
||||
# GCC produces bogus -Warray-bounds warnings from xbyak headers for code paths that are not
|
||||
# actually reachable. Specifically, it happens in cases where some code casts an Operand&
|
||||
# to Address& after first checking isMEM(), and that code is inlined in a situation where
|
||||
@@ -141,7 +141,7 @@ else()
|
||||
list(APPEND DYNARMIC_CXX_FLAGS -Wstack-usage=4096)
|
||||
endif()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang")
|
||||
if (CXX_CLANG)
|
||||
# Bracket depth determines maximum size of a fold expression in Clang since 9c9974c3ccb6.
|
||||
# And this in turns limits the size of a std::array.
|
||||
list(APPEND DYNARMIC_CXX_FLAGS -fbracket-depth=1024)
|
||||
|
||||
@@ -277,7 +277,7 @@ void EmitX64::EmitNZCVFromPackedFlags(EmitContext& ctx, IR::Inst* inst) {
|
||||
}
|
||||
|
||||
void EmitX64::EmitAddCycles(size_t cycles) {
|
||||
ASSERT(cycles < std::numeric_limits<s32>::max());
|
||||
ASSERT(cycles < (std::numeric_limits<s32>::max)());
|
||||
code.sub(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)], static_cast<u32>(cycles));
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ void EmitSignedSaturatedOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst)
|
||||
Xbyak::Reg addend = ctx.reg_alloc.UseGpr(args[1]).changeBit(size);
|
||||
Xbyak::Reg overflow = ctx.reg_alloc.ScratchGpr().changeBit(size);
|
||||
|
||||
constexpr u64 int_max = static_cast<u64>(std::numeric_limits<mcl::signed_integer_of_size<size>>::max());
|
||||
constexpr u64 int_max = static_cast<u64>((std::numeric_limits<mcl::signed_integer_of_size<size>>::max)());
|
||||
if constexpr (size < 64) {
|
||||
code.xor_(overflow.cvt32(), overflow.cvt32());
|
||||
code.bt(result.cvt32(), size - 1);
|
||||
@@ -82,7 +82,7 @@ void EmitUnsignedSaturatedOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst
|
||||
Xbyak::Reg op_result = ctx.reg_alloc.UseScratchGpr(args[0]).changeBit(size);
|
||||
Xbyak::Reg addend = ctx.reg_alloc.UseScratchGpr(args[1]).changeBit(size);
|
||||
|
||||
constexpr u64 boundary = op == Op::Add ? std::numeric_limits<mcl::unsigned_integer_of_size<size>>::max() : 0;
|
||||
constexpr u64 boundary = op == Op::Add ? (std::numeric_limits<mcl::unsigned_integer_of_size<size>>::max)() : 0;
|
||||
|
||||
if constexpr (op == Op::Add) {
|
||||
code.add(op_result, addend);
|
||||
|
||||
@@ -548,7 +548,7 @@ void EmitX64::EmitVectorArithmeticShiftRight32(EmitContext& ctx, IR::Inst* inst)
|
||||
void EmitX64::EmitVectorArithmeticShiftRight64(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
const Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]);
|
||||
const u8 shift_amount = std::min(args[1].GetImmediateU8(), u8(63));
|
||||
const u8 shift_amount = (std::min)(args[1].GetImmediateU8(), u8(63));
|
||||
|
||||
if (code.HasHostFeature(HostFeature::AVX512_Ortho)) {
|
||||
code.vpsraq(result, result, shift_amount);
|
||||
@@ -2139,7 +2139,7 @@ void EmitX64::EmitVectorMaxS64(EmitContext& ctx, IR::Inst* inst) {
|
||||
}
|
||||
|
||||
EmitTwoArgumentFallback(code, ctx, inst, [](VectorArray<s64>& result, const VectorArray<s64>& a, const VectorArray<s64>& b) {
|
||||
std::transform(a.begin(), a.end(), b.begin(), result.begin(), [](auto x, auto y) { return std::max(x, y); });
|
||||
std::transform(a.begin(), a.end(), b.begin(), result.begin(), [](auto x, auto y) { return (std::max)(x, y); });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2201,7 +2201,7 @@ void EmitX64::EmitVectorMaxU64(EmitContext& ctx, IR::Inst* inst) {
|
||||
}
|
||||
|
||||
EmitTwoArgumentFallback(code, ctx, inst, [](VectorArray<u64>& result, const VectorArray<u64>& a, const VectorArray<u64>& b) {
|
||||
std::transform(a.begin(), a.end(), b.begin(), result.begin(), [](auto x, auto y) { return std::max(x, y); });
|
||||
std::transform(a.begin(), a.end(), b.begin(), result.begin(), [](auto x, auto y) { return (std::max)(x, y); });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2259,7 +2259,7 @@ void EmitX64::EmitVectorMinS64(EmitContext& ctx, IR::Inst* inst) {
|
||||
}
|
||||
|
||||
EmitTwoArgumentFallback(code, ctx, inst, [](VectorArray<s64>& result, const VectorArray<s64>& a, const VectorArray<s64>& b) {
|
||||
std::transform(a.begin(), a.end(), b.begin(), result.begin(), [](auto x, auto y) { return std::min(x, y); });
|
||||
std::transform(a.begin(), a.end(), b.begin(), result.begin(), [](auto x, auto y) { return (std::min)(x, y); });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2321,7 +2321,7 @@ void EmitX64::EmitVectorMinU64(EmitContext& ctx, IR::Inst* inst) {
|
||||
}
|
||||
|
||||
EmitTwoArgumentFallback(code, ctx, inst, [](VectorArray<u64>& result, const VectorArray<u64>& a, const VectorArray<u64>& b) {
|
||||
std::transform(a.begin(), a.end(), b.begin(), result.begin(), [](auto x, auto y) { return std::min(x, y); });
|
||||
std::transform(a.begin(), a.end(), b.begin(), result.begin(), [](auto x, auto y) { return (std::min)(x, y); });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2837,22 +2837,22 @@ static void LowerPairedOperation(VectorArray<T>& result, const VectorArray<T>& x
|
||||
|
||||
template<typename T>
|
||||
static void PairedMax(VectorArray<T>& result, const VectorArray<T>& x, const VectorArray<T>& y) {
|
||||
PairedOperation(result, x, y, [](auto a, auto b) { return std::max(a, b); });
|
||||
PairedOperation(result, x, y, [](auto a, auto b) { return (std::max)(a, b); });
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void PairedMin(VectorArray<T>& result, const VectorArray<T>& x, const VectorArray<T>& y) {
|
||||
PairedOperation(result, x, y, [](auto a, auto b) { return std::min(a, b); });
|
||||
PairedOperation(result, x, y, [](auto a, auto b) { return (std::min)(a, b); });
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void LowerPairedMax(VectorArray<T>& result, const VectorArray<T>& x, const VectorArray<T>& y) {
|
||||
LowerPairedOperation(result, x, y, [](auto a, auto b) { return std::max(a, b); });
|
||||
LowerPairedOperation(result, x, y, [](auto a, auto b) { return (std::max)(a, b); });
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void LowerPairedMin(VectorArray<T>& result, const VectorArray<T>& x, const VectorArray<T>& y) {
|
||||
LowerPairedOperation(result, x, y, [](auto a, auto b) { return std::min(a, b); });
|
||||
LowerPairedOperation(result, x, y, [](auto a, auto b) { return (std::min)(a, b); });
|
||||
}
|
||||
|
||||
template<typename Function>
|
||||
@@ -4933,7 +4933,7 @@ static bool VectorSignedSaturatedShiftLeft(VectorArray<T>& dst, const VectorArra
|
||||
for (size_t i = 0; i < dst.size(); i++) {
|
||||
const T element = data[i];
|
||||
const T shift = std::clamp<T>(static_cast<T>(mcl::bit::sign_extend<8>(static_cast<U>(shift_values[i] & 0xFF))),
|
||||
-static_cast<T>(bit_size_minus_one), std::numeric_limits<T>::max());
|
||||
-static_cast<T>(bit_size_minus_one), (std::numeric_limits<T>::max)());
|
||||
|
||||
if (element == 0) {
|
||||
dst[i] = 0;
|
||||
@@ -4995,7 +4995,7 @@ static bool VectorSignedSaturatedShiftLeftUnsigned(VectorArray<T>& dst, const Ve
|
||||
const U shifted_test = shifted >> static_cast<U>(shift);
|
||||
|
||||
if (shifted_test != static_cast<U>(element)) {
|
||||
dst[i] = static_cast<T>(std::numeric_limits<U>::max());
|
||||
dst[i] = static_cast<T>((std::numeric_limits<U>::max)());
|
||||
qc_flag = true;
|
||||
} else {
|
||||
dst[i] = shifted;
|
||||
@@ -5845,11 +5845,11 @@ static bool EmitVectorUnsignedSaturatedAccumulateSigned(VectorArray<U>& result,
|
||||
const s64 y = static_cast<s64>(static_cast<std::make_unsigned_t<U>>(rhs[i]));
|
||||
const s64 sum = x + y;
|
||||
|
||||
if (sum > std::numeric_limits<U>::max()) {
|
||||
result[i] = std::numeric_limits<U>::max();
|
||||
if (sum > (std::numeric_limits<U>::max)()) {
|
||||
result[i] = (std::numeric_limits<U>::max)();
|
||||
qc_flag = true;
|
||||
} else if (sum < 0) {
|
||||
result[i] = std::numeric_limits<U>::min();
|
||||
result[i] = (std::numeric_limits<U>::min)();
|
||||
qc_flag = true;
|
||||
} else {
|
||||
result[i] = static_cast<U>(sum);
|
||||
@@ -5947,20 +5947,20 @@ static bool VectorUnsignedSaturatedShiftLeft(VectorArray<T>& dst, const VectorAr
|
||||
for (size_t i = 0; i < dst.size(); i++) {
|
||||
const T element = data[i];
|
||||
const S shift = std::clamp(static_cast<S>(mcl::bit::sign_extend<8>(static_cast<T>(shift_values[i] & 0xFF))),
|
||||
negative_bit_size, std::numeric_limits<S>::max());
|
||||
negative_bit_size, (std::numeric_limits<S>::max)());
|
||||
|
||||
if (element == 0 || shift <= negative_bit_size) {
|
||||
dst[i] = 0;
|
||||
} else if (shift < 0) {
|
||||
dst[i] = static_cast<T>(element >> -shift);
|
||||
} else if (shift >= static_cast<S>(bit_size)) {
|
||||
dst[i] = std::numeric_limits<T>::max();
|
||||
dst[i] = (std::numeric_limits<T>::max)();
|
||||
qc_flag = true;
|
||||
} else {
|
||||
const T shifted = element << shift;
|
||||
|
||||
if ((shifted >> shift) != element) {
|
||||
dst[i] = std::numeric_limits<T>::max();
|
||||
dst[i] = (std::numeric_limits<T>::max)();
|
||||
qc_flag = true;
|
||||
} else {
|
||||
dst[i] = shifted;
|
||||
|
||||
@@ -2116,7 +2116,7 @@ void EmitFPVectorToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
}
|
||||
} else {
|
||||
using FPT = mcl::unsigned_integer_of_size<fsize>; // WORKAROUND: For issue 678 on MSVC
|
||||
constexpr u64 integer_max = static_cast<FPT>(std::numeric_limits<std::conditional_t<unsigned_, FPT, std::make_signed_t<FPT>>>::max());
|
||||
constexpr u64 integer_max = static_cast<FPT>((std::numeric_limits<std::conditional_t<unsigned_, FPT, std::make_signed_t<FPT>>>::max)());
|
||||
|
||||
code.movaps(xmm0, GetVectorOf<fsize, float_upper_limit_signed>(code));
|
||||
FCODE(cmplep)(xmm0, src);
|
||||
|
||||
@@ -85,7 +85,7 @@ void HostLocInfo::ReleaseOne() noexcept {
|
||||
if (current_references == 0)
|
||||
return;
|
||||
|
||||
ASSERT(size_t(accumulated_uses) + 1 < std::numeric_limits<uint16_t>::max());
|
||||
ASSERT(size_t(accumulated_uses) + 1 < (std::numeric_limits<uint16_t>::max)());
|
||||
accumulated_uses++;
|
||||
current_references--;
|
||||
|
||||
@@ -116,7 +116,7 @@ void HostLocInfo::AddValue(IR::Inst* inst) noexcept {
|
||||
values.clear();
|
||||
}
|
||||
values.push_back(inst);
|
||||
ASSERT(size_t(total_uses) + inst->UseCount() < std::numeric_limits<uint16_t>::max());
|
||||
ASSERT(size_t(total_uses) + inst->UseCount() < (std::numeric_limits<uint16_t>::max)());
|
||||
total_uses += inst->UseCount();
|
||||
max_bit_width = std::max<uint8_t>(max_bit_width, GetBitWidth(inst->GetType()));
|
||||
}
|
||||
@@ -400,14 +400,14 @@ void RegAlloc::HostCall(IR::Inst* result_def,
|
||||
}
|
||||
|
||||
void RegAlloc::AllocStackSpace(const size_t stack_space) noexcept {
|
||||
ASSERT(stack_space < size_t(std::numeric_limits<s32>::max()));
|
||||
ASSERT(stack_space < size_t((std::numeric_limits<s32>::max)()));
|
||||
ASSERT(reserved_stack_space == 0);
|
||||
reserved_stack_space = stack_space;
|
||||
code->sub(code->rsp, u32(stack_space));
|
||||
}
|
||||
|
||||
void RegAlloc::ReleaseStackSpace(const size_t stack_space) noexcept {
|
||||
ASSERT(stack_space < size_t(std::numeric_limits<s32>::max()));
|
||||
ASSERT(stack_space < size_t((std::numeric_limits<s32>::max)()));
|
||||
ASSERT(reserved_stack_space == stack_space);
|
||||
reserved_stack_space = 0;
|
||||
code->add(code->rsp, u32(stack_space));
|
||||
|
||||
@@ -52,18 +52,18 @@ public:
|
||||
is_set_last_use = true;
|
||||
}
|
||||
inline void ReadLock() noexcept {
|
||||
ASSERT(size_t(is_being_used_count) + 1 < std::numeric_limits<uint16_t>::max());
|
||||
ASSERT(size_t(is_being_used_count) + 1 < (std::numeric_limits<uint16_t>::max)());
|
||||
ASSERT(!is_scratch);
|
||||
is_being_used_count++;
|
||||
}
|
||||
inline void WriteLock() noexcept {
|
||||
ASSERT(size_t(is_being_used_count) + 1 < std::numeric_limits<uint16_t>::max());
|
||||
ASSERT(size_t(is_being_used_count) + 1 < (std::numeric_limits<uint16_t>::max)());
|
||||
ASSERT(is_being_used_count == 0);
|
||||
is_being_used_count++;
|
||||
is_scratch = true;
|
||||
}
|
||||
inline void AddArgReference() noexcept {
|
||||
ASSERT(size_t(current_references) + 1 < std::numeric_limits<uint16_t>::max());
|
||||
ASSERT(size_t(current_references) + 1 < (std::numeric_limits<uint16_t>::max)());
|
||||
current_references++;
|
||||
ASSERT(accumulated_uses + current_references <= total_uses);
|
||||
}
|
||||
|
||||
@@ -106,6 +106,7 @@ inline size_t RegNumber(ExtReg reg) {
|
||||
}
|
||||
|
||||
ASSERT_MSG(false, "Invalid extended register");
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline Reg operator+(Reg reg, size_t number) {
|
||||
|
||||
Reference in New Issue
Block a user