diff --git a/src/xenia/cpu/backend/a64/a64_backend.cc b/src/xenia/cpu/backend/a64/a64_backend.cc index 211ddc97d..e6ebc045d 100644 --- a/src/xenia/cpu/backend/a64/a64_backend.cc +++ b/src/xenia/cpu/backend/a64/a64_backend.cc @@ -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(); diff --git a/src/xenia/cpu/backend/a64/a64_emitter.cc b/src/xenia/cpu/backend/a64/a64_emitter.cc index 744e2548a..9325e5f3c 100644 --- a/src/xenia/cpu/backend/a64/a64_emitter.cc +++ b/src/xenia/cpu/backend/a64/a64_emitter.cc @@ -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]); diff --git a/src/xenia/cpu/backend/a64/a64_emitter.h b/src/xenia/cpu/backend/a64/a64_emitter.h index d44700847..60641fdba 100644 --- a/src/xenia/cpu/backend/a64/a64_emitter.h +++ b/src/xenia/cpu/backend/a64/a64_emitter.h @@ -137,13 +137,13 @@ class A64Emitter : public oaknut::CodeBlock, public oaknut::CodeGenerator { std::vector* 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