backend/a64: Port hostloc

This commit is contained in:
SachinVin 2019-08-03 10:24:35 +05:30
parent 9ca0155c19
commit be80e558c9
2 changed files with 185 additions and 0 deletions

View File

@ -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<Arm64Gen::ARM64Reg>(static_cast<int>(Arm64Gen::X0) + static_cast<int>(loc));
}
Arm64Gen::ARM64Reg HostLocToFpr(HostLoc loc) {
ASSERT(HostLocIsFPR(loc));
return EncodeRegToQuad(static_cast<Arm64Gen::ARM64Reg>(static_cast<int>(loc) - static_cast<int>(HostLoc::Q0)));
}
} // namespace Dynarmic::BackendX64

164
src/backend/A64/hostloc.h Normal file
View File

@ -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<size_t>(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<HostLoc>(idx);
}
inline HostLoc HostLocFprIdx(int idx) {
ASSERT(idx >= 0 && idx <= 31);
return static_cast<HostLoc>(static_cast<size_t>(HostLoc::Q0) + idx);
}
inline HostLoc HostLocSpill(size_t i) {
return static_cast<HostLoc>(static_cast<size_t>(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<HostLoc>;
// 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 <typename JitStateType>
size_t SpillToOpArg(HostLoc loc) {
ASSERT(HostLocIsSpill(loc));
size_t i = static_cast<size_t>(loc) - static_cast<size_t>(HostLoc::FirstSpill);
ASSERT_MSG(i < JitStateType::SpillCount, "Spill index greater than number of available spill locations");
return JitStateType::GetSpillLocationOffsetFromIndex(i);
}
} // namespace Dynarmic::BackendX64