abi: Implement ABI_PushCallerSaveRegistersAndAdjustStack and ABI_PopCallerSaveRegistersAndAdjustStack
This commit is contained in:
parent
702e181b35
commit
57169ec093
3 changed files with 35 additions and 17 deletions
|
@ -55,15 +55,16 @@ static FrameInfo CalculateFrameInfo(size_t num_gprs, size_t num_xmms, size_t fra
|
||||||
return frame_info;
|
return frame_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABI_PushCalleeSaveRegistersAndAdjustStack(Xbyak::CodeGenerator* code, size_t frame_size) {
|
template<typename RegisterArrayT>
|
||||||
|
void ABI_PushRegistersAndAdjustStack(Xbyak::CodeGenerator* code, size_t frame_size, const RegisterArrayT& regs) {
|
||||||
using namespace Xbyak::util;
|
using namespace Xbyak::util;
|
||||||
|
|
||||||
const size_t num_gprs = std::count_if(ABI_ALL_CALLEE_SAVE.begin(), ABI_ALL_CALLEE_SAVE.end(), HostLocIsGPR);
|
const size_t num_gprs = std::count_if(regs.begin(), regs.end(), HostLocIsGPR);
|
||||||
const size_t num_xmms = std::count_if(ABI_ALL_CALLEE_SAVE.begin(), ABI_ALL_CALLEE_SAVE.end(), HostLocIsXMM);
|
const size_t num_xmms = std::count_if(regs.begin(), regs.end(), HostLocIsXMM);
|
||||||
|
|
||||||
FrameInfo frame_info = CalculateFrameInfo(num_gprs, num_xmms, frame_size);
|
FrameInfo frame_info = CalculateFrameInfo(num_gprs, num_xmms, frame_size);
|
||||||
|
|
||||||
for (HostLoc gpr : ABI_ALL_CALLEE_SAVE) {
|
for (HostLoc gpr : regs) {
|
||||||
if (HostLocIsGPR(gpr)) {
|
if (HostLocIsGPR(gpr)) {
|
||||||
code->push(HostLocToReg64(gpr));
|
code->push(HostLocToReg64(gpr));
|
||||||
}
|
}
|
||||||
|
@ -74,7 +75,7 @@ void ABI_PushCalleeSaveRegistersAndAdjustStack(Xbyak::CodeGenerator* code, size_
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t xmm_offset = frame_info.xmm_offset;
|
size_t xmm_offset = frame_info.xmm_offset;
|
||||||
for (HostLoc xmm : ABI_ALL_CALLEE_SAVE) {
|
for (HostLoc xmm : regs) {
|
||||||
if (HostLocIsXMM(xmm)) {
|
if (HostLocIsXMM(xmm)) {
|
||||||
code->movaps(code->xword[rsp + xmm_offset], HostLocToXmm(xmm));
|
code->movaps(code->xword[rsp + xmm_offset], HostLocToXmm(xmm));
|
||||||
xmm_offset += XMM_SIZE;
|
xmm_offset += XMM_SIZE;
|
||||||
|
@ -82,16 +83,17 @@ void ABI_PushCalleeSaveRegistersAndAdjustStack(Xbyak::CodeGenerator* code, size_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABI_PopCalleeSaveRegistersAndAdjustStack(Xbyak::CodeGenerator* code, size_t frame_size) {
|
template<typename RegisterArrayT>
|
||||||
|
void ABI_PopRegistersAndAdjustStack(Xbyak::CodeGenerator* code, size_t frame_size, const RegisterArrayT& regs) {
|
||||||
using namespace Xbyak::util;
|
using namespace Xbyak::util;
|
||||||
|
|
||||||
const size_t num_gprs = std::count_if(ABI_ALL_CALLEE_SAVE.begin(), ABI_ALL_CALLEE_SAVE.end(), HostLocIsGPR);
|
const size_t num_gprs = std::count_if(regs.begin(), regs.end(), HostLocIsGPR);
|
||||||
const size_t num_xmms = std::count_if(ABI_ALL_CALLEE_SAVE.begin(), ABI_ALL_CALLEE_SAVE.end(), HostLocIsXMM);
|
const size_t num_xmms = std::count_if(regs.begin(), regs.end(), HostLocIsXMM);
|
||||||
|
|
||||||
FrameInfo frame_info = CalculateFrameInfo(num_gprs, num_xmms, frame_size);
|
FrameInfo frame_info = CalculateFrameInfo(num_gprs, num_xmms, frame_size);
|
||||||
|
|
||||||
size_t xmm_offset = frame_info.xmm_offset;
|
size_t xmm_offset = frame_info.xmm_offset;
|
||||||
for (HostLoc xmm : ABI_ALL_CALLEE_SAVE) {
|
for (HostLoc xmm : regs) {
|
||||||
if (HostLocIsXMM(xmm)) {
|
if (HostLocIsXMM(xmm)) {
|
||||||
code->movaps(HostLocToXmm(xmm), code->xword[rsp + xmm_offset]);
|
code->movaps(HostLocToXmm(xmm), code->xword[rsp + xmm_offset]);
|
||||||
xmm_offset += XMM_SIZE;
|
xmm_offset += XMM_SIZE;
|
||||||
|
@ -102,12 +104,28 @@ void ABI_PopCalleeSaveRegistersAndAdjustStack(Xbyak::CodeGenerator* code, size_t
|
||||||
code->add(rsp, u32(frame_info.stack_subtraction));
|
code->add(rsp, u32(frame_info.stack_subtraction));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (HostLoc gpr : Common::Reverse(ABI_ALL_CALLEE_SAVE)) {
|
for (HostLoc gpr : Common::Reverse(regs)) {
|
||||||
if (HostLocIsGPR(gpr)) {
|
if (HostLocIsGPR(gpr)) {
|
||||||
code->pop(HostLocToReg64(gpr));
|
code->pop(HostLocToReg64(gpr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ABI_PushCalleeSaveRegistersAndAdjustStack(Xbyak::CodeGenerator* code, size_t frame_size) {
|
||||||
|
ABI_PushRegistersAndAdjustStack(code, frame_size, ABI_ALL_CALLEE_SAVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABI_PopCalleeSaveRegistersAndAdjustStack(Xbyak::CodeGenerator* code, size_t frame_size) {
|
||||||
|
ABI_PopRegistersAndAdjustStack(code, frame_size, ABI_ALL_CALLEE_SAVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABI_PushCallerSaveRegistersAndAdjustStack(Xbyak::CodeGenerator* code, size_t frame_size) {
|
||||||
|
ABI_PushRegistersAndAdjustStack(code, frame_size, ABI_ALL_CALLER_SAVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABI_PopCallerSaveRegistersAndAdjustStack(Xbyak::CodeGenerator* code, size_t frame_size) {
|
||||||
|
ABI_PopRegistersAndAdjustStack(code, frame_size, ABI_ALL_CALLER_SAVE);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace BackendX64
|
} // namespace BackendX64
|
||||||
} // namespace Dynarmic
|
} // namespace Dynarmic
|
||||||
|
|
|
@ -21,8 +21,7 @@ constexpr HostLoc ABI_PARAM2 = HostLoc::RDX;
|
||||||
constexpr HostLoc ABI_PARAM3 = HostLoc::R8;
|
constexpr HostLoc ABI_PARAM3 = HostLoc::R8;
|
||||||
constexpr HostLoc ABI_PARAM4 = HostLoc::R9;
|
constexpr HostLoc ABI_PARAM4 = HostLoc::R9;
|
||||||
|
|
||||||
constexpr std::array<HostLoc, 13> ABI_ALL_CALLER_SAVE = {
|
constexpr std::array<HostLoc, 12> ABI_ALL_CALLER_SAVE = {
|
||||||
HostLoc::RAX,
|
|
||||||
HostLoc::RCX,
|
HostLoc::RCX,
|
||||||
HostLoc::RDX,
|
HostLoc::RDX,
|
||||||
HostLoc::R8,
|
HostLoc::R8,
|
||||||
|
@ -69,8 +68,7 @@ constexpr HostLoc ABI_PARAM2 = HostLoc::RSI;
|
||||||
constexpr HostLoc ABI_PARAM3 = HostLoc::RDX;
|
constexpr HostLoc ABI_PARAM3 = HostLoc::RDX;
|
||||||
constexpr HostLoc ABI_PARAM4 = HostLoc::RCX;
|
constexpr HostLoc ABI_PARAM4 = HostLoc::RCX;
|
||||||
|
|
||||||
constexpr std::array<HostLoc, 25> ABI_ALL_CALLER_SAVE = {
|
constexpr std::array<HostLoc, 24> ABI_ALL_CALLER_SAVE = {
|
||||||
HostLoc::RAX,
|
|
||||||
HostLoc::RCX,
|
HostLoc::RCX,
|
||||||
HostLoc::RDX,
|
HostLoc::RDX,
|
||||||
HostLoc::RDI,
|
HostLoc::RDI,
|
||||||
|
@ -110,10 +108,12 @@ constexpr size_t ABI_SHADOW_SPACE = 0; // bytes
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static_assert(ABI_ALL_CALLER_SAVE.size() + ABI_ALL_CALLEE_SAVE.size() == 31, "Invalid total number of registers");
|
static_assert(ABI_ALL_CALLER_SAVE.size() + ABI_ALL_CALLEE_SAVE.size() == 30, "Invalid total number of registers");
|
||||||
|
|
||||||
void ABI_PushCalleeSaveRegistersAndAdjustStack(Xbyak::CodeGenerator* code, size_t frame_size = 0);
|
void ABI_PushCalleeSaveRegistersAndAdjustStack(Xbyak::CodeGenerator* code, size_t frame_size = 0);
|
||||||
void ABI_PopCalleeSaveRegistersAndAdjustStack(Xbyak::CodeGenerator* code, size_t frame_size = 0);
|
void ABI_PopCalleeSaveRegistersAndAdjustStack(Xbyak::CodeGenerator* code, size_t frame_size = 0);
|
||||||
|
void ABI_PushCallerSaveRegistersAndAdjustStack(Xbyak::CodeGenerator* code, size_t frame_size = 0);
|
||||||
|
void ABI_PopCallerSaveRegistersAndAdjustStack(Xbyak::CodeGenerator* code, size_t frame_size = 0);
|
||||||
|
|
||||||
} // namespace BackendX64
|
} // namespace BackendX64
|
||||||
} // namespace Dynarmic
|
} // namespace Dynarmic
|
||||||
|
|
|
@ -278,10 +278,10 @@ void RegAlloc::HostCall(IR::Inst* result_def, IR::Value arg0_use, IR::Value arg1
|
||||||
constexpr std::array<HostLoc, args_count> args_hostloc = { ABI_PARAM1, ABI_PARAM2, ABI_PARAM3, ABI_PARAM4 };
|
constexpr std::array<HostLoc, args_count> args_hostloc = { ABI_PARAM1, ABI_PARAM2, ABI_PARAM3, ABI_PARAM4 };
|
||||||
const std::array<IR::Value*, args_count> args = {&arg0_use, &arg1_use, &arg2_use, &arg3_use};
|
const std::array<IR::Value*, args_count> args = {&arg0_use, &arg1_use, &arg2_use, &arg3_use};
|
||||||
|
|
||||||
const static std::vector<HostLoc> other_caller_save = [](){
|
const static std::vector<HostLoc> other_caller_save = [args_hostloc](){
|
||||||
std::vector<HostLoc> ret(ABI_ALL_CALLER_SAVE.begin(), ABI_ALL_CALLER_SAVE.end());
|
std::vector<HostLoc> ret(ABI_ALL_CALLER_SAVE.begin(), ABI_ALL_CALLER_SAVE.end());
|
||||||
|
|
||||||
for (auto hostloc : {ABI_RETURN, ABI_PARAM1, ABI_PARAM2, ABI_PARAM3, ABI_PARAM4})
|
for (auto hostloc : args_hostloc)
|
||||||
ret.erase(std::find(ret.begin(), ret.end(), hostloc));
|
ret.erase(std::find(ret.begin(), ret.end(), hostloc));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Reference in a new issue