[backend-llir]修复了许多重构的bug
This commit is contained in:
@@ -1,44 +1,71 @@
|
||||
#include "RISCv64AsmPrinter.h"
|
||||
#include "RISCv64ISel.h"
|
||||
#include <stdexcept>
|
||||
|
||||
namespace sysy {
|
||||
|
||||
void RISCv64AsmPrinter::runOnMachineFunction(MachineFunction* mfunc, std::ostream& os) {
|
||||
// 检查是否为内存加载/存储指令,以处理特殊的打印格式
|
||||
bool isMemoryOp(RVOpcodes opcode) {
|
||||
switch (opcode) {
|
||||
case RVOpcodes::LB: case RVOpcodes::LH: case RVOpcodes::LW: case RVOpcodes::LD:
|
||||
case RVOpcodes::LBU: case RVOpcodes::LHU: case RVOpcodes::LWU:
|
||||
case RVOpcodes::SB: case RVOpcodes::SH: case RVOpcodes::SW: case RVOpcodes::SD:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
RISCv64AsmPrinter::RISCv64AsmPrinter(MachineFunction* mfunc) : MFunc(mfunc) {}
|
||||
|
||||
void RISCv64AsmPrinter::run(std::ostream& os) {
|
||||
OS = &os;
|
||||
|
||||
// 打印函数声明和全局符号
|
||||
*OS << ".text\n";
|
||||
*OS << ".globl " << mfunc->getName() << "\n";
|
||||
*OS << mfunc->getName() << ":\n";
|
||||
*OS << ".globl " << MFunc->getName() << "\n";
|
||||
*OS << MFunc->getName() << ":\n";
|
||||
|
||||
// 打印函数序言
|
||||
printPrologue(mfunc);
|
||||
printPrologue();
|
||||
|
||||
// 遍历并打印所有基本块
|
||||
for (auto& mbb : mfunc->getBlocks()) {
|
||||
for (auto& mbb : MFunc->getBlocks()) {
|
||||
printBasicBlock(mbb.get());
|
||||
}
|
||||
}
|
||||
|
||||
void RISCv64AsmPrinter::printPrologue(MachineFunction* mfunc) {
|
||||
int stack_size = mfunc->getFrameInfo().frame_size;
|
||||
|
||||
// 确保栈大小是16字节对齐
|
||||
int aligned_stack_size = (stack_size + 15) & ~15;
|
||||
void RISCv64AsmPrinter::printPrologue() {
|
||||
StackFrameInfo& frame_info = MFunc->getFrameInfo();
|
||||
// 序言需要为保存ra和s0预留16字节
|
||||
int total_stack_size = frame_info.locals_size + frame_info.spill_size + 16;
|
||||
int aligned_stack_size = (total_stack_size + 15) & ~15;
|
||||
frame_info.total_size = aligned_stack_size;
|
||||
|
||||
if (aligned_stack_size > 0) {
|
||||
*OS << " addi sp, sp, -" << aligned_stack_size << "\n";
|
||||
// RV64中ra和s0都是8字节
|
||||
*OS << " sd ra, " << (aligned_stack_size - 8) << "(sp)\n";
|
||||
*OS << " sd s0, " << (aligned_stack_size - 16) << "(sp)\n";
|
||||
*OS << " mv s0, sp\n";
|
||||
}
|
||||
|
||||
// 忠实还原保存函数入口参数的逻辑
|
||||
Function* F = MFunc->getFunc();
|
||||
if (F && F->getEntryBlock()) {
|
||||
int arg_idx = 0;
|
||||
RISCv64ISel* isel = MFunc->getISel();
|
||||
for (AllocaInst* alloca_for_param : F->getEntryBlock()->getArguments()) {
|
||||
if (arg_idx >= 8) break;
|
||||
|
||||
unsigned vreg = isel->getVReg(alloca_for_param);
|
||||
if (frame_info.alloca_offsets.count(vreg)) {
|
||||
int offset = frame_info.alloca_offsets.at(vreg);
|
||||
auto arg_reg = static_cast<PhysicalReg>(static_cast<int>(PhysicalReg::A0) + arg_idx);
|
||||
*OS << " sw " << regToString(arg_reg) << ", " << offset << "(s0)\n";
|
||||
}
|
||||
arg_idx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RISCv64AsmPrinter::printEpilogue(MachineFunction* mfunc) {
|
||||
int stack_size = mfunc->getFrameInfo().frame_size;
|
||||
int aligned_stack_size = (stack_size + 15) & ~15;
|
||||
|
||||
void RISCv64AsmPrinter::printEpilogue() {
|
||||
int aligned_stack_size = MFunc->getFrameInfo().total_size;
|
||||
if (aligned_stack_size > 0) {
|
||||
*OS << " ld ra, " << (aligned_stack_size - 8) << "(sp)\n";
|
||||
*OS << " ld s0, " << (aligned_stack_size - 16) << "(sp)\n";
|
||||
@@ -46,129 +73,85 @@ void RISCv64AsmPrinter::printEpilogue(MachineFunction* mfunc) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RISCv64AsmPrinter::printBasicBlock(MachineBasicBlock* mbb) {
|
||||
// 打印基本块标签
|
||||
if (!mbb->getName().empty()) {
|
||||
*OS << mbb->getName() << ":\n";
|
||||
}
|
||||
|
||||
// 打印指令
|
||||
for (auto& instr : mbb->getInstructions()) {
|
||||
printInstruction(instr.get(), mbb);
|
||||
printInstruction(instr.get());
|
||||
}
|
||||
}
|
||||
|
||||
void RISCv64AsmPrinter::printInstruction(MachineInstr* instr, MachineBasicBlock* parent_bb) {
|
||||
*OS << " "; // 指令缩进
|
||||
|
||||
void RISCv64AsmPrinter::printInstruction(MachineInstr* instr) {
|
||||
auto opcode = instr->getOpcode();
|
||||
|
||||
// RET指令需要特殊处理,在打印ret之前先打印函数尾声
|
||||
if (opcode == RVOpcodes::RET) {
|
||||
printEpilogue(parent_bb->getParent());
|
||||
printEpilogue();
|
||||
}
|
||||
|
||||
// 使用switch将Opcode转换为汇编助记符
|
||||
if (opcode != RVOpcodes::LABEL) {
|
||||
*OS << " ";
|
||||
}
|
||||
|
||||
switch (opcode) {
|
||||
// Arithmatic
|
||||
case RVOpcodes::ADD: *OS << "add "; break;
|
||||
case RVOpcodes::ADDI: *OS << "addi "; break;
|
||||
case RVOpcodes::ADDW: *OS << "addw "; break;
|
||||
case RVOpcodes::ADDIW: *OS << "addiw "; break;
|
||||
case RVOpcodes::SUB: *OS << "sub "; break;
|
||||
case RVOpcodes::SUBW: *OS << "subw "; break;
|
||||
case RVOpcodes::MUL: *OS << "mul "; break;
|
||||
case RVOpcodes::MULW: *OS << "mulw "; break;
|
||||
case RVOpcodes::DIV: *OS << "div "; break;
|
||||
case RVOpcodes::DIVW: *OS << "divw "; break;
|
||||
case RVOpcodes::REM: *OS << "rem "; break;
|
||||
case RVOpcodes::REMW: *OS << "remw "; break;
|
||||
// Logical
|
||||
case RVOpcodes::XOR: *OS << "xor "; break;
|
||||
case RVOpcodes::XORI: *OS << "xori "; break;
|
||||
case RVOpcodes::OR: *OS << "or "; break;
|
||||
case RVOpcodes::ORI: *OS << "ori "; break;
|
||||
case RVOpcodes::AND: *OS << "and "; break;
|
||||
case RVOpcodes::ANDI: *OS << "andi "; break;
|
||||
// Shift
|
||||
case RVOpcodes::SLL: *OS << "sll "; break;
|
||||
case RVOpcodes::SLLI: *OS << "slli "; break;
|
||||
case RVOpcodes::SLLW: *OS << "sllw "; break;
|
||||
case RVOpcodes::SLLIW: *OS << "slliw "; break;
|
||||
case RVOpcodes::SRL: *OS << "srl "; break;
|
||||
case RVOpcodes::SRLI: *OS << "srli "; break;
|
||||
case RVOpcodes::SRLW: *OS << "srlw "; break;
|
||||
case RVOpcodes::SRLIW: *OS << "srliw "; break;
|
||||
case RVOpcodes::SRA: *OS << "sra "; break;
|
||||
case RVOpcodes::SRAI: *OS << "srai "; break;
|
||||
case RVOpcodes::SRAW: *OS << "sraw "; break;
|
||||
case RVOpcodes::SRAIW: *OS << "sraiw "; break;
|
||||
// Compare
|
||||
case RVOpcodes::SLT: *OS << "slt "; break;
|
||||
case RVOpcodes::SLTI: *OS << "slti "; break;
|
||||
case RVOpcodes::SLTU: *OS << "sltu "; break;
|
||||
case RVOpcodes::SLTIU: *OS << "sltiu "; break;
|
||||
// Memory
|
||||
case RVOpcodes::LW: *OS << "lw "; break;
|
||||
case RVOpcodes::LH: *OS << "lh "; break;
|
||||
case RVOpcodes::LB: *OS << "lb "; break;
|
||||
case RVOpcodes::LWU: *OS << "lwu "; break;
|
||||
case RVOpcodes::LHU: *OS << "lhu "; break;
|
||||
case RVOpcodes::LBU: *OS << "lbu "; break;
|
||||
case RVOpcodes::SW: *OS << "sw "; break;
|
||||
case RVOpcodes::SH: *OS << "sh "; break;
|
||||
case RVOpcodes::SB: *OS << "sb "; break;
|
||||
case RVOpcodes::LD: *OS << "ld "; break;
|
||||
case RVOpcodes::ADD: *OS << "add "; break; case RVOpcodes::ADDI: *OS << "addi "; break;
|
||||
case RVOpcodes::ADDW: *OS << "addw "; break; case RVOpcodes::ADDIW: *OS << "addiw "; break;
|
||||
case RVOpcodes::SUB: *OS << "sub "; break; case RVOpcodes::SUBW: *OS << "subw "; break;
|
||||
case RVOpcodes::MUL: *OS << "mul "; break; case RVOpcodes::MULW: *OS << "mulw "; break;
|
||||
case RVOpcodes::DIV: *OS << "div "; break; case RVOpcodes::DIVW: *OS << "divw "; break;
|
||||
case RVOpcodes::REM: *OS << "rem "; break; case RVOpcodes::REMW: *OS << "remw "; break;
|
||||
case RVOpcodes::XOR: *OS << "xor "; break; case RVOpcodes::XORI: *OS << "xori "; break;
|
||||
case RVOpcodes::OR: *OS << "or "; break; case RVOpcodes::ORI: *OS << "ori "; break;
|
||||
case RVOpcodes::AND: *OS << "and "; break; case RVOpcodes::ANDI: *OS << "andi "; break;
|
||||
case RVOpcodes::SLL: *OS << "sll "; break; case RVOpcodes::SLLI: *OS << "slli "; break;
|
||||
case RVOpcodes::SLLW: *OS << "sllw "; break; case RVOpcodes::SLLIW: *OS << "slliw "; break;
|
||||
case RVOpcodes::SRL: *OS << "srl "; break; case RVOpcodes::SRLI: *OS << "srli "; break;
|
||||
case RVOpcodes::SRLW: *OS << "srlw "; break; case RVOpcodes::SRLIW: *OS << "srliw "; break;
|
||||
case RVOpcodes::SRA: *OS << "sra "; break; case RVOpcodes::SRAI: *OS << "srai "; break;
|
||||
case RVOpcodes::SRAW: *OS << "sraw "; break; case RVOpcodes::SRAIW: *OS << "sraiw "; break;
|
||||
case RVOpcodes::SLT: *OS << "slt "; break; case RVOpcodes::SLTI: *OS << "slti "; break;
|
||||
case RVOpcodes::SLTU: *OS << "sltu "; break; case RVOpcodes::SLTIU: *OS << "sltiu "; break;
|
||||
case RVOpcodes::LW: *OS << "lw "; break; case RVOpcodes::LH: *OS << "lh "; break;
|
||||
case RVOpcodes::LB: *OS << "lb "; break; case RVOpcodes::LWU: *OS << "lwu "; break;
|
||||
case RVOpcodes::LHU: *OS << "lhu "; break; case RVOpcodes::LBU: *OS << "lbu "; break;
|
||||
case RVOpcodes::SW: *OS << "sw "; break; case RVOpcodes::SH: *OS << "sh "; break;
|
||||
case RVOpcodes::SB: *OS << "sb "; break; case RVOpcodes::LD: *OS << "ld "; break;
|
||||
case RVOpcodes::SD: *OS << "sd "; break;
|
||||
// Control Flow
|
||||
case RVOpcodes::J: *OS << "j "; break;
|
||||
case RVOpcodes::JAL: *OS << "jal "; break;
|
||||
case RVOpcodes::JALR: *OS << "jalr "; break;
|
||||
case RVOpcodes::RET: *OS << "ret"; break;
|
||||
case RVOpcodes::BEQ: *OS << "beq "; break;
|
||||
case RVOpcodes::BNE: *OS << "bne "; break;
|
||||
case RVOpcodes::BLT: *OS << "blt "; break;
|
||||
case RVOpcodes::BGE: *OS << "bge "; break;
|
||||
case RVOpcodes::BLTU: *OS << "bltu "; break;
|
||||
case RVOpcodes::BGEU: *OS << "bgeu "; break;
|
||||
// Pseudo-Instructions
|
||||
case RVOpcodes::LI: *OS << "li "; break;
|
||||
case RVOpcodes::LA: *OS << "la "; break;
|
||||
case RVOpcodes::MV: *OS << "mv "; break;
|
||||
case RVOpcodes::NEG: *OS << "neg "; break;
|
||||
case RVOpcodes::NEGW: *OS << "negw "; break;
|
||||
case RVOpcodes::SEQZ: *OS << "seqz "; break;
|
||||
case RVOpcodes::J: *OS << "j "; break; case RVOpcodes::JAL: *OS << "jal "; break;
|
||||
case RVOpcodes::JALR: *OS << "jalr "; break; case RVOpcodes::RET: *OS << "ret"; break;
|
||||
case RVOpcodes::BEQ: *OS << "beq "; break; case RVOpcodes::BNE: *OS << "bne "; break;
|
||||
case RVOpcodes::BLT: *OS << "blt "; break; case RVOpcodes::BGE: *OS << "bge "; break;
|
||||
case RVOpcodes::BLTU: *OS << "bltu "; break; case RVOpcodes::BGEU: *OS << "bgeu "; break;
|
||||
case RVOpcodes::LI: *OS << "li "; break; case RVOpcodes::LA: *OS << "la "; break;
|
||||
case RVOpcodes::MV: *OS << "mv "; break; case RVOpcodes::NEG: *OS << "neg "; break;
|
||||
case RVOpcodes::NEGW: *OS << "negw "; break; case RVOpcodes::SEQZ: *OS << "seqz "; break;
|
||||
case RVOpcodes::SNEZ: *OS << "snez "; break;
|
||||
// Call
|
||||
case RVOpcodes::CALL: *OS << "call "; break;
|
||||
// Special
|
||||
case RVOpcodes::LABEL:
|
||||
*OS << "\b\b\b\b";
|
||||
printOperand(instr->getOperands()[0].get());
|
||||
*OS << ":";
|
||||
break;
|
||||
case RVOpcodes::FRAME_LOAD:
|
||||
case RVOpcodes::FRAME_STORE:
|
||||
// These should have been eliminated by RegAlloc
|
||||
throw std::runtime_error("FRAME pseudo-instruction not eliminated before AsmPrinter");
|
||||
default:
|
||||
throw std::runtime_error("Unknown opcode in AsmPrinter");
|
||||
}
|
||||
|
||||
// 打印操作数
|
||||
const auto& operands = instr->getOperands();
|
||||
for (size_t i = 0; i < operands.size(); ++i) {
|
||||
// 对于LW/SW, 操作数格式是 rd, offset(rs1)
|
||||
if (opcode == RVOpcodes::LW || opcode == RVOpcodes::SW || opcode == RVOpcodes::LD || opcode == RVOpcodes::SD) {
|
||||
if (!operands.empty()) {
|
||||
if (isMemoryOp(opcode)) {
|
||||
printOperand(operands[0].get());
|
||||
*OS << ", ";
|
||||
printOperand(operands[1].get());
|
||||
break; // LW/SW只有两个操作数部分
|
||||
}
|
||||
|
||||
printOperand(operands[i].get());
|
||||
if (i < operands.size() - 1) {
|
||||
*OS << ", ";
|
||||
} else {
|
||||
for (size_t i = 0; i < operands.size(); ++i) {
|
||||
printOperand(operands[i].get());
|
||||
if (i < operands.size() - 1) {
|
||||
*OS << ", ";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*OS << "\n";
|
||||
}
|
||||
|
||||
@@ -178,21 +161,18 @@ void RISCv64AsmPrinter::printOperand(MachineOperand* op) {
|
||||
case MachineOperand::KIND_REG: {
|
||||
auto reg_op = static_cast<RegOperand*>(op);
|
||||
if (reg_op->isVirtual()) {
|
||||
// 在这个阶段不应该再有虚拟寄存器了
|
||||
*OS << "%vreg" << reg_op->getVRegNum();
|
||||
} else {
|
||||
*OS << regToString(reg_op->getPReg());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MachineOperand::KIND_IMM: {
|
||||
case MachineOperand::KIND_IMM:
|
||||
*OS << static_cast<ImmOperand*>(op)->getValue();
|
||||
break;
|
||||
}
|
||||
case MachineOperand::KIND_LABEL: {
|
||||
case MachineOperand::KIND_LABEL:
|
||||
*OS << static_cast<LabelOperand*>(op)->getName();
|
||||
break;
|
||||
}
|
||||
case MachineOperand::KIND_MEM: {
|
||||
auto mem_op = static_cast<MemOperand*>(op);
|
||||
printOperand(mem_op->getOffset());
|
||||
@@ -204,41 +184,40 @@ void RISCv64AsmPrinter::printOperand(MachineOperand* op) {
|
||||
}
|
||||
}
|
||||
|
||||
// 物理寄存器到字符串的转换 (从原RISCv64Backend.cpp迁移)
|
||||
std::string RISCv64AsmPrinter::regToString(PhysicalReg reg) {
|
||||
switch (reg) {
|
||||
case PhysicalReg::ZERO: return "x0";
|
||||
case PhysicalReg::RA: return "ra";
|
||||
case PhysicalReg::SP: return "sp";
|
||||
case PhysicalReg::GP: return "gp";
|
||||
case PhysicalReg::TP: return "tp";
|
||||
case PhysicalReg::T0: return "t0";
|
||||
case PhysicalReg::T1: return "t1";
|
||||
case PhysicalReg::T2: return "t2";
|
||||
case PhysicalReg::S0: return "s0";
|
||||
case PhysicalReg::S1: return "s1";
|
||||
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";
|
||||
case PhysicalReg::S2: return "s2";
|
||||
case PhysicalReg::S3: return "s3";
|
||||
case PhysicalReg::S4: return "s4";
|
||||
case PhysicalReg::S5: return "s5";
|
||||
case PhysicalReg::S6: return "s6";
|
||||
case PhysicalReg::S7: return "s7";
|
||||
case PhysicalReg::S8: return "s8";
|
||||
case PhysicalReg::S9: return "s9";
|
||||
case PhysicalReg::S10: return "s10";
|
||||
case PhysicalReg::S11: return "s11";
|
||||
case PhysicalReg::T3: return "t3";
|
||||
case PhysicalReg::T4: return "t4";
|
||||
case PhysicalReg::T5: return "t5";
|
||||
case PhysicalReg::T6: return "t6";
|
||||
case PhysicalReg::ZERO: return "x0"; case PhysicalReg::RA: return "ra";
|
||||
case PhysicalReg::SP: return "sp"; case PhysicalReg::GP: return "gp";
|
||||
case PhysicalReg::TP: return "tp"; case PhysicalReg::T0: return "t0";
|
||||
case PhysicalReg::T1: return "t1"; case PhysicalReg::T2: return "t2";
|
||||
case PhysicalReg::S0: return "s0"; case PhysicalReg::S1: return "s1";
|
||||
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";
|
||||
case PhysicalReg::S2: return "s2"; case PhysicalReg::S3: return "s3";
|
||||
case PhysicalReg::S4: return "s4"; case PhysicalReg::S5: return "s5";
|
||||
case PhysicalReg::S6: return "s6"; case PhysicalReg::S7: return "s7";
|
||||
case PhysicalReg::S8: return "s8"; case PhysicalReg::S9: return "s9";
|
||||
case PhysicalReg::S10: return "s10"; case PhysicalReg::S11: return "s11";
|
||||
case PhysicalReg::T3: return "t3"; case PhysicalReg::T4: return "t4";
|
||||
case PhysicalReg::T5: return "t5"; case PhysicalReg::T6: return "t6";
|
||||
case PhysicalReg::F0: return "f0"; case PhysicalReg::F1: return "f1";
|
||||
case PhysicalReg::F2: return "f2"; case PhysicalReg::F3: return "f3";
|
||||
case PhysicalReg::F4: return "f4"; case PhysicalReg::F5: return "f5";
|
||||
case PhysicalReg::F6: return "f6"; case PhysicalReg::F7: return "f7";
|
||||
case PhysicalReg::F8: return "f8"; case PhysicalReg::F9: return "f9";
|
||||
case PhysicalReg::F10: return "f10"; case PhysicalReg::F11: return "f11";
|
||||
case PhysicalReg::F12: return "f12"; case PhysicalReg::F13: return "f13";
|
||||
case PhysicalReg::F14: return "f14"; case PhysicalReg::F15: return "f15";
|
||||
case PhysicalReg::F16: return "f16"; case PhysicalReg::F17: return "f17";
|
||||
case PhysicalReg::F18: return "f18"; case PhysicalReg::F19: return "f19";
|
||||
case PhysicalReg::F20: return "f20"; case PhysicalReg::F21: return "f21";
|
||||
case PhysicalReg::F22: return "f22"; case PhysicalReg::F23: return "f23";
|
||||
case PhysicalReg::F24: return "f24"; case PhysicalReg::F25: return "f25";
|
||||
case PhysicalReg::F26: return "f26"; case PhysicalReg::F27: return "f27";
|
||||
case PhysicalReg::F28: return "f28"; case PhysicalReg::F29: return "f29";
|
||||
case PhysicalReg::F30: return "f30"; case PhysicalReg::F31: return "f31";
|
||||
default: return "UNKNOWN_REG";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user