diff options
author | Yuri Kunde Schlesner <yuriks@yuriks.net> | 2016-12-12 10:23:08 +0100 |
---|---|---|
committer | Yuri Kunde Schlesner <yuriks@yuriks.net> | 2016-12-15 05:06:08 +0100 |
commit | f4e98ecf3f3c144e0db2bc866e3fe5aac39f6ec9 (patch) | |
tree | 9cb61994f928e64ca68d07150fc2cb5719fe6457 /src/common/x64/xbyak_util.h | |
parent | Externals: Add Xbyak (diff) | |
download | yuzu-f4e98ecf3f3c144e0db2bc866e3fe5aac39f6ec9.tar yuzu-f4e98ecf3f3c144e0db2bc866e3fe5aac39f6ec9.tar.gz yuzu-f4e98ecf3f3c144e0db2bc866e3fe5aac39f6ec9.tar.bz2 yuzu-f4e98ecf3f3c144e0db2bc866e3fe5aac39f6ec9.tar.lz yuzu-f4e98ecf3f3c144e0db2bc866e3fe5aac39f6ec9.tar.xz yuzu-f4e98ecf3f3c144e0db2bc866e3fe5aac39f6ec9.tar.zst yuzu-f4e98ecf3f3c144e0db2bc866e3fe5aac39f6ec9.zip |
Diffstat (limited to '')
-rw-r--r-- | src/common/x64/xbyak_util.h | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/common/x64/xbyak_util.h b/src/common/x64/xbyak_util.h new file mode 100644 index 000000000..0f52f704b --- /dev/null +++ b/src/common/x64/xbyak_util.h @@ -0,0 +1,49 @@ +// 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 { +namespace 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<T>(), "Argument must be a (function) pointer."); + size_t addr = reinterpret_cast<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 X64 +} // namespace Common |