From 9c87cb397bf1c68187cd722a4d0c7c0515e92e07 Mon Sep 17 00:00:00 2001 From: Lixuanwang Date: Tue, 22 Jul 2025 00:07:54 +0800 Subject: [PATCH] =?UTF-8?q?[backend]=E8=A7=A3=E5=86=B3=E4=BA=86=E9=9D=9E?= =?UTF-8?q?=E9=9B=B6=E6=95=B0=E7=BB=84=E5=88=9D=E5=A7=8B=E5=8C=96=E4=B8=8D?= =?UTF-8?q?=E6=AD=A3=E7=A1=AE=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/RISCv64ISel.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/RISCv64ISel.cpp b/src/RISCv64ISel.cpp index 2da2373..fdef521 100644 --- a/src/RISCv64ISel.cpp +++ b/src/RISCv64ISel.cpp @@ -238,7 +238,52 @@ void RISCv64ISel::selectNode(DAGNode* node) { auto bin = dynamic_cast(node->value); Value* lhs = bin->getLhs(); Value* rhs = bin->getRhs(); + + // 检查是否是“基地址+偏移量”的地址计算模式 + if (bin->getKind() == BinaryInst::kAdd) { + Value* base = nullptr; + Value* offset = nullptr; + // 判断哪个是基地址(AllocaInst),哪个是偏移量 + if (dynamic_cast(lhs)) { + base = lhs; + offset = rhs; + } else if (dynamic_cast(rhs)) { + base = rhs; + offset = lhs; + } + + // 如果成功匹配到该模式 + if (base) { + // [最终修复] + // 1. 先为偏移量加载常量(如果它是常量的话) + if (auto const_offset = dynamic_cast(offset)) { + auto li = std::make_unique(RVOpcodes::LI); + li->addOperand(std::make_unique(getVReg(const_offset))); + li->addOperand(std::make_unique(const_offset->getInt())); + CurMBB->addInstruction(std::move(li)); + } + + // 2. 使用FRAME_ADDR伪指令来获取基地址 + auto base_addr_vreg = getNewVReg(); // 创建一个新的临时vreg来存放基地址 + auto frame_addr_instr = std::make_unique(RVOpcodes::FRAME_ADDR); + frame_addr_instr->addOperand(std::make_unique(base_addr_vreg)); + frame_addr_instr->addOperand(std::make_unique(getVReg(base))); + CurMBB->addInstruction(std::move(frame_addr_instr)); + + // 3. 生成真正的add指令,计算最终地址 + auto final_addr_vreg = getVReg(bin); // 这是整个二元运算的结果vreg + auto offset_vreg = getVReg(offset); + auto add_instr = std::make_unique(RVOpcodes::ADD); // 指针运算是64位 + add_instr->addOperand(std::make_unique(final_addr_vreg)); + add_instr->addOperand(std::make_unique(base_addr_vreg)); + add_instr->addOperand(std::make_unique(offset_vreg)); + CurMBB->addInstruction(std::move(add_instr)); + + return; // 地址计算处理完毕,直接返回 + } + } + // [V2优点] 在BINARY节点内部按需加载常量操作数。 auto load_val_if_const = [&](Value* val) { if (auto c = dynamic_cast(val)) {