diff --git a/.patch/xbyak/0002-address-frame-ctor.patch b/.patch/xbyak/0002-address-frame-ctor.patch new file mode 100644 index 0000000000..43892c9940 --- /dev/null +++ b/.patch/xbyak/0002-address-frame-ctor.patch @@ -0,0 +1,13 @@ +diff --git a/xbyak/xbyak.h b/xbyak/xbyak.h +index 176ee58..b44d62a 100644 +--- a/xbyak/xbyak.h ++++ b/xbyak/xbyak.h +@@ -1467,8 +1467,6 @@ inline XBYAK_CONSTEXPR bool Operand::hasRex2() const + } + + class AddressFrame { +- void operator=(const AddressFrame&); +- AddressFrame(const AddressFrame&); + public: + const uint32_t bit_; + const bool broadcast_; diff --git a/externals/cpmfile.json b/externals/cpmfile.json index 2cc784cf1f..7f4e552159 100644 --- a/externals/cpmfile.json +++ b/externals/cpmfile.json @@ -61,8 +61,10 @@ "hash": "d93971cc8f17f20818e36099aa862d15d30b60f17c7dff0cc8b7ac89ad6dc6453256dd47a454904666a85cea6ca27f9867f782c7b2c6d0c16039af8e3e28e6cc", "git_version": "7.35.4", "bundled": true, + "skip_updates": true, "patches": [ - "0001-rvalue-optimize.patch" + "0001-rvalue-optimize.patch", + "0002-address-frame-ctor.patch" ] }, "oaknut": { diff --git a/src/dynarmic/src/dynarmic/CMakeLists.txt b/src/dynarmic/src/dynarmic/CMakeLists.txt index c51a660c03..e003380832 100644 --- a/src/dynarmic/src/dynarmic/CMakeLists.txt +++ b/src/dynarmic/src/dynarmic/CMakeLists.txt @@ -367,7 +367,6 @@ if (BOOST_NO_HEADERS) else() target_link_libraries(dynarmic PRIVATE Boost::headers) endif() - if (DYNARMIC_USE_LLVM) target_include_directories(dynarmic PRIVATE ${LLVM_INCLUDE_DIRS}) target_compile_definitions(dynarmic PRIVATE DYNARMIC_USE_LLVM=1 ${LLVM_DEFINITIONS}) @@ -385,4 +384,7 @@ endif() if (CMAKE_SYSTEM_NAME STREQUAL "Windows") target_compile_definitions(dynarmic PRIVATE FMT_USE_WINDOWS_H=0) endif() +if (xbyak_ADDED) + target_compile_definitions(dynarmic PRIVATE XBYAK_BUNDLED=1) +endif() target_compile_definitions(dynarmic PRIVATE FMT_USE_USER_DEFINED_LITERALS=1) diff --git a/src/dynarmic/src/dynarmic/backend/x64/block_of_code.h b/src/dynarmic/src/dynarmic/backend/x64/block_of_code.h index 83b6fe95c4..f347e8723a 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/block_of_code.h +++ b/src/dynarmic/src/dynarmic/backend/x64/block_of_code.h @@ -24,6 +24,7 @@ #include "dynarmic/common/cast_util.h" #include "dynarmic/interface/halt_reason.h" #include "dynarmic/ir/cond.h" +#include "xbyak/xbyak.h" namespace Dynarmic::Backend::X64 { @@ -124,14 +125,26 @@ public: } } - [[nodiscard]] Xbyak::Address Const(const Xbyak::AddressFrame&& frame, u64 lower, u64 upper) { - return constant_pool.GetConstant(std::move(frame), lower, upper); + // Xbyak benefits slightly from not having & references on some of its ctors, however one main + // disadvantage is that this breaks ABI slightly because we need to hijack the main privated ctor, hence + // we define two paths, one for gentoo (non bundled) and one for our custom bundled set with patch +#ifdef XBYAK_BUNDLED + [[nodiscard]] Xbyak::Address Const(const Xbyak::AddressFrame frame, u64 lower, u64 upper = 0) { + return constant_pool.GetConstant(Xbyak::AddressFrame(frame.bit_, frame.broadcast_), lower, upper); } - template [[nodiscard]] Xbyak::Address BConst(const Xbyak::AddressFrame frame, u64 value) { - return Const(std::move(frame), mcl::bit::replicate_element(esize, value), mcl::bit::replicate_element(esize, value)); + return Const(Xbyak::AddressFrame(frame.bit_, frame.broadcast_), mcl::bit::replicate_element(esize, value), mcl::bit::replicate_element(esize, value)); } +#else + [[nodiscard]] Xbyak::Address Const(const Xbyak::AddressFrame& frame, u64 lower, u64 upper = 0) { + return constant_pool.GetConstant(frame, lower, upper); + } + template + [[nodiscard]] Xbyak::Address BConst(const Xbyak::AddressFrame& frame, u64 value) { + return Const(frame, mcl::bit::replicate_element(esize, value), mcl::bit::replicate_element(esize, value)); + } +#endif CodePtr GetCodeBegin() const; size_t GetTotalCodeSize() const; diff --git a/src/dynarmic/src/dynarmic/backend/x64/constant_pool.cpp b/src/dynarmic/src/dynarmic/backend/x64/constant_pool.cpp index 8e9daf63ce..cc802c744c 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/constant_pool.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/constant_pool.cpp @@ -25,7 +25,11 @@ ConstantPool::ConstantPool(BlockOfCode& code, size_t size) reinterpret_cast(code.AllocateFromCodeSpace(size)), size / align_size); } -Xbyak::Address ConstantPool::GetConstant(const Xbyak::AddressFrame&& frame, u64 lower, u64 upper) { +#ifdef XBYAK_BUNDLED +Xbyak::Address ConstantPool::GetConstant(const Xbyak::AddressFrame frame, u64 lower, u64 upper) { +#else +Xbyak::Address ConstantPool::GetConstant(const Xbyak::AddressFrame& frame, u64 lower, u64 upper) { +#endif const auto constant = ConstantT(lower, upper); auto iter = constant_info.find(constant); if (iter == constant_info.end()) { diff --git a/src/dynarmic/src/dynarmic/backend/x64/constant_pool.h b/src/dynarmic/src/dynarmic/backend/x64/constant_pool.h index a5d9105afb..51ac3205d2 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/constant_pool.h +++ b/src/dynarmic/src/dynarmic/backend/x64/constant_pool.h @@ -29,7 +29,11 @@ class ConstantPool final { public: ConstantPool(BlockOfCode& code, size_t size); - Xbyak::Address GetConstant(const Xbyak::AddressFrame&& frame, u64 lower, u64 upper = 0); +#ifdef XBYAK_BUNDLED + Xbyak::Address GetConstant(const Xbyak::AddressFrame frame, u64 lower, u64 upper = 0); +#else + Xbyak::Address GetConstant(const Xbyak::AddressFrame& frame, u64 lower, u64 upper = 0); +#endif private: static constexpr size_t align_size = 16; // bytes diff --git a/src/dynarmic/src/dynarmic/backend/x64/emit_x64_packed.cpp b/src/dynarmic/src/dynarmic/backend/x64/emit_x64_packed.cpp index 7002eb5169..8f9c13b316 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/emit_x64_packed.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/emit_x64_packed.cpp @@ -595,7 +595,8 @@ void EmitX64::EmitPackedHalvingSubAddS16(EmitContext& ctx, IR::Inst* inst) { EmitPackedSubAdd(code, ctx, inst, false, true, true); } -static void EmitPackedOperation(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, void (Xbyak::CodeGenerator::*fn)(const Xbyak::Mmx mmx, const Xbyak::Operand&)) { +template +static void EmitPackedOperation(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, F&& fn) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]); diff --git a/src/dynarmic/src/dynarmic/backend/x64/emit_x64_vector_saturation.cpp b/src/dynarmic/src/dynarmic/backend/x64/emit_x64_vector_saturation.cpp index 71e3535ce7..6cf78576b1 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/emit_x64_vector_saturation.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/emit_x64_vector_saturation.cpp @@ -23,7 +23,8 @@ using namespace Xbyak::util; namespace { -static void EmitVectorSaturatedNative(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, void (Xbyak::CodeGenerator::*saturated_fn)(const Xbyak::Mmx mmx, const Xbyak::Operand&), void (Xbyak::CodeGenerator::*unsaturated_fn)(const Xbyak::Mmx mmx, const Xbyak::Operand&), void (Xbyak::CodeGenerator::*sub_fn)(const Xbyak::Mmx mmx, const Xbyak::Operand&)) { +template +static void EmitVectorSaturatedNative(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, F1&& saturated_fn, F2&& unsaturated_fn, F3&& sub_fn) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); const Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(code, args[0]);