diff --git a/include/mir/MIR.h b/include/mir/MIR.h index 2573711..a879bef 100644 --- a/include/mir/MIR.h +++ b/include/mir/MIR.h @@ -136,6 +136,10 @@ enum class Opcode { // 添加 LoadStackAddr, // 将栈帧地址加载到寄存器 (add xd, sp, #offset) + + // 用于全局变量地址计算 + Adrp, // ADRP Xd, label + AddLabel, // ADD Xd, Xn, :lo12:label }; // ========== 操作数类 ========== @@ -289,8 +293,22 @@ class MachineModule { return nullptr; } + struct GlobalDecl { + std::string name; + int size; // 字节大小 + int alignment; // 对齐要求(通常为 4 或 8) + bool is_zero_init; // 是否为零初始化 + }; + + void AddGlobal(const std::string& name, int size, int alignment, bool is_zero_init = true) { + globals_.push_back({name, size, alignment, is_zero_init}); + } + + const std::vector& GetGlobals() const { return globals_; } + private: std::vector> functions_; + std::vector globals_; }; // ========== 后端流程函数 ========== diff --git a/src/mir/AsmPrinter.cpp b/src/mir/AsmPrinter.cpp index aaf9825..eaee05b 100644 --- a/src/mir/AsmPrinter.cpp +++ b/src/mir/AsmPrinter.cpp @@ -394,9 +394,22 @@ void PrintInstruction(std::ostream& os, const MachineInstr& instr, } break; } + case Opcode::Adrp: { + // adrp Xd, label + os << " adrp " << PhysRegName(ops.at(0).GetReg()) << ", " + << ops.at(1).GetLabel() << "\n"; + break; + } + case Opcode::AddLabel: { + // add Xd, Xn, :lo12:label + os << " add " << PhysRegName(ops.at(0).GetReg()) << ", " + << PhysRegName(ops.at(1).GetReg()) << ", :lo12:" + << ops.at(2).GetLabel() << "\n"; + break; + } default: - os << " // unknown instruction\n"; - break; + os << " // unknown instruction\n"; + break; } } @@ -439,6 +452,25 @@ void PrintAsm(const MachineFunction& function, std::ostream& os) { void PrintAsm(const MachineModule& module, std::ostream& os) { // 输出文件头 os << ".arch armv8-a\n"; + + // 输出数据段:全局变量 + const auto& globals = module.GetGlobals(); + if (!globals.empty()) { + os << "\n.data\n"; + for (const auto& g : globals) { + os << ".global " << g.name << "\n"; + os << ".type " << g.name << ", %object\n"; + os << ".align " << g.alignment << "\n"; + os << g.name << ":\n"; + if (g.is_zero_init) { + os << " .zero " << g.size << "\n"; + } else { + // TODO: 处理非零初始化值(需要从 IR 提取 initializer) + os << " .zero " << g.size << " // unhandled initializer\n"; + } + os << ".size " << g.name << ", " << g.size << "\n\n"; + } + } DEBUG_MSG("module"); // 遍历所有函数,输出汇编 diff --git a/src/mir/Lowering.cpp b/src/mir/Lowering.cpp index aeb169f..39bea1c 100644 --- a/src/mir/Lowering.cpp +++ b/src/mir/Lowering.cpp @@ -196,26 +196,7 @@ void EmitValueToReg(const ir::Value* value, PhysReg target, block.Append(Opcode::LoadStack, {Operand::Reg(target), Operand::FrameIndex(slot)}); return; } - // 处理全局变量 - if (auto* global = dynamic_cast(value)) { - // 全局变量:需要加载其地址 - // 在 ARM64 中,使用 ADRP + ADD 指令获取全局变量地址 - // 简化版本:先为全局变量分配一个栈槽,然后加载地址到该栈槽 - - // 检查是否已经为这个全局变量分配了栈槽 - auto it = slots.find(value); - if (it == slots.end()) { - // 为全局变量创建栈槽 - const_cast(slots).emplace(value, - const_cast(function).CreateFrameIndex(8)); - it = slots.find(value); - } - - // 从栈槽加载地址到目标寄存器 - block.Append(Opcode::LoadStack, - {Operand::Reg(target), Operand::FrameIndex(it->second)}); - return; - } + // 处理零常量 if (dynamic_cast(value) || dynamic_cast(value)) { @@ -279,6 +260,18 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function, const ir::Value* ptr = store.GetPtr(); const ir::Value* val = store.GetValue(); + // 处理全局变量作为存储目标 + if (auto* global = dynamic_cast(ptr)) { + // 生成全局变量地址到 x8 + block.Append(Opcode::Adrp, {Operand::Reg(PhysReg::X8), Operand::Label(global->GetName())}); + block.Append(Opcode::AddLabel, {Operand::Reg(PhysReg::X8), Operand::Reg(PhysReg::X8), Operand::Label(global->GetName())}); + // 加载要存储的值到 w9 + EmitValueToReg(val, PhysReg::W9, slots, block, function); + // 间接存储:str w9, [x8] + block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W9), Operand::Reg(PhysReg::X8)}); + return; + } + auto dstIt = slots.find(ptr); if (dstIt == slots.end()) { // 指针不在 slots 中(例如直接来自函数参数的指针) @@ -305,6 +298,19 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function, auto& load = static_cast(inst); const ir::Value* ptr = load.GetPtr(); int dstSlot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); + + // 处理全局变量作为加载源 + if (auto* global = dynamic_cast(ptr)) { + // 生成全局变量地址到 x8 + block.Append(Opcode::Adrp, {Operand::Reg(PhysReg::X8), Operand::Label(global->GetName())}); + block.Append(Opcode::AddLabel, {Operand::Reg(PhysReg::X8), Operand::Reg(PhysReg::X8), Operand::Label(global->GetName())}); + // 间接加载到 w9 + block.Append(Opcode::LoadStack, {Operand::Reg(PhysReg::W9), Operand::Reg(PhysReg::X8)}); + // 存储结果到栈槽 + block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W9), Operand::FrameIndex(dstSlot)}); + slots.emplace(&inst, dstSlot); + return; + } auto srcIt = slots.find(ptr); if (srcIt == slots.end()) { @@ -1000,6 +1006,15 @@ std::unique_ptr LowerToMIR(const ir::Module& module) { auto machine_module = std::make_unique(); + // 收集全局变量信息 + 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); + } + std::vector globals; // 处理全局变量 for (const auto& global : module.GetGlobals()) {