arm64/abi: Deduplicate register code
This commit is contained in:
parent
f3bf27c816
commit
77634509b5
1 changed files with 13 additions and 30 deletions
|
@ -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) {
|
void ABI_PushRegisters(oaknut::CodeGenerator& code, RegisterList rl, size_t frame_size) {
|
||||||
const FrameInfo frame_info = CalculateFrameInfo(rl, frame_size);
|
const FrameInfo frame_info = CalculateFrameInfo(rl, frame_size);
|
||||||
|
|
||||||
code.SUB(SP, SP, frame_info.gprs_size + frame_info.fprs_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) {
|
DO_IT(gpr, XReg, STP, STR, 0)
|
||||||
code.STP(oaknut::XReg{frame_info.gprs[i]}, oaknut::XReg{frame_info.gprs[i + 1]}, SP, i * gpr_size);
|
DO_IT(fpr, QReg, STP, STR, frame_info.gprs_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);
|
|
||||||
}
|
|
||||||
|
|
||||||
code.SUB(SP, SP, frame_info.frame_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);
|
code.ADD(SP, SP, frame_info.frame_size);
|
||||||
|
|
||||||
for (size_t i = 0; i < frame_info.gprs.size() - 1; i += 2) {
|
DO_IT(gpr, XReg, LDP, LDR, 0)
|
||||||
code.LDP(oaknut::XReg{frame_info.gprs[i]}, oaknut::XReg{frame_info.gprs[i + 1]}, SP, i * gpr_size);
|
DO_IT(fpr, QReg, LDP, LDR, frame_info.gprs_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);
|
|
||||||
}
|
|
||||||
|
|
||||||
code.ADD(SP, SP, frame_info.gprs_size + frame_info.fprs_size);
|
code.ADD(SP, SP, frame_info.gprs_size + frame_info.fprs_size);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue