(mir)修正编译程序死循环问题

mxr 3 weeks ago
parent fdeb3fc66e
commit 35885f3eba

@ -140,6 +140,9 @@ enum class Opcode {
// 用于全局变量地址计算
Adrp, // ADRP Xd, label
AddLabel, // ADD Xd, Xn, :lo12:label
// 新增
Sxtw, // 符号扩展字到双字sxtw Xd, Wn
};
// ========== 操作数类 ==========
@ -298,12 +301,21 @@ class MachineModule {
int size; // 字节大小
int alignment; // 对齐要求(通常为 4 或 8
bool is_zero_init; // 是否为零初始化
bool has_init_data; // 是否包含初始化数据(用于标量常量)
uint64_t init_data; // 初始化数据≤8字节
// 构造函数,默认零初始化
GlobalDecl(const std::string& n, int sz, int align, bool zero = true,
bool has_data = false, uint64_t data = 0)
: name(n), size(sz), alignment(align), is_zero_init(zero),
has_init_data(has_data), init_data(data) {}
};
void AddGlobal(const std::string& name, int size, int alignment, bool is_zero_init = true) {
globals_.push_back({name, size, alignment, is_zero_init});
void AddGlobal(const std::string& name, int size, int alignment,
bool is_zero_init = true,
bool has_init_data = false, uint64_t init_data = 0) {
globals_.emplace_back(name, size, alignment, is_zero_init,
has_init_data, init_data);
}
const std::vector<GlobalDecl>& GetGlobals() const { return globals_; }
private:

@ -384,6 +384,10 @@ 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";
break;
default:
os << " // unknown instruction\n";
break;
@ -441,8 +445,17 @@ void PrintAsm(const MachineModule& module, std::ostream& os) {
os << g.name << ":\n";
if (g.is_zero_init) {
os << " .zero " << g.size << "\n";
} else if (g.has_init_data) {
if (g.size == 4) {
os << " .word " << static_cast<uint32_t>(g.init_data) << "\n";
} else if (g.size == 8) {
os << " .quad " << g.init_data << "\n";
} else {
// 暂不支持的标量大小,回退为零初始化
os << " .zero " << g.size << " // unhandled init size\n";
}
} else {
// TODO: 处理非零初始化值(需要从 IR 提取 initializer
// 有初始值但无法提取(例如数组、结构体
os << " .zero " << g.size << " // unhandled initializer\n";
}
os << ".size " << g.name << ", " << g.size << "\n\n";

@ -21,6 +21,10 @@ namespace {
using ValueSlotMap = std::unordered_map<const ir::Value*, int>;
inline bool IsInt32Type(const ir::Type* type) {
return type && type->IsInt32() && type->Size() == 4;
}
static uint32_t FloatToBits(float f) {
uint32_t bits;
memcpy(&bits, &f, sizeof(bits));
@ -364,83 +368,224 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
auto& bin = static_cast<const ir::BinaryInst&>(inst);
const ir::Type* lhsTy = bin.GetLhs()->GetType().get();
const ir::Type* rhsTy = bin.GetRhs()->GetType().get();
const ir::Type* resultTy = inst.GetType().get();
// 指针判断:指令结果类型是指针,或者任一操作数是指针(指针算术)
bool isPointer = (lhsTy->IsPtrInt32() || lhsTy->IsPtrFloat() || lhsTy->IsPtrInt1() || lhsTy->IsArray()) ||
(rhsTy->IsPtrInt32() || rhsTy->IsPtrFloat() || rhsTy->IsPtrInt1() || rhsTy->IsArray()) ||
inst.GetType()->IsPtrInt32() || inst.GetType()->IsPtrFloat() || inst.GetType()->IsPtrInt1() || inst.GetType()->IsArray();
(rhsTy->IsPtrInt32() || rhsTy->IsPtrFloat() || rhsTy->IsPtrInt1() || rhsTy->IsArray()) ||
resultTy->IsPtrInt32() || resultTy->IsPtrFloat() || resultTy->IsPtrInt1() || resultTy->IsArray();
// 判断是否为纯 32 位有符号整数加法(需要提升为 64 位以避免溢出)
bool isI32 = !isPointer && IsInt32Type(lhsTy) && IsInt32Type(rhsTy) && IsInt32Type(resultTy);
int slotSize = isPointer ? 8 : 4;
PhysReg lhsReg = isPointer ? PhysReg::X8 : PhysReg::W8;
PhysReg rhsReg = isPointer ? PhysReg::X9 : PhysReg::W9;
PhysReg dstReg = isPointer ? PhysReg::X8 : PhysReg::W8;
int dst_slot = function.CreateFrameIndex(slotSize); // 使用计算出的 slotSize
EmitValueToReg(bin.GetLhs(), lhsReg, slots, block, function);
EmitValueToReg(bin.GetRhs(), rhsReg, slots, block, function);
int dst_slot = function.CreateFrameIndex(slotSize);
PhysReg lhsReg, rhsReg, dstReg;
if (isI32) {
// 使用 64 位寄存器,先符号扩展
lhsReg = PhysReg::X8;
rhsReg = PhysReg::X9;
dstReg = PhysReg::X8;
EmitValueToReg(bin.GetLhs(), PhysReg::W8, slots, block, function);
block.Append(Opcode::Sxtw, {Operand::Reg(PhysReg::X8), Operand::Reg(PhysReg::W8)});
EmitValueToReg(bin.GetRhs(), PhysReg::W9, slots, block, function);
block.Append(Opcode::Sxtw, {Operand::Reg(PhysReg::X9), Operand::Reg(PhysReg::W9)});
} else {
lhsReg = isPointer ? PhysReg::X8 : PhysReg::W8;
rhsReg = isPointer ? PhysReg::X9 : PhysReg::W9;
dstReg = isPointer ? PhysReg::X8 : PhysReg::W8;
EmitValueToReg(bin.GetLhs(), lhsReg, slots, block, function);
EmitValueToReg(bin.GetRhs(), rhsReg, slots, block, function);
}
block.Append(Opcode::AddRR, {Operand::Reg(dstReg), Operand::Reg(lhsReg), Operand::Reg(rhsReg)});
block.Append(Opcode::StoreStack, {Operand::Reg(dstReg), Operand::FrameIndex(dst_slot)});
if (isI32) {
// 结果在 X8 中,只需存储低 32 位W8
block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
} else {
block.Append(Opcode::StoreStack, {Operand::Reg(dstReg), Operand::FrameIndex(dst_slot)});
}
slots.emplace(&inst, dst_slot);
return;
}
case ir::Opcode::Sub: {
auto& bin = static_cast<const ir::BinaryInst&>(inst);
const ir::Type* lhsTy = bin.GetLhs()->GetType().get();
const ir::Type* rhsTy = bin.GetRhs()->GetType().get();
// 指针判断:指令结果类型是指针,或者任一操作数是指针(指针算术)
const ir::Type* resultTy = inst.GetType().get();
bool isPointer = (lhsTy->IsPtrInt32() || lhsTy->IsPtrFloat() || lhsTy->IsPtrInt1() || lhsTy->IsArray()) ||
(rhsTy->IsPtrInt32() || rhsTy->IsPtrFloat() || rhsTy->IsPtrInt1() || rhsTy->IsArray()) ||
inst.GetType()->IsPtrInt32() || inst.GetType()->IsPtrFloat() || inst.GetType()->IsPtrInt1() || inst.GetType()->IsArray();
(rhsTy->IsPtrInt32() || rhsTy->IsPtrFloat() || rhsTy->IsPtrInt1() || rhsTy->IsArray()) ||
resultTy->IsPtrInt32() || resultTy->IsPtrFloat() || resultTy->IsPtrInt1() || resultTy->IsArray();
bool isI32 = !isPointer && IsInt32Type(lhsTy) && IsInt32Type(rhsTy) && IsInt32Type(resultTy);
int slotSize = isPointer ? 8 : 4;
PhysReg lhsReg = isPointer ? PhysReg::X8 : PhysReg::W8;
PhysReg rhsReg = isPointer ? PhysReg::X9 : PhysReg::W9;
PhysReg dstReg = isPointer ? PhysReg::X8 : PhysReg::W8;
int dst_slot = function.CreateFrameIndex(slotSize); // 使用计算出的 slotSize
EmitValueToReg(bin.GetLhs(), lhsReg, slots, block, function);
EmitValueToReg(bin.GetRhs(), rhsReg, slots, block, function);
int dst_slot = function.CreateFrameIndex(slotSize);
PhysReg lhsReg, rhsReg, dstReg;
if (isI32) {
lhsReg = PhysReg::X8;
rhsReg = PhysReg::X9;
dstReg = PhysReg::X8;
EmitValueToReg(bin.GetLhs(), PhysReg::W8, slots, block, function);
block.Append(Opcode::Sxtw, {Operand::Reg(PhysReg::X8), Operand::Reg(PhysReg::W8)});
EmitValueToReg(bin.GetRhs(), PhysReg::W9, slots, block, function);
block.Append(Opcode::Sxtw, {Operand::Reg(PhysReg::X9), Operand::Reg(PhysReg::W9)});
} else {
lhsReg = isPointer ? PhysReg::X8 : PhysReg::W8;
rhsReg = isPointer ? PhysReg::X9 : PhysReg::W9;
dstReg = isPointer ? PhysReg::X8 : PhysReg::W8;
EmitValueToReg(bin.GetLhs(), lhsReg, slots, block, function);
EmitValueToReg(bin.GetRhs(), rhsReg, slots, block, function);
}
block.Append(Opcode::SubRR, {Operand::Reg(dstReg), Operand::Reg(lhsReg), Operand::Reg(rhsReg)});
block.Append(Opcode::StoreStack, {Operand::Reg(dstReg), Operand::FrameIndex(dst_slot)});
if (isI32) {
block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
} else {
block.Append(Opcode::StoreStack, {Operand::Reg(dstReg), Operand::FrameIndex(dst_slot)});
}
slots.emplace(&inst, dst_slot);
return;
}
case ir::Opcode::Mul: {
auto& bin = static_cast<const ir::BinaryInst&>(inst);
const ir::Type* ty = inst.GetType().get();
bool isPointer = ty->IsPtrInt32() || ty->IsPtrFloat() || ty->IsPtrInt1();
const ir::Type* lhsTy = bin.GetLhs()->GetType().get();
const ir::Type* rhsTy = bin.GetRhs()->GetType().get();
const ir::Type* resultTy = inst.GetType().get();
// 乘法一般不涉及指针,但保留判断
bool isPointer = (lhsTy->IsPtrInt32() || lhsTy->IsPtrFloat() || lhsTy->IsPtrInt1()) ||
(rhsTy->IsPtrInt32() || rhsTy->IsPtrFloat() || rhsTy->IsPtrInt1()) ||
resultTy->IsPtrInt32() || resultTy->IsPtrFloat() || resultTy->IsPtrInt1();
bool isI32 = !isPointer && IsInt32Type(lhsTy) && IsInt32Type(rhsTy) && IsInt32Type(resultTy);
int slotSize = isPointer ? 8 : 4;
PhysReg lhsReg = isPointer ? PhysReg::X8 : PhysReg::W8;
PhysReg rhsReg = isPointer ? PhysReg::X9 : PhysReg::W9;
PhysReg dstReg = isPointer ? PhysReg::X8 : PhysReg::W8; // 可复用 lhsReg
int dst_slot = function.CreateFrameIndex(slotSize);
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); // 分配结果栈槽
EmitValueToReg(bin.GetLhs(), lhsReg, slots, block, function);
EmitValueToReg(bin.GetRhs(), rhsReg, slots, block, function);
block.Append(Opcode::MulRR, {Operand::Reg(dstReg),
Operand::Reg(lhsReg),
Operand::Reg(rhsReg)});
block.Append(Opcode::StoreStack,
{Operand::Reg(dstReg), Operand::FrameIndex(dst_slot)});
PhysReg lhsReg, rhsReg, dstReg;
if (isI32) {
lhsReg = PhysReg::X8;
rhsReg = PhysReg::X9;
dstReg = PhysReg::X8;
EmitValueToReg(bin.GetLhs(), PhysReg::W8, slots, block, function);
block.Append(Opcode::Sxtw, {Operand::Reg(PhysReg::X8), Operand::Reg(PhysReg::W8)});
EmitValueToReg(bin.GetRhs(), PhysReg::W9, slots, block, function);
block.Append(Opcode::Sxtw, {Operand::Reg(PhysReg::X9), Operand::Reg(PhysReg::W9)});
} else {
lhsReg = isPointer ? PhysReg::X8 : PhysReg::W8;
rhsReg = isPointer ? PhysReg::X9 : PhysReg::W9;
dstReg = isPointer ? PhysReg::X8 : PhysReg::W8;
EmitValueToReg(bin.GetLhs(), lhsReg, slots, block, function);
EmitValueToReg(bin.GetRhs(), rhsReg, slots, block, function);
}
block.Append(Opcode::MulRR, {Operand::Reg(dstReg), Operand::Reg(lhsReg), Operand::Reg(rhsReg)});
if (isI32) {
block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
} else {
block.Append(Opcode::StoreStack, {Operand::Reg(dstReg), Operand::FrameIndex(dst_slot)});
}
slots.emplace(&inst, dst_slot);
return;
}
case ir::Opcode::Div: {
auto& bin = static_cast<const ir::BinaryInst&>(inst);
const ir::Type* ty = inst.GetType().get();
bool isPointer = ty->IsPtrInt32() || ty->IsPtrFloat() || ty->IsPtrInt1();
const ir::Type* lhsTy = bin.GetLhs()->GetType().get();
const ir::Type* rhsTy = bin.GetRhs()->GetType().get();
const ir::Type* resultTy = inst.GetType().get();
bool isPointer = (lhsTy->IsPtrInt32() || lhsTy->IsPtrFloat() || lhsTy->IsPtrInt1()) ||
(rhsTy->IsPtrInt32() || rhsTy->IsPtrFloat() || rhsTy->IsPtrInt1()) ||
resultTy->IsPtrInt32() || resultTy->IsPtrFloat() || resultTy->IsPtrInt1();
bool isI32 = !isPointer && IsInt32Type(lhsTy) && IsInt32Type(rhsTy) && IsInt32Type(resultTy);
int slotSize = isPointer ? 8 : 4;
PhysReg lhsReg = isPointer ? PhysReg::X8 : PhysReg::W8;
PhysReg rhsReg = isPointer ? PhysReg::X9 : PhysReg::W9;
PhysReg dstReg = isPointer ? PhysReg::X8 : PhysReg::W8; // 可复用 lhsReg
int dst_slot = function.CreateFrameIndex(slotSize);
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); // 分配结果栈槽
EmitValueToReg(bin.GetLhs(), lhsReg, slots, block, function);
EmitValueToReg(bin.GetRhs(), rhsReg, slots, block, function);
block.Append(Opcode::SDivRR, {Operand::Reg(dstReg),
Operand::Reg(lhsReg),
Operand::Reg(rhsReg)});
block.Append(Opcode::StoreStack,
{Operand::Reg(dstReg), Operand::FrameIndex(dst_slot)});
PhysReg lhsReg, rhsReg, dstReg;
if (isI32) {
lhsReg = PhysReg::X8;
rhsReg = PhysReg::X9;
dstReg = PhysReg::X8;
EmitValueToReg(bin.GetLhs(), PhysReg::W8, slots, block, function);
block.Append(Opcode::Sxtw, {Operand::Reg(PhysReg::X8), Operand::Reg(PhysReg::W8)});
EmitValueToReg(bin.GetRhs(), PhysReg::W9, slots, block, function);
block.Append(Opcode::Sxtw, {Operand::Reg(PhysReg::X9), Operand::Reg(PhysReg::W9)});
} else {
lhsReg = isPointer ? PhysReg::X8 : PhysReg::W8;
rhsReg = isPointer ? PhysReg::X9 : PhysReg::W9;
dstReg = isPointer ? PhysReg::X8 : PhysReg::W8;
EmitValueToReg(bin.GetLhs(), lhsReg, slots, block, function);
EmitValueToReg(bin.GetRhs(), rhsReg, slots, block, function);
}
block.Append(Opcode::SDivRR, {Operand::Reg(dstReg), Operand::Reg(lhsReg), Operand::Reg(rhsReg)});
if (isI32) {
block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
} else {
block.Append(Opcode::StoreStack, {Operand::Reg(dstReg), Operand::FrameIndex(dst_slot)});
}
slots.emplace(&inst, dst_slot);
return;
}
case ir::Opcode::Mod: {
// Mod 指令a % b = a - (a / b) * b
// 我们直接复用提升策略:使用 64 位运算
const ir::Value* lhs = inst.GetOperand(0);
const ir::Value* rhs = inst.GetOperand(1);
const ir::Type* lhsTy = lhs->GetType().get();
const ir::Type* rhsTy = rhs->GetType().get();
const ir::Type* resultTy = inst.GetType().get();
bool isI32 = IsInt32Type(lhsTy) && IsInt32Type(rhsTy) && IsInt32Type(resultTy);
int dst_slot = function.CreateFrameIndex(4); // 结果总是 32 位
if (isI32) {
// 加载并扩展 lhs
EmitValueToReg(lhs, PhysReg::W8, slots, block, function);
block.Append(Opcode::Sxtw, {Operand::Reg(PhysReg::X8), Operand::Reg(PhysReg::W8)});
// 加载并扩展 rhs
EmitValueToReg(rhs, PhysReg::W9, slots, block, function);
block.Append(Opcode::Sxtw, {Operand::Reg(PhysReg::X9), Operand::Reg(PhysReg::W9)});
// X10 = X8 / X9
block.Append(Opcode::SDivRR, {Operand::Reg(PhysReg::X10), Operand::Reg(PhysReg::X8), Operand::Reg(PhysReg::X9)});
// X10 = X10 * X9
block.Append(Opcode::MulRR, {Operand::Reg(PhysReg::X10), Operand::Reg(PhysReg::X10), Operand::Reg(PhysReg::X9)});
// X8 = X8 - X10
block.Append(Opcode::SubRR, {Operand::Reg(PhysReg::X8), Operand::Reg(PhysReg::X8), Operand::Reg(PhysReg::X10)});
// 存储低 32 位
block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
} else {
// 原有逻辑(假设不会用于指针或 64 位整数)
EmitValueToReg(lhs, PhysReg::W8, slots, block, function);
EmitValueToReg(rhs, PhysReg::W9, slots, block, function);
block.Append(Opcode::SDivRR, {Operand::Reg(PhysReg::W10), Operand::Reg(PhysReg::W8), Operand::Reg(PhysReg::W9)});
block.Append(Opcode::MulRR, {Operand::Reg(PhysReg::W10), Operand::Reg(PhysReg::W10), Operand::Reg(PhysReg::W9)});
block.Append(Opcode::SubRR, {Operand::Reg(PhysReg::W8), Operand::Reg(PhysReg::W8), Operand::Reg(PhysReg::W10)});
block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
}
slots.emplace(&inst, dst_slot);
return;
}
@ -900,39 +1045,6 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
slots.emplace(&inst, dst_slot);
return;
}
// 处理 Mod 指令
case ir::Opcode::Mod: {
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get()));
// 通过操作数获取左右值
const ir::Value* lhs = nullptr;
const ir::Value* rhs = nullptr;
if (inst.GetNumOperands() >= 2) {
lhs = inst.GetOperand(0);
rhs = inst.GetOperand(1);
}
if (lhs && rhs) {
EmitValueToReg(lhs, PhysReg::W8, slots, block, function);
EmitValueToReg(rhs, PhysReg::W9, slots, block, function);
// a % b = a - (a / b) * b
block.Append(Opcode::SDivRR, {Operand::Reg(PhysReg::W10),
Operand::Reg(PhysReg::W8),
Operand::Reg(PhysReg::W9)});
block.Append(Opcode::MulRR, {Operand::Reg(PhysReg::W10),
Operand::Reg(PhysReg::W10),
Operand::Reg(PhysReg::W9)});
block.Append(Opcode::SubRR, {Operand::Reg(PhysReg::W8),
Operand::Reg(PhysReg::W8),
Operand::Reg(PhysReg::W10)});
}
block.Append(Opcode::StoreStack,
{Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
slots.emplace(&inst, dst_slot);
return;
}
// 处理 And 指令
case ir::Opcode::And: {
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get()));
@ -1144,9 +1256,28 @@ std::unique_ptr<MachineModule> LowerToMIR(const ir::Module& module) {
for (const auto& global : module.GetGlobals()) {
int size = GetTypeSize(global->GetType().get());
int alignment = global->GetType()->Alignment();
// 简化:假设无显式初始化的全局变量都是零初始化
bool is_zero_init = !global->HasInitializer();
machine_module->AddGlobal(global->GetName(), size, alignment, is_zero_init);
bool has_init_data = false;
uint64_t init_data = 0;
if (!is_zero_init) {
const auto& init = global->GetInitializer();
// 简单处理只支持单个元素的标量初始化float 或 int
if (init.size() == 1) {
if (auto* cf = dynamic_cast<const ir::ConstantFloat*>(init[0])) {
float fval = cf->GetValue();
uint32_t bits;
memcpy(&bits, &fval, sizeof(bits));
init_data = bits;
has_init_data = true;
} else if (auto* ci = dynamic_cast<const ir::ConstantInt*>(init[0])) {
init_data = static_cast<uint64_t>(ci->GetValue());
has_init_data = true;
}
}
}
machine_module->AddGlobal(global->GetName(), size, alignment,
is_zero_init, has_init_data, init_data);
}
std::vector<const ir::GlobalValue*> globals;

Loading…
Cancel
Save