From 69610e6ee9d1485de726a8c125b3aa22d77aaaa4 Mon Sep 17 00:00:00 2001 From: SachinVin Date: Sat, 3 Aug 2019 10:24:35 +0530 Subject: [PATCH] backend/a64: Port hostloc --- src/backend/A64/hostloc.cpp | 21 +++++ src/backend/A64/hostloc.h | 164 ++++++++++++++++++++++++++++++++++++ 2 files changed, 185 insertions(+) create mode 100644 src/backend/A64/hostloc.cpp create mode 100644 src/backend/A64/hostloc.h diff --git a/src/backend/A64/hostloc.cpp b/src/backend/A64/hostloc.cpp new file mode 100644 index 00000000..8d1094ec --- /dev/null +++ b/src/backend/A64/hostloc.cpp @@ -0,0 +1,21 @@ +/* This file is part of the dynarmic project. + * Copyright (c) 2016 MerryMage + * This software may be used and distributed according to the terms of the GNU + * General Public License version 2 or any later version. + */ + +#include "backend/A64/hostloc.h" + +namespace Dynarmic::BackendA64 { + +Arm64Gen::ARM64Reg HostLocToReg64(HostLoc loc) { + ASSERT(HostLocIsGPR(loc)); + return static_cast(static_cast(Arm64Gen::X0) + static_cast(loc)); +} + +Arm64Gen::ARM64Reg HostLocToFpr(HostLoc loc) { + ASSERT(HostLocIsFPR(loc)); + return EncodeRegToQuad(static_cast(static_cast(loc) - static_cast(HostLoc::Q0))); +} + +} // namespace Dynarmic::BackendX64 diff --git a/src/backend/A64/hostloc.h b/src/backend/A64/hostloc.h new file mode 100644 index 00000000..bf6e87b0 --- /dev/null +++ b/src/backend/A64/hostloc.h @@ -0,0 +1,164 @@ +/* This file is part of the dynarmic project. + * Copyright (c) 2016 MerryMage + * This software may be used and distributed according to the terms of the GNU + * General Public License version 2 or any later version. + */ +#pragma once + +#include "backend/A64/emitter/a64_emitter.h" +#include "common/assert.h" +#include "common/common_types.h" + +namespace Dynarmic::BackendA64 { + +enum class HostLoc { + // Ordering of the registers is intentional. See also: HostLocToA64. + + // 64bit GPR registers + X0, + X1, + X2, + X3, + X4, + X5, + X6, + X7, + X8, + X9, + X10, + X11, + X12, + X13, + X14, + X15, + X16, + X17, + X18, + X19, + X20, + X21, + X22, + X23, + X24, + X25, + X26, + X27, + X28, + X29, + X30, + + SP, // 64bit stack pointer + + // Qword FPR registers + Q0, + Q1, + Q2, + Q3, + Q4, + Q5, + Q6, + Q7, + Q8, + Q9, + Q10, + Q11, + Q12, + Q13, + Q14, + Q15, + Q16, + Q17, + Q18, + Q19, + Q20, + Q21, + Q22, + Q23, + Q24, + Q25, + Q26, + Q27, + Q28, + Q29, + Q30, + Q31, + + FirstSpill, +}; + +constexpr size_t NonSpillHostLocCount = static_cast(HostLoc::FirstSpill); + +inline bool HostLocIsGPR(HostLoc reg) { + return reg >= HostLoc::X0 && reg <= HostLoc::X30; +} + +inline bool HostLocIsFPR(HostLoc reg) { + return reg >= HostLoc::Q0 && reg <= HostLoc::Q31; +} + +inline bool HostLocIsRegister(HostLoc reg) { + return HostLocIsGPR(reg) || HostLocIsFPR(reg); +} + +inline HostLoc HostLocRegIdx(int idx) { + ASSERT(idx >= 0 && idx <= 30); + return static_cast(idx); +} + +inline HostLoc HostLocFprIdx(int idx) { + ASSERT(idx >= 0 && idx <= 31); + return static_cast(static_cast(HostLoc::Q0) + idx); +} + +inline HostLoc HostLocSpill(size_t i) { + return static_cast(static_cast(HostLoc::FirstSpill) + i); +} + +inline bool HostLocIsSpill(HostLoc reg) { + return reg >= HostLoc::FirstSpill; +} + +inline size_t HostLocBitWidth(HostLoc loc) { + if (HostLocIsGPR(loc)) + return 64; + if (HostLocIsFPR(loc)) + return 128; + if (HostLocIsSpill(loc)) + return 128; + UNREACHABLE(); +} + +using HostLocList = std::initializer_list; + + +// X18 may be reserved.(Windows and iOS) +// X28 used for holding the JitState. +// X30 is the link register. +const HostLocList any_gpr = { + HostLoc::X0, HostLoc::X1, HostLoc::X2, HostLoc::X3, HostLoc::X4, HostLoc::X5, HostLoc::X6, HostLoc::X7, + HostLoc::X8, HostLoc::X9, HostLoc::X10, HostLoc::X11, HostLoc::X12, HostLoc::X13, HostLoc::X14, HostLoc::X15, + HostLoc::X16, HostLoc::X17, HostLoc::X19, HostLoc::X20, HostLoc::X21, HostLoc::X22, HostLoc::X23, HostLoc::X24, + HostLoc::X25, HostLoc::X26, HostLoc::X27, // HostLoc::X29, +}; + +const HostLocList any_fpr = { + HostLoc::Q0, HostLoc::Q1, HostLoc::Q2, HostLoc::Q3, HostLoc::Q4, HostLoc::Q5, HostLoc::Q6, HostLoc::Q7, + HostLoc::Q8, HostLoc::Q9, HostLoc::Q10, HostLoc::Q11, HostLoc::Q12, HostLoc::Q13, HostLoc::Q14, HostLoc::Q15, + HostLoc::Q16, HostLoc::Q17, HostLoc::Q18, HostLoc::Q19, HostLoc::Q20, HostLoc::Q21, HostLoc::Q22, HostLoc::Q23, + HostLoc::Q24, HostLoc::Q25, HostLoc::Q26, HostLoc::Q27, HostLoc::Q28, HostLoc::Q29, HostLoc::Q30, HostLoc::Q31, +}; + +Arm64Gen::ARM64Reg HostLocToReg64(HostLoc loc); +Arm64Gen::ARM64Reg HostLocToFpr(HostLoc loc); + +template +size_t SpillToOpArg(HostLoc loc) { + ASSERT(HostLocIsSpill(loc)); + + size_t i = static_cast(loc) - static_cast(HostLoc::FirstSpill); + ASSERT_MSG(i < JitStateType::SpillCount, "Spill index greater than number of available spill locations"); + + return JitStateType::GetSpillLocationOffsetFromIndex(i); +} + +} // namespace Dynarmic::BackendX64