diff --git a/src/dynarmic/backend/arm64/abi.cpp b/src/dynarmic/backend/arm64/abi.cpp index 1ea59595..b34f807b 100644 --- a/src/dynarmic/backend/arm64/abi.cpp +++ b/src/dynarmic/backend/arm64/abi.cpp @@ -55,26 +55,22 @@ static FrameInfo CalculateFrameInfo(RegisterList rl, size_t frame_size) { }; } +#define DO_IT(TYPE, REG_TYPE, PAIR_OP, SINGLE_OP, OFFSET) \ + for (size_t i = 0; i < frame_info.TYPE##s.size() - 1; i += 2) { \ + code.PAIR_OP(oaknut::REG_TYPE{frame_info.TYPE##s[i]}, oaknut::REG_TYPE{frame_info.TYPE##s[i + 1]}, SP, (OFFSET) + i * TYPE##_size); \ + } \ + if (frame_info.TYPE##s.size() % 2 == 1) { \ + const size_t i = frame_info.TYPE##s.size() - 1; \ + code.SINGLE_OP(oaknut::REG_TYPE{frame_info.TYPE##s[i]}, SP, (OFFSET) + i * TYPE##_size); \ + } + void ABI_PushRegisters(oaknut::CodeGenerator& code, RegisterList rl, size_t frame_size) { const FrameInfo frame_info = CalculateFrameInfo(rl, frame_size); code.SUB(SP, SP, frame_info.gprs_size + frame_info.fprs_size); - for (size_t i = 0; i < frame_info.gprs.size() - 1; i += 2) { - code.STP(oaknut::XReg{frame_info.gprs[i]}, oaknut::XReg{frame_info.gprs[i + 1]}, SP, i * gpr_size); - } - if (frame_info.gprs.size() % 2 == 1) { - const size_t i = frame_info.gprs.size() - 1; - code.STR(oaknut::XReg{frame_info.gprs[i]}, SP, i * gpr_size); - } - - for (size_t i = 0; i < frame_info.fprs.size() - 1; i += 2) { - code.STP(oaknut::QReg{frame_info.fprs[i]}, oaknut::QReg{frame_info.fprs[i + 1]}, SP, frame_info.gprs_size + i * fpr_size); - } - if (frame_info.fprs.size() % 2 == 1) { - const size_t i = frame_info.fprs.size() - 1; - code.STR(oaknut::QReg{frame_info.fprs[i]}, SP, frame_info.gprs_size + i * fpr_size); - } + DO_IT(gpr, XReg, STP, STR, 0) + DO_IT(fpr, QReg, STP, STR, frame_info.gprs_size) code.SUB(SP, SP, frame_info.frame_size); } @@ -84,21 +80,8 @@ void ABI_PopRegisters(oaknut::CodeGenerator& code, RegisterList rl, size_t frame code.ADD(SP, SP, frame_info.frame_size); - for (size_t i = 0; i < frame_info.gprs.size() - 1; i += 2) { - code.LDP(oaknut::XReg{frame_info.gprs[i]}, oaknut::XReg{frame_info.gprs[i + 1]}, SP, i * gpr_size); - } - if (frame_info.gprs.size() % 2 == 1) { - const size_t i = frame_info.gprs.size() - 1; - code.LDR(oaknut::XReg{frame_info.gprs[i]}, SP, i * gpr_size); - } - - for (size_t i = 0; i < frame_info.fprs.size() - 1; i += 2) { - code.LDP(oaknut::QReg{frame_info.fprs[i]}, oaknut::QReg{frame_info.fprs[i + 1]}, SP, frame_info.gprs_size + i * fpr_size); - } - if (frame_info.fprs.size() % 2 == 1) { - const size_t i = frame_info.fprs.size() - 1; - code.LDR(oaknut::QReg{frame_info.fprs[i]}, SP, frame_info.gprs_size + i * fpr_size); - } + DO_IT(gpr, XReg, LDP, LDR, 0) + DO_IT(fpr, QReg, LDP, LDR, frame_info.gprs_size) code.ADD(SP, SP, frame_info.gprs_size + frame_info.fprs_size); }