From f7f1cf2b41c5a17020182af41e4ac76583bd356c Mon Sep 17 00:00:00 2001 From: Lixuanwang Date: Mon, 4 Aug 2025 21:54:24 +0800 Subject: [PATCH] =?UTF-8?q?[backend]=E6=B5=AE=E7=82=B9=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E4=B8=8Egcc=E4=BF=9D=E6=8C=81=E4=B8=80=E8=87=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/RISCv64/RISCv64AsmPrinter.cpp | 3 +- src/backend/RISCv64/RISCv64ISel.cpp | 100 ++++------------------ src/include/backend/RISCv64/RISCv64ISel.h | 1 - src/include/backend/RISCv64/RISCv64LLIR.h | 1 + 4 files changed, 18 insertions(+), 87 deletions(-) diff --git a/src/backend/RISCv64/RISCv64AsmPrinter.cpp b/src/backend/RISCv64/RISCv64AsmPrinter.cpp index 4dd8fd8..5a01b8e 100644 --- a/src/backend/RISCv64/RISCv64AsmPrinter.cpp +++ b/src/backend/RISCv64/RISCv64AsmPrinter.cpp @@ -82,7 +82,7 @@ void RISCv64AsmPrinter::printInstruction(MachineInstr* instr, bool debug) { case RVOpcodes::SB: *OS << "sb "; break; case RVOpcodes::LD: *OS << "ld "; break; case RVOpcodes::SD: *OS << "sd "; break; case RVOpcodes::FLW: *OS << "flw "; break; case RVOpcodes::FSW: *OS << "fsw "; break; case RVOpcodes::FLD: *OS << "fld "; break; - case RVOpcodes::FSD: *OS << "fsd "; break; + case RVOpcodes::FSD: *OS << "fsd "; 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; @@ -102,6 +102,7 @@ void RISCv64AsmPrinter::printInstruction(MachineInstr* instr, bool debug) { case RVOpcodes::FLE_S: *OS << "fle.s "; break; case RVOpcodes::FCVT_S_W: *OS << "fcvt.s.w "; break; case RVOpcodes::FCVT_W_S: *OS << "fcvt.w.s "; break; + case RVOpcodes::FCVT_W_S_RTZ: *OS << "fcvt.w.s "; break; case RVOpcodes::FMV_S: *OS << "fmv.s "; break; case RVOpcodes::FMV_W_X: *OS << "fmv.w.x "; break; case RVOpcodes::FMV_X_W: *OS << "fmv.x.w "; break; diff --git a/src/backend/RISCv64/RISCv64ISel.cpp b/src/backend/RISCv64/RISCv64ISel.cpp index dad1bbb..21e8e3c 100644 --- a/src/backend/RISCv64/RISCv64ISel.cpp +++ b/src/backend/RISCv64/RISCv64ISel.cpp @@ -745,83 +745,12 @@ void RISCv64ISel::selectNode(DAGNode* node) { CurMBB->addInstruction(std::move(instr)); break; } - case Instruction::kFtoI: { // 浮点 to 整数 (带向下取整) - // 目标:实现 floor(x) 的效果, C/C++中浮点转整数是截断(truncate) - // 对于正数,floor(x) == truncate(x) - // RISC-V的 fcvt.w.s 默认是“四舍五入到偶数” - // 我们需要手动实现截断逻辑 - // 逻辑: - // temp_i = fcvt.w.s(x) // 四舍五入 - // temp_f = fcvt.s.w(temp_i) // 转回浮点 - // if (x < temp_f) { // 如果原数更小,说明被“五入”了 - // result = temp_i - 1 - // } else { - // result = temp_i - // } - - auto temp_i_vreg = getNewVReg(Type::getIntType()); - auto temp_f_vreg = getNewVReg(Type::getFloatType()); - auto cmp_vreg = getNewVReg(Type::getIntType()); - - // 1. fcvt.w.s temp_i_vreg, src_vreg - auto fcvt_w = std::make_unique(RVOpcodes::FCVT_W_S); - fcvt_w->addOperand(std::make_unique(temp_i_vreg)); - fcvt_w->addOperand(std::make_unique(src_vreg)); - CurMBB->addInstruction(std::move(fcvt_w)); - - // 2. fcvt.s.w temp_f_vreg, temp_i_vreg - auto fcvt_s = std::make_unique(RVOpcodes::FCVT_S_W); - fcvt_s->addOperand(std::make_unique(temp_f_vreg)); - fcvt_s->addOperand(std::make_unique(temp_i_vreg)); - CurMBB->addInstruction(std::move(fcvt_s)); - - // 3. flt.s cmp_vreg, src_vreg, temp_f_vreg - auto flt = std::make_unique(RVOpcodes::FLT_S); - flt->addOperand(std::make_unique(cmp_vreg)); - flt->addOperand(std::make_unique(src_vreg)); - flt->addOperand(std::make_unique(temp_f_vreg)); - CurMBB->addInstruction(std::move(flt)); - - // 创建标签 - int unique_id = this->local_label_counter++; - std::string rounded_up_label = MFunc->getName() + "_ftoi_rounded_up_" + std::to_string(unique_id); - std::string done_label = MFunc->getName() + "_ftoi_done_" + std::to_string(unique_id); - - // 4. bne cmp_vreg, x0, rounded_up_label - auto bne = std::make_unique(RVOpcodes::BNE); - bne->addOperand(std::make_unique(cmp_vreg)); - bne->addOperand(std::make_unique(PhysicalReg::ZERO)); - bne->addOperand(std::make_unique(rounded_up_label)); - CurMBB->addInstruction(std::move(bne)); - - // 5. else 分支: mv dest_vreg, temp_i_vreg - auto mv = std::make_unique(RVOpcodes::MV); - mv->addOperand(std::make_unique(dest_vreg)); - mv->addOperand(std::make_unique(temp_i_vreg)); - CurMBB->addInstruction(std::move(mv)); - - // 6. j done_label - auto j = std::make_unique(RVOpcodes::J); - j->addOperand(std::make_unique(done_label)); - CurMBB->addInstruction(std::move(j)); - - // 7. rounded_up_label: - auto label_up = std::make_unique(RVOpcodes::LABEL); - label_up->addOperand(std::make_unique(rounded_up_label)); - CurMBB->addInstruction(std::move(label_up)); - - // 8. addiw dest_vreg, temp_i_vreg, -1 - auto addi = std::make_unique(RVOpcodes::ADDIW); - addi->addOperand(std::make_unique(dest_vreg)); - addi->addOperand(std::make_unique(temp_i_vreg)); - addi->addOperand(std::make_unique(-1)); - CurMBB->addInstruction(std::move(addi)); - - // 9. done_label: - auto label_done = std::make_unique(RVOpcodes::LABEL); - label_done->addOperand(std::make_unique(done_label)); - CurMBB->addInstruction(std::move(label_done)); - + case Instruction::kFtoI: { // 浮点 to 整数 (使用硬件指令进行向零截断) + // 直接生成一条带有 rtz 舍入模式的转换指令 + auto instr = std::make_unique(RVOpcodes::FCVT_W_S_RTZ); + instr->addOperand(std::make_unique(dest_vreg)); // 目标是整数vreg + instr->addOperand(std::make_unique(src_vreg)); // 源是浮点vreg + CurMBB->addInstruction(std::move(instr)); break; } case Instruction::kFNeg: { // 浮点取负 @@ -1202,10 +1131,11 @@ void RISCv64ISel::selectNode(DAGNode* node) { auto r_value_byte = getVReg(memset->getValue()); // 为memset内部逻辑创建新的临时虚拟寄存器 - auto r_counter = getNewVReg(); - auto r_end_addr = getNewVReg(); - auto r_current_addr = getNewVReg(); - auto r_temp_val = getNewVReg(); + Type* ptr_type = Type::getPointerType(Type::getIntType()); + auto r_counter = getNewVReg(ptr_type); + auto r_end_addr = getNewVReg(ptr_type); + auto r_current_addr = getNewVReg(ptr_type); + auto r_temp_val = getNewVReg(Type::getIntType()); // 定义一系列lambda表达式来简化指令创建 auto add_instr = [&](RVOpcodes op, unsigned rd, unsigned rs1, unsigned rs2) { @@ -1296,7 +1226,7 @@ void RISCv64ISel::selectNode(DAGNode* node) { // --- Step 1: 获取基地址 (此部分逻辑正确,保持不变) --- auto base_ptr_node = node->operands[0]; - auto current_addr_vreg = getNewVReg(); + auto current_addr_vreg = getNewVReg(gep->getType()); if (auto alloca_base = dynamic_cast(base_ptr_node->value)) { auto frame_addr_instr = std::make_unique(RVOpcodes::FRAME_ADDR); @@ -1338,13 +1268,13 @@ void RISCv64ISel::selectNode(DAGNode* node) { // 如果步长为0(例如对一个void类型或空结构体索引),则不产生任何偏移 if (stride != 0) { // --- 为当前索引和步长生成偏移计算指令 --- - auto offset_vreg = getNewVReg(); + auto offset_vreg = getNewVReg(Type::getIntType()); // 处理索引 - 区分常量与动态值 unsigned index_vreg; if (auto const_index = dynamic_cast(indexValue)) { // 对于常量索引,直接创建新的虚拟寄存器 - index_vreg = getNewVReg(); + index_vreg = getNewVReg(Type::getIntType()); auto li = std::make_unique(RVOpcodes::LI); li->addOperand(std::make_unique(index_vreg)); li->addOperand(std::make_unique(const_index->getInt())); @@ -1362,7 +1292,7 @@ void RISCv64ISel::selectNode(DAGNode* node) { CurMBB->addInstruction(std::move(mv)); } else { // 步长不为1,需要生成乘法指令 - auto size_vreg = getNewVReg(); + auto size_vreg = getNewVReg(Type::getIntType()); auto li_size = std::make_unique(RVOpcodes::LI); li_size->addOperand(std::make_unique(size_vreg)); li_size->addOperand(std::make_unique(stride)); diff --git a/src/include/backend/RISCv64/RISCv64ISel.h b/src/include/backend/RISCv64/RISCv64ISel.h index e9bb27c..35fb7a7 100644 --- a/src/include/backend/RISCv64/RISCv64ISel.h +++ b/src/include/backend/RISCv64/RISCv64ISel.h @@ -22,7 +22,6 @@ public: // 公开接口,以便后续模块(如RegAlloc)可以查询或创建vreg unsigned getVReg(Value* val); - unsigned getNewVReg() { return vreg_counter++; } unsigned getNewVReg(Type* type); unsigned getVRegCounter() const; // 获取 vreg_map 的公共接口 diff --git a/src/include/backend/RISCv64/RISCv64LLIR.h b/src/include/backend/RISCv64/RISCv64LLIR.h index 5d4a15f..977b348 100644 --- a/src/include/backend/RISCv64/RISCv64LLIR.h +++ b/src/include/backend/RISCv64/RISCv64LLIR.h @@ -88,6 +88,7 @@ enum class RVOpcodes { // 浮点转换 FCVT_S_W, // fcvt.s.w rd, rs1 (有符号整数 -> 单精度浮点) FCVT_W_S, // fcvt.w.s rd, rs1 (单精度浮点 -> 有符号整数) + FCVT_W_S_RTZ, // fcvt.w.s rd, rs1, rtz (使用向零截断模式) // 浮点传送/移动 FMV_S, // fmv.s rd, rs1 (浮点寄存器之间)