Browse Source
common: Remove dependency on xbyak
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).pull/15/merge
6 changed files with 0 additions and 287 deletions
-
3.gitmodules
-
9externals/CMakeLists.txt
-
1externals/xbyak
-
5src/common/CMakeLists.txt
-
222src/common/x64/xbyak_abi.h
-
47src/common/x64/xbyak_util.h
@ -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 |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue