You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1164 lines
50 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "mir/MIR.h"
#include <stdexcept>
#include <unordered_map>
#include <cstring>
#include "ir/IR.h"
#include "utils/Log.h"
//#define DEBUG_Lower
#ifdef DEBUG_Lower
#include <iostream>
#define DEBUG_MSG(msg) std::cerr << "[Lower Debug] " << msg << std::endl
#else
#define DEBUG_MSG(msg) ((void)0)
#endif
namespace mir {
namespace {
using ValueSlotMap = std::unordered_map<const ir::Value*, int>;
static uint32_t FloatToBits(float f) {
uint32_t bits;
memcpy(&bits, &f, sizeof(bits));
return bits;
}
// 获取类型大小(字节)
int GetTypeSize(const ir::Type* type) {
if (!type) return 4;
size_t size = type->Size();
return size > 0 ? static_cast<int>(size) : 4;
}
// 将 IR 整数比较谓词转换为 ARMv8 条件码
CondCode IcmpToCondCode(ir::IcmpInst::Predicate pred) {
switch (pred) {
case ir::IcmpInst::Predicate::EQ: return CondCode::EQ;
case ir::IcmpInst::Predicate::NE: return CondCode::NE;
case ir::IcmpInst::Predicate::LT: return CondCode::LT;
case ir::IcmpInst::Predicate::GT: return CondCode::GT;
case ir::IcmpInst::Predicate::LE: return CondCode::LE;
case ir::IcmpInst::Predicate::GE: return CondCode::GE;
default: return CondCode::AL;
}
}
// 将 IR 浮点比较谓词转换为 ARMv8 条件码
CondCode FcmpToCondCode(ir::FcmpInst::Predicate pred, bool& isOrdered) {
isOrdered = true;
switch (pred) {
case ir::FcmpInst::Predicate::OEQ: return CondCode::EQ;
case ir::FcmpInst::Predicate::ONE: return CondCode::NE;
case ir::FcmpInst::Predicate::OLT: return CondCode::LT;
case ir::FcmpInst::Predicate::OGT: return CondCode::GT;
case ir::FcmpInst::Predicate::OLE: return CondCode::LE;
case ir::FcmpInst::Predicate::OGE: return CondCode::GE;
case ir::FcmpInst::Predicate::UEQ: isOrdered = false; return CondCode::EQ;
case ir::FcmpInst::Predicate::UNE: isOrdered = false; return CondCode::NE;
case ir::FcmpInst::Predicate::ULT: isOrdered = false; return CondCode::LT;
case ir::FcmpInst::Predicate::UGT: isOrdered = false; return CondCode::GT;
case ir::FcmpInst::Predicate::ULE: isOrdered = false; return CondCode::LE;
case ir::FcmpInst::Predicate::UGE: isOrdered = false; return CondCode::GE;
default: return CondCode::AL;
}
}
// 获取基本块的标签名(用于汇编输出)
std::string GetBlockLabel(const ir::BasicBlock* bb) {
if (!bb || !bb->GetParent()) {
return ".Lunknown";
}
// 格式:.L函数名_基本块名
std::string funcName = bb->GetParent()->GetName();
std::string blockName = bb->GetName();
// 如果基本块没有名字,使用地址作为标识
if (blockName.empty()) {
blockName = std::to_string(reinterpret_cast<uintptr_t>(bb));
}
return ".L" + funcName + "_" + blockName;
}
// 获取数组类型的维度信息
static const ir::ArrayType* GetArrayType(const ir::Type* type) {
if (type->IsArray()) {
return static_cast<const ir::ArrayType*>(type);
}
return nullptr;
}
static std::vector<int> GetArrayStrides(const ir::ArrayType* arrayType) {
std::vector<int> strides;
const std::vector<int>& dims = arrayType->GetDimensions();
int stride = 4; // 元素大小int/float 是 4 字节)
// 从最后一维向前计算步长
for (int i = dims.size() - 1; i >= 0; --i) {
strides.insert(strides.begin(), stride);
stride *= dims[i];
}
return strides;
}
// 在 Lowering.cpp 中添加辅助函数
const ir::Value* GetOperand(const ir::Instruction& inst, size_t index) {
if (index < inst.GetNumOperands()) {
return inst.GetOperand(index);
}
return nullptr;
}
const ir::BasicBlock* GetBasicBlockOperand(const ir::Instruction& inst, size_t index) {
const ir::Value* operand = GetOperand(inst, index);
if (operand) {
return dynamic_cast<const ir::BasicBlock*>(operand);
}
return nullptr;
}
void EmitValueToReg(const ir::Value* value, PhysReg target,
const ValueSlotMap& slots, MachineBasicBlock& block,
MachineFunction& function) {
// 处理整数常量
if (value == nullptr) {
DEBUG_MSG( "EmitValueToReg called with null value\n");
}
// 辅助函数判断32位立即数是否可用单条 movz/movn 编码
auto isLegalMovImm = [](uint32_t imm) -> bool {
// 检查是否可以通过 movz 或 movn 表示16位立即数可左移0/16/32/48位
// 对于32位寄存器只考虑 lsl 0 或 16
if ((imm & 0xFFFF) == imm) return true; // 低16位lsl #0
if ((imm & 0xFFFF0000) == imm) return true; // 高16位lsl #16
// 可选:检查 movn 情况(~imm 满足上述条件),为了简单可不做,直接返回 false
return false;
};
if (auto* constant = dynamic_cast<const ir::ConstantInt*>(value)) {
uint32_t imm = static_cast<uint32_t>(constant->GetValue());
if (isLegalMovImm(imm)) {
block.Append(Opcode::MovImm,
{Operand::Reg(target), Operand::Imm(static_cast<int64_t>(imm))});
} else {
// 分解为 movz (低16位) + movk (高16位)
uint16_t low = imm & 0xFFFF;
uint16_t high = (imm >> 16) & 0xFFFF;
block.Append(Opcode::MovImm,
{Operand::Reg(target), Operand::Imm(low)}); // 先加载低16位
if (high != 0) {
// 使用 Movk 指令写入高16位
block.Append(Opcode::Movk,
{Operand::Reg(target), Operand::Imm(high), Operand::Imm(16)});
}
}
return;
}
// 处理浮点常量
if (auto* fconstant = dynamic_cast<const ir::ConstantFloat*>(value)) {
// 检查是否已经为这个常量分配了栈槽
auto it = slots.find(value);
int slot;
if (it == slots.end()) {
DEBUG_MSG("Value not found: " << value->GetName());
// 输出所有 slots 的键名用于调试
for (auto& p : slots) {
DEBUG_MSG(" Slot key: " << p.first->GetName());
}
// 分配新的栈槽
slot = function.CreateFrameIndex(4);
// 将浮点常量存储到栈槽
float fval = fconstant->GetValue();
uint32_t int_val = FloatToBits(fval);
// 同样需要对 int_val 进行大立即数分解
if (isLegalMovImm(int_val)) {
block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(static_cast<int64_t>(int_val))});
} else {
uint16_t low = int_val & 0xFFFF;
uint16_t high = (int_val >> 16) & 0xFFFF;
block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(low)});
if (high != 0) {
block.Append(Opcode::Movk, {Operand::Reg(PhysReg::W8), Operand::Imm(high), Operand::Imm(16)});
}
}
block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(slot)});
const_cast<ValueSlotMap&>(slots).emplace(value, slot);
} else {
slot = it->second;
}
// 从栈槽加载到目标寄存器
block.Append(Opcode::LoadStack, {Operand::Reg(target), Operand::FrameIndex(slot)});
return;
}
// 处理零常量
if (dynamic_cast<const ir::ConstantZero*>(value) ||
dynamic_cast<const ir::ConstantAggregateZero*>(value)) {
// 零常量:直接加载 0
block.Append(Opcode::MovImm,
{Operand::Reg(target), Operand::Imm(0)});
return;
}
// ========== 处理全局变量 ==========
if (auto* global = dynamic_cast<const ir::GlobalValue*>(value)) {
// 如果目标是 32 位寄存器,升级为对应的 64 位寄存器
PhysReg addrTarget = target;
if (target >= PhysReg::W0 && target <= PhysReg::W30) {
// 映射 Wn → Xn
addrTarget = static_cast<PhysReg>(
static_cast<int>(target) - static_cast<int>(PhysReg::W0) + static_cast<int>(PhysReg::X0));
}
// 现在 addrTarget 一定是 64 位寄存器
block.Append(Opcode::Adrp, {Operand::Reg(addrTarget), Operand::Label(global->GetName())});
block.Append(Opcode::AddLabel, {Operand::Reg(addrTarget), Operand::Reg(addrTarget), Operand::Label(global->GetName())});
return;
}
// ========== 处理从栈槽加载的值 ==========
auto it = slots.find(value);
if (it == slots.end()) {
// 使用值的地址作为调试信息
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) {
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", "找不到值对应的栈槽: " + valueName));
}
PhysReg actualTarget = target;
const ir::Type* ty = value->GetType().get();
bool isPointer = ty->IsPtrInt32() || ty->IsPtrFloat() || ty->IsPtrInt1()
|| ty->IsArray(); // 数组类型在地址上下文中视为指针
// 若非指针类型且目标是 64 位寄存器,降级为对应的 32 位寄存器(自动零扩展)
if (!isPointer && target >= PhysReg::X0 && target <= PhysReg::X30) {
actualTarget = static_cast<PhysReg>(
static_cast<int>(target) - static_cast<int>(PhysReg::X0) + static_cast<int>(PhysReg::W0));
}
block.Append(Opcode::LoadStack,
{Operand::Reg(actualTarget), Operand::FrameIndex(it->second)});
}
void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
ValueSlotMap& slots, MachineBasicBlock& block,
std::unordered_map<const ir::BasicBlock*,
MachineBasicBlock*>& blockMap) {
//auto& block = function.GetEntry();
DEBUG_MSG("Processing instruction: " << inst.GetName()
<< " (opcode: " << static_cast<int>(inst.GetOpcode()) << ")");
switch (inst.GetOpcode()) {
case ir::Opcode::Alloca: {
// 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);
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 中(例如直接来自函数参数的指针)
// 计算指针地址到 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;
}
case ir::Opcode::Load: {
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()) {
// 指针不在 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(dstSlot)});
slots.emplace(&inst, dstSlot);
return;
}
case ir::Opcode::Add: {
auto& bin = static_cast<const ir::BinaryInst&>(inst);
const ir::Type* lhsTy = bin.GetLhs()->GetType().get();
const ir::Type* rhsTy = bin.GetRhs()->GetType().get();
// 指针判断:指令结果类型是指针,或者任一操作数是指针(指针算术)
bool isPointer = (lhsTy->IsPtrInt32() || lhsTy->IsPtrFloat() || lhsTy->IsPtrInt1() || lhsTy->IsArray()) ||
(rhsTy->IsPtrInt32() || rhsTy->IsPtrFloat() || rhsTy->IsPtrInt1() || rhsTy->IsArray()) ||
inst.GetType()->IsPtrInt32() || inst.GetType()->IsPtrFloat() || inst.GetType()->IsPtrInt1() || inst.GetType()->IsArray();
int slotSize = isPointer ? 8 : 4;
PhysReg lhsReg = isPointer ? PhysReg::X8 : PhysReg::W8;
PhysReg rhsReg = isPointer ? PhysReg::X9 : PhysReg::W9;
PhysReg dstReg = isPointer ? PhysReg::X8 : PhysReg::W8;
int dst_slot = function.CreateFrameIndex(slotSize); // 使用计算出的 slotSize
EmitValueToReg(bin.GetLhs(), lhsReg, slots, block, function);
EmitValueToReg(bin.GetRhs(), rhsReg, slots, block, function);
block.Append(Opcode::AddRR, {Operand::Reg(dstReg), Operand::Reg(lhsReg), Operand::Reg(rhsReg)});
block.Append(Opcode::StoreStack, {Operand::Reg(dstReg), Operand::FrameIndex(dst_slot)});
slots.emplace(&inst, dst_slot);
return;
}
case ir::Opcode::Sub: {
auto& bin = static_cast<const ir::BinaryInst&>(inst);
const ir::Type* lhsTy = bin.GetLhs()->GetType().get();
const ir::Type* rhsTy = bin.GetRhs()->GetType().get();
// 指针判断:指令结果类型是指针,或者任一操作数是指针(指针算术)
bool isPointer = (lhsTy->IsPtrInt32() || lhsTy->IsPtrFloat() || lhsTy->IsPtrInt1() || lhsTy->IsArray()) ||
(rhsTy->IsPtrInt32() || rhsTy->IsPtrFloat() || rhsTy->IsPtrInt1() || rhsTy->IsArray()) ||
inst.GetType()->IsPtrInt32() || inst.GetType()->IsPtrFloat() || inst.GetType()->IsPtrInt1() || inst.GetType()->IsArray();
int slotSize = isPointer ? 8 : 4;
PhysReg lhsReg = isPointer ? PhysReg::X8 : PhysReg::W8;
PhysReg rhsReg = isPointer ? PhysReg::X9 : PhysReg::W9;
PhysReg dstReg = isPointer ? PhysReg::X8 : PhysReg::W8;
int dst_slot = function.CreateFrameIndex(slotSize); // 使用计算出的 slotSize
EmitValueToReg(bin.GetLhs(), lhsReg, slots, block, function);
EmitValueToReg(bin.GetRhs(), rhsReg, slots, block, function);
block.Append(Opcode::SubRR, {Operand::Reg(dstReg), Operand::Reg(lhsReg), Operand::Reg(rhsReg)});
block.Append(Opcode::StoreStack, {Operand::Reg(dstReg), Operand::FrameIndex(dst_slot)});
slots.emplace(&inst, dst_slot);
return;
}
case ir::Opcode::Mul: {
auto& bin = static_cast<const ir::BinaryInst&>(inst);
const ir::Type* ty = inst.GetType().get();
bool isPointer = ty->IsPtrInt32() || ty->IsPtrFloat() || ty->IsPtrInt1();
int slotSize = isPointer ? 8 : 4;
PhysReg lhsReg = isPointer ? PhysReg::X8 : PhysReg::W8;
PhysReg rhsReg = isPointer ? PhysReg::X9 : PhysReg::W9;
PhysReg dstReg = isPointer ? PhysReg::X8 : PhysReg::W8; // 可复用 lhsReg
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); // 分配结果栈槽
EmitValueToReg(bin.GetLhs(), lhsReg, slots, block, function);
EmitValueToReg(bin.GetRhs(), rhsReg, slots, block, function);
block.Append(Opcode::MulRR, {Operand::Reg(dstReg),
Operand::Reg(lhsReg),
Operand::Reg(rhsReg)});
block.Append(Opcode::StoreStack,
{Operand::Reg(dstReg), Operand::FrameIndex(dst_slot)});
slots.emplace(&inst, dst_slot);
return;
}
case ir::Opcode::Div: {
auto& bin = static_cast<const ir::BinaryInst&>(inst);
const ir::Type* ty = inst.GetType().get();
bool isPointer = ty->IsPtrInt32() || ty->IsPtrFloat() || ty->IsPtrInt1();
int slotSize = isPointer ? 8 : 4;
PhysReg lhsReg = isPointer ? PhysReg::X8 : PhysReg::W8;
PhysReg rhsReg = isPointer ? PhysReg::X9 : PhysReg::W9;
PhysReg dstReg = isPointer ? PhysReg::X8 : PhysReg::W8; // 可复用 lhsReg
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); // 分配结果栈槽
EmitValueToReg(bin.GetLhs(), lhsReg, slots, block, function);
EmitValueToReg(bin.GetRhs(), rhsReg, slots, block, function);
block.Append(Opcode::SDivRR, {Operand::Reg(dstReg),
Operand::Reg(lhsReg),
Operand::Reg(rhsReg)});
block.Append(Opcode::StoreStack,
{Operand::Reg(dstReg), Operand::FrameIndex(dst_slot)});
slots.emplace(&inst, dst_slot);
return;
}
case ir::Opcode::Ret: {
auto& ret = static_cast<const ir::ReturnInst&>(inst);
const ir::Value* retVal = ret.GetValue();
if (retVal != nullptr) {
const ir::Type* retType = retVal->GetType().get();
PhysReg retReg = PhysReg::W0; // 默认整数返回值
if (retType->IsFloat()) {
retReg = PhysReg::S0;
} else if (retType->IsPtrInt32() || retType->IsPtrFloat() || retType->IsPtrInt1()) {
retReg = PhysReg::X0;
} else {
retReg = PhysReg::W0;
}
EmitValueToReg(retVal, retReg, slots, block, function);
}
block.Append(Opcode::Ret);
return;
}
case ir::Opcode::FAdd: {
auto& bin = static_cast<const ir::BinaryInst&>(inst);
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); // 分配结果栈槽
// 浮点值加载到 S0, S1使用浮点寄存器
EmitValueToReg(bin.GetLhs(), PhysReg::S0, slots, block, function);
EmitValueToReg(bin.GetRhs(), PhysReg::S1, slots, block, function);
block.Append(Opcode::FAddRR, {Operand::Reg(PhysReg::S0),
Operand::Reg(PhysReg::S0),
Operand::Reg(PhysReg::S1)});
block.Append(Opcode::StoreStack,
{Operand::Reg(PhysReg::S0), Operand::FrameIndex(dst_slot)});
slots.emplace(&inst, dst_slot);
return;
}
case ir::Opcode::FSub: {
auto& bin = static_cast<const ir::BinaryInst&>(inst);
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); // 分配结果栈槽
// 浮点值加载到 S0, S1使用浮点寄存器
EmitValueToReg(bin.GetLhs(), PhysReg::S0, slots, block, function);
EmitValueToReg(bin.GetRhs(), PhysReg::S1, slots, block, function);
block.Append(Opcode::FSubRR, {Operand::Reg(PhysReg::S0),
Operand::Reg(PhysReg::S0),
Operand::Reg(PhysReg::S1)});
block.Append(Opcode::StoreStack,
{Operand::Reg(PhysReg::S0), Operand::FrameIndex(dst_slot)});
slots.emplace(&inst, dst_slot);
return;
}
case ir::Opcode::FMul: {
auto& bin = static_cast<const ir::BinaryInst&>(inst);
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); // 分配结果栈槽
// 浮点值加载到 S0, S1使用浮点寄存器
EmitValueToReg(bin.GetLhs(), PhysReg::S0, slots, block, function);
EmitValueToReg(bin.GetRhs(), PhysReg::S1, slots, block, function);
block.Append(Opcode::FMulRR, {Operand::Reg(PhysReg::S0),
Operand::Reg(PhysReg::S0),
Operand::Reg(PhysReg::S1)});
block.Append(Opcode::StoreStack,
{Operand::Reg(PhysReg::S0), Operand::FrameIndex(dst_slot)});
slots.emplace(&inst, dst_slot);
return;
}
case ir::Opcode::FDiv: {
auto& bin = static_cast<const ir::BinaryInst&>(inst);
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); // 分配结果栈槽
// 浮点值加载到 S0, S1使用浮点寄存器
EmitValueToReg(bin.GetLhs(), PhysReg::S0, slots, block, function);
EmitValueToReg(bin.GetRhs(), PhysReg::S1, slots, block, function);
block.Append(Opcode::FDivRR, {Operand::Reg(PhysReg::S0),
Operand::Reg(PhysReg::S0),
Operand::Reg(PhysReg::S1)});
block.Append(Opcode::StoreStack,
{Operand::Reg(PhysReg::S0), Operand::FrameIndex(dst_slot)});
slots.emplace(&inst, dst_slot);
return;
}
// ========== 整数比较指令(修正版)==========
case ir::Opcode::Icmp: {
auto& icmp = static_cast<const ir::IcmpInst&>(inst);
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get()));
EmitValueToReg(icmp.GetLhs(), PhysReg::W8, slots, block, function);
EmitValueToReg(icmp.GetRhs(), PhysReg::W9, slots, block, function);
block.Append(Opcode::CmpRR, {Operand::Reg(PhysReg::W8), Operand::Reg(PhysReg::W9)});
CondCode cc = IcmpToCondCode(icmp.GetPredicate());
// 使用 CSET 模式
block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(1)});
block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W9), Operand::Imm(0)});
std::string true_label = ".L_cset_true_" + std::to_string(reinterpret_cast<uintptr_t>(&icmp));
std::string end_label = ".L_cset_end_" + std::to_string(reinterpret_cast<uintptr_t>(&icmp));
block.Append(Opcode::BCond, {Operand::Cond(cc), Operand::Label(true_label)});
block.Append(Opcode::MovReg, {Operand::Reg(PhysReg::W8), Operand::Reg(PhysReg::W9)});
block.Append(Opcode::B, {Operand::Label(end_label)});
block.Append(Opcode::Label, {Operand::Label(true_label)});
block.Append(Opcode::Label, {Operand::Label(end_label)});
block.Append(Opcode::StoreStack,
{Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
slots.emplace(&inst, dst_slot);
return;
}
// ========== 浮点比较指令 ==========
case ir::Opcode::FCmp: {
auto& fcmp = static_cast<const ir::FcmpInst&>(inst);
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get()));
// 加载浮点操作数到 s0, s1
EmitValueToReg(fcmp.GetLhs(), PhysReg::S0, slots, block, function);
EmitValueToReg(fcmp.GetRhs(), PhysReg::S1, slots, block, function);
// 生成浮点比较指令
block.Append(Opcode::FCmpRR, {Operand::Reg(PhysReg::S0), Operand::Reg(PhysReg::S1)});
// 简化实现:存储 1 作为结果
block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(1)});
block.Append(Opcode::StoreStack,
{Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
slots.emplace(&inst, dst_slot);
return;
}
// ========== 跳转指令(使用标签操作数)==========
case ir::Opcode::Br: {
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);
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)});
return;
}
// ========== 函数调用 ==========
case ir::Opcode::Call: {
auto& call = static_cast<const ir::CallInst&>(inst);
const ir::Function* callee = call.GetCallee();
const std::string& calleeName = callee->GetName();
// 分配结果栈槽(如果有返回值)
int dst_slot = -1;
if (!inst.GetType()->IsVoid()) {
dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get()));
}
// 按照 ARM64 调用约定传递参数
const auto& args = call.GetArgs();
size_t intArgCount = 0;
size_t fpArgCount = 0;
for (size_t i = 0; i < args.size(); ++i) {
const auto* arg = args[i];
const ir::Type* argType = arg->GetType().get();
if (argType->IsFloat()) {
// 浮点参数
PhysReg reg = static_cast<PhysReg>(static_cast<int>(PhysReg::S0) + fpArgCount);
EmitValueToReg(arg, reg, slots, block, function);
fpArgCount++;
} else if (argType->IsPtrInt32() || argType->IsPtrFloat() || argType->IsPtrInt1()) {
// 指针参数 → X 寄存器(占用一个整数参数槽)
PhysReg reg = static_cast<PhysReg>(static_cast<int>(PhysReg::X0) + intArgCount);
EmitValueToReg(arg, reg, slots, block, function);
intArgCount++;
} else {
// 普通整数 → W 寄存器
PhysReg reg = static_cast<PhysReg>(static_cast<int>(PhysReg::W0) + intArgCount);
EmitValueToReg(arg, reg, slots, block, function);
intArgCount++;
}
}
// 生成调用指令
//block.Append(Opcode::Call, {Operand::Imm(0)}); // 实际需要传递函数名
block.Append(Opcode::Call, {Operand::Label(calleeName)});
// 保存返回值
if (dst_slot != -1) {
const ir::Type* retType = inst.GetType().get();
PhysReg srcReg = PhysReg::W0;
if (retType->IsFloat()) {
srcReg = PhysReg::S0;
} else if (retType->IsPtrInt32() || retType->IsPtrFloat() || retType->IsPtrInt1()) {
srcReg = PhysReg::X0;
} else {
srcReg = PhysReg::W0;
}
block.Append(Opcode::StoreStack,
{Operand::Reg(srcReg), Operand::FrameIndex(dst_slot)});
slots.emplace(&inst, dst_slot);
}
return;
}
// ========== 类型转换指令 ==========
case ir::Opcode::ZExt: {
auto& zext = static_cast<const ir::ZExtInst&>(inst);
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get()));
// 加载源值到 w8
EmitValueToReg(zext.GetValue(), PhysReg::W8, slots, block, function);
// 零扩展i1 -> i32直接存储即可因为 i1 已经是 0 或 1
block.Append(Opcode::StoreStack,
{Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
slots.emplace(&inst, dst_slot);
return;
}
case ir::Opcode::SIToFP: {
auto& sitofp = static_cast<const ir::SIToFPInst&>(inst);
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get()));
// 加载整数到 w8
EmitValueToReg(sitofp.GetValue(), PhysReg::W8, slots, block, function);
// 整数转浮点SCVTF s0, w8
block.Append(Opcode::SIToFP, {Operand::Reg(PhysReg::S0), Operand::Reg(PhysReg::W8)});
block.Append(Opcode::StoreStack,
{Operand::Reg(PhysReg::S0), Operand::FrameIndex(dst_slot)});
slots.emplace(&inst, dst_slot);
return;
}
case ir::Opcode::FPToSI: {
auto& fptosi = static_cast<const ir::FPToSIInst&>(inst);
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get()));
// 加载浮点数到 s0
EmitValueToReg(fptosi.GetValue(), PhysReg::S0, slots, block, function);
// 浮点转整数FCVTZS w8, s0
block.Append(Opcode::FPToSI, {Operand::Reg(PhysReg::W8), Operand::Reg(PhysReg::S0)});
block.Append(Opcode::StoreStack,
{Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
slots.emplace(&inst, dst_slot);
return;
}
case ir::Opcode::GEP: {
auto& gep = static_cast<const ir::GEPInst&>(inst);
DEBUG_MSG("Processing GEP instruction: " << inst.GetName());
// GEP 返回指针类型,在 ARM64 上指针是 8 字节
int dst_slot = function.CreateFrameIndex(8);
// 获取基地址(数组的起始地址)
ir::Value* base = gep.GetBase();
const auto& indices = gep.GetIndices();
std::string baseName = base->GetName().empty() ? "unnamed" : base->GetName();
DEBUG_MSG("Base value: " << baseName);
DEBUG_MSG("Number of indices: " << indices.size());
// 打印索引值
for (size_t idx_i = 0; idx_i < indices.size(); ++idx_i) {
if (auto* const_int = dynamic_cast<const ir::ConstantInt*>(indices[idx_i])) {
DEBUG_MSG(" Index[" << idx_i << "] = " << const_int->GetValue() << " (constant)");
} else {
DEBUG_MSG(" Index[" << idx_i << "] = variable");
}
}
// 加载基地址到 x8
EmitValueToReg(base, PhysReg::X8, slots, block, function);
if (indices.empty()) {
DEBUG_MSG("No indices, storing base address directly");
block.Append(Opcode::StoreStack,
{Operand::Reg(PhysReg::X8), Operand::FrameIndex(dst_slot)});
slots.emplace(&inst, dst_slot);
return;
}
// 获取基地址类型
const ir::Type* baseType = base->GetType().get();
DEBUG_MSG("Base type kind: " << static_cast<int>(baseType->GetKind()));
// 关键修改:对于数组指针类型,第一个索引是多余的,应该跳过
size_t start_index = 0;
if (baseType->IsPtrInt32() || baseType->IsPtrFloat() || baseType->IsPtrInt1()) {
// 对于指针类型,第一个索引是偏移量,不能跳过
DEBUG_MSG("Base is pointer type, using all indices for pointer arithmetic");
start_index = 0;
} else if (baseType->IsArray()) {
// 对于数组类型(非指针),第一个索引是多余的
// 因为 base 已经是数组本身,不需要再解引用
DEBUG_MSG("Base is array type, skipping first index (array decay)");
start_index = 1;
}
// 如果基地址是数组类型,需要处理多维数组
if (baseType->IsArray()) {
DEBUG_MSG("Base is array type, processing multi-dimensional array");
const ir::ArrayType* arrayType = static_cast<const ir::ArrayType*>(baseType);
const std::vector<int>& dims = arrayType->GetDimensions();
DEBUG_MSG("Array dimensions: ");
for (size_t i = 0; i < dims.size(); ++i) {
DEBUG_MSG(" dim[" << i << "] = " << dims[i]);
}
// 正确计算每个维度的步长
std::vector<int> strides(dims.size());
int element_size = 4; // 元素大小int/float 是 4 字节)
for (int i = dims.size() - 1; i >= 0; --i) {
if (i == static_cast<int>(dims.size()) - 1) {
strides[i] = element_size;
DEBUG_MSG("strides[" << i << "] = " << strides[i] << " (element size)");
} else {
strides[i] = strides[i + 1] * dims[i + 1];
DEBUG_MSG("strides[" << i << "] = " << strides[i+1] << " * " << dims[i+1]
<< " = " << strides[i]);
}
}
// 计算总偏移,跳过第一个索引
size_t numIndices = indices.size();
size_t effective_indices = numIndices - start_index;
if (effective_indices > dims.size()) {
DEBUG_MSG("Warning: effective indices (" << effective_indices << ") > dims.size() ("
<< dims.size() << "), truncating");
effective_indices = dims.size();
}
DEBUG_MSG("Using " << effective_indices << " effective indices (starting from " << start_index << ")");
// 加载当前地址到 x9 作为偏移量累加器
block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::X9), Operand::Imm(0)});
// 用于调试的静态偏移计算
int debug_offset = 0;
for (size_t i = 0; i < effective_indices; ++i) {
size_t idx_pos = start_index + i;
int index_value = 0;
if (auto* const_int = dynamic_cast<const ir::ConstantInt*>(indices[idx_pos])) {
index_value = const_int->GetValue();
DEBUG_MSG("Index[" << idx_pos << "] = " << index_value << " (constant)");
debug_offset += index_value * strides[i];
DEBUG_MSG(" Contribution = " << index_value << " * " << strides[i]
<< " = " << (index_value * strides[i]));
DEBUG_MSG(" Running offset = " << debug_offset);
} else {
DEBUG_MSG("Index[" << idx_pos << "] = variable");
}
// 加载当前索引到 x10
EmitValueToReg(indices[idx_pos], PhysReg::X10, slots, block, function);
// 乘以步长
block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::X11), Operand::Imm(strides[i])});
block.Append(Opcode::MulRR, {Operand::Reg(PhysReg::X10),
Operand::Reg(PhysReg::X10),
Operand::Reg(PhysReg::X11)});
// 累加到偏移量
block.Append(Opcode::AddRR, {Operand::Reg(PhysReg::X9),
Operand::Reg(PhysReg::X9),
Operand::Reg(PhysReg::X10)});
}
DEBUG_MSG("Total computed offset = " << debug_offset);
// 最终地址 = base + offset
block.Append(Opcode::AddRR, {Operand::Reg(PhysReg::X8),
Operand::Reg(PhysReg::X8),
Operand::Reg(PhysReg::X9)});
// 存储计算出的地址
block.Append(Opcode::StoreStack,
{Operand::Reg(PhysReg::X8), Operand::FrameIndex(dst_slot)});
slots.emplace(&inst, dst_slot);
DEBUG_MSG("Array GEP completed, result stored in slot " << dst_slot);
return;
}
// 其他情况的处理...
DEBUG_MSG("Base is other type, using simple handling");
if (indices.size() >= 1) {
EmitValueToReg(indices[0], PhysReg::X9, slots, block, function);
// 乘以元素大小(默认 4 字节)
block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::X10), Operand::Imm(4)});
block.Append(Opcode::MulRR, {Operand::Reg(PhysReg::X9),
Operand::Reg(PhysReg::X9),
Operand::Reg(PhysReg::X10)});
block.Append(Opcode::AddRR, {Operand::Reg(PhysReg::X8),
Operand::Reg(PhysReg::X8),
Operand::Reg(PhysReg::X9)});
}
block.Append(Opcode::StoreStack,
{Operand::Reg(PhysReg::X8), Operand::FrameIndex(dst_slot)});
slots.emplace(&inst, dst_slot);
DEBUG_MSG("Simple GEP completed");
return;
}
// 处理 Trunc 指令
case ir::Opcode::Trunc: {
auto& inst_ref = static_cast<const ir::Instruction&>(inst);
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get()));
// 假设 Trunc 指令有 GetValue() 方法
// 如果没有,需要通过操作数列表获取
const ir::Value* src_val = nullptr;
if (inst.GetNumOperands() > 0) {
src_val = inst.GetOperand(0);
}
if (src_val) {
EmitValueToReg(src_val, PhysReg::W8, slots, block, function);
}
block.Append(Opcode::StoreStack,
{Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
slots.emplace(&inst, dst_slot);
return;
}
// 处理 Mod 指令
case ir::Opcode::Mod: {
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get()));
// 通过操作数获取左右值
const ir::Value* lhs = nullptr;
const ir::Value* rhs = nullptr;
if (inst.GetNumOperands() >= 2) {
lhs = inst.GetOperand(0);
rhs = inst.GetOperand(1);
}
if (lhs && rhs) {
EmitValueToReg(lhs, PhysReg::W8, slots, block, function);
EmitValueToReg(rhs, PhysReg::W9, slots, block, function);
// a % b = a - (a / b) * b
block.Append(Opcode::SDivRR, {Operand::Reg(PhysReg::W10),
Operand::Reg(PhysReg::W8),
Operand::Reg(PhysReg::W9)});
block.Append(Opcode::MulRR, {Operand::Reg(PhysReg::W10),
Operand::Reg(PhysReg::W10),
Operand::Reg(PhysReg::W9)});
block.Append(Opcode::SubRR, {Operand::Reg(PhysReg::W8),
Operand::Reg(PhysReg::W8),
Operand::Reg(PhysReg::W10)});
}
block.Append(Opcode::StoreStack,
{Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
slots.emplace(&inst, dst_slot);
return;
}
// 处理 And 指令
case ir::Opcode::And: {
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get()));
const ir::Value* lhs = nullptr;
const ir::Value* rhs = nullptr;
if (inst.GetNumOperands() >= 2) {
lhs = inst.GetOperand(0);
rhs = inst.GetOperand(1);
}
if (lhs && rhs) {
EmitValueToReg(lhs, PhysReg::W8, slots, block, function);
EmitValueToReg(rhs, PhysReg::W9, slots, block, function);
block.Append(Opcode::AndRR, {Operand::Reg(PhysReg::W8),
Operand::Reg(PhysReg::W8),
Operand::Reg(PhysReg::W9)});
}
block.Append(Opcode::StoreStack,
{Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
slots.emplace(&inst, dst_slot);
return;
}
// 处理 Or 指令
case ir::Opcode::Or: {
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get()));
const ir::Value* lhs = nullptr;
const ir::Value* rhs = nullptr;
if (inst.GetNumOperands() >= 2) {
lhs = inst.GetOperand(0);
rhs = inst.GetOperand(1);
}
if (lhs && rhs) {
EmitValueToReg(lhs, PhysReg::W8, slots, block, function);
EmitValueToReg(rhs, PhysReg::W9, slots, block, function);
block.Append(Opcode::OrRR, {Operand::Reg(PhysReg::W8),
Operand::Reg(PhysReg::W8),
Operand::Reg(PhysReg::W9)});
}
block.Append(Opcode::StoreStack,
{Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
slots.emplace(&inst, dst_slot);
return;
}
// 处理 Not 指令
case ir::Opcode::Not: {
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get()));
const ir::Value* src_val = nullptr;
if (inst.GetNumOperands() > 0) {
src_val = inst.GetOperand(0);
}
if (src_val) {
EmitValueToReg(src_val, PhysReg::W8, slots, block, function);
// NOT = XOR with -1
block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W9), Operand::Imm(-1)});
block.Append(Opcode::EorRR, {Operand::Reg(PhysReg::W8),
Operand::Reg(PhysReg::W8),
Operand::Reg(PhysReg::W9)});
}
block.Append(Opcode::StoreStack,
{Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
slots.emplace(&inst, dst_slot);
return;
}
// 处理 FPExt浮点扩展
case ir::Opcode::FPExt: {
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get()));
const ir::Value* src_val = nullptr;
if (inst.GetNumOperands() > 0) {
src_val = inst.GetOperand(0);
}
if (src_val) {
EmitValueToReg(src_val, PhysReg::S0, slots, block, function);
}
block.Append(Opcode::StoreStack,
{Operand::Reg(PhysReg::S0), Operand::FrameIndex(dst_slot)});
slots.emplace(&inst, dst_slot);
return;
}
// 处理 FPTrunc浮点截断
case ir::Opcode::FPTrunc: {
int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get()));
const ir::Value* src_val = nullptr;
if (inst.GetNumOperands() > 0) {
src_val = inst.GetOperand(0);
}
if (src_val) {
EmitValueToReg(src_val, PhysReg::S0, slots, block, function);
}
block.Append(Opcode::StoreStack,
{Operand::Reg(PhysReg::S0), Operand::FrameIndex(dst_slot)});
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()))));
}
}
} // namespace
// 辅助函数,将单个 IR 函数转换为 MachineFunction
std::unique_ptr<MachineFunction> LowerFunction(const ir::Function& func) {
auto machine_func = std::make_unique<MachineFunction>(func.GetName());
ValueSlotMap slots;
// 存储参数信息,稍后处理
struct ParamInfo {
const ir::Value* arg;
int slot;
bool isFloat;
bool isPointer;
};
std::vector<ParamInfo> paramInfos;
// 为函数参数分配栈槽
for (const auto& arg : func.GetArguments()) {
int slot = machine_func->CreateFrameIndex(GetTypeSize(arg->GetType().get()));
slots.emplace(arg.get(), slot);
bool isFloat = arg->GetType()->IsFloat();
bool isPointer = arg->GetType()->IsPtrInt32() || arg->GetType()->IsPtrFloat() || arg->GetType()->IsPtrInt1();
paramInfos.push_back({arg.get(), slot, isFloat, isPointer});
}
// IR 基本块到 MIR 基本块的映射
std::unordered_map<const ir::BasicBlock*, MachineBasicBlock*> blockMap;
// 第一遍:为每个 IR 基本块创建 MIR 基本块
std::string func_name = func.GetName();
for (const auto& bb : func.GetBlocks()) {
// 格式: .L函数名_基本块名
auto mirBB = std::make_unique<MachineBasicBlock>(".L" + func_name + "_" + bb->GetName());
blockMap[bb.get()] = mirBB.get();
machine_func->AddBasicBlock(std::move(mirBB));
}
// 在入口基本块的开头添加参数加载指令
if (!func.GetBlocks().empty()) {
MachineBasicBlock* entryBB = blockMap[func.GetEntry()];
if (entryBB) {
size_t intArgIdx = 0;
size_t fpArgIdx = 0;
for (const auto& param : paramInfos) {
if (param.isFloat) {
if (fpArgIdx < 8) {
PhysReg reg = static_cast<PhysReg>(static_cast<int>(PhysReg::S0) + fpArgIdx);
entryBB->Append(Opcode::StoreStack,
{Operand::Reg(reg), Operand::FrameIndex(param.slot)});
}
fpArgIdx++;
} else if (param.isPointer) {
if (intArgIdx < 8) {
PhysReg reg = static_cast<PhysReg>(static_cast<int>(PhysReg::X0) + intArgIdx);
entryBB->Append(Opcode::StoreStack, {Operand::Reg(reg), Operand::FrameIndex(param.slot)});
}
intArgIdx++;
} else {
if (intArgIdx < 8) {
PhysReg reg = static_cast<PhysReg>(static_cast<int>(PhysReg::W0) + intArgIdx);
entryBB->Append(Opcode::StoreStack,
{Operand::Reg(reg), Operand::FrameIndex(param.slot)});
}
intArgIdx++;
}
}
}
}
// 第二遍:遍历每个基本块,转换指令
for (const auto& bb : func.GetBlocks()) {
MachineBasicBlock* mirBB = blockMap[bb.get()];
if (!mirBB) {
throw std::runtime_error(FormatError("mir", "找不到基本块对应的 MIR 基本块"));
}
for (const auto& inst : bb->GetInstructions()) {
LowerInstruction(*inst, *machine_func, slots, *mirBB, blockMap);
}
}
return machine_func;
}
std::unique_ptr<MachineModule> LowerToMIR(const ir::Module& module) {
DefaultContext();
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()) {
// 为全局变量在数据段分配空间
// 这里需要扩展 MachineModule 来支持全局变量
DEBUG_MSG("Global variable: " << global->GetName());
globals.push_back(global.get());
}
// 遍历模块中的所有函数
for (const auto& func : module.GetFunctions()) {
try {
auto machine_func = LowerFunction(*func);
machine_module->AddFunction(std::move(machine_func));
} catch (const std::runtime_error& e) {
// 记录错误但继续处理其他函数
throw std::runtime_error(FormatError("mir", "转换函数失败: " + func->GetName() + " - " + e.what()));
}
}
if (machine_module->GetFunctions().empty()) {
throw std::runtime_error(FormatError("mir", "模块中没有成功转换的函数"));
}
return machine_module;
}
} // namespace mir