[backend]修复了多参数传递的错误
This commit is contained in:
@@ -1,12 +1,27 @@
|
||||
#include "PrologueEpilogueInsertion.h"
|
||||
#include "RISCv64ISel.h"
|
||||
#include "RISCv64RegAlloc.h" // 需要访问RegAlloc的结果
|
||||
#include <algorithm>
|
||||
|
||||
namespace sysy {
|
||||
|
||||
char PrologueEpilogueInsertionPass::ID = 0;
|
||||
|
||||
void PrologueEpilogueInsertionPass::runOnMachineFunction(MachineFunction* mfunc) {
|
||||
for (auto& mbb : mfunc->getBlocks()) {
|
||||
auto& instrs = mbb->getInstructions();
|
||||
|
||||
// 使用标准的 Erase-Remove Idiom 来删除满足条件的元素
|
||||
instrs.erase(
|
||||
std::remove_if(instrs.begin(), instrs.end(),
|
||||
[](const std::unique_ptr<MachineInstr>& instr) {
|
||||
return instr->getOpcode() == RVOpcodes::PSEUDO_KEEPALIVE;
|
||||
}
|
||||
),
|
||||
instrs.end()
|
||||
);
|
||||
}
|
||||
|
||||
StackFrameInfo& frame_info = mfunc->getFrameInfo();
|
||||
Function* F = mfunc->getFunc();
|
||||
RISCv64ISel* isel = mfunc->getISel();
|
||||
@@ -64,54 +79,35 @@ void PrologueEpilogueInsertionPass::runOnMachineFunction(MachineFunction* mfunc)
|
||||
set_fp->addOperand(std::make_unique<ImmOperand>(aligned_stack_size));
|
||||
prologue_instrs.push_back(std::move(set_fp));
|
||||
|
||||
// --- [正确逻辑] 在s0设置完毕后,使用物理寄存器加载栈参数 ---
|
||||
// --- 在s0设置完毕后,使用物理寄存器加载栈参数 ---
|
||||
if (F && isel) {
|
||||
// 定义暂存寄存器
|
||||
const PhysicalReg INT_SCRATCH_REG = PhysicalReg::T5;
|
||||
const PhysicalReg FP_SCRATCH_REG = PhysicalReg::F7;
|
||||
|
||||
int arg_idx = 0;
|
||||
for (Argument* arg : F->getArguments()) {
|
||||
if (arg_idx >= 8) {
|
||||
unsigned vreg = isel->getVReg(arg);
|
||||
|
||||
// 确认RegAlloc已经为这个vreg计算了偏移量,并且分配了物理寄存器
|
||||
if (frame_info.alloca_offsets.count(vreg) && vreg_to_preg_map.count(vreg)) {
|
||||
int offset = frame_info.alloca_offsets.at(vreg);
|
||||
PhysicalReg dest_preg = vreg_to_preg_map.at(vreg);
|
||||
Type* arg_type = arg->getType();
|
||||
|
||||
// 根据类型执行不同的加载序列
|
||||
if (arg_type->isFloat()) {
|
||||
// 1. flw ft7, offset(s0)
|
||||
auto load_arg = std::make_unique<MachineInstr>(RVOpcodes::FLW);
|
||||
load_arg->addOperand(std::make_unique<RegOperand>(FP_SCRATCH_REG));
|
||||
load_arg->addOperand(std::make_unique<RegOperand>(dest_preg));
|
||||
load_arg->addOperand(std::make_unique<MemOperand>(
|
||||
std::make_unique<RegOperand>(PhysicalReg::S0),
|
||||
std::make_unique<ImmOperand>(offset)
|
||||
));
|
||||
prologue_instrs.push_back(std::move(load_arg));
|
||||
// 2. fmv.s dest_preg, ft7
|
||||
auto move_arg = std::make_unique<MachineInstr>(RVOpcodes::FMV_S);
|
||||
move_arg->addOperand(std::make_unique<RegOperand>(dest_preg));
|
||||
move_arg->addOperand(std::make_unique<RegOperand>(FP_SCRATCH_REG));
|
||||
prologue_instrs.push_back(std::move(move_arg));
|
||||
} else {
|
||||
// 确定是加载32位(lw)还是64位(ld)
|
||||
RVOpcodes load_op = arg_type->isPointer() ? RVOpcodes::LD : RVOpcodes::LW;
|
||||
// 1. lw/ld t5, offset(s0)
|
||||
auto load_arg = std::make_unique<MachineInstr>(load_op);
|
||||
load_arg->addOperand(std::make_unique<RegOperand>(INT_SCRATCH_REG));
|
||||
load_arg->addOperand(std::make_unique<RegOperand>(dest_preg));
|
||||
load_arg->addOperand(std::make_unique<MemOperand>(
|
||||
std::make_unique<RegOperand>(PhysicalReg::S0),
|
||||
std::make_unique<ImmOperand>(offset)
|
||||
));
|
||||
prologue_instrs.push_back(std::move(load_arg));
|
||||
// 2. mv dest_preg, t5
|
||||
auto move_arg = std::make_unique<MachineInstr>(RVOpcodes::MV);
|
||||
move_arg->addOperand(std::make_unique<RegOperand>(dest_preg));
|
||||
move_arg->addOperand(std::make_unique<RegOperand>(INT_SCRATCH_REG));
|
||||
prologue_instrs.push_back(std::move(move_arg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user