From dc7202849cfa59afd1d2e7c85771876ceadda3cd Mon Sep 17 00:00:00 2001 From: lixuanwang Date: Mon, 26 May 2025 23:17:31 +0800 Subject: [PATCH] [lab3] add middle-end and backend with bugs to fix --- src/SysYIRGenerator.cpp | 2 +- src/pysrc/sysy/backend/x86_emitter.py | 15 ++++++--- src/pysrc/sysy/middle_ir.py | 7 ++-- src/pysrc/sysy/utils/ir_parser.py | 46 ++++++++++++++++----------- src/pysrc/tests/test_add.ll | 5 --- 5 files changed, 44 insertions(+), 31 deletions(-) delete mode 100644 src/pysrc/tests/test_add.ll diff --git a/src/SysYIRGenerator.cpp b/src/SysYIRGenerator.cpp index 27eb9af..f700363 100644 --- a/src/SysYIRGenerator.cpp +++ b/src/SysYIRGenerator.cpp @@ -12,7 +12,7 @@ std::string SysYIRGenerator::generateIR(SysYParser::CompUnitContext* unit) { } std::string SysYIRGenerator::getNextTemp() { - std::string ret = "%" + std::to_string(tempCounter++); + std::string ret = "%." + std::to_string(tempCounter++); tmpTable[ret] = "void"; return ret; } diff --git a/src/pysrc/sysy/backend/x86_emitter.py b/src/pysrc/sysy/backend/x86_emitter.py index a58d981..71c5d08 100644 --- a/src/pysrc/sysy/backend/x86_emitter.py +++ b/src/pysrc/sysy/backend/x86_emitter.py @@ -1,3 +1,5 @@ +from ..middle_ir import * + class X86Emitter: def __init__(self): self.reg_pool = ["eax", "ebx", "ecx", "edx"] # 简化寄存器分配 @@ -13,8 +15,13 @@ class X86Emitter: def emit_instruction(self, instr: MiddleInstruction) -> str: op = instr.opcode if op == "add": - dest, src1, src2 = instr.operands - return f" addl {self.map_operand(src2)}, {self.map_operand(dest)}" + src1, src2 = instr.operands + dest = instr.dest + #TODO(Lixuan Wang): src1 src2 的类型标签还没有去除,如i32 5,会出现在汇编文件中,这是不对的 + return ( + f" movl ${src1}, %{self.map_operand(dest)}\n" + f" addl ${src2}, %{self.map_operand(dest)}" + ) elif op == "ret": return " ret" else: @@ -22,6 +29,6 @@ class X86Emitter: def map_operand(self, operand: str) -> str: """将虚拟寄存器映射到物理寄存器(简化版)""" - if operand.startswith('%'): - return self.reg_pool[int(operand[1:]) % len(self.reg_pool)] + if operand.startswith('%.'): + return self.reg_pool[int(operand[2:]) % len(self.reg_pool)] return operand diff --git a/src/pysrc/sysy/middle_ir.py b/src/pysrc/sysy/middle_ir.py index ddc5859..f30a40d 100644 --- a/src/pysrc/sysy/middle_ir.py +++ b/src/pysrc/sysy/middle_ir.py @@ -9,6 +9,7 @@ class MiddleBasicBlock: self.instructions = [] # List[MiddleInstruction] class MiddleInstruction: - def __init__(self, opcode: str, operands: list): - self.opcode = opcode # e.g., 'add', 'ret' - self.operands = operands # e.g., ['%0', '%1', '%2'] + def __init__(self, opcode: str, operands: list, dest=None): + self.opcode = opcode # e.g., 'add' + self.operands = operands # e.g., ['5', '7'] + self.dest = dest # e.g., '%0' diff --git a/src/pysrc/sysy/utils/ir_parser.py b/src/pysrc/sysy/utils/ir_parser.py index 479803f..d80072a 100644 --- a/src/pysrc/sysy/utils/ir_parser.py +++ b/src/pysrc/sysy/utils/ir_parser.py @@ -1,22 +1,32 @@ from llvmlite import ir +from ..middle_ir import * + def parse_llvm_ir(ir_text: str) -> MiddleFunction: """将 LLVM IR 文本转换为 MiddleIR 结构(简化版)""" - module = ir.Module() - module.parse(ir_text) - - # 提取第一个函数 - func = list(module.functions)[0] - middle_func = MiddleFunction(func.name) - - # 转换基本块和指令 - for block in func.blocks: - mid_block = MiddleBasicBlock(block.name) - for instr in block.instructions: - opcode = instr.opcode - operands = [str(op) for op in instr.operands] - mid_instr = MiddleInstruction(opcode, operands) - mid_block.instructions.append(mid_instr) - middle_func.basic_blocks.append(mid_block) - - return middle_func + from llvmlite.binding import parse_assembly + + # 使用 binding 模块解析 LLVM IR 文本 + with parse_assembly(ir_text) as module: + # 获取第一个函数 + func = list(module.functions)[0] + middle_func = MiddleFunction(func.name) + + # 转换基本块和指令 + for block in func.blocks: + mid_block = MiddleBasicBlock(block.name) + for instr in block.instructions: + opcode = instr.opcode + operands = [str(op) for op in instr.operands] + # 调试输出 + print(f"Instruction: {instr}, Opcode: {opcode}, Operands: {operands}") + # 如果是有返回值的指令(如 add),第一个操作数是 dest + dest = None + if hasattr(instr, 'name') and instr.name: + dest = f"%{instr.name}" # 获取 LLVM IR 中的目标寄存器名 + + mid_instr = MiddleInstruction(opcode, operands, dest) + mid_block.instructions.append(mid_instr) + middle_func.basic_blocks.append(mid_block) + + return middle_func \ No newline at end of file diff --git a/src/pysrc/tests/test_add.ll b/src/pysrc/tests/test_add.ll deleted file mode 100644 index 1ca881f..0000000 --- a/src/pysrc/tests/test_add.ll +++ /dev/null @@ -1,5 +0,0 @@ -define i32 @add(i32 %a, i32 %b) { -entry: - %sum = add i32 %a, %b - ret i32 %sum -}