#include "LegalizeImmediates.h" #include "RISCv64ISel.h" // 需要包含它以调用 getNewVReg() #include "RISCv64AsmPrinter.h" #include #include // 声明外部调试控制变量 extern int DEBUG; extern int DEEPDEBUG; namespace sysy { char LegalizeImmediatesPass::ID = 0; // 辅助函数:检查一个立即数是否在RISC-V的12位有符号范围内 static bool isLegalImmediate(int64_t imm) { return imm >= -2048 && imm <= 2047; } void LegalizeImmediatesPass::runOnMachineFunction(MachineFunction* mfunc) { if (DEBUG) { std::cerr << "===== Running Legalize Immediates Pass on function: " << mfunc->getName() << " =====\n"; } // 定义我们保留的、用于暂存的物理寄存器 const PhysicalReg TEMP_REG = PhysicalReg::T5; // 创建一个临时的AsmPrinter用于打印指令,方便调试 RISCv64AsmPrinter temp_printer(mfunc); if (DEEPDEBUG) { temp_printer.setStream(std::cerr); } for (auto& mbb : mfunc->getBlocks()) { if (DEEPDEBUG) { std::cerr << "--- Processing Basic Block: " << mbb->getName() << " ---\n"; } // 创建一个新的指令列表,用于存放合法化后的指令 std::vector> new_instructions; for (auto& instr_ptr : mbb->getInstructions()) { if (DEEPDEBUG) { std::cerr << " Checking: "; // 打印指令时末尾会带换行符,所以这里不用 std::endl temp_printer.printInstruction(instr_ptr.get(), true); } bool legalized = false; // 标记当前指令是否已被展开处理 switch (instr_ptr->getOpcode()) { case RVOpcodes::ADDI: case RVOpcodes::ADDIW: { auto& operands = instr_ptr->getOperands(); // 确保操作数足够多,以防万一 if (operands.size() < 3) break; auto imm_op = static_cast(operands.back().get()); if (!isLegalImmediate(imm_op->getValue())) { if (DEEPDEBUG) { std::cerr << " >> ILLEGAL immediate (" << imm_op->getValue() << "). Expanding...\n"; } // 立即数超出范围,需要展开 auto rd_op = std::make_unique(*static_cast(operands[0].get())); auto rs1_op = std::make_unique(*static_cast(operands[1].get())); // 1. li t5, immediate auto li = std::make_unique(RVOpcodes::LI); li->addOperand(std::make_unique(TEMP_REG)); li->addOperand(std::make_unique(imm_op->getValue())); // 2. add/addw rd, rs1, t5 auto new_op = (instr_ptr->getOpcode() == RVOpcodes::ADDI) ? RVOpcodes::ADD : RVOpcodes::ADDW; auto add = std::make_unique(new_op); add->addOperand(std::move(rd_op)); add->addOperand(std::move(rs1_op)); add->addOperand(std::make_unique(TEMP_REG)); if (DEEPDEBUG) { std::cerr << " New sequence:\n "; temp_printer.printInstruction(li.get(), true); std::cerr << " "; temp_printer.printInstruction(add.get(), true); } new_instructions.push_back(std::move(li)); new_instructions.push_back(std::move(add)); legalized = true; } break; } // 处理所有内存加载/存储指令 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: case RVOpcodes::FLW: case RVOpcodes::FSW: { auto& operands = instr_ptr->getOperands(); auto mem_op = static_cast(operands.back().get()); auto offset_op = mem_op->getOffset(); if (!isLegalImmediate(offset_op->getValue())) { if (DEEPDEBUG) { std::cerr << " >> ILLEGAL immediate offset (" << offset_op->getValue() << "). Expanding...\n"; } // 偏移量超出范围,需要展开 auto data_reg_op = std::make_unique(*static_cast(operands[0].get())); auto base_reg_op = std::make_unique(*mem_op->getBase()); // 1. li t5, offset auto li = std::make_unique(RVOpcodes::LI); li->addOperand(std::make_unique(TEMP_REG)); li->addOperand(std::make_unique(offset_op->getValue())); // 2. add t5, base_reg, t5 (计算最终地址,结果也放在t5) auto add = std::make_unique(RVOpcodes::ADD); add->addOperand(std::make_unique(TEMP_REG)); add->addOperand(std::move(base_reg_op)); add->addOperand(std::make_unique(TEMP_REG)); // 3. lw/sw data_reg, 0(t5) auto mem_instr = std::make_unique(instr_ptr->getOpcode()); mem_instr->addOperand(std::move(data_reg_op)); mem_instr->addOperand(std::make_unique( std::make_unique(TEMP_REG), std::make_unique(0) )); if (DEEPDEBUG) { std::cerr << " New sequence:\n "; temp_printer.printInstruction(li.get(), true); std::cerr << " "; temp_printer.printInstruction(add.get(), true); std::cerr << " "; temp_printer.printInstruction(mem_instr.get(), true); } new_instructions.push_back(std::move(li)); new_instructions.push_back(std::move(add)); new_instructions.push_back(std::move(mem_instr)); legalized = true; } break; } default: // 其他指令不需要处理 break; } if (!legalized) { if (DEEPDEBUG) { std::cerr << " -- Immediate is legal. Skipping.\n"; } // 如果当前指令不需要合法化,直接将其移动到新列表中 new_instructions.push_back(std::move(instr_ptr)); } } // 用新的、已合法化的指令列表替换旧的列表 mbb->getInstructions() = std::move(new_instructions); } if (DEBUG) { std::cerr << "===== Finished Legalize Immediates Pass =====\n\n"; } } } // namespace sysy