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) {
|
||||
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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue