67 lines
2.0 KiB
C++
67 lines
2.0 KiB
C++
#ifndef RISCV32_BACKEND_H
|
|
#define RISCV32_BACKEND_H
|
|
|
|
#include "IR.h"
|
|
#include <string>
|
|
#include <vector>
|
|
#include <map>
|
|
#include <set>
|
|
|
|
namespace sysy {
|
|
|
|
class RISCv32CodeGen {
|
|
public:
|
|
explicit RISCv32CodeGen(Module* mod) : module(mod) {}
|
|
std::string code_gen(); // 生成模块的汇编代码
|
|
|
|
private:
|
|
Module* module;
|
|
|
|
// 物理寄存器
|
|
enum class PhysicalReg {
|
|
T0, T1, T2, T3, T4, T5, T6, // x5-x7, x28-x31
|
|
A0, A1, A2, A3, A4, A5, A6, A7 // x10-x17
|
|
};
|
|
static const std::vector<PhysicalReg> allocable_regs;
|
|
|
|
// 操作数
|
|
struct Operand {
|
|
enum class Kind { Reg, Imm, Label };
|
|
Kind kind;
|
|
Value* value; // 用于寄存器
|
|
std::string label; // 用于标签或立即数
|
|
Operand(Kind k, Value* v) : kind(k), value(v), label("") {}
|
|
Operand(Kind k, const std::string& l) : kind(k), value(nullptr), label(l) {}
|
|
};
|
|
|
|
// RISC-V 指令
|
|
struct RISCv32Inst {
|
|
std::string opcode;
|
|
std::vector<Operand> operands;
|
|
RISCv32Inst(const std::string& op, const std::vector<Operand>& ops)
|
|
: opcode(op), operands(ops) {}
|
|
};
|
|
|
|
// 寄存器分配结果
|
|
struct RegAllocResult {
|
|
std::map<Value*, PhysicalReg> reg_map; // 虚拟寄存器到物理寄存器的映射
|
|
std::map<Value*, int> stack_map; // 虚拟寄存器到堆栈槽的映射
|
|
int stack_size; // 堆栈帧大小
|
|
};
|
|
|
|
// 后端方法
|
|
std::string module_gen();
|
|
std::string function_gen(Function* func);
|
|
std::string basicBlock_gen(BasicBlock* bb, const RegAllocResult& alloc);
|
|
std::vector<RISCv32Inst> instruction_gen(Instruction* inst);
|
|
RegAllocResult register_allocation(Function* func);
|
|
void eliminate_phi(Function* func);
|
|
std::map<Instruction*, std::set<Value*>> liveness_analysis(Function* func);
|
|
std::map<Value*, std::set<Value*>> build_interference_graph(
|
|
const std::map<Instruction*, std::set<Value*>>& live_sets);
|
|
std::string reg_to_string(PhysicalReg reg);
|
|
};
|
|
|
|
} // namespace sysy
|
|
|
|
#endif // RISCV32_BACKEND_H
|