[a64] Reorganize guest register allocation
Share a somewhat similar calling convention as ARM64
This commit is contained in:
parent
0f9769baac
commit
49f9edbfab
|
@ -49,8 +49,17 @@ class A64ThunkEmitter : public A64Emitter {
|
|||
// The following four functions provide save/load functionality for registers.
|
||||
// They assume at least StackLayout::THUNK_STACK_SIZE bytes have been
|
||||
// allocated on the stack.
|
||||
|
||||
// Caller saved:
|
||||
// Dont assume these registers will survive a subroutine call
|
||||
// x0, v0 is not saved/preserved since this is used to return values from
|
||||
// subroutines x1-x15, x30 | d0-d7 and d16-v31
|
||||
void EmitSaveVolatileRegs();
|
||||
void EmitLoadVolatileRegs();
|
||||
|
||||
// Callee saved:
|
||||
// Subroutines must preserve these registers if they intend to use them
|
||||
// x19-x30 | d8-d15
|
||||
void EmitSaveNonvolatileRegs();
|
||||
void EmitLoadNonvolatileRegs();
|
||||
};
|
||||
|
@ -78,7 +87,7 @@ bool A64Backend::Initialize(Processor* processor) {
|
|||
std::strcpy(fprs.name, "v");
|
||||
fprs.types = MachineInfo::RegisterSet::FLOAT_TYPES |
|
||||
MachineInfo::RegisterSet::VEC_TYPES;
|
||||
fprs.count = A64Emitter::XMM_COUNT;
|
||||
fprs.count = A64Emitter::FPR_COUNT;
|
||||
|
||||
code_cache_ = A64CodeCache::Create();
|
||||
Backend::code_cache_ = code_cache_.get();
|
||||
|
|
|
@ -62,12 +62,13 @@ static const size_t kMaxCodeSize = 1_MiB;
|
|||
static const size_t kStashOffset = 32;
|
||||
// static const size_t kStashOffsetHigh = 32 + 32;
|
||||
|
||||
const uint32_t A64Emitter::gpr_reg_map_[A64Emitter::GPR_COUNT] = {
|
||||
1, 10, 11, 12, 13, 14, 15,
|
||||
// Register indices that the HIR is allowed to use for operands
|
||||
const uint8_t A64Emitter::gpr_reg_map_[A64Emitter::GPR_COUNT] = {
|
||||
19, 20, 21, 22, 23, 24, 25, 26,
|
||||
};
|
||||
|
||||
const uint32_t A64Emitter::xmm_reg_map_[A64Emitter::XMM_COUNT] = {
|
||||
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
const uint8_t A64Emitter::fpr_reg_map_[A64Emitter::FPR_COUNT] = {
|
||||
8, 9, 10, 11, 12, 13, 14, 15,
|
||||
};
|
||||
|
||||
A64Emitter::A64Emitter(A64Backend* backend)
|
||||
|
@ -665,8 +666,8 @@ oaknut::XReg A64Emitter::GetNativeParam(uint32_t param) {
|
|||
}
|
||||
|
||||
// Important: If you change these, you must update the thunks in a64_backend.cc!
|
||||
oaknut::XReg A64Emitter::GetContextReg() { return X19; }
|
||||
oaknut::XReg A64Emitter::GetMembaseReg() { return X20; }
|
||||
oaknut::XReg A64Emitter::GetContextReg() { return X27; }
|
||||
oaknut::XReg A64Emitter::GetMembaseReg() { return X28; }
|
||||
|
||||
void A64Emitter::ReloadContext() {
|
||||
// mov(GetContextReg(), qword[rsp + StackLayout::GUEST_CTX_HOME]);
|
||||
|
|
|
@ -137,13 +137,13 @@ class A64Emitter : public oaknut::CodeBlock, public oaknut::CodeGenerator {
|
|||
std::vector<SourceMapEntry>* out_source_map);
|
||||
|
||||
public:
|
||||
// Reserved: XSP, X19, X20
|
||||
// Scratch: X0/X1/X2
|
||||
// Reserved: XSP, X27, X28
|
||||
// Scratch: X1-X15, X30 | V0-v7 and V16-V31
|
||||
// V0-2
|
||||
// Available: X1, X10-r15
|
||||
// Available: X19-X26
|
||||
// V4-V15 (save to get V3)
|
||||
static const int GPR_COUNT = 7;
|
||||
static const int XMM_COUNT = 12;
|
||||
static const size_t GPR_COUNT = 8;
|
||||
static const size_t FPR_COUNT = 8;
|
||||
|
||||
static void SetupReg(const hir::Value* v, oaknut::WReg& r) {
|
||||
const auto idx = gpr_reg_map_[v->reg.index];
|
||||
|
@ -154,15 +154,15 @@ class A64Emitter : public oaknut::CodeBlock, public oaknut::CodeGenerator {
|
|||
r = oaknut::XReg(idx);
|
||||
}
|
||||
static void SetupReg(const hir::Value* v, oaknut::SReg& r) {
|
||||
const auto idx = xmm_reg_map_[v->reg.index];
|
||||
const auto idx = fpr_reg_map_[v->reg.index];
|
||||
r = oaknut::SReg(idx);
|
||||
}
|
||||
static void SetupReg(const hir::Value* v, oaknut::DReg& r) {
|
||||
const auto idx = xmm_reg_map_[v->reg.index];
|
||||
const auto idx = fpr_reg_map_[v->reg.index];
|
||||
r = oaknut::DReg(idx);
|
||||
}
|
||||
static void SetupReg(const hir::Value* v, oaknut::QReg& r) {
|
||||
const auto idx = xmm_reg_map_[v->reg.index];
|
||||
const auto idx = fpr_reg_map_[v->reg.index];
|
||||
r = oaknut::QReg(idx);
|
||||
}
|
||||
|
||||
|
@ -247,8 +247,8 @@ class A64Emitter : public oaknut::CodeBlock, public oaknut::CodeGenerator {
|
|||
|
||||
size_t stack_size_ = 0;
|
||||
|
||||
static const uint32_t gpr_reg_map_[GPR_COUNT];
|
||||
static const uint32_t xmm_reg_map_[XMM_COUNT];
|
||||
static const uint8_t gpr_reg_map_[GPR_COUNT];
|
||||
static const uint8_t fpr_reg_map_[FPR_COUNT];
|
||||
};
|
||||
|
||||
} // namespace a64
|
||||
|
|
Loading…
Reference in New Issue