feat(mir)修正全局变量地址计算和数据段生成

mxr 4 weeks ago
parent 5e492f531b
commit 7438c366fd

@ -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<GlobalDecl>& GetGlobals() const { return globals_; }
private:
std::vector<std::unique_ptr<MachineFunction>> functions_;
std::vector<GlobalDecl> globals_;
};
// ========== 后端流程函数 ==========

@ -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");
// 遍历所有函数,输出汇编

@ -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<const ir::GlobalValue*>(value)) {
// 全局变量:需要加载其地址
// 在 ARM64 中,使用 ADRP + ADD 指令获取全局变量地址
// 简化版本:先为全局变量分配一个栈槽,然后加载地址到该栈槽
// 检查是否已经为这个全局变量分配了栈槽
auto it = slots.find(value);
if (it == slots.end()) {
// 为全局变量创建栈槽
const_cast<ValueSlotMap&>(slots).emplace(value,
const_cast<MachineFunction&>(function).CreateFrameIndex(8));
it = slots.find(value);
}
// 从栈槽加载地址到目标寄存器
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)) {
@ -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<const ir::GlobalValue*>(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<const ir::LoadInst&>(inst);
const ir::Value* ptr = load.GetPtr();
int dstSlot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get()));
// 处理全局变量作为加载源
if (auto* global = dynamic_cast<const ir::GlobalValue*>(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<MachineModule> LowerToMIR(const ir::Module& module) {
auto machine_module = std::make_unique<MachineModule>();
// 收集全局变量信息
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<const ir::GlobalValue*> globals;
// 处理全局变量
for (const auto& global : module.GetGlobals()) {

Loading…
Cancel
Save