|
|
|
|
@ -15,10 +15,12 @@ namespace mir
|
|
|
|
|
|
|
|
|
|
// ---- AArch64 可分配寄存器 --------------------------------------------
|
|
|
|
|
|
|
|
|
|
// GP 可分配:x8(间接结果)/x9-x12/temp/x15/x16-x17/IP0-IP1/x19-x28/callee-saved
|
|
|
|
|
// x0-x7 参数传递,x13-x14 临时(被排除避免调用冲突),x18 平台,x29-31 保留
|
|
|
|
|
static const int GP_ALLOCATABLE[] = {8, 9, 10, 11, 12, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28};
|
|
|
|
|
static const int K_GP = 18;
|
|
|
|
|
// GP 可分配:x19-x28(callee-saved)。当前限定为 callee-saved
|
|
|
|
|
// 避免跨函数调用时 caller-saved 寄存器被破坏。TODO:后续可加入
|
|
|
|
|
// caller-saved 寄存器(x8-x12,x15-x17)用于不跨调用活跃的 vreg。
|
|
|
|
|
// x0-x7 参数传递,x13-x14/scratch,x18 平台,x29-31 保留。
|
|
|
|
|
static const int GP_ALLOCATABLE[] = {19, 20, 21, 22, 23, 24, 25, 26, 27, 28};
|
|
|
|
|
static const int K_GP = 10;
|
|
|
|
|
|
|
|
|
|
// FP 可分配:s8-s31
|
|
|
|
|
static const int FP_ALLOCATABLE[] = {8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
|
|
|
|
|
@ -323,6 +325,29 @@ namespace mir
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---- 记录 callee-saved 寄存器使用 ----
|
|
|
|
|
// 当前 GP_ALLOCATABLE 全为 callee-saved(x19-x28),遍历已分配的
|
|
|
|
|
// 范围找出实际使用的寄存器,通知 FrameLowering 保存/恢复。
|
|
|
|
|
std::unordered_set<int> used_callee_gp;
|
|
|
|
|
std::unordered_set<int> used_callee_fp;
|
|
|
|
|
for (int vi = 0; vi < num_vregs; ++vi)
|
|
|
|
|
{
|
|
|
|
|
for (const auto &rng : vreg_ranges[vi])
|
|
|
|
|
{
|
|
|
|
|
if (rng.reg_idx < 0)
|
|
|
|
|
continue;
|
|
|
|
|
VRegClass vc = func.GetVRegClass(vi);
|
|
|
|
|
if (vc == VRegClass::Float)
|
|
|
|
|
used_callee_fp.insert(rng.reg_idx);
|
|
|
|
|
else
|
|
|
|
|
used_callee_gp.insert(rng.reg_idx);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (int idx : used_callee_gp)
|
|
|
|
|
func.AddCalleeSavedReg(AllocIdxToPhysReg(idx, VRegClass::Int));
|
|
|
|
|
for (int idx : used_callee_fp)
|
|
|
|
|
func.AddCalleeSavedReg(AllocIdxToPhysReg(idx, VRegClass::Float));
|
|
|
|
|
|
|
|
|
|
// ---- 重写指令 ----------------------------------------------------------
|
|
|
|
|
RewriteWithAllocation(func, vreg_ranges, vreg_to_slot, save_points);
|
|
|
|
|
}
|
|
|
|
|
|