|
|
|
|
@ -64,6 +64,10 @@ void PrintOperand(std::ostream& os, const Operand& op) {
|
|
|
|
|
case Operand::Kind::Reg:
|
|
|
|
|
os << PhysRegName(op.GetReg());
|
|
|
|
|
break;
|
|
|
|
|
case Operand::Kind::VReg:
|
|
|
|
|
throw std::runtime_error(
|
|
|
|
|
FormatError("asm", "寄存器分配未完成: 存在虚拟寄存器 #" +
|
|
|
|
|
std::to_string(op.GetVReg())));
|
|
|
|
|
case Operand::Kind::Imm:
|
|
|
|
|
os << "#" << op.GetImm();
|
|
|
|
|
break;
|
|
|
|
|
@ -88,6 +92,57 @@ static bool IsLegalAddSubImm(int64_t imm) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---- 寄存器宽度规范化 ----
|
|
|
|
|
static bool IsWReg(PhysReg reg) {
|
|
|
|
|
return reg >= PhysReg::W0 && reg <= PhysReg::W30;
|
|
|
|
|
}
|
|
|
|
|
static bool IsXReg(PhysReg reg) {
|
|
|
|
|
return reg >= PhysReg::X0 && reg <= PhysReg::X30;
|
|
|
|
|
}
|
|
|
|
|
static bool IsSReg(PhysReg reg) {
|
|
|
|
|
return reg >= PhysReg::S0 && reg <= PhysReg::S31;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Xn → Wn, Wn → Wn, Sn → Sn
|
|
|
|
|
static PhysReg ToW(PhysReg reg) {
|
|
|
|
|
if (IsXReg(reg))
|
|
|
|
|
return static_cast<PhysReg>(
|
|
|
|
|
static_cast<int>(reg) - static_cast<int>(PhysReg::X0) + static_cast<int>(PhysReg::W0));
|
|
|
|
|
return reg;
|
|
|
|
|
}
|
|
|
|
|
// Wn → Xn, Xn → Xn, Sn → Sn
|
|
|
|
|
static PhysReg ToX(PhysReg reg) {
|
|
|
|
|
if (IsWReg(reg))
|
|
|
|
|
return static_cast<PhysReg>(
|
|
|
|
|
static_cast<int>(reg) - static_cast<int>(PhysReg::W0) + static_cast<int>(PhysReg::X0));
|
|
|
|
|
return reg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查一组操作数是否全是同一宽度(W/X/S)
|
|
|
|
|
static bool AllSameRegWidth(const std::vector<Operand>& ops) {
|
|
|
|
|
int kind = -1;
|
|
|
|
|
for (const auto& op : ops) {
|
|
|
|
|
if (op.GetKind() != Operand::Kind::Reg) continue;
|
|
|
|
|
PhysReg r = op.GetReg();
|
|
|
|
|
if (IsWReg(r)) { if (kind == -1) kind = 0; else if (kind != 0) return false; }
|
|
|
|
|
else if (IsXReg(r)) { if (kind == -1) kind = 1; else if (kind != 1) return false; }
|
|
|
|
|
else if (IsSReg(r)) { if (kind == -1) kind = 2; else if (kind != 2) return false; }
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据目的地宽度规范化所有寄存器操作数
|
|
|
|
|
static void NormalizeRegOps(std::vector<Operand>& ops, PhysReg dst) {
|
|
|
|
|
PhysReg base = dst;
|
|
|
|
|
bool wantW = IsWReg(base);
|
|
|
|
|
bool wantX = IsXReg(base);
|
|
|
|
|
for (auto& op : ops) {
|
|
|
|
|
if (op.GetKind() != Operand::Kind::Reg) continue;
|
|
|
|
|
if (wantW) op = Operand::Reg(ToW(op.GetReg()));
|
|
|
|
|
else if (wantX) op = Operand::Reg(ToX(op.GetReg()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 在匿名命名空间添加辅助函数
|
|
|
|
|
static void PrintLoadImm64(std::ostream& os, PhysReg reg, uint64_t imm) {
|
|
|
|
|
// 输出 movz + movk 序列
|
|
|
|
|
@ -148,37 +203,48 @@ void PrintInstruction(std::ostream& os, const MachineInstr& instr,
|
|
|
|
|
os << " mov " << PhysRegName(ops.at(0).GetReg()) << ", #"
|
|
|
|
|
<< ops.at(1).GetImm() << "\n";
|
|
|
|
|
break;
|
|
|
|
|
case Opcode::MovReg:
|
|
|
|
|
os << " mov " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << "\n";
|
|
|
|
|
case Opcode::MovReg:{
|
|
|
|
|
PhysReg dst = ops.at(0).GetReg();
|
|
|
|
|
PhysReg src = ops.at(1).GetReg();
|
|
|
|
|
if (IsSReg(dst) || IsSReg(src)) {
|
|
|
|
|
// 涉及 S 寄存器的 move:使用 fmov
|
|
|
|
|
if (!IsSReg(dst)) dst = ToW(dst); // 确保是 W 寄存器
|
|
|
|
|
if (!IsSReg(src)) src = ToW(src);
|
|
|
|
|
os << " fmov " << PhysRegName(dst) << ", " << PhysRegName(src) << "\n";
|
|
|
|
|
} else {
|
|
|
|
|
// GPR move:规范化宽度
|
|
|
|
|
if (IsWReg(dst) && IsXReg(src)) {
|
|
|
|
|
src = ToW(src);
|
|
|
|
|
} else if (IsXReg(dst) && IsWReg(src)) {
|
|
|
|
|
src = ToX(src);
|
|
|
|
|
}
|
|
|
|
|
os << " mov " << PhysRegName(dst) << ", " << PhysRegName(src) << "\n";
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Opcode::StoreStack: {
|
|
|
|
|
// 检查第二个操作数的类型
|
|
|
|
|
if (ops.size() >= 2 && ops.at(1).GetKind() == Operand::Kind::FrameIndex) {
|
|
|
|
|
// 存储到栈槽
|
|
|
|
|
const auto& slot = GetFrameSlot(function, ops.at(1));
|
|
|
|
|
PrintStackAccess(os, "stur", ops.at(0).GetReg(), slot.offset);
|
|
|
|
|
} else if (ops.size() >= 2 && ops.at(1).GetKind() == Operand::Kind::Reg) {
|
|
|
|
|
// 间接存储:存储到寄存器指向的地址
|
|
|
|
|
// STR W9, [X8]
|
|
|
|
|
// 间接存储:基址必须是 X 寄存器
|
|
|
|
|
PhysReg base = ToX(ops.at(1).GetReg());
|
|
|
|
|
os << " str " << PhysRegName(ops.at(0).GetReg()) << ", ["
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << "]\n";
|
|
|
|
|
<< PhysRegName(base) << "]\n";
|
|
|
|
|
} else {
|
|
|
|
|
throw std::runtime_error("StoreStack: 无效的操作数类型");
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Opcode::LoadStack: {
|
|
|
|
|
// 检查第二个操作数的类型
|
|
|
|
|
if (ops.size() >= 2 && ops.at(1).GetKind() == Operand::Kind::FrameIndex) {
|
|
|
|
|
// 从栈槽加载
|
|
|
|
|
const auto& slot = GetFrameSlot(function, ops.at(1));
|
|
|
|
|
PrintStackAccess(os, "ldur", ops.at(0).GetReg(), slot.offset);
|
|
|
|
|
} else if (ops.size() >= 2 && ops.at(1).GetKind() == Operand::Kind::Reg) {
|
|
|
|
|
// 间接加载:从寄存器指向的地址加载
|
|
|
|
|
// LDR W9, [X8]
|
|
|
|
|
// 间接加载:基址必须是 X 寄存器
|
|
|
|
|
PhysReg base = ToX(ops.at(1).GetReg());
|
|
|
|
|
os << " ldr " << PhysRegName(ops.at(0).GetReg()) << ", ["
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << "]\n";
|
|
|
|
|
<< PhysRegName(base) << "]\n";
|
|
|
|
|
} else {
|
|
|
|
|
throw std::runtime_error("LoadStack: 无效的操作数类型");
|
|
|
|
|
}
|
|
|
|
|
@ -204,115 +270,181 @@ void PrintInstruction(std::ostream& os, const MachineInstr& instr,
|
|
|
|
|
}
|
|
|
|
|
os << "\n";
|
|
|
|
|
break;
|
|
|
|
|
case Opcode::AddRR:
|
|
|
|
|
os << " add " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(2).GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
case Opcode::AddRI:
|
|
|
|
|
os << " add " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ", #"
|
|
|
|
|
<< ops.at(2).GetImm() << "\n";
|
|
|
|
|
break;
|
|
|
|
|
case Opcode::SubRR:
|
|
|
|
|
os << " sub " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(2).GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
case Opcode::SubRI:
|
|
|
|
|
os << " sub " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ", #"
|
|
|
|
|
<< ops.at(2).GetImm() << "\n";
|
|
|
|
|
break;
|
|
|
|
|
case Opcode::MulRR:
|
|
|
|
|
os << " mul " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(2).GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
case Opcode::SDivRR:
|
|
|
|
|
os << " sdiv " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(2).GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
case Opcode::UDivRR:
|
|
|
|
|
os << " udiv " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(2).GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
case Opcode::FAddRR:
|
|
|
|
|
os << " fadd " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(2).GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
case Opcode::FSubRR:
|
|
|
|
|
os << " fsub " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(2).GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
case Opcode::FMulRR:
|
|
|
|
|
os << " fmul " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(2).GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
case Opcode::FDivRR:
|
|
|
|
|
os << " fdiv " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(2).GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
case Opcode::CmpRR:
|
|
|
|
|
os << " cmp " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
case Opcode::CmpRI:
|
|
|
|
|
os << " cmp " << PhysRegName(ops.at(0).GetReg()) << ", #"
|
|
|
|
|
<< ops.at(1).GetImm() << "\n";
|
|
|
|
|
case Opcode::AddRR: {
|
|
|
|
|
std::vector<Operand> nops = ops;
|
|
|
|
|
NormalizeRegOps(nops, nops[0].GetReg());
|
|
|
|
|
os << " add " << PhysRegName(nops[0].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[1].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[2].GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Opcode::AddRI: {
|
|
|
|
|
std::vector<Operand> nops = ops;
|
|
|
|
|
NormalizeRegOps(nops, nops[0].GetReg());
|
|
|
|
|
os << " add " << PhysRegName(nops[0].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[1].GetReg()) << ", #"
|
|
|
|
|
<< nops[2].GetImm() << "\n";
|
|
|
|
|
break;
|
|
|
|
|
case Opcode::FCmpRR:
|
|
|
|
|
os << " fcmp " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << "\n";
|
|
|
|
|
}
|
|
|
|
|
case Opcode::SubRR: {
|
|
|
|
|
std::vector<Operand> nops = ops;
|
|
|
|
|
NormalizeRegOps(nops, nops[0].GetReg());
|
|
|
|
|
os << " sub " << PhysRegName(nops[0].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[1].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[2].GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
case Opcode::SIToFP:
|
|
|
|
|
os << " scvtf " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << "\n";
|
|
|
|
|
}
|
|
|
|
|
case Opcode::SubRI: {
|
|
|
|
|
std::vector<Operand> nops = ops;
|
|
|
|
|
NormalizeRegOps(nops, nops[0].GetReg());
|
|
|
|
|
os << " sub " << PhysRegName(nops[0].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[1].GetReg()) << ", #"
|
|
|
|
|
<< nops[2].GetImm() << "\n";
|
|
|
|
|
break;
|
|
|
|
|
case Opcode::FPToSI:
|
|
|
|
|
os << " fcvtzs " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << "\n";
|
|
|
|
|
}
|
|
|
|
|
case Opcode::MulRR: {
|
|
|
|
|
std::vector<Operand> nops = ops;
|
|
|
|
|
NormalizeRegOps(nops, nops[0].GetReg());
|
|
|
|
|
os << " mul " << PhysRegName(nops[0].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[1].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[2].GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Opcode::SDivRR: {
|
|
|
|
|
std::vector<Operand> nops = ops;
|
|
|
|
|
NormalizeRegOps(nops, nops[0].GetReg());
|
|
|
|
|
os << " sdiv " << PhysRegName(nops[0].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[1].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[2].GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Opcode::UDivRR: {
|
|
|
|
|
std::vector<Operand> nops = ops;
|
|
|
|
|
NormalizeRegOps(nops, nops[0].GetReg());
|
|
|
|
|
os << " udiv " << PhysRegName(nops[0].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[1].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[2].GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Opcode::FAddRR: {
|
|
|
|
|
std::vector<Operand> nops = ops;
|
|
|
|
|
NormalizeRegOps(nops, nops[0].GetReg());
|
|
|
|
|
os << " fadd " << PhysRegName(nops[0].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[1].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[2].GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Opcode::FSubRR: {
|
|
|
|
|
std::vector<Operand> nops = ops;
|
|
|
|
|
NormalizeRegOps(nops, nops[0].GetReg());
|
|
|
|
|
os << " fsub " << PhysRegName(nops[0].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[1].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[2].GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Opcode::FMulRR: {
|
|
|
|
|
std::vector<Operand> nops = ops;
|
|
|
|
|
NormalizeRegOps(nops, nops[0].GetReg());
|
|
|
|
|
os << " fmul " << PhysRegName(nops[0].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[1].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[2].GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Opcode::FDivRR: {
|
|
|
|
|
std::vector<Operand> nops = ops;
|
|
|
|
|
NormalizeRegOps(nops, nops[0].GetReg());
|
|
|
|
|
os << " fdiv " << PhysRegName(nops[0].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[1].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[2].GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Opcode::CmpRR: {
|
|
|
|
|
std::vector<Operand> nops = ops;
|
|
|
|
|
NormalizeRegOps(nops, nops[0].GetReg());
|
|
|
|
|
os << " cmp " << PhysRegName(nops[0].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[1].GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Opcode::CmpRI: {
|
|
|
|
|
std::vector<Operand> nops = ops;
|
|
|
|
|
NormalizeRegOps(nops, nops[0].GetReg());
|
|
|
|
|
os << " cmp " << PhysRegName(nops[0].GetReg()) << ", #"
|
|
|
|
|
<< nops[1].GetImm() << "\n";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Opcode::FCmpRR: {
|
|
|
|
|
std::vector<Operand> nops = ops;
|
|
|
|
|
NormalizeRegOps(nops, nops[0].GetReg());
|
|
|
|
|
os << " fcmp " << PhysRegName(nops[0].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[1].GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Opcode::SIToFP: {
|
|
|
|
|
PhysReg dst = ops.at(0).GetReg();
|
|
|
|
|
PhysReg src = ops.at(1).GetReg();
|
|
|
|
|
if (!IsWReg(src)) src = ToW(src);
|
|
|
|
|
os << " scvtf " << PhysRegName(dst) << ", " << PhysRegName(src) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Opcode::FPToSI: {
|
|
|
|
|
PhysReg dst = ops.at(0).GetReg();
|
|
|
|
|
PhysReg src = ops.at(1).GetReg();
|
|
|
|
|
if (!IsWReg(dst)) dst = ToW(dst);
|
|
|
|
|
os << " fcvtzs " << PhysRegName(dst) << ", " << PhysRegName(src) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Opcode::ZExt:
|
|
|
|
|
os << " and " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ", #1\n";
|
|
|
|
|
break;
|
|
|
|
|
case Opcode::AndRR:
|
|
|
|
|
os << " and " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(2).GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
case Opcode::OrRR:
|
|
|
|
|
os << " orr " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(2).GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
case Opcode::EorRR:
|
|
|
|
|
os << " eor " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(2).GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
case Opcode::LslRR:
|
|
|
|
|
os << " lsl " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(2).GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
case Opcode::LsrRR:
|
|
|
|
|
os << " lsr " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(2).GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
case Opcode::AsrRR:
|
|
|
|
|
os << " asr " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(2).GetReg()) << "\n";
|
|
|
|
|
case Opcode::AndRR: {
|
|
|
|
|
std::vector<Operand> nops = ops;
|
|
|
|
|
NormalizeRegOps(nops, nops[0].GetReg());
|
|
|
|
|
os << " and " << PhysRegName(nops[0].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[1].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[2].GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Opcode::OrRR: {
|
|
|
|
|
std::vector<Operand> nops = ops;
|
|
|
|
|
NormalizeRegOps(nops, nops[0].GetReg());
|
|
|
|
|
os << " orr " << PhysRegName(nops[0].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[1].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[2].GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Opcode::EorRR: {
|
|
|
|
|
std::vector<Operand> nops = ops;
|
|
|
|
|
NormalizeRegOps(nops, nops[0].GetReg());
|
|
|
|
|
os << " eor " << PhysRegName(nops[0].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[1].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[2].GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Opcode::LslRR: {
|
|
|
|
|
std::vector<Operand> nops = ops;
|
|
|
|
|
NormalizeRegOps(nops, nops[0].GetReg());
|
|
|
|
|
os << " lsl " << PhysRegName(nops[0].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[1].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[2].GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Opcode::LsrRR: {
|
|
|
|
|
std::vector<Operand> nops = ops;
|
|
|
|
|
NormalizeRegOps(nops, nops[0].GetReg());
|
|
|
|
|
os << " lsr " << PhysRegName(nops[0].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[1].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[2].GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Opcode::AsrRR: {
|
|
|
|
|
std::vector<Operand> nops = ops;
|
|
|
|
|
NormalizeRegOps(nops, nops[0].GetReg());
|
|
|
|
|
os << " asr " << PhysRegName(nops[0].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[1].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(nops[2].GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Opcode::B:
|
|
|
|
|
os << " b ";
|
|
|
|
|
PrintOperand(os, ops.at(0));
|
|
|
|
|
@ -345,8 +477,8 @@ void PrintInstruction(std::ostream& os, const MachineInstr& instr,
|
|
|
|
|
break;
|
|
|
|
|
case Opcode::LoadStackAddr: {
|
|
|
|
|
const FrameSlot& slot = GetFrameSlot(function, ops.at(1));
|
|
|
|
|
int64_t offset = slot.offset; // 负值,如 -8
|
|
|
|
|
PhysReg dst = ops.at(0).GetReg();
|
|
|
|
|
int64_t offset = slot.offset;
|
|
|
|
|
PhysReg dst = ToX(ops.at(0).GetReg()); // 地址必须是 X 寄存器
|
|
|
|
|
|
|
|
|
|
auto tryEmitSimple = [&]() -> bool {
|
|
|
|
|
if (offset >= 0 && offset <= 4095) {
|
|
|
|
|
@ -384,10 +516,15 @@ void PrintInstruction(std::ostream& os, const MachineInstr& instr,
|
|
|
|
|
<< ops.at(2).GetLabel() << "\n";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Opcode::Sxtw:
|
|
|
|
|
os << " sxtw " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << "\n";
|
|
|
|
|
case Opcode::Sxtw: {
|
|
|
|
|
PhysReg dst = ops.at(0).GetReg();
|
|
|
|
|
PhysReg src = ops.at(1).GetReg();
|
|
|
|
|
// sxtw 要求 X 目标,W 源
|
|
|
|
|
if (!IsXReg(dst)) dst = ToX(dst);
|
|
|
|
|
if (!IsWReg(src)) src = ToW(src);
|
|
|
|
|
os << " sxtw " << PhysRegName(dst) << ", " << PhysRegName(src) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
os << " // unknown instruction\n";
|
|
|
|
|
break;
|
|
|
|
|
|