|
|
|
|
@ -11,6 +11,19 @@
|
|
|
|
|
std::vector<mir::GlobalVarInfo> g_globalVars;
|
|
|
|
|
namespace mir {
|
|
|
|
|
namespace {
|
|
|
|
|
static bool IsFloatReg(PhysReg reg) {
|
|
|
|
|
switch (reg) {
|
|
|
|
|
case PhysReg::FT0: case PhysReg::FT1: case PhysReg::FT2: case PhysReg::FT3:
|
|
|
|
|
case PhysReg::FT4: case PhysReg::FT5: case PhysReg::FT6: case PhysReg::FT7:
|
|
|
|
|
case PhysReg::FT8: case PhysReg::FT9: case PhysReg::FT10: case PhysReg::FT11:
|
|
|
|
|
case PhysReg::FA0: case PhysReg::FA1: case PhysReg::FA2: case PhysReg::FA3:
|
|
|
|
|
case PhysReg::FA4: case PhysReg::FA5: case PhysReg::FA6: case PhysReg::FA7:
|
|
|
|
|
case PhysReg::FS0: case PhysReg::FS1:
|
|
|
|
|
return true;
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
using ValueSlotMap = std::unordered_map<const ir::Value*, int>;
|
|
|
|
|
static std::unordered_map<const ir::BasicBlock*, MachineBasicBlock*> block_map;
|
|
|
|
|
|
|
|
|
|
@ -29,24 +42,42 @@ MachineBasicBlock* GetOrCreateBlock(const ir::BasicBlock* ir_block,
|
|
|
|
|
block_map[ir_block] = block;
|
|
|
|
|
return block;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EmitValueToReg(const ir::Value* value, PhysReg target,
|
|
|
|
|
const ValueSlotMap& slots, MachineBasicBlock& block,
|
|
|
|
|
bool for_address=false) {
|
|
|
|
|
if (auto* arg = dynamic_cast<const ir::Argument*>(value)) {
|
|
|
|
|
auto it = slots.find(arg);
|
|
|
|
|
if (it != slots.end()) {
|
|
|
|
|
// 从栈槽加载参数值
|
|
|
|
|
if (value->GetType()->IsFloat32()) {
|
|
|
|
|
bool for_address = false) {
|
|
|
|
|
// 处理参数(Argument)
|
|
|
|
|
if (auto* arg = dynamic_cast<const ir::Argument*>(value)) {
|
|
|
|
|
auto it = slots.find(arg);
|
|
|
|
|
if (it != slots.end()) {
|
|
|
|
|
bool src_is_float = value->GetType()->IsFloat32();
|
|
|
|
|
bool dst_is_float = IsFloatReg(target);
|
|
|
|
|
if (src_is_float && !dst_is_float) {
|
|
|
|
|
// 浮点 -> 整数
|
|
|
|
|
block.Append(Opcode::LoadFloat,
|
|
|
|
|
{Operand::Reg(PhysReg::FT0), Operand::FrameIndex(it->second)});
|
|
|
|
|
block.Append(Opcode::FPToSI, {Operand::Reg(target), Operand::Reg(PhysReg::FT0)});
|
|
|
|
|
} else if (!src_is_float && dst_is_float) {
|
|
|
|
|
// 整数 -> 浮点
|
|
|
|
|
block.Append(Opcode::Load,
|
|
|
|
|
{Operand::Reg(PhysReg::T0), Operand::FrameIndex(it->second)});
|
|
|
|
|
block.Append(Opcode::SIToFP, {Operand::Reg(target), Operand::Reg(PhysReg::T0)});
|
|
|
|
|
} else {
|
|
|
|
|
// 同类型直接加载
|
|
|
|
|
if (src_is_float) {
|
|
|
|
|
block.Append(Opcode::LoadFloat,
|
|
|
|
|
{Operand::Reg(target), Operand::FrameIndex(it->second)});
|
|
|
|
|
{Operand::Reg(target), Operand::FrameIndex(it->second)});
|
|
|
|
|
} else {
|
|
|
|
|
block.Append(Opcode::Load,
|
|
|
|
|
{Operand::Reg(target), Operand::FrameIndex(it->second)});
|
|
|
|
|
{Operand::Reg(target), Operand::FrameIndex(it->second)});
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (auto* constant = dynamic_cast<const ir::ConstantInt*>(value)) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理整数常量
|
|
|
|
|
if (auto* constant = dynamic_cast<const ir::ConstantInt*>(value)) {
|
|
|
|
|
int64_t val = constant->GetValue();
|
|
|
|
|
block.Append(Opcode::MovImm,
|
|
|
|
|
{Operand::Reg(target), Operand::Imm(static_cast<int>(val))});
|
|
|
|
|
@ -58,29 +89,19 @@ void EmitValueToReg(const ir::Value* value, PhysReg target,
|
|
|
|
|
float val = fconstant->GetValue();
|
|
|
|
|
uint32_t bits;
|
|
|
|
|
memcpy(&bits, &val, sizeof(val));
|
|
|
|
|
|
|
|
|
|
// 检查目标是否是浮点寄存器
|
|
|
|
|
bool target_is_fp = (target == PhysReg::FT0 || target == PhysReg::FT1 ||
|
|
|
|
|
target == PhysReg::FT2 || target == PhysReg::FT3 ||
|
|
|
|
|
target == PhysReg::FT4 || target == PhysReg::FT5 ||
|
|
|
|
|
target == PhysReg::FT6 || target == PhysReg::FT7 ||
|
|
|
|
|
target == PhysReg::FA0 || target == PhysReg::FA1 ||
|
|
|
|
|
target == PhysReg::FA2 || target == PhysReg::FA3 ||
|
|
|
|
|
target == PhysReg::FA4 || target == PhysReg::FA5 ||
|
|
|
|
|
target == PhysReg::FA6 || target == PhysReg::FA7);
|
|
|
|
|
|
|
|
|
|
bool target_is_fp = IsFloatReg(target);
|
|
|
|
|
if (target_is_fp) {
|
|
|
|
|
block.Append(Opcode::MovImm,
|
|
|
|
|
{Operand::Reg(PhysReg::T0), Operand::Imm(static_cast<int>(bits))});
|
|
|
|
|
{Operand::Reg(PhysReg::T0), Operand::Imm(static_cast<int>(bits))});
|
|
|
|
|
block.Append(Opcode::FMovWX, {Operand::Reg(target), Operand::Reg(PhysReg::T0)});
|
|
|
|
|
} else {
|
|
|
|
|
// 目标是整数寄存器,直接加载
|
|
|
|
|
block.Append(Opcode::MovImm,
|
|
|
|
|
{Operand::Reg(target), Operand::Imm(static_cast<int>(bits))});
|
|
|
|
|
{Operand::Reg(target), Operand::Imm(static_cast<int>(bits))});
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理 GEP 指令
|
|
|
|
|
if (auto* gep = dynamic_cast<const ir::GepInst*>(value)) {
|
|
|
|
|
EmitValueToReg(gep->GetBasePtr(), target, slots, block, true);
|
|
|
|
|
EmitValueToReg(gep->GetIndex(), PhysReg::T1, slots, block);
|
|
|
|
|
@ -93,6 +114,7 @@ void EmitValueToReg(const ir::Value* value, PhysReg target,
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理 Alloca 指令
|
|
|
|
|
if (auto* alloca = dynamic_cast<const ir::AllocaInst*>(value)) {
|
|
|
|
|
auto it = slots.find(alloca);
|
|
|
|
|
if (it != slots.end()) {
|
|
|
|
|
@ -102,6 +124,7 @@ void EmitValueToReg(const ir::Value* value, PhysReg target,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理全局变量
|
|
|
|
|
if (auto* global = dynamic_cast<const ir::GlobalVariable*>(value)) {
|
|
|
|
|
block.Append(Opcode::LoadGlobalAddr,
|
|
|
|
|
{Operand::Reg(target), Operand::Global(global->GetName())});
|
|
|
|
|
@ -117,25 +140,38 @@ void EmitValueToReg(const ir::Value* value, PhysReg target,
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 关键:在 slots 中查找,并根据类型生成正确的加载指令
|
|
|
|
|
// 处理一般栈槽中的值
|
|
|
|
|
auto it = slots.find(value);
|
|
|
|
|
if (it != slots.end()) {
|
|
|
|
|
if (value->GetType()->IsFloat32()) {
|
|
|
|
|
bool src_is_float = value->GetType()->IsFloat32();
|
|
|
|
|
bool dst_is_float = IsFloatReg(target);
|
|
|
|
|
if (src_is_float && !dst_is_float) {
|
|
|
|
|
// 浮点 -> 整数
|
|
|
|
|
block.Append(Opcode::LoadFloat,
|
|
|
|
|
{Operand::Reg(target), Operand::FrameIndex(it->second)});
|
|
|
|
|
} else {
|
|
|
|
|
{Operand::Reg(PhysReg::FT0), Operand::FrameIndex(it->second)});
|
|
|
|
|
block.Append(Opcode::FPToSI, {Operand::Reg(target), Operand::Reg(PhysReg::FT0)});
|
|
|
|
|
} else if (!src_is_float && dst_is_float) {
|
|
|
|
|
// 整数 -> 浮点
|
|
|
|
|
block.Append(Opcode::Load,
|
|
|
|
|
{Operand::Reg(target), Operand::FrameIndex(it->second)});
|
|
|
|
|
{Operand::Reg(PhysReg::T0), Operand::FrameIndex(it->second)});
|
|
|
|
|
block.Append(Opcode::SIToFP, {Operand::Reg(target), Operand::Reg(PhysReg::T0)});
|
|
|
|
|
} else {
|
|
|
|
|
// 同类型直接加载
|
|
|
|
|
if (src_is_float) {
|
|
|
|
|
block.Append(Opcode::LoadFloat,
|
|
|
|
|
{Operand::Reg(target), Operand::FrameIndex(it->second)});
|
|
|
|
|
} else {
|
|
|
|
|
block.Append(Opcode::Load,
|
|
|
|
|
{Operand::Reg(target), Operand::FrameIndex(it->second)});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果以上都未找到,报错
|
|
|
|
|
std::cerr << "未找到的值: " << value << std::endl;
|
|
|
|
|
std::cerr << " 名称: " << value->GetName() << std::endl;
|
|
|
|
|
std::cerr << " 类型: " << (value->GetType()->IsFloat32() ? "float" : "int") << std::endl;
|
|
|
|
|
std::cerr << " 是否是 ConstantInt: " << (dynamic_cast<const ir::ConstantInt*>(value) != nullptr) << std::endl;
|
|
|
|
|
std::cerr << " 是否是 ConstantFloat: " << (dynamic_cast<const ir::ConstantFloat*>(value) != nullptr) << std::endl;
|
|
|
|
|
std::cerr << " 是否是 Instruction: " << (dynamic_cast<const ir::Instruction*>(value) != nullptr) << std::endl;
|
|
|
|
|
|
|
|
|
|
throw std::runtime_error(
|
|
|
|
|
FormatError("mir", "找不到值对应的栈槽: " + value->GetName()));
|
|
|
|
|
}
|
|
|
|
|
@ -150,8 +186,6 @@ void StoreRegToSlot(PhysReg reg, int slot, MachineBasicBlock& block, bool isFloa
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 将 LowerInstruction 重命名为 LowerInstructionToBlock,并添加 MachineBasicBlock 参数
|
|
|
|
|
void LowerInstructionToBlock(const ir::Instruction& inst, MachineFunction& function,
|
|
|
|
|
ValueSlotMap& slots, MachineBasicBlock& block) {
|
|
|
|
|
@ -247,30 +281,56 @@ void LowerInstructionToBlock(const ir::Instruction& inst, MachineFunction& funct
|
|
|
|
|
case ir::Opcode::Sub:
|
|
|
|
|
case ir::Opcode::Mul:
|
|
|
|
|
case ir::Opcode::Div:
|
|
|
|
|
case ir::Opcode::Mod: {
|
|
|
|
|
case ir::Opcode::Mod:
|
|
|
|
|
case ir::Opcode::FAdd:
|
|
|
|
|
case ir::Opcode::FSub:
|
|
|
|
|
case ir::Opcode::FMul:
|
|
|
|
|
case ir::Opcode::FDiv: {
|
|
|
|
|
auto& bin = static_cast<const ir::BinaryInst&>(inst);
|
|
|
|
|
int dst_slot = function.CreateFrameIndex();
|
|
|
|
|
EmitValueToReg(bin.GetLhs(), PhysReg::T0, slots, block);
|
|
|
|
|
EmitValueToReg(bin.GetRhs(), PhysReg::T1, slots, block);
|
|
|
|
|
|
|
|
|
|
Opcode op;
|
|
|
|
|
switch (inst.GetOpcode()) {
|
|
|
|
|
case ir::Opcode::Add: op = Opcode::Add; break;
|
|
|
|
|
case ir::Opcode::Sub: op = Opcode::Sub; break;
|
|
|
|
|
case ir::Opcode::Mul: op = Opcode::Mul; break;
|
|
|
|
|
case ir::Opcode::Div: op = Opcode::Div; break;
|
|
|
|
|
case ir::Opcode::Mod: op = Opcode::Rem; break;
|
|
|
|
|
default: op = Opcode::Add; break;
|
|
|
|
|
bool lhs_is_float = bin.GetLhs()->GetType()->IsFloat32();
|
|
|
|
|
bool rhs_is_float = bin.GetRhs()->GetType()->IsFloat32();
|
|
|
|
|
bool result_is_float = lhs_is_float || rhs_is_float;
|
|
|
|
|
|
|
|
|
|
int dst_slot = function.CreateFrameIndex(4);
|
|
|
|
|
|
|
|
|
|
if (result_is_float) {
|
|
|
|
|
EmitValueToReg(bin.GetLhs(), PhysReg::FT0, slots, block);
|
|
|
|
|
EmitValueToReg(bin.GetRhs(), PhysReg::FT1, slots, block);
|
|
|
|
|
|
|
|
|
|
Opcode op;
|
|
|
|
|
switch (inst.GetOpcode()) {
|
|
|
|
|
case ir::Opcode::Add: case ir::Opcode::FAdd: op = Opcode::FAdd; break;
|
|
|
|
|
case ir::Opcode::Sub: case ir::Opcode::FSub: op = Opcode::FSub; break;
|
|
|
|
|
case ir::Opcode::Mul: case ir::Opcode::FMul: op = Opcode::FMul; break;
|
|
|
|
|
case ir::Opcode::Div: case ir::Opcode::FDiv: op = Opcode::FDiv; break;
|
|
|
|
|
default: op = Opcode::FAdd; break;
|
|
|
|
|
}
|
|
|
|
|
block.Append(op, {Operand::Reg(PhysReg::FT0),
|
|
|
|
|
Operand::Reg(PhysReg::FT0),
|
|
|
|
|
Operand::Reg(PhysReg::FT1)});
|
|
|
|
|
StoreRegToSlot(PhysReg::FT0, dst_slot, block, true);
|
|
|
|
|
} else {
|
|
|
|
|
EmitValueToReg(bin.GetLhs(), PhysReg::T0, slots, block);
|
|
|
|
|
EmitValueToReg(bin.GetRhs(), PhysReg::T1, slots, block);
|
|
|
|
|
|
|
|
|
|
Opcode op;
|
|
|
|
|
switch (inst.GetOpcode()) {
|
|
|
|
|
case ir::Opcode::Add: op = Opcode::Add; break;
|
|
|
|
|
case ir::Opcode::Sub: op = Opcode::Sub; break;
|
|
|
|
|
case ir::Opcode::Mul: op = Opcode::Mul; break;
|
|
|
|
|
case ir::Opcode::Div: op = Opcode::Div; break;
|
|
|
|
|
case ir::Opcode::Mod: op = Opcode::Rem; break;
|
|
|
|
|
default: op = Opcode::Add; break;
|
|
|
|
|
}
|
|
|
|
|
block.Append(op, {Operand::Reg(PhysReg::T0),
|
|
|
|
|
Operand::Reg(PhysReg::T0),
|
|
|
|
|
Operand::Reg(PhysReg::T1)});
|
|
|
|
|
StoreRegToSlot(PhysReg::T0, dst_slot, block, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
block.Append(op, {Operand::Reg(PhysReg::T0),
|
|
|
|
|
Operand::Reg(PhysReg::T0),
|
|
|
|
|
Operand::Reg(PhysReg::T1)});
|
|
|
|
|
StoreRegToSlot(PhysReg::T0, dst_slot, block);
|
|
|
|
|
slots.emplace(&inst, dst_slot);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case ir::Opcode::Gep: {
|
|
|
|
|
int dst_slot = function.CreateFrameIndex();
|
|
|
|
|
slots.emplace(&inst, dst_slot);
|
|
|
|
|
@ -280,14 +340,26 @@ void LowerInstructionToBlock(const ir::Instruction& inst, MachineFunction& funct
|
|
|
|
|
case ir::Opcode::Call: {
|
|
|
|
|
auto& call = static_cast<const ir::CallInst&>(inst);
|
|
|
|
|
for (size_t i = 0; i < call.GetNumArgs() && i < 8; i++) {
|
|
|
|
|
PhysReg argReg = static_cast<PhysReg>(static_cast<int>(PhysReg::A0) + i);
|
|
|
|
|
EmitValueToReg(call.GetArg(i), argReg, slots, block);
|
|
|
|
|
// 根据参数的实际类型决定使用浮点还是整数寄存器
|
|
|
|
|
bool arg_is_float = call.GetArg(i)->GetType()->IsFloat32();
|
|
|
|
|
if (arg_is_float) {
|
|
|
|
|
PhysReg floatArgReg = static_cast<PhysReg>(static_cast<int>(PhysReg::FA0) + i);
|
|
|
|
|
EmitValueToReg(call.GetArg(i), floatArgReg, slots, block);
|
|
|
|
|
} else {
|
|
|
|
|
PhysReg intArgReg = static_cast<PhysReg>(static_cast<int>(PhysReg::A0) + i);
|
|
|
|
|
EmitValueToReg(call.GetArg(i), intArgReg, slots, block);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
std::string func_name = call.GetCalleeName();
|
|
|
|
|
block.Append(Opcode::Call, {Operand::Func(func_name)});
|
|
|
|
|
if (!call.GetType()->IsVoid()) {
|
|
|
|
|
int dst_slot = function.CreateFrameIndex();
|
|
|
|
|
StoreRegToSlot(PhysReg::A0, dst_slot, block);
|
|
|
|
|
bool ret_is_float = call.GetType()->IsFloat32();
|
|
|
|
|
if (ret_is_float) {
|
|
|
|
|
StoreRegToSlot(PhysReg::FA0, dst_slot, block, true);
|
|
|
|
|
} else {
|
|
|
|
|
StoreRegToSlot(PhysReg::A0, dst_slot, block, false);
|
|
|
|
|
}
|
|
|
|
|
slots.emplace(&inst, dst_slot);
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
@ -358,42 +430,14 @@ void LowerInstructionToBlock(const ir::Instruction& inst, MachineFunction& funct
|
|
|
|
|
}
|
|
|
|
|
case ir::Opcode::ZExt: {
|
|
|
|
|
auto& zext = static_cast<const ir::ZExtInst&>(inst);
|
|
|
|
|
int dst_slot = function.CreateFrameIndex(4); // i32 是 4 字节
|
|
|
|
|
int dst_slot = function.CreateFrameIndex(4);
|
|
|
|
|
|
|
|
|
|
// 获取源操作数的值
|
|
|
|
|
EmitValueToReg(zext.GetSrc(), PhysReg::T0, slots, block);
|
|
|
|
|
// 存储到新栈槽
|
|
|
|
|
StoreRegToSlot(PhysReg::T0, dst_slot, block);
|
|
|
|
|
slots.emplace(&inst, dst_slot);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
case ir::Opcode::FAdd:
|
|
|
|
|
case ir::Opcode::FSub:
|
|
|
|
|
case ir::Opcode::FMul:
|
|
|
|
|
case ir::Opcode::FDiv: {
|
|
|
|
|
auto& bin = static_cast<const ir::BinaryInst&>(inst);
|
|
|
|
|
int dst_slot = function.CreateFrameIndex(4);
|
|
|
|
|
|
|
|
|
|
EmitValueToReg(bin.GetLhs(), PhysReg::FT0, slots, block);
|
|
|
|
|
EmitValueToReg(bin.GetRhs(), PhysReg::FT1, slots, block);
|
|
|
|
|
|
|
|
|
|
Opcode op;
|
|
|
|
|
switch (inst.GetOpcode()) {
|
|
|
|
|
case ir::Opcode::FAdd: op = Opcode::FAdd; break;
|
|
|
|
|
case ir::Opcode::FSub: op = Opcode::FSub; break;
|
|
|
|
|
case ir::Opcode::FMul: op = Opcode::FMul; break;
|
|
|
|
|
case ir::Opcode::FDiv: op = Opcode::FDiv; break;
|
|
|
|
|
default: op = Opcode::FAdd; break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
block.Append(op, {Operand::Reg(PhysReg::FT0),
|
|
|
|
|
Operand::Reg(PhysReg::FT0),
|
|
|
|
|
Operand::Reg(PhysReg::FT1)});
|
|
|
|
|
StoreRegToSlot(PhysReg::FT0, dst_slot, block);
|
|
|
|
|
slots.emplace(&inst, dst_slot);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case ir::Opcode::FCmp: {
|
|
|
|
|
auto& fcmp = static_cast<const ir::FCmpInst&>(inst);
|
|
|
|
|
int dst_slot = function.CreateFrameIndex(4);
|
|
|
|
|
@ -482,25 +526,12 @@ void LowerInstructionToBlock(const ir::Instruction& inst, MachineFunction& funct
|
|
|
|
|
auto* true_bb = condbr.GetTrueBB();
|
|
|
|
|
auto* false_bb = condbr.GetFalseBB();
|
|
|
|
|
|
|
|
|
|
// 如果条件涉及函数调用,需要特殊处理
|
|
|
|
|
// 简单方案:将条件值保存到栈槽
|
|
|
|
|
int cond_slot = function.CreateFrameIndex(4);
|
|
|
|
|
EmitValueToReg(condbr.GetCond(), PhysReg::T0, slots, block);
|
|
|
|
|
|
|
|
|
|
// 保存条件值到栈
|
|
|
|
|
block.Append(Opcode::Store, {Operand::Reg(PhysReg::T0), Operand::FrameIndex(cond_slot)});
|
|
|
|
|
|
|
|
|
|
// 从栈加载条件值(确保函数调用后还能获取)
|
|
|
|
|
block.Append(Opcode::Load, {Operand::Reg(PhysReg::T0), Operand::FrameIndex(cond_slot)});
|
|
|
|
|
|
|
|
|
|
block.Append(Opcode::Sltu, {Operand::Reg(PhysReg::T1),
|
|
|
|
|
Operand::Reg(PhysReg::ZERO),
|
|
|
|
|
Operand::Reg(PhysReg::T0)});
|
|
|
|
|
|
|
|
|
|
MachineBasicBlock* true_block = GetOrCreateBlock(true_bb, function);
|
|
|
|
|
MachineBasicBlock* false_block = GetOrCreateBlock(false_bb, function);
|
|
|
|
|
|
|
|
|
|
block.Append(Opcode::CondBr, {Operand::Reg(PhysReg::T1),
|
|
|
|
|
block.Append(Opcode::CondBr, {Operand::Reg(PhysReg::T0),
|
|
|
|
|
Operand::Imm64(reinterpret_cast<intptr_t>(true_block)),
|
|
|
|
|
Operand::Imm64(reinterpret_cast<intptr_t>(false_block))});
|
|
|
|
|
return;
|
|
|
|
|
@ -510,15 +541,7 @@ void LowerInstructionToBlock(const ir::Instruction& inst, MachineFunction& funct
|
|
|
|
|
if (ret.GetValue()) {
|
|
|
|
|
auto val = ret.GetValue();
|
|
|
|
|
if (val->GetType()->IsFloat32()) {
|
|
|
|
|
auto it = slots.find(val);
|
|
|
|
|
if (it != slots.end()) {
|
|
|
|
|
block.Append(Opcode::LoadFloat,
|
|
|
|
|
{Operand::Reg(PhysReg::FT0), Operand::FrameIndex(it->second)});
|
|
|
|
|
block.Append(Opcode::FPToSI, {Operand::Reg(PhysReg::A0),
|
|
|
|
|
Operand::Reg(PhysReg::FT0)});
|
|
|
|
|
} else {
|
|
|
|
|
throw std::runtime_error(FormatError("mir", "Ret: 找不到浮点返回值的栈槽"));
|
|
|
|
|
}
|
|
|
|
|
EmitValueToReg(val, PhysReg::FA0, slots, block);
|
|
|
|
|
} else {
|
|
|
|
|
EmitValueToReg(val, PhysReg::A0, slots, block);
|
|
|
|
|
}
|
|
|
|
|
@ -546,21 +569,24 @@ std::unique_ptr<MachineFunction> LowerFunctionToMIR(const ir::Function& func) {
|
|
|
|
|
// ========== 新增:为函数参数分配栈槽 ==========
|
|
|
|
|
for (size_t i = 0; i < func.GetNumArgs(); i++) {
|
|
|
|
|
ir::Argument* arg = func.GetArgument(i);
|
|
|
|
|
int slot = machine_func->CreateFrameIndex(4); // int 和指针都是 4 字节
|
|
|
|
|
|
|
|
|
|
// 将参数值从寄存器存储到栈槽
|
|
|
|
|
// 🔑 修改:指针类型分配 8 字节,其他分配 4 字节
|
|
|
|
|
int size = 4;
|
|
|
|
|
if (arg->GetType()->IsPtrInt32() || arg->GetType()->IsPtrFloat32()) {
|
|
|
|
|
size = 8; // 指针在 RV64 上是 8 字节
|
|
|
|
|
}
|
|
|
|
|
int slot = machine_func->CreateFrameIndex(size);
|
|
|
|
|
|
|
|
|
|
PhysReg argReg = static_cast<PhysReg>(static_cast<int>(PhysReg::A0) + i);
|
|
|
|
|
MachineBasicBlock* entry = machine_func->GetEntry();
|
|
|
|
|
|
|
|
|
|
// 存储参数到栈槽
|
|
|
|
|
if (arg->GetType()->IsPtrInt32() || arg->GetType()->IsPtrFloat32()) {
|
|
|
|
|
// 指针类型
|
|
|
|
|
// 指针类型:使用 64 位存储(注意:Store 在 MIR 层会根据 slot.size 决定用 sw 还是 sd)
|
|
|
|
|
entry->Append(Opcode::Store, {Operand::Reg(argReg), Operand::FrameIndex(slot)});
|
|
|
|
|
} else if (arg->GetType()->IsInt32()) {
|
|
|
|
|
// 整数类型
|
|
|
|
|
entry->Append(Opcode::Store, {Operand::Reg(argReg), Operand::FrameIndex(slot)});
|
|
|
|
|
} else if (arg->GetType()->IsFloat32()) {
|
|
|
|
|
// 浮点类型
|
|
|
|
|
entry->Append(Opcode::StoreFloat, {Operand::Reg(argReg), Operand::FrameIndex(slot)});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -587,7 +613,7 @@ std::unique_ptr<MachineFunction> LowerFunctionToMIR(const ir::Function& func) {
|
|
|
|
|
std::vector<std::unique_ptr<MachineFunction>> LowerToMIR(const ir::Module& module) {
|
|
|
|
|
DefaultContext();
|
|
|
|
|
|
|
|
|
|
// 收集全局变量(只做一次)
|
|
|
|
|
// 收集全局变量
|
|
|
|
|
g_globalVars.clear();
|
|
|
|
|
for (const auto& global : module.GetGlobalVariables()) {
|
|
|
|
|
GlobalVarInfo info;
|
|
|
|
|
@ -631,7 +657,6 @@ std::vector<std::unique_ptr<MachineFunction>> LowerToMIR(const ir::Module& modul
|
|
|
|
|
|
|
|
|
|
std::vector<std::unique_ptr<MachineFunction>> result;
|
|
|
|
|
|
|
|
|
|
// 为每个函数生成 MachineFunction
|
|
|
|
|
for (const auto& func : functions) {
|
|
|
|
|
auto machine_func = LowerFunctionToMIR(*func);
|
|
|
|
|
result.push_back(std::move(machine_func));
|
|
|
|
|
|