73 lines
2.4 KiB
C++
73 lines
2.4 KiB
C++
#include "RISCv64Backend.h"
|
|
#include "RISCv64ISel.h"
|
|
#include "RISCv64RegAlloc.h"
|
|
#include "RISCv64AsmPrinter.h"
|
|
#include <sstream>
|
|
|
|
namespace sysy {
|
|
|
|
// 顶层入口
|
|
std::string RISCv64CodeGen::code_gen() {
|
|
return module_gen();
|
|
}
|
|
|
|
// 模块级代码生成 (移植自原文件,处理.data段和驱动函数生成)
|
|
std::string RISCv64CodeGen::module_gen() {
|
|
std::stringstream ss;
|
|
|
|
// 1. 处理全局变量 (.data段)
|
|
if (!module->getGlobals().empty()) {
|
|
ss << ".data\n";
|
|
for (const auto& global : module->getGlobals()) {
|
|
ss << ".globl " << global->getName() << "\n";
|
|
ss << global->getName() << ":\n";
|
|
const auto& init_values = global->getInitValues();
|
|
for (size_t i = 0; i < init_values.getValues().size(); ++i) {
|
|
auto val = init_values.getValues()[i];
|
|
auto count = init_values.getNumbers()[i];
|
|
if (auto constant = dynamic_cast<ConstantValue*>(val)) {
|
|
for (unsigned j = 0; j < count; ++j) {
|
|
if (constant->isInt()) {
|
|
ss << " .word " << constant->getInt() << "\n";
|
|
} else {
|
|
float f = constant->getFloat();
|
|
uint32_t float_bits = *(uint32_t*)&f;
|
|
ss << " .word " << float_bits << "\n";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 2. 处理函数 (.text段)
|
|
if (!module->getFunctions().empty()) {
|
|
ss << ".text\n";
|
|
for (const auto& func_pair : module->getFunctions()) {
|
|
if (func_pair.second.get()) {
|
|
ss << function_gen(func_pair.second.get());
|
|
}
|
|
}
|
|
}
|
|
return ss.str();
|
|
}
|
|
|
|
// function_gen 现在是新的、模块化的处理流水线
|
|
std::string RISCv64CodeGen::function_gen(Function* func) {
|
|
// 阶段 1: 指令选择 (sysy::IR -> LLIR with virtual registers)
|
|
RISCv64ISel isel;
|
|
std::unique_ptr<MachineFunction> mfunc = isel.runOnFunction(func);
|
|
|
|
// 阶段 2: 寄存器分配 (包含栈帧布局, 活跃性分析, 图着色, spill/rewrite)
|
|
RISCv64RegAlloc reg_alloc(mfunc.get());
|
|
reg_alloc.run();
|
|
|
|
// 阶段 3: 代码发射 (LLIR with physical regs -> Assembly Text)
|
|
std::stringstream ss;
|
|
RISCv64AsmPrinter printer(mfunc.get());
|
|
printer.run(ss);
|
|
|
|
return ss.str();
|
|
}
|
|
|
|
} // namespace sysy
|