common: Remove dependency on xbyak
Xbyak is currently entirely unused. Rather than carting it along, remove it and get rid of a dependency. If it's ever needed in the future, then it can be re-added (and likely be more up to date at that point in time).
This commit is contained in:
parent
5af4160bf2
commit
3533d33ff5
|
@ -13,9 +13,6 @@
|
||||||
[submodule "dynarmic"]
|
[submodule "dynarmic"]
|
||||||
path = externals/dynarmic
|
path = externals/dynarmic
|
||||||
url = https://github.com/MerryMage/dynarmic.git
|
url = https://github.com/MerryMage/dynarmic.git
|
||||||
[submodule "xbyak"]
|
|
||||||
path = externals/xbyak
|
|
||||||
url = https://github.com/herumi/xbyak.git
|
|
||||||
[submodule "fmt"]
|
[submodule "fmt"]
|
||||||
path = externals/fmt
|
path = externals/fmt
|
||||||
url = https://github.com/fmtlib/fmt.git
|
url = https://github.com/fmtlib/fmt.git
|
||||||
|
|
|
@ -9,7 +9,6 @@ target_include_directories(catch-single-include INTERFACE catch/single_include)
|
||||||
|
|
||||||
# Dynarmic
|
# Dynarmic
|
||||||
if (ARCHITECTURE_x86_64)
|
if (ARCHITECTURE_x86_64)
|
||||||
add_library(xbyak INTERFACE)
|
|
||||||
set(DYNARMIC_TESTS OFF)
|
set(DYNARMIC_TESTS OFF)
|
||||||
set(DYNARMIC_NO_BUNDLED_FMT ON)
|
set(DYNARMIC_NO_BUNDLED_FMT ON)
|
||||||
add_subdirectory(dynarmic)
|
add_subdirectory(dynarmic)
|
||||||
|
@ -53,14 +52,6 @@ target_include_directories(unicorn-headers INTERFACE ./unicorn/include)
|
||||||
# SoundTouch
|
# SoundTouch
|
||||||
add_subdirectory(soundtouch)
|
add_subdirectory(soundtouch)
|
||||||
|
|
||||||
# Xbyak
|
|
||||||
if (ARCHITECTURE_x86_64)
|
|
||||||
# Defined before "dynarmic" above
|
|
||||||
# add_library(xbyak INTERFACE)
|
|
||||||
target_include_directories(xbyak INTERFACE ./xbyak/xbyak)
|
|
||||||
target_compile_definitions(xbyak INTERFACE XBYAK_NO_OP_NAMES)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Opus
|
# Opus
|
||||||
add_subdirectory(opus)
|
add_subdirectory(opus)
|
||||||
target_include_directories(opus INTERFACE ./opus/include)
|
target_include_directories(opus INTERFACE ./opus/include)
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 1de435ed04c8e74775804da944d176baf0ce56e2
|
|
|
@ -95,14 +95,9 @@ if(ARCHITECTURE_x86_64)
|
||||||
PRIVATE
|
PRIVATE
|
||||||
x64/cpu_detect.cpp
|
x64/cpu_detect.cpp
|
||||||
x64/cpu_detect.h
|
x64/cpu_detect.h
|
||||||
x64/xbyak_abi.h
|
|
||||||
x64/xbyak_util.h
|
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
create_target_directory_groups(common)
|
create_target_directory_groups(common)
|
||||||
|
|
||||||
target_link_libraries(common PUBLIC Boost::boost fmt microprofile)
|
target_link_libraries(common PUBLIC Boost::boost fmt microprofile)
|
||||||
if (ARCHITECTURE_x86_64)
|
|
||||||
target_link_libraries(common PRIVATE xbyak)
|
|
||||||
endif()
|
|
||||||
|
|
|
@ -1,222 +0,0 @@
|
||||||
// Copyright 2016 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <initializer_list>
|
|
||||||
#include <xbyak.h>
|
|
||||||
#include "common/assert.h"
|
|
||||||
#include "common/bit_set.h"
|
|
||||||
|
|
||||||
namespace Common::X64 {
|
|
||||||
|
|
||||||
inline int RegToIndex(const Xbyak::Reg& reg) {
|
|
||||||
using Kind = Xbyak::Reg::Kind;
|
|
||||||
ASSERT_MSG((reg.getKind() & (Kind::REG | Kind::XMM)) != 0,
|
|
||||||
"RegSet only support GPRs and XMM registers.");
|
|
||||||
ASSERT_MSG(reg.getIdx() < 16, "RegSet only supports XXM0-15.");
|
|
||||||
return reg.getIdx() + (reg.getKind() == Kind::REG ? 0 : 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Xbyak::Reg64 IndexToReg64(int reg_index) {
|
|
||||||
ASSERT(reg_index < 16);
|
|
||||||
return Xbyak::Reg64(reg_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Xbyak::Xmm IndexToXmm(int reg_index) {
|
|
||||||
ASSERT(reg_index >= 16 && reg_index < 32);
|
|
||||||
return Xbyak::Xmm(reg_index - 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Xbyak::Reg IndexToReg(int reg_index) {
|
|
||||||
if (reg_index < 16) {
|
|
||||||
return IndexToReg64(reg_index);
|
|
||||||
} else {
|
|
||||||
return IndexToXmm(reg_index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline BitSet32 BuildRegSet(std::initializer_list<Xbyak::Reg> regs) {
|
|
||||||
BitSet32 bits;
|
|
||||||
for (const Xbyak::Reg& reg : regs) {
|
|
||||||
bits[RegToIndex(reg)] = true;
|
|
||||||
}
|
|
||||||
return bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
const BitSet32 ABI_ALL_GPRS(0x0000FFFF);
|
|
||||||
const BitSet32 ABI_ALL_XMMS(0xFFFF0000);
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
|
|
||||||
// Microsoft x64 ABI
|
|
||||||
const Xbyak::Reg ABI_RETURN = Xbyak::util::rax;
|
|
||||||
const Xbyak::Reg ABI_PARAM1 = Xbyak::util::rcx;
|
|
||||||
const Xbyak::Reg ABI_PARAM2 = Xbyak::util::rdx;
|
|
||||||
const Xbyak::Reg ABI_PARAM3 = Xbyak::util::r8;
|
|
||||||
const Xbyak::Reg ABI_PARAM4 = Xbyak::util::r9;
|
|
||||||
|
|
||||||
const BitSet32 ABI_ALL_CALLER_SAVED = BuildRegSet({
|
|
||||||
// GPRs
|
|
||||||
Xbyak::util::rcx,
|
|
||||||
Xbyak::util::rdx,
|
|
||||||
Xbyak::util::r8,
|
|
||||||
Xbyak::util::r9,
|
|
||||||
Xbyak::util::r10,
|
|
||||||
Xbyak::util::r11,
|
|
||||||
// XMMs
|
|
||||||
Xbyak::util::xmm0,
|
|
||||||
Xbyak::util::xmm1,
|
|
||||||
Xbyak::util::xmm2,
|
|
||||||
Xbyak::util::xmm3,
|
|
||||||
Xbyak::util::xmm4,
|
|
||||||
Xbyak::util::xmm5,
|
|
||||||
});
|
|
||||||
|
|
||||||
const BitSet32 ABI_ALL_CALLEE_SAVED = BuildRegSet({
|
|
||||||
// GPRs
|
|
||||||
Xbyak::util::rbx,
|
|
||||||
Xbyak::util::rsi,
|
|
||||||
Xbyak::util::rdi,
|
|
||||||
Xbyak::util::rbp,
|
|
||||||
Xbyak::util::r12,
|
|
||||||
Xbyak::util::r13,
|
|
||||||
Xbyak::util::r14,
|
|
||||||
Xbyak::util::r15,
|
|
||||||
// XMMs
|
|
||||||
Xbyak::util::xmm6,
|
|
||||||
Xbyak::util::xmm7,
|
|
||||||
Xbyak::util::xmm8,
|
|
||||||
Xbyak::util::xmm9,
|
|
||||||
Xbyak::util::xmm10,
|
|
||||||
Xbyak::util::xmm11,
|
|
||||||
Xbyak::util::xmm12,
|
|
||||||
Xbyak::util::xmm13,
|
|
||||||
Xbyak::util::xmm14,
|
|
||||||
Xbyak::util::xmm15,
|
|
||||||
});
|
|
||||||
|
|
||||||
constexpr std::size_t ABI_SHADOW_SPACE = 0x20;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// System V x86-64 ABI
|
|
||||||
const Xbyak::Reg ABI_RETURN = Xbyak::util::rax;
|
|
||||||
const Xbyak::Reg ABI_PARAM1 = Xbyak::util::rdi;
|
|
||||||
const Xbyak::Reg ABI_PARAM2 = Xbyak::util::rsi;
|
|
||||||
const Xbyak::Reg ABI_PARAM3 = Xbyak::util::rdx;
|
|
||||||
const Xbyak::Reg ABI_PARAM4 = Xbyak::util::rcx;
|
|
||||||
|
|
||||||
const BitSet32 ABI_ALL_CALLER_SAVED = BuildRegSet({
|
|
||||||
// GPRs
|
|
||||||
Xbyak::util::rcx,
|
|
||||||
Xbyak::util::rdx,
|
|
||||||
Xbyak::util::rdi,
|
|
||||||
Xbyak::util::rsi,
|
|
||||||
Xbyak::util::r8,
|
|
||||||
Xbyak::util::r9,
|
|
||||||
Xbyak::util::r10,
|
|
||||||
Xbyak::util::r11,
|
|
||||||
// XMMs
|
|
||||||
Xbyak::util::xmm0,
|
|
||||||
Xbyak::util::xmm1,
|
|
||||||
Xbyak::util::xmm2,
|
|
||||||
Xbyak::util::xmm3,
|
|
||||||
Xbyak::util::xmm4,
|
|
||||||
Xbyak::util::xmm5,
|
|
||||||
Xbyak::util::xmm6,
|
|
||||||
Xbyak::util::xmm7,
|
|
||||||
Xbyak::util::xmm8,
|
|
||||||
Xbyak::util::xmm9,
|
|
||||||
Xbyak::util::xmm10,
|
|
||||||
Xbyak::util::xmm11,
|
|
||||||
Xbyak::util::xmm12,
|
|
||||||
Xbyak::util::xmm13,
|
|
||||||
Xbyak::util::xmm14,
|
|
||||||
Xbyak::util::xmm15,
|
|
||||||
});
|
|
||||||
|
|
||||||
const BitSet32 ABI_ALL_CALLEE_SAVED = BuildRegSet({
|
|
||||||
// GPRs
|
|
||||||
Xbyak::util::rbx,
|
|
||||||
Xbyak::util::rbp,
|
|
||||||
Xbyak::util::r12,
|
|
||||||
Xbyak::util::r13,
|
|
||||||
Xbyak::util::r14,
|
|
||||||
Xbyak::util::r15,
|
|
||||||
});
|
|
||||||
|
|
||||||
constexpr std::size_t ABI_SHADOW_SPACE = 0;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline void ABI_CalculateFrameSize(BitSet32 regs, std::size_t rsp_alignment,
|
|
||||||
std::size_t needed_frame_size, s32* out_subtraction,
|
|
||||||
s32* out_xmm_offset) {
|
|
||||||
int count = (regs & ABI_ALL_GPRS).Count();
|
|
||||||
rsp_alignment -= count * 8;
|
|
||||||
std::size_t subtraction = 0;
|
|
||||||
int xmm_count = (regs & ABI_ALL_XMMS).Count();
|
|
||||||
if (xmm_count) {
|
|
||||||
// If we have any XMMs to save, we must align the stack here.
|
|
||||||
subtraction = rsp_alignment & 0xF;
|
|
||||||
}
|
|
||||||
subtraction += 0x10 * xmm_count;
|
|
||||||
std::size_t xmm_base_subtraction = subtraction;
|
|
||||||
subtraction += needed_frame_size;
|
|
||||||
subtraction += ABI_SHADOW_SPACE;
|
|
||||||
// Final alignment.
|
|
||||||
rsp_alignment -= subtraction;
|
|
||||||
subtraction += rsp_alignment & 0xF;
|
|
||||||
|
|
||||||
*out_subtraction = (s32)subtraction;
|
|
||||||
*out_xmm_offset = (s32)(subtraction - xmm_base_subtraction);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::size_t ABI_PushRegistersAndAdjustStack(Xbyak::CodeGenerator& code, BitSet32 regs,
|
|
||||||
std::size_t rsp_alignment,
|
|
||||||
std::size_t needed_frame_size = 0) {
|
|
||||||
s32 subtraction, xmm_offset;
|
|
||||||
ABI_CalculateFrameSize(regs, rsp_alignment, needed_frame_size, &subtraction, &xmm_offset);
|
|
||||||
|
|
||||||
for (int reg_index : (regs & ABI_ALL_GPRS)) {
|
|
||||||
code.push(IndexToReg64(reg_index));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (subtraction != 0) {
|
|
||||||
code.sub(code.rsp, subtraction);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int reg_index : (regs & ABI_ALL_XMMS)) {
|
|
||||||
code.movaps(code.xword[code.rsp + xmm_offset], IndexToXmm(reg_index));
|
|
||||||
xmm_offset += 0x10;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ABI_SHADOW_SPACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void ABI_PopRegistersAndAdjustStack(Xbyak::CodeGenerator& code, BitSet32 regs,
|
|
||||||
std::size_t rsp_alignment,
|
|
||||||
std::size_t needed_frame_size = 0) {
|
|
||||||
s32 subtraction, xmm_offset;
|
|
||||||
ABI_CalculateFrameSize(regs, rsp_alignment, needed_frame_size, &subtraction, &xmm_offset);
|
|
||||||
|
|
||||||
for (int reg_index : (regs & ABI_ALL_XMMS)) {
|
|
||||||
code.movaps(IndexToXmm(reg_index), code.xword[code.rsp + xmm_offset]);
|
|
||||||
xmm_offset += 0x10;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (subtraction != 0) {
|
|
||||||
code.add(code.rsp, subtraction);
|
|
||||||
}
|
|
||||||
|
|
||||||
// GPRs need to be popped in reverse order
|
|
||||||
for (int reg_index = 15; reg_index >= 0; reg_index--) {
|
|
||||||
if (regs[reg_index]) {
|
|
||||||
code.pop(IndexToReg64(reg_index));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Common::X64
|
|
|
@ -1,47 +0,0 @@
|
||||||
// Copyright 2016 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <type_traits>
|
|
||||||
#include <xbyak.h>
|
|
||||||
#include "common/x64/xbyak_abi.h"
|
|
||||||
|
|
||||||
namespace Common::X64 {
|
|
||||||
|
|
||||||
// Constants for use with cmpps/cmpss
|
|
||||||
enum {
|
|
||||||
CMP_EQ = 0,
|
|
||||||
CMP_LT = 1,
|
|
||||||
CMP_LE = 2,
|
|
||||||
CMP_UNORD = 3,
|
|
||||||
CMP_NEQ = 4,
|
|
||||||
CMP_NLT = 5,
|
|
||||||
CMP_NLE = 6,
|
|
||||||
CMP_ORD = 7,
|
|
||||||
};
|
|
||||||
|
|
||||||
inline bool IsWithin2G(uintptr_t ref, uintptr_t target) {
|
|
||||||
u64 distance = target - (ref + 5);
|
|
||||||
return !(distance >= 0x8000'0000ULL && distance <= ~0x8000'0000ULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool IsWithin2G(const Xbyak::CodeGenerator& code, uintptr_t target) {
|
|
||||||
return IsWithin2G(reinterpret_cast<uintptr_t>(code.getCurr()), target);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline void CallFarFunction(Xbyak::CodeGenerator& code, const T f) {
|
|
||||||
static_assert(std::is_pointer_v<T>, "Argument must be a (function) pointer.");
|
|
||||||
std::size_t addr = reinterpret_cast<std::size_t>(f);
|
|
||||||
if (IsWithin2G(code, addr)) {
|
|
||||||
code.call(f);
|
|
||||||
} else {
|
|
||||||
// ABI_RETURN is a safe temp register to use before a call
|
|
||||||
code.mov(ABI_RETURN, addr);
|
|
||||||
code.call(ABI_RETURN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Common::X64
|
|
Reference in New Issue