|
|
|
|
@ -258,55 +258,74 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
|
|
|
|
<< " (opcode: " << static_cast<int>(inst.GetOpcode()) << ")");
|
|
|
|
|
switch (inst.GetOpcode()) {
|
|
|
|
|
case ir::Opcode::Alloca: {
|
|
|
|
|
slots.emplace(&inst, function.CreateFrameIndex(GetTypeSize(inst.GetType().get())));
|
|
|
|
|
return;
|
|
|
|
|
// alloca 返回一个指针,我们需要为该指针分配一个栈槽(存放地址值)
|
|
|
|
|
int ptrSlot = function.CreateFrameIndex(8); // 指针占8字节
|
|
|
|
|
// 为数组数据分配实际栈空间
|
|
|
|
|
int arraySlot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get()));
|
|
|
|
|
|
|
|
|
|
// 将数组基地址(sp + arraySlot_offset)加载到 x8
|
|
|
|
|
block.Append(Opcode::LoadStackAddr,
|
|
|
|
|
{Operand::Reg(PhysReg::X8), Operand::FrameIndex(arraySlot)});
|
|
|
|
|
// 将地址存储到指针槽
|
|
|
|
|
block.Append(Opcode::StoreStack,
|
|
|
|
|
{Operand::Reg(PhysReg::X8), Operand::FrameIndex(ptrSlot)});
|
|
|
|
|
|
|
|
|
|
// 将 alloca 指令映射到指针槽,后续使用 alloca 值即获得地址
|
|
|
|
|
slots.emplace(&inst, ptrSlot);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
case ir::Opcode::Store: {
|
|
|
|
|
auto& store = static_cast<const ir::StoreInst&>(inst);
|
|
|
|
|
auto dst = slots.find(store.GetPtr());
|
|
|
|
|
if (dst == slots.end()) {
|
|
|
|
|
//throw std::runtime_error(
|
|
|
|
|
// FormatError("mir", "暂不支持对非栈变量地址进行写入"));
|
|
|
|
|
EmitValueToReg(store.GetPtr(), PhysReg::X8, slots, block, function);
|
|
|
|
|
// 加载值到 w9
|
|
|
|
|
EmitValueToReg(store.GetValue(), PhysReg::W9, slots, block, function);
|
|
|
|
|
// 存储值到地址
|
|
|
|
|
block.Append(Opcode::StoreStack,
|
|
|
|
|
{Operand::Reg(PhysReg::W9), Operand::Reg(PhysReg::X8)});
|
|
|
|
|
auto& store = static_cast<const ir::StoreInst&>(inst);
|
|
|
|
|
const ir::Value* ptr = store.GetPtr();
|
|
|
|
|
const ir::Value* val = store.GetValue();
|
|
|
|
|
|
|
|
|
|
auto dstIt = slots.find(ptr);
|
|
|
|
|
if (dstIt == slots.end()) {
|
|
|
|
|
// 指针不在 slots 中(例如直接来自函数参数的指针)
|
|
|
|
|
// 计算指针地址到 x8
|
|
|
|
|
EmitValueToReg(ptr, PhysReg::X8, slots, block, function);
|
|
|
|
|
// 加载要存储的值到 w9
|
|
|
|
|
EmitValueToReg(val, PhysReg::W9, slots, block, function);
|
|
|
|
|
// 使用 StoreStack 的寄存器间接形式(str w9, [x8])
|
|
|
|
|
block.Append(Opcode::StoreStack,
|
|
|
|
|
{Operand::Reg(PhysReg::W9), Operand::Reg(PhysReg::X8)});
|
|
|
|
|
} else {
|
|
|
|
|
// 指针在 slots 中(alloca 或 gep 的结果),从指针槽加载地址到 x8
|
|
|
|
|
block.Append(Opcode::LoadStack,
|
|
|
|
|
{Operand::Reg(PhysReg::X8), Operand::FrameIndex(dstIt->second)});
|
|
|
|
|
// 加载要存储的值到 w9
|
|
|
|
|
EmitValueToReg(val, PhysReg::W9, slots, block, function);
|
|
|
|
|
// 间接存储
|
|
|
|
|
block.Append(Opcode::StoreStack,
|
|
|
|
|
{Operand::Reg(PhysReg::W9), Operand::Reg(PhysReg::X8)});
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
EmitValueToReg(store.GetValue(), PhysReg::W8, slots, block, function);
|
|
|
|
|
block.Append(Opcode::StoreStack,
|
|
|
|
|
{Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst->second)});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
case ir::Opcode::Load: {
|
|
|
|
|
auto& load = static_cast<const ir::LoadInst&>(inst);
|
|
|
|
|
auto src = slots.find(load.GetPtr());
|
|
|
|
|
if (src == slots.end()) {
|
|
|
|
|
//throw std::runtime_error(
|
|
|
|
|
// FormatError("mir", "暂不支持对非栈变量地址进行读取"));
|
|
|
|
|
// 对于非栈变量地址(如 GEP 结果),地址本身在栈槽中
|
|
|
|
|
// 需要先加载地址,然后从该地址加载值
|
|
|
|
|
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get()));
|
|
|
|
|
// 加载地址到 x8
|
|
|
|
|
EmitValueToReg(load.GetPtr(), PhysReg::X8, slots, block, function);
|
|
|
|
|
// 从地址加载值到 w9
|
|
|
|
|
block.Append(Opcode::LoadStack,
|
|
|
|
|
{Operand::Reg(PhysReg::W9), Operand::Reg(PhysReg::X8)});
|
|
|
|
|
// 存储值到结果栈槽
|
|
|
|
|
auto& load = static_cast<const ir::LoadInst&>(inst);
|
|
|
|
|
const ir::Value* ptr = load.GetPtr();
|
|
|
|
|
int dstSlot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get()));
|
|
|
|
|
|
|
|
|
|
auto srcIt = slots.find(ptr);
|
|
|
|
|
if (srcIt == slots.end()) {
|
|
|
|
|
// 指针不在 slots 中,计算地址到 x8
|
|
|
|
|
EmitValueToReg(ptr, PhysReg::X8, slots, block, function);
|
|
|
|
|
// 间接加载到 w9
|
|
|
|
|
block.Append(Opcode::LoadStack,
|
|
|
|
|
{Operand::Reg(PhysReg::W9), Operand::Reg(PhysReg::X8)});
|
|
|
|
|
} else {
|
|
|
|
|
// 从指针槽加载地址到 x8
|
|
|
|
|
block.Append(Opcode::LoadStack,
|
|
|
|
|
{Operand::Reg(PhysReg::X8), Operand::FrameIndex(srcIt->second)});
|
|
|
|
|
// 间接加载到 w9
|
|
|
|
|
block.Append(Opcode::LoadStack,
|
|
|
|
|
{Operand::Reg(PhysReg::W9), Operand::Reg(PhysReg::X8)});
|
|
|
|
|
}
|
|
|
|
|
// 将加载的值存入结果槽
|
|
|
|
|
block.Append(Opcode::StoreStack,
|
|
|
|
|
{Operand::Reg(PhysReg::W9), Operand::FrameIndex(dst_slot)});
|
|
|
|
|
slots.emplace(&inst, dst_slot);
|
|
|
|
|
{Operand::Reg(PhysReg::W9), Operand::FrameIndex(dstSlot)});
|
|
|
|
|
slots.emplace(&inst, dstSlot);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); // 分配结果槽
|
|
|
|
|
block.Append(Opcode::LoadStack,
|
|
|
|
|
{Operand::Reg(PhysReg::W8), Operand::FrameIndex(src->second)});
|
|
|
|
|
block.Append(Opcode::StoreStack,
|
|
|
|
|
{Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
|
|
|
|
|
slots.emplace(&inst, dst_slot);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
case ir::Opcode::Add: {
|
|
|
|
|
auto& bin = static_cast<const ir::BinaryInst&>(inst);
|
|
|
|
|
@ -973,7 +992,6 @@ std::unique_ptr<MachineFunction> LowerFunction(const ir::Function& func) {
|
|
|
|
|
LowerInstruction(*inst, *machine_func, slots, *mirBB, blockMap);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return machine_func;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|