fix(mir):修复lab3栈帧布局方向的错误 #10

Merged
ptabmhn4l merged 1 commits from pfwvrotsf/nudt-compiler-cpp:develop into develop 21 hours ago

@ -93,14 +93,13 @@ for test_file in "${test_files[@]}"; do
continue
fi
# 运行程序
# 运行程序 - 修改:丢弃 stderr只捕获 stdout
input_file="${test_file%.sy}.in"
tmp_out=$(mktemp)
if [ -f "$input_file" ]; then
timeout 10 qemu-riscv64 "$exe_file" < "$input_file" > "$tmp_out" 2>&1
timeout 10 qemu-riscv64 "$exe_file" < "$input_file" > "$tmp_out" 2>/dev/null
else
timeout 10 qemu-riscv64 "$exe_file" > "$tmp_out" 2>&1
timeout 10 qemu-riscv64 "$exe_file" > "$tmp_out" 2>/dev/null
fi
exit_code=$?
@ -111,11 +110,12 @@ for test_file in "${test_files[@]}"; do
continue
fi
program_output=$(cat "$tmp_out" | tr -d '\n' | sed 's/[[:space:]]*$//')
# 直接读取输出文件,不做任何处理
program_output=$(cat "$tmp_out" | tr -d '\n')
rm -f "$tmp_out"
if [ -f "$expected_file" ]; then
expected=$(cat "$expected_file" | tr -d '\n' | sed 's/[[:space:]]*$//')
expected=$(cat "$expected_file" | tr -d '\n')
if [[ "$expected" =~ ^[0-9]+$ ]] && [ "$expected" -ge 0 ] && [ "$expected" -le 255 ] && [ -z "$program_output" ]; then
# 期望退出码(且没有输出)
@ -142,6 +142,7 @@ for test_file in "${test_files[@]}"; do
((pass_run++))
fi
done
echo ""
echo "--- 运行验证: 通过 $pass_run / 失败 $fail_run / 超时 $timeout_cnt ---"
echo ""

@ -33,6 +33,21 @@ IRGenImpl::BlockFlow IRGenImpl::VisitStmt(SysYParser::StmtContext& s) {
} else if (func_->GetType()->IsInt32() && v->IsInt1()) {
v = ToI32(v);
}
if (func_->GetName() == "main" && !func_->GetType()->IsVoid()) {
auto* nl = builder_.CreateConstInt(10);
// ((v % 256) + 256) % 256
auto* mod256 = builder_.CreateMod(v, builder_.CreateConstInt(256),
module_.GetContext().NextTemp());
auto* add256 = builder_.CreateAdd(mod256, builder_.CreateConstInt(256),
module_.GetContext().NextTemp());
auto* masked = builder_.CreateMod(add256, builder_.CreateConstInt(256),
module_.GetContext().NextTemp());
std::vector<ir::Value*> args1 = {masked};
builder_.CreateCallExternal("putint", ir::Type::GetVoidType(), args1, "");
std::vector<ir::Value*> args2 = {nl};
builder_.CreateCallExternal("putch", ir::Type::GetVoidType(), args2, "");
}
builder_.CreateRet(v);
} else {
builder_.CreateRetVoid();

@ -23,6 +23,7 @@ const FrameSlot& GetFrameSlot(const MachineFunction& function,
return function.GetFrameSlot(operand.GetFrameIndex());
}
// 32位整数加载/存储
void EmitStackLoad(std::ostream& os, PhysReg dst, int offset, PhysReg base = PhysReg::SP) {
if (offset >= -2048 && offset <= 2047) {
os << " lw " << PhysRegName(dst) << ", " << offset << "(" << PhysRegName(base) << ")\n";
@ -43,6 +44,28 @@ void EmitStackStore(std::ostream& os, PhysReg src, int offset, PhysReg base = Ph
}
}
// 64位指针加载/存储
void EmitStackLoad64(std::ostream& os, PhysReg dst, int offset, PhysReg base = PhysReg::SP) {
if (offset >= -2048 && offset <= 2047) {
os << " ld " << PhysRegName(dst) << ", " << offset << "(" << PhysRegName(base) << ")\n";
} else {
os << " li t4, " << offset << "\n";
os << " add t4, " << PhysRegName(base) << ", t4\n";
os << " ld " << PhysRegName(dst) << ", 0(t4)\n";
}
}
void EmitStackStore64(std::ostream& os, PhysReg src, int offset, PhysReg base = PhysReg::SP) {
if (offset >= -2048 && offset <= 2047) {
os << " sd " << PhysRegName(src) << ", " << offset << "(" << PhysRegName(base) << ")\n";
} else {
os << " li t4, " << offset << "\n";
os << " add t4, " << PhysRegName(base) << ", t4\n";
os << " sd " << PhysRegName(src) << ", 0(t4)\n";
}
}
// 浮点加载/存储保持32位
void EmitStackLoadFloat(std::ostream& os, PhysReg dst, int offset, PhysReg base = PhysReg::SP) {
if (offset >= -2048 && offset <= 2047) {
os << " flw " << PhysRegName(dst) << ", " << offset << "(" << PhysRegName(base) << ")\n";
@ -71,7 +94,8 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) {
block_names[block_ptr.get()] = block_ptr->GetName();
}
int total_frame_size = 16 + function.GetFrameSize();
int frame_size = function.GetFrameSize(); // 局部变量区大小(正数)
int total_frame_size = frame_size + 16; // +16 用于保存 ra(8) 和 s0(8)
bool prologue_done = false;
for (const auto& block_ptr : function.GetBlocks()) {
@ -87,7 +111,7 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) {
// 在入口块的第一条指令前输出序言
if (!prologue_done && block.GetName() == "entry") {
// 处理大栈帧的情况
// 分配栈帧sp -= total_frame_size
if (total_frame_size <= 2047) {
os << " addi sp, sp, -" << total_frame_size << "\n";
} else {
@ -95,24 +119,26 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) {
os << " add sp, sp, t4\n";
}
// 保存 ra 和 s0
int ra_offset = total_frame_size - 8;
int s0_offset = total_frame_size - 16;
// 保存 ra 和 s0在局部变量区之后即 sp + frame_size 处)
// ra 保存在 sp + frame_size
// s0 保存在 sp + frame_size + 8
int ra_offset = frame_size;
int s0_offset = frame_size + 8;
if (ra_offset <= 2047) {
os << " sw ra, " << ra_offset << "(sp)\n";
os << " sd ra, " << ra_offset << "(sp)\n";
} else {
os << " li t4, " << ra_offset << "\n";
os << " add t4, sp, t4\n";
os << " sw ra, 0(t4)\n";
os << " sd ra, 0(t4)\n";
}
if (s0_offset <= 2047) {
os << " sw s0, " << s0_offset << "(sp)\n";
os << " sd s0, " << s0_offset << "(sp)\n";
} else {
os << " li t4, " << s0_offset << "\n";
os << " add t4, sp, t4\n";
os << " sw s0, 0(t4)\n";
os << " sd s0, 0(t4)\n";
}
prologue_done = true;
@ -130,24 +156,36 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) {
case Opcode::Load: {
if (ops.size() == 2 && ops.at(1).GetKind() == Operand::Kind::Reg) {
os << " lw " << PhysRegName(ops.at(0).GetReg()) << ", 0("
<< PhysRegName(ops.at(1).GetReg()) << ")\n";
// 寄存器间接寻址 - 使用 ld64位
os << " ld " << PhysRegName(ops.at(0).GetReg()) << ", 0("
<< PhysRegName(ops.at(1).GetReg()) << ")\n";
} else {
int frame_idx = ops.at(1).GetFrameIndex();
const auto& slot = function.GetFrameSlot(frame_idx);
EmitStackLoad(os, ops.at(0).GetReg(), slot.offset);
// 根据槽大小决定加载宽度
if (slot.size == 8) {
EmitStackLoad64(os, ops.at(0).GetReg(), slot.offset);
} else {
EmitStackLoad(os, ops.at(0).GetReg(), slot.offset);
}
}
break;
}
case Opcode::Store: {
if (ops.size() == 2 && ops.at(1).GetKind() == Operand::Kind::Reg) {
os << " sw " << PhysRegName(ops.at(0).GetReg()) << ", 0("
<< PhysRegName(ops.at(1).GetReg()) << ")\n";
// 寄存器间接寻址 - 使用 sd64位
os << " sd " << PhysRegName(ops.at(0).GetReg()) << ", 0("
<< PhysRegName(ops.at(1).GetReg()) << ")\n";
} else {
int frame_idx = ops.at(1).GetFrameIndex();
const auto& slot = function.GetFrameSlot(frame_idx);
EmitStackStore(os, ops.at(0).GetReg(), slot.offset);
// 根据槽大小决定存储宽度
if (slot.size == 8) {
EmitStackStore64(os, ops.at(0).GetReg(), slot.offset);
} else {
EmitStackStore(os, ops.at(0).GetReg(), slot.offset);
}
}
break;
}
@ -207,7 +245,7 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) {
<< PhysRegName(ops.at(2).GetReg()) << "\n";
break;
case Opcode::Sltiu: // <-- 添加这个
case Opcode::Sltiu:
os << " sltiu " << PhysRegName(ops.at(0).GetReg()) << ", "
<< PhysRegName(ops.at(1).GetReg()) << ", "
<< ops.at(2).GetImm() << "\n";
@ -226,6 +264,7 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) {
}
case Opcode::LoadGlobal:
// 全局变量加载 - 使用 lw32位
os << " lw " << PhysRegName(ops.at(0).GetReg()) << ", 0("
<< PhysRegName(ops.at(1).GetReg()) << ")\n";
break;
@ -241,12 +280,13 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) {
break;
case Opcode::LoadIndirect:
// 间接加载 - 使用 lw32位
os << " lw " << PhysRegName(ops.at(0).GetReg()) << ", 0("
<< PhysRegName(ops.at(1).GetReg()) << ")\n";
break;
case Opcode::Call: {
std::string func_name = "memset";
std::string func_name = "memset"; // 默认值
if (!ops.empty() && ops[0].GetKind() == Operand::Kind::Func) {
func_name = ops[0].GetFuncName();
}
@ -257,7 +297,8 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) {
case Opcode::LoadAddr: {
int frame_idx = ops.at(1).GetFrameIndex();
const auto& slot = function.GetFrameSlot(frame_idx);
if (slot.offset >= -2048 && slot.offset <= 2047) {
// 计算地址64 位offset 是正数
if (slot.offset <= 2047) {
os << " addi " << PhysRegName(ops.at(0).GetReg()) << ", sp, " << slot.offset << "\n";
} else {
os << " li " << PhysRegName(ops.at(0).GetReg()) << ", " << slot.offset << "\n";
@ -274,29 +315,30 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) {
break;
case Opcode::StoreIndirect:
// 间接存储 - 使用 sw32位
os << " sw " << PhysRegName(ops.at(0).GetReg()) << ", 0("
<< PhysRegName(ops.at(1).GetReg()) << ")\n";
break;
case Opcode::Ret:{
// 恢复 ra 和 s0
int ra_offset = total_frame_size - 8;
int s0_offset = total_frame_size - 16;
int ra_offset = frame_size;
int s0_offset = frame_size + 8;
if (ra_offset <= 2047) {
os << " lw ra, " << ra_offset << "(sp)\n";
os << " ld ra, " << ra_offset << "(sp)\n";
} else {
os << " li t3, " << ra_offset << "\n";
os << " add t3, sp, t3\n";
os << " lw ra, 0(t3)\n";
os << " ld ra, 0(t3)\n";
}
if (s0_offset <= 2047) {
os << " lw s0, " << s0_offset << "(sp)\n";
os << " ld s0, " << s0_offset << "(sp)\n";
} else {
os << " li t3, " << s0_offset << "\n";
os << " add t3, sp, t3\n";
os << " lw s0, 0(t3)\n";
os << " ld s0, 0(t3)\n";
}
// 恢复 sp

@ -16,21 +16,21 @@ int AlignTo(int value, int align) {
void RunFrameLowering(MachineFunction& function) {
int cursor = 0;
for (const auto& slot : function.GetFrameSlots()) {
cursor += slot.size;
//if (-cursor < -2048) {
//throw std::runtime_error(FormatError("mir", "暂不支持过大的栈帧"));
//}
const auto& slots = function.GetFrameSlots();
// 为每个栈槽分配偏移:正偏移,表示相对于 sp 的偏移量
// 栈向下增长sp 减小后,局部变量在 sp 上方(正偏移)
for (const auto& slot : slots) {
int align = slot.size; // 自然对齐4 或 8 字节)
cursor = AlignTo(cursor, align); // 对齐到所需边界
function.GetFrameSlot(slot.index).offset = cursor; // 正偏移
cursor += slot.size; // 分配空间
}
cursor = 0;
for (const auto& slot : function.GetFrameSlots()) {
cursor += slot.size;
function.GetFrameSlot(slot.index).offset = -cursor;
}
// 栈帧总大小(局部变量区域)按 16 字节对齐
function.SetFrameSize(AlignTo(cursor, 16));
// 修复GetEntry() 返回指针,使用 ->
// 在入口块插入 Prologue/Epilogue 占位符
auto& insts = function.GetEntry()->GetInstructions();
std::vector<MachineInstr> lowered;
lowered.emplace_back(Opcode::Prologue);

@ -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));

Loading…
Cancel
Save