From f4e98ecf3f3c144e0db2bc866e3fe5aac39f6ec9 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Mon, 12 Dec 2016 01:23:08 -0800 Subject: VideoCore: Convert x64 shader JIT to use Xbyak for assembly --- src/common/x64/xbyak_util.h | 49 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/common/x64/xbyak_util.h (limited to 'src/common/x64/xbyak_util.h') 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 +#include +#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(code.getCurr()), target); +} + +template +inline void CallFarFunction(Xbyak::CodeGenerator& code, const T f) { + static_assert(std::is_pointer(), "Argument must be a (function) pointer."); + size_t addr = reinterpret_cast(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 -- cgit v1.2.3