backend/a64: Port ABI functions
This commit is contained in:
parent
ab07872025
commit
a37f9c4cc6
87
src/backend/A64/abi.cpp
Normal file
87
src/backend/A64/abi.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
// Copyright (C) 2003 Dolphin Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// 20th Sep 2018: This code was modified for Dynarmic.
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "backend/A64/abi.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/math_util.h"
|
||||
#include "common/iterator_util.h"
|
||||
|
||||
namespace Dynarmic::BackendA64 {
|
||||
|
||||
template<typename RegisterArrayT>
|
||||
void ABI_PushRegistersAndAdjustStack(BlockOfCode& code, const RegisterArrayT& regs) {
|
||||
u32 gprs = 0 , fprs = 0;
|
||||
|
||||
for (HostLoc reg : regs) {
|
||||
if (HostLocIsGPR(reg)) {
|
||||
gprs |= 0x1 << static_cast<u32>(DecodeReg(HostLocToReg64(reg)));
|
||||
} else if (HostLocIsFPR(reg)) {
|
||||
fprs |= 0x1 << static_cast<u32>(DecodeReg(HostLocToFpr(reg)));
|
||||
}
|
||||
}
|
||||
|
||||
code.fp_emitter.ABI_PushRegisters(fprs);
|
||||
code.ABI_PushRegisters(gprs);
|
||||
}
|
||||
|
||||
template<typename RegisterArrayT>
|
||||
void ABI_PopRegistersAndAdjustStack(BlockOfCode& code, const RegisterArrayT& regs) {
|
||||
u32 gprs = 0, fprs = 0;
|
||||
|
||||
for (HostLoc reg : regs) {
|
||||
if (HostLocIsGPR(reg)) {
|
||||
gprs |= 0x1 << static_cast<u32>(DecodeReg(HostLocToReg64(reg)));
|
||||
} else if (HostLocIsFPR(reg)) {
|
||||
fprs |= 0x1 << static_cast<u32>(DecodeReg(HostLocToFpr(reg)));
|
||||
}
|
||||
}
|
||||
|
||||
code.ABI_PopRegisters(gprs);
|
||||
code.fp_emitter.ABI_PopRegisters(fprs);
|
||||
}
|
||||
|
||||
void ABI_PushCalleeSaveRegistersAndAdjustStack(BlockOfCode& code) {
|
||||
ABI_PushRegistersAndAdjustStack(code, ABI_ALL_CALLEE_SAVE);
|
||||
}
|
||||
|
||||
void ABI_PopCalleeSaveRegistersAndAdjustStack(BlockOfCode& code) {
|
||||
ABI_PopRegistersAndAdjustStack(code, ABI_ALL_CALLEE_SAVE);
|
||||
}
|
||||
|
||||
void ABI_PushCallerSaveRegistersAndAdjustStack(BlockOfCode& code) {
|
||||
ABI_PushRegistersAndAdjustStack(code, ABI_ALL_CALLER_SAVE);
|
||||
}
|
||||
|
||||
void ABI_PopCallerSaveRegistersAndAdjustStack(BlockOfCode& code) {
|
||||
ABI_PopRegistersAndAdjustStack(code, ABI_ALL_CALLER_SAVE);
|
||||
}
|
||||
|
||||
void ABI_PushCallerSaveRegistersAndAdjustStackExcept(BlockOfCode& code, HostLoc exception) {
|
||||
std::vector<HostLoc> regs;
|
||||
std::remove_copy(ABI_ALL_CALLER_SAVE.begin(), ABI_ALL_CALLER_SAVE.end(), std::back_inserter(regs), exception);
|
||||
ABI_PushRegistersAndAdjustStack(code, regs);
|
||||
}
|
||||
|
||||
void ABI_PopCallerSaveRegistersAndAdjustStackExcept(BlockOfCode& code, HostLoc exception) {
|
||||
std::vector<HostLoc> regs;
|
||||
std::remove_copy(ABI_ALL_CALLER_SAVE.begin(), ABI_ALL_CALLER_SAVE.end(), std::back_inserter(regs), exception);
|
||||
ABI_PopRegistersAndAdjustStack(code, regs);
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::BackendX64
|
109
src/backend/A64/abi.h
Normal file
109
src/backend/A64/abi.h
Normal file
@ -0,0 +1,109 @@
|
||||
/* 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 <array>
|
||||
|
||||
#include "backend/A64/block_of_code.h"
|
||||
#include "backend/A64/hostloc.h"
|
||||
|
||||
namespace Dynarmic::BackendA64 {
|
||||
|
||||
constexpr HostLoc ABI_RETURN = HostLoc::X0;
|
||||
|
||||
constexpr HostLoc ABI_PARAM1 = HostLoc::X0;
|
||||
constexpr HostLoc ABI_PARAM2 = HostLoc::X1;
|
||||
constexpr HostLoc ABI_PARAM3 = HostLoc::X2;
|
||||
constexpr HostLoc ABI_PARAM4 = HostLoc::X3;
|
||||
constexpr HostLoc ABI_PARAM5 = HostLoc::X4;
|
||||
constexpr HostLoc ABI_PARAM6 = HostLoc::X5;
|
||||
constexpr HostLoc ABI_PARAM7 = HostLoc::X6;
|
||||
constexpr HostLoc ABI_PARAM8 = HostLoc::X7;
|
||||
|
||||
constexpr std::array<HostLoc, 36> ABI_ALL_CALLER_SAVE = {
|
||||
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::X18,
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
constexpr std::array<HostLoc, 27> ABI_ALL_CALLEE_SAVE = {
|
||||
HostLoc::X19,
|
||||
HostLoc::X20,
|
||||
HostLoc::X21,
|
||||
HostLoc::X22,
|
||||
HostLoc::X23,
|
||||
HostLoc::X24,
|
||||
HostLoc::X25,
|
||||
HostLoc::X26,
|
||||
HostLoc::X27,
|
||||
HostLoc::X28,
|
||||
HostLoc::X29,
|
||||
HostLoc::X30,
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
constexpr size_t ABI_SHADOW_SPACE = 0; // bytes
|
||||
|
||||
static_assert(ABI_ALL_CALLER_SAVE.size() + ABI_ALL_CALLEE_SAVE.size() == 63, "Invalid total number of registers");
|
||||
|
||||
void ABI_PushCalleeSaveRegistersAndAdjustStack(BlockOfCode& code);
|
||||
void ABI_PopCalleeSaveRegistersAndAdjustStack(BlockOfCode& code);
|
||||
void ABI_PushCallerSaveRegistersAndAdjustStack(BlockOfCode& code);
|
||||
void ABI_PopCallerSaveRegistersAndAdjustStack(BlockOfCode& code);
|
||||
|
||||
void ABI_PushCallerSaveRegistersAndAdjustStackExcept(BlockOfCode& code, HostLoc exception);
|
||||
void ABI_PopCallerSaveRegistersAndAdjustStackExcept(BlockOfCode& code, HostLoc exception);
|
||||
|
||||
} // namespace Dynarmic::BackendX64
|
Loading…
x
Reference in New Issue
Block a user