[backend] introduced rv32 backend

This commit is contained in:
lixuanwang
2025-06-21 17:26:50 +08:00
parent 5727d3bde5
commit 232ed6d023
9 changed files with 244 additions and 1726 deletions

169
src/RISCv32Backend.cpp Normal file
View File

@@ -0,0 +1,169 @@
#include "RISCv32Backend.h"
#include <sstream>
#include <algorithm>
namespace sysy {
const std::vector<RISCv32CodeGen::PhysicalReg> RISCv32CodeGen::allocable_regs = {
PhysicalReg::T0, PhysicalReg::T1, PhysicalReg::T2, PhysicalReg::T3,
PhysicalReg::T4, PhysicalReg::T5, PhysicalReg::T6,
PhysicalReg::A0, PhysicalReg::A1, PhysicalReg::A2, PhysicalReg::A3,
PhysicalReg::A4, PhysicalReg::A5, PhysicalReg::A6, PhysicalReg::A7
};
std::string RISCv32CodeGen::reg_to_string(PhysicalReg reg) {
switch (reg) {
case PhysicalReg::T0: return "t0"; case PhysicalReg::T1: return "t1";
case PhysicalReg::T2: return "t2"; case PhysicalReg::T3: return "t3";
case PhysicalReg::T4: return "t4"; case PhysicalReg::T5: return "t5";
case PhysicalReg::T6: return "t6"; case PhysicalReg::A0: return "a0";
case PhysicalReg::A1: return "a1"; case PhysicalReg::A2: return "a2";
case PhysicalReg::A3: return "a3"; case PhysicalReg::A4: return "a4";
case PhysicalReg::A5: return "a5"; case PhysicalReg::A6: return "a6";
case PhysicalReg::A7: return "a7";
default: return "";
}
}
std::string RISCv32CodeGen::code_gen() {
std::stringstream ss;
ss << ".text\n";
ss << module_gen();
return ss.str();
}
std::string RISCv32CodeGen::module_gen() {
std::stringstream ss;
// 生成全局变量(数据段)
for (auto global : *module->getGlobalValues()) {
ss << ".data\n";
ss << ".globl " << global->getName() << "\n";
ss << global->getName() << ":\n";
ss << " .word 0\n"; // 假设初始化为0
}
// 生成函数
ss << ".text\n";
for (auto func : *module->getFunctions()) {
ss << function_gen(func);
}
return ss.str();
}
std::string RISCv32CodeGen::function_gen(Function* func) {
std::stringstream ss;
// 函数标签
ss << ".globl " << func->getName() << "\n";
ss << func->getName() << ":\n";
// 序言保存ra分配堆栈
bool is_leaf = true; // 简单假设,实际需检查是否调用其他函数
ss << " addi sp, sp, -16\n"; // 分配堆栈空间
ss << " sw ra, 12(sp)\n"; // 保存返回地址
// 寄存器分配
auto alloc = register_allocation(func);
// 生成基本块代码
for (auto bb : func->getBasicBlocks()) {
ss << basicBlock_gen(bb, alloc);
}
// 结尾恢复ra释放堆栈
ss << " lw ra, 12(sp)\n";
ss << " addi sp, sp, 16\n";
ss << " ret\n";
return ss.str();
}
std::string RISCv32CodeGen::basicBlock_gen(BasicBlock* bb, const RegAllocResult& alloc) {
std::stringstream ss;
ss << bb->getName() << ":\n";
for (auto inst : bb->getInstructions()) {
auto riscv_insts = instruction_gen(inst);
for (const auto& riscv_inst : riscv_insts) {
ss << " " << riscv_inst.opcode;
for (size_t i = 0; i < riscv_inst.operands.size(); ++i) {
if (i > 0) ss << ", ";
if (riscv_inst.operands[i].kind == Operand::Reg) {
auto it = alloc.reg_map.find((Value*)riscv_inst.operands[i].value.c_str());
if (it != alloc.reg_map.end()) {
ss << reg_to_string(it->second);
} else {
// 溢出到堆栈
auto stack_it = alloc.stack_map.find((Value*)riscv_inst.operands[i].value.c_str());
ss << "[sp+" << stack_it->second << "]";
}
} else {
ss << riscv_inst.operands[i].value;
}
}
ss << "\n";
}
}
return ss.str();
}
std::vector<RISCv32CodeGen::RISCv32Inst> RISCv32CodeGen::instruction_gen(Instruction* inst) {
std::vector<RISCv32Inst> insts;
if (auto bin = dynamic_cast<BinaryInst*>(inst)) {
std::string opcode;
if (bin->getOpcode() == BinaryInst::Add) opcode = "add";
else if (bin->getOpcode() == BinaryInst::Sub) opcode = "sub";
else if (bin->getOpcode() == BinaryInst::Mul) opcode = "mul";
else return insts; // 未实现其他操作
insts.emplace_back(opcode, std::vector<Operand>{
{Operand::Reg, std::string((const char*)bin->getResult())},
{Operand::Reg, std::string((const char*)bin->getLHS())},
{Operand::Reg, std::string((const char*)bin->getRHS())}
});
} else if (auto load = dynamic_cast<LoadInst*>(inst)) {
insts.emplace_back("lw", std::vector<Operand>{
{Operand::Reg, std::string((const char*)load->getResult())},
{Operand::Label, load->getPointer()->getName()}
});
} else if (auto store = dynamic_cast<StoreInst*>(inst)) {
insts.emplace_back("sw", std::vector<Operand>{
{Operand::Reg, std::string((const char*)store->getValue())},
{Operand::Label, store->getPointer()->getName()}
});
} // 其他指令类型待实现
return insts;
}
void RISCv32CodeGen::eliminate_phi(Function* func) {
// 简单实现假设CopyInst存在
for (auto bb : func->getBasicBlocks()) {
for (auto inst : bb->getInstructions()) {
if (/* inst is PhiInst */) {
// 插入CopyInst到前驱块
// 移除phi指令
}
}
}
}
std::map<Instruction*, std::set<Value*>> RISCv32CodeGen::liveness_analysis(Function* func) {
std::map<Instruction*, std::set<Value*>> live_sets;
// 简单实现:需实际计算活跃性
return live_sets;
}
std::map<Value*, std::set<Value*>> RISCv32CodeGen::build_interference_graph(
const std::map<Instruction*, std::set<Value*>>& live_sets) {
std::map<Value*, std::set<Value*>> graph;
// 简单实现:需实际构建干扰图
return graph;
}
RISCv32CodeGen::RegAllocResult RISCv32CodeGen::register_allocation(Function* func) {
RegAllocResult result;
eliminate_phi(func);
auto live_sets = liveness_analysis(func);
auto graph = build_interference_graph(live_sets);
// 图着色算法
std::vector<Value*> stack;
std::map<Value*, int> degrees;
for (const auto& pair : graph) {
degrees[pair.first] = pair.second.size();
if (degrees[pair.first] < allocable_regs.size()) {
stack.push_back(pair.first);
}
}
// 简单实现:需完成图着色和溢出处理
return result;
}
}