2016-08-24 20:07:08 +01:00
|
|
|
/* 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 <xbyak.h>
|
|
|
|
|
|
|
|
#include "common/assert.h"
|
|
|
|
#include "common/common_types.h"
|
|
|
|
|
|
|
|
namespace Dynarmic {
|
|
|
|
namespace BackendX64 {
|
|
|
|
|
|
|
|
enum class HostLoc {
|
|
|
|
// Ordering of the registers is intentional. See also: HostLocToX64.
|
|
|
|
RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, R8, R9, R10, R11, R12, R13, R14, R15,
|
|
|
|
XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
|
|
|
|
XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15,
|
|
|
|
CF, PF, AF, ZF, SF, OF,
|
|
|
|
FirstSpill,
|
|
|
|
};
|
|
|
|
|
2018-01-04 21:12:02 +00:00
|
|
|
constexpr size_t NonSpillHostLocCount = static_cast<size_t>(HostLoc::FirstSpill);
|
2016-08-24 20:07:08 +01:00
|
|
|
|
|
|
|
inline bool HostLocIsGPR(HostLoc reg) {
|
2016-11-30 18:38:03 +00:00
|
|
|
return reg >= HostLoc::RAX && reg <= HostLoc::R15;
|
2016-08-24 20:07:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
inline bool HostLocIsXMM(HostLoc reg) {
|
|
|
|
return reg >= HostLoc::XMM0 && reg <= HostLoc::XMM15;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool HostLocIsRegister(HostLoc reg) {
|
|
|
|
return HostLocIsGPR(reg) || HostLocIsXMM(reg);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool HostLocIsFlag(HostLoc reg) {
|
|
|
|
return reg >= HostLoc::CF && reg <= HostLoc::OF;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline HostLoc HostLocSpill(size_t i) {
|
2018-01-04 21:12:02 +00:00
|
|
|
return static_cast<HostLoc>(static_cast<size_t>(HostLoc::FirstSpill) + i);
|
2016-08-24 20:07:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
inline bool HostLocIsSpill(HostLoc reg) {
|
2018-01-04 21:12:02 +00:00
|
|
|
return reg >= HostLoc::FirstSpill;
|
2016-08-24 20:07:08 +01:00
|
|
|
}
|
|
|
|
|
2018-01-18 13:00:07 +00:00
|
|
|
inline size_t HostLocBitWidth(HostLoc loc) {
|
|
|
|
if (HostLocIsGPR(loc))
|
|
|
|
return 64;
|
|
|
|
if (HostLocIsXMM(loc))
|
|
|
|
return 128;
|
|
|
|
if (HostLocIsSpill(loc))
|
|
|
|
return 64;
|
|
|
|
if (HostLocIsFlag(loc))
|
|
|
|
return 1;
|
|
|
|
UNREACHABLE();
|
|
|
|
}
|
|
|
|
|
2016-08-24 20:07:08 +01:00
|
|
|
using HostLocList = std::initializer_list<HostLoc>;
|
|
|
|
|
|
|
|
// RSP is preserved for function calls
|
|
|
|
// R15 contains the JitState pointer
|
|
|
|
const HostLocList any_gpr = {
|
|
|
|
HostLoc::RAX,
|
|
|
|
HostLoc::RBX,
|
|
|
|
HostLoc::RCX,
|
|
|
|
HostLoc::RDX,
|
|
|
|
HostLoc::RSI,
|
|
|
|
HostLoc::RDI,
|
|
|
|
HostLoc::RBP,
|
|
|
|
HostLoc::R8,
|
|
|
|
HostLoc::R9,
|
|
|
|
HostLoc::R10,
|
|
|
|
HostLoc::R11,
|
|
|
|
HostLoc::R12,
|
|
|
|
HostLoc::R13,
|
|
|
|
HostLoc::R14,
|
|
|
|
};
|
|
|
|
|
|
|
|
const HostLocList any_xmm = {
|
|
|
|
HostLoc::XMM0,
|
|
|
|
HostLoc::XMM1,
|
|
|
|
HostLoc::XMM2,
|
|
|
|
HostLoc::XMM3,
|
|
|
|
HostLoc::XMM4,
|
|
|
|
HostLoc::XMM5,
|
|
|
|
HostLoc::XMM6,
|
|
|
|
HostLoc::XMM7,
|
|
|
|
HostLoc::XMM8,
|
|
|
|
HostLoc::XMM9,
|
|
|
|
HostLoc::XMM10,
|
|
|
|
HostLoc::XMM11,
|
|
|
|
HostLoc::XMM12,
|
|
|
|
HostLoc::XMM13,
|
|
|
|
HostLoc::XMM14,
|
|
|
|
HostLoc::XMM15,
|
|
|
|
};
|
|
|
|
|
|
|
|
Xbyak::Reg64 HostLocToReg64(HostLoc loc);
|
|
|
|
Xbyak::Xmm HostLocToXmm(HostLoc loc);
|
2018-01-04 21:12:02 +00:00
|
|
|
|
|
|
|
template <typename JitStateType>
|
|
|
|
Xbyak::Address 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::GetSpillLocationFromIndex(i);
|
|
|
|
}
|
2016-08-24 20:07:08 +01:00
|
|
|
|
|
|
|
} // namespace BackendX64
|
|
|
|
} // namespace Dynarmic
|