|
|
|
|
@ -25,12 +25,59 @@ const FrameSlot& GetFrameSlot(const MachineFunction& function,
|
|
|
|
|
return function.GetFrameSlot(operand.GetFrameIndex());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PrintStackAccess(std::ostream& os, const char* mnemonic, PhysReg reg,
|
|
|
|
|
/*void PrintStackAccess(std::ostream& os, const char* mnemonic, PhysReg reg,
|
|
|
|
|
int offset) {
|
|
|
|
|
//os << " " << mnemonic << " " << PhysRegName(reg) << ", [x29, #" << offset
|
|
|
|
|
// << "]\n";
|
|
|
|
|
// 使用 sp 相对寻址
|
|
|
|
|
os << " " << mnemonic << " " << PhysRegName(reg) << ", [sp, #" << offset << "]\n";
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
void PrintStackAccess(std::ostream& os, const char* insn, PhysReg reg, int64_t offset) {
|
|
|
|
|
// 合法范围:-256 到 255
|
|
|
|
|
if (offset >= -256 && offset <= 255) {
|
|
|
|
|
os << " " << insn << " " << PhysRegName(reg) << ", [sp, #" << offset << "]\n";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 大偏移:使用 x16 计算地址
|
|
|
|
|
os << " mov x16, sp"<< "\n";
|
|
|
|
|
|
|
|
|
|
// 处理正偏移
|
|
|
|
|
if (offset >= 0) {
|
|
|
|
|
// AArch64 add immediate 范围 0~4095,超过则需要分解
|
|
|
|
|
if (offset <= 4095) {
|
|
|
|
|
os << " add x16, x16, #" << offset << "\n";
|
|
|
|
|
} else {
|
|
|
|
|
// 简单分解:高部分必须是 4096 的倍数?这里为了通用,分两次加
|
|
|
|
|
// 更严谨的做法是循环,但栈帧一般不超过 8192,两次足够
|
|
|
|
|
int64_t low = offset & 0xFFF; // 低12位
|
|
|
|
|
int64_t high = offset - low;
|
|
|
|
|
if (high > 0) {
|
|
|
|
|
os << " add x16, x16, #" << high << "\n";
|
|
|
|
|
}
|
|
|
|
|
if (low > 0) {
|
|
|
|
|
os << " add x16, x16, #" << low << "\n";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 处理负偏移
|
|
|
|
|
else {
|
|
|
|
|
int64_t abs_offset = -offset;
|
|
|
|
|
if (abs_offset <= 4095) {
|
|
|
|
|
os << " sub x16, x16, #" << abs_offset << "\n";
|
|
|
|
|
} else {
|
|
|
|
|
int64_t low = abs_offset & 0xFFF;
|
|
|
|
|
int64_t high = abs_offset - low;
|
|
|
|
|
if (high > 0) {
|
|
|
|
|
os << " sub x16, x16, #" << high << "\n";
|
|
|
|
|
}
|
|
|
|
|
if (low > 0) {
|
|
|
|
|
os << " sub x16, x16, #" << low << "\n";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 最后使用无偏移的 ldr/str(注意不是 ldur/stur)
|
|
|
|
|
os << " " << insn << " " << PhysRegName(reg) << ", [x16]\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 打印单个操作数
|
|
|
|
|
|