xbyak_util.h 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. // Copyright 2016 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <type_traits>
  6. #include <xbyak.h>
  7. #include "common/x64/xbyak_abi.h"
  8. namespace Common::X64 {
  9. // Constants for use with cmpps/cmpss
  10. enum {
  11. CMP_EQ = 0,
  12. CMP_LT = 1,
  13. CMP_LE = 2,
  14. CMP_UNORD = 3,
  15. CMP_NEQ = 4,
  16. CMP_NLT = 5,
  17. CMP_NLE = 6,
  18. CMP_ORD = 7,
  19. };
  20. constexpr bool IsWithin2G(uintptr_t ref, uintptr_t target) {
  21. const u64 distance = target - (ref + 5);
  22. return !(distance >= 0x8000'0000ULL && distance <= ~0x8000'0000ULL);
  23. }
  24. inline bool IsWithin2G(const Xbyak::CodeGenerator& code, uintptr_t target) {
  25. return IsWithin2G(reinterpret_cast<uintptr_t>(code.getCurr()), target);
  26. }
  27. template <typename T>
  28. inline void CallFarFunction(Xbyak::CodeGenerator& code, const T f) {
  29. static_assert(std::is_pointer_v<T>, "Argument must be a (function) pointer.");
  30. size_t addr = reinterpret_cast<size_t>(f);
  31. if (IsWithin2G(code, addr)) {
  32. code.call(f);
  33. } else {
  34. // ABI_RETURN is a safe temp register to use before a call
  35. code.mov(ABI_RETURN, addr);
  36. code.call(ABI_RETURN);
  37. }
  38. }
  39. } // namespace Common::X64