summaryrefslogtreecommitdiffstats
path: root/src/common/x64/xbyak_util.h
diff options
context:
space:
mode:
authorYuri Kunde Schlesner <yuriks@yuriks.net>2016-12-12 10:23:08 +0100
committerYuri Kunde Schlesner <yuriks@yuriks.net>2016-12-15 05:06:08 +0100
commitf4e98ecf3f3c144e0db2bc866e3fe5aac39f6ec9 (patch)
tree9cb61994f928e64ca68d07150fc2cb5719fe6457 /src/common/x64/xbyak_util.h
parentExternals: Add Xbyak (diff)
downloadyuzu-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.h49
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