|
|
|
|
@ -178,7 +178,7 @@ void EmitValueToReg(const ir::Value* value, PhysReg target,
|
|
|
|
|
block.Append(Opcode::LoadStack,
|
|
|
|
|
{Operand::Reg(target), Operand::FrameIndex(it->second)});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 处理零常量
|
|
|
|
|
if (dynamic_cast<const ir::ConstantZero*>(value) ||
|
|
|
|
|
dynamic_cast<const ir::ConstantAggregateZero*>(value)) {
|
|
|
|
|
@ -190,13 +190,22 @@ void EmitValueToReg(const ir::Value* value, PhysReg target,
|
|
|
|
|
|
|
|
|
|
auto it = slots.find(value);
|
|
|
|
|
if (it == slots.end()) {
|
|
|
|
|
DEBUG_MSG("Value not found: " << value->GetName());
|
|
|
|
|
// 使用值的地址作为调试信息
|
|
|
|
|
std::string valueName = value->GetName();
|
|
|
|
|
if (valueName.empty()) {
|
|
|
|
|
valueName = "(anonymous at " + std::to_string(reinterpret_cast<uintptr_t>(value)) + ")";
|
|
|
|
|
}
|
|
|
|
|
DEBUG_MSG("Value not found: " << valueName);
|
|
|
|
|
// 输出所有 slots 的键名用于调试
|
|
|
|
|
for (auto& p : slots) {
|
|
|
|
|
DEBUG_MSG(" Slot key: " << p.first->GetName());
|
|
|
|
|
std::string slotName = p.first->GetName();
|
|
|
|
|
if (slotName.empty()) {
|
|
|
|
|
slotName = "(anonymous at " + std::to_string(reinterpret_cast<uintptr_t>(p.first)) + ")";
|
|
|
|
|
}
|
|
|
|
|
DEBUG_MSG(" Slot key: " << slotName);
|
|
|
|
|
}
|
|
|
|
|
throw std::runtime_error(
|
|
|
|
|
FormatError("mir", "找不到值对应的栈槽: " + value->GetName()));
|
|
|
|
|
FormatError("mir", "找不到值对应的栈槽: " + valueName));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
block.Append(Opcode::LoadStack,
|
|
|
|
|
@ -222,9 +231,6 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
|
|
|
|
if (dst == slots.end()) {
|
|
|
|
|
//throw std::runtime_error(
|
|
|
|
|
// FormatError("mir", "暂不支持对非栈变量地址进行写入"));
|
|
|
|
|
// 对于非栈变量地址(如 GEP 结果),地址本身在栈槽中
|
|
|
|
|
// 需要先加载地址,然后存储值到该地址
|
|
|
|
|
// 先加载地址到 x8
|
|
|
|
|
EmitValueToReg(store.GetPtr(), PhysReg::X8, slots, block, function);
|
|
|
|
|
// 加载值到 w9
|
|
|
|
|
EmitValueToReg(store.GetValue(), PhysReg::W9, slots, block, function);
|
|
|
|
|
@ -430,52 +436,40 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
|
|
|
|
}
|
|
|
|
|
// ========== 跳转指令(使用标签操作数)==========
|
|
|
|
|
case ir::Opcode::Br: {
|
|
|
|
|
DEBUG_MSG("Processing Br");
|
|
|
|
|
auto& br = static_cast<const ir::BranchInst&>(inst);
|
|
|
|
|
|
|
|
|
|
auto* cond = br.GetCondition();
|
|
|
|
|
DEBUG_MSG("Condition value ptr: " << cond);
|
|
|
|
|
DEBUG_MSG("Condition name: " << cond->GetName());
|
|
|
|
|
auto it = slots.find(cond);
|
|
|
|
|
if (it == slots.end()) {
|
|
|
|
|
DEBUG_MSG("Condition not found in slots!");
|
|
|
|
|
// 输出所有 slots 的键名
|
|
|
|
|
for (auto& p : slots) {
|
|
|
|
|
DEBUG_MSG(" Slot key: " << p.first->GetName());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (br.IsConditional()) {
|
|
|
|
|
// 条件跳转: br i1 %cond, label %then, label %else
|
|
|
|
|
// 加载条件值到 w8
|
|
|
|
|
DEBUG_MSG("Processing Br");
|
|
|
|
|
auto& br = static_cast<const ir::BranchInst&>(inst);
|
|
|
|
|
|
|
|
|
|
if (br.IsConditional()) {
|
|
|
|
|
// 条件跳转
|
|
|
|
|
EmitValueToReg(br.GetCondition(), PhysReg::W8, slots, block, function);
|
|
|
|
|
block.Append(Opcode::CmpRI, {Operand::Reg(PhysReg::W8), Operand::Imm(0)});
|
|
|
|
|
|
|
|
|
|
std::string trueLabel = GetBlockLabel(br.GetTrueTarget());
|
|
|
|
|
std::string falseLabel = GetBlockLabel(br.GetFalseTarget());
|
|
|
|
|
|
|
|
|
|
block.Append(Opcode::BCond, {Operand::Cond(CondCode::NE), Operand::Label(trueLabel)});
|
|
|
|
|
block.Append(Opcode::B, {Operand::Label(falseLabel)});
|
|
|
|
|
} else {
|
|
|
|
|
// 无条件跳转
|
|
|
|
|
std::string targetLabel = GetBlockLabel(br.GetTarget());
|
|
|
|
|
block.Append(Opcode::B, {Operand::Label(targetLabel)});
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
case ir::Opcode::CondBr: {
|
|
|
|
|
DEBUG_MSG("Processing CondBr");
|
|
|
|
|
auto& br = static_cast<const ir::BranchInst&>(inst);
|
|
|
|
|
|
|
|
|
|
// 条件跳转处理
|
|
|
|
|
EmitValueToReg(br.GetCondition(), PhysReg::W8, slots, block, function);
|
|
|
|
|
|
|
|
|
|
// 比较条件值是否为 0
|
|
|
|
|
block.Append(Opcode::CmpRI, {Operand::Reg(PhysReg::W8), Operand::Imm(0)});
|
|
|
|
|
|
|
|
|
|
// 获取目标基本块的标签名
|
|
|
|
|
const ir::BasicBlock* irTrueTarget = br.GetTrueTarget();
|
|
|
|
|
const ir::BasicBlock* irFalseTarget = br.GetFalseTarget();
|
|
|
|
|
|
|
|
|
|
std::string trueLabel = GetBlockLabel(irTrueTarget);
|
|
|
|
|
std::string falseLabel = GetBlockLabel(irFalseTarget);
|
|
|
|
|
std::string trueLabel = GetBlockLabel(br.GetTrueTarget());
|
|
|
|
|
std::string falseLabel = GetBlockLabel(br.GetFalseTarget());
|
|
|
|
|
|
|
|
|
|
// 生成 B.NE true_label
|
|
|
|
|
block.Append(Opcode::BCond, {Operand::Cond(CondCode::NE), Operand::Label(trueLabel)});
|
|
|
|
|
// 生成 B false_label
|
|
|
|
|
block.Append(Opcode::B, {Operand::Label(falseLabel)});
|
|
|
|
|
DEBUG_MSG("Generating conditional branch: cond=" << br.GetCondition()->GetName()
|
|
|
|
|
<< ", true=" << trueLabel << ", false=" << falseLabel);
|
|
|
|
|
} else {
|
|
|
|
|
// 无条件跳转: br label %target
|
|
|
|
|
const ir::BasicBlock* irTarget = br.GetTarget();
|
|
|
|
|
std::string targetLabel = GetBlockLabel(irTarget);
|
|
|
|
|
DEBUG_MSG("b: targetLabel is " << GetBlockLabel(irTarget));
|
|
|
|
|
|
|
|
|
|
// 生成 B target_label
|
|
|
|
|
block.Append(Opcode::B, {Operand::Label(targetLabel)});
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// ========== 函数调用 ==========
|
|
|
|
|
case ir::Opcode::Call: {
|
|
|
|
|
@ -512,8 +506,8 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 生成调用指令
|
|
|
|
|
block.Append(Opcode::Call, {Operand::Imm(0)}); // 实际需要传递函数名
|
|
|
|
|
|
|
|
|
|
//block.Append(Opcode::Call, {Operand::Imm(0)}); // 实际需要传递函数名
|
|
|
|
|
block.Append(Opcode::Call, {Operand::Label(calleeName)});
|
|
|
|
|
// 保存返回值
|
|
|
|
|
if (dst_slot != -1) {
|
|
|
|
|
if (inst.GetType()->IsFloat()) {
|
|
|
|
|
@ -820,37 +814,6 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
|
|
|
|
slots.emplace(&inst, dst_slot);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// 处理 CondBr 指令
|
|
|
|
|
case ir::Opcode::CondBr: {
|
|
|
|
|
// CondBr 通常有两个目标基本块和一个条件
|
|
|
|
|
const ir::Value* condition = nullptr;
|
|
|
|
|
const ir::BasicBlock* trueTarget = nullptr;
|
|
|
|
|
const ir::BasicBlock* falseTarget = nullptr;
|
|
|
|
|
|
|
|
|
|
if (inst.GetNumOperands() >= 3) {
|
|
|
|
|
condition = inst.GetOperand(0);
|
|
|
|
|
// 操作数1和2应该是 BasicBlock 引用
|
|
|
|
|
// 具体获取方式取决于你的 IR 实现
|
|
|
|
|
if (auto* bb = dynamic_cast<const ir::BasicBlock*>(inst.GetOperand(1))) {
|
|
|
|
|
trueTarget = bb;
|
|
|
|
|
}
|
|
|
|
|
if (auto* bb = dynamic_cast<const ir::BasicBlock*>(inst.GetOperand(2))) {
|
|
|
|
|
falseTarget = bb;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (condition && trueTarget && falseTarget) {
|
|
|
|
|
EmitValueToReg(condition, PhysReg::W8, slots, block, function);
|
|
|
|
|
block.Append(Opcode::CmpRI, {Operand::Reg(PhysReg::W8), Operand::Imm(0)});
|
|
|
|
|
|
|
|
|
|
std::string trueLabel = GetBlockLabel(trueTarget);
|
|
|
|
|
std::string falseLabel = GetBlockLabel(falseTarget);
|
|
|
|
|
|
|
|
|
|
block.Append(Opcode::BCond, {Operand::Cond(CondCode::NE), Operand::Label(trueLabel)});
|
|
|
|
|
block.Append(Opcode::B, {Operand::Label(falseLabel)});
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// 处理 FPExt(浮点扩展)
|
|
|
|
|
case ir::Opcode::FPExt: {
|
|
|
|
|
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get()));
|
|
|
|
|
@ -887,9 +850,14 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
|
|
|
|
slots.emplace(&inst, dst_slot);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
DEBUG_MSG("Unhandled opcode: " << static_cast<int>(inst.GetOpcode())
|
|
|
|
|
<< " for instruction: " << inst.GetName());
|
|
|
|
|
throw std::runtime_error(FormatError("mir", "暂不支持该 IR 指令,opcode: "
|
|
|
|
|
+ std::to_string(static_cast<int>(inst.GetOpcode()))));
|
|
|
|
|
//throw std::runtime_error(FormatError("mir", "暂不支持该 IR 指令"));
|
|
|
|
|
throw std::runtime_error(FormatError("mir", "暂不支持该 IR 指令,opcode: "
|
|
|
|
|
+ std::to_string(static_cast<int>(inst.GetOpcode()))));
|
|
|
|
|
//throw std::runtime_error(FormatError("mir", "暂不支持该 IR 指令,opcode: "
|
|
|
|
|
// + std::to_string(static_cast<int>(inst.GetOpcode()))));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -975,11 +943,13 @@ std::unique_ptr<MachineModule> LowerToMIR(const ir::Module& module) {
|
|
|
|
|
|
|
|
|
|
auto machine_module = std::make_unique<MachineModule>();
|
|
|
|
|
|
|
|
|
|
std::vector<const ir::GlobalValue*> globals;
|
|
|
|
|
// 处理全局变量
|
|
|
|
|
for (const auto& global : module.GetGlobals()) {
|
|
|
|
|
// 为全局变量在数据段分配空间
|
|
|
|
|
// 这里需要扩展 MachineModule 来支持全局变量
|
|
|
|
|
DEBUG_MSG("Global variable: " << global->GetName());
|
|
|
|
|
globals.push_back(global.get());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 遍历模块中的所有函数
|
|
|
|
|
@ -1000,4 +970,4 @@ std::unique_ptr<MachineModule> LowerToMIR(const ir::Module& module) {
|
|
|
|
|
return machine_module;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace mir
|
|
|
|
|
} // namespace mir
|