修改condbr

feature/mir
ftt 2 days ago
parent 7d8ee45a42
commit 8b4ffdde44

@ -27,8 +27,10 @@ const FrameSlot& GetFrameSlot(const MachineFunction& function,
void PrintStackAccess(std::ostream& os, const char* mnemonic, PhysReg reg,
int offset) {
os << " " << mnemonic << " " << PhysRegName(reg) << ", [x29, #" << offset
<< "]\n";
//os << " " << mnemonic << " " << PhysRegName(reg) << ", [x29, #" << offset
// << "]\n";
// 使用 sp 相对寻址
os << " " << mnemonic << " " << PhysRegName(reg) << ", [sp, #" << offset << "]\n";
}
// 打印单个操作数
@ -59,14 +61,14 @@ void PrintInstruction(std::ostream& os, const MachineInstr& instr,
const auto& ops = instr.GetOperands();
switch (instr.GetOpcode()) {
case Opcode::Prologue:
os << " stp x29, x30, [sp, #-16]!\n";
os << " mov x29, sp\n";
if (function.GetFrameSize() > 0) {
os << " sub sp, sp, #" << function.GetFrameSize() << "\n";
}
break;
case Opcode::Epilogue:
case Opcode::Prologue:
os << " stp x29, x30, [sp, #-16]!\n";
os << " mov x29, sp\n";
if (function.GetFrameSize() > 0) {
os << " sub sp, sp, #" << function.GetFrameSize() << "\n";
}
break;
case Opcode::Epilogue:
if (function.GetFrameSize() > 0) {
os << " add sp, sp, #" << function.GetFrameSize() << "\n";
}
@ -80,14 +82,36 @@ void PrintInstruction(std::ostream& os, const MachineInstr& instr,
os << " mov " << PhysRegName(ops.at(0).GetReg()) << ", "
<< PhysRegName(ops.at(1).GetReg()) << "\n";
break;
case Opcode::LoadStack: {
const auto& slot = GetFrameSlot(function, ops.at(1));
PrintStackAccess(os, "ldur", ops.at(0).GetReg(), slot.offset);
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]
os << " str " << PhysRegName(ops.at(0).GetReg()) << ", ["
<< PhysRegName(ops.at(1).GetReg()) << "]\n";
} else {
throw std::runtime_error("StoreStack: 无效的操作数类型");
}
break;
}
case Opcode::StoreStack: {
const auto& slot = GetFrameSlot(function, ops.at(1));
PrintStackAccess(os, "stur", ops.at(0).GetReg(), slot.offset);
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]
os << " ldr " << PhysRegName(ops.at(0).GetReg()) << ", ["
<< PhysRegName(ops.at(1).GetReg()) << "]\n";
} else {
throw std::runtime_error("LoadStack: 无效的操作数类型");
}
break;
}
case Opcode::StoreStackPair:

@ -27,12 +27,14 @@ void RunFrameLowering(MachineFunction& function) {
DEBUG_MSG("function RunFrameLowering");
int cursor = 0;
for (const auto& slot : function.GetFrameSlots()) {
//cursor += slot.size;
// 使用正偏移,从 sp 开始
function.GetFrameSlot(slot.index).offset = cursor;
cursor += slot.size;
if (-cursor < -256) {
throw std::runtime_error(FormatError("mir", "暂不支持过大的栈帧"));
}
}
cursor = 0;
for (const auto& slot : function.GetFrameSlots()) {
cursor += slot.size;
@ -77,5 +79,4 @@ void RunFrameLowering(MachineModule& module) {
}
}
} // namespace mir
} // namespace mir

@ -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
Loading…
Cancel
Save