[lab3] add middle-end and backend with bugs to fix

This commit is contained in:
lixuanwang
2025-05-26 23:17:31 +08:00
parent 338e5ef9a4
commit dc7202849c
5 changed files with 44 additions and 31 deletions

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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'

View File

@@ -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

View File

@@ -1,5 +0,0 @@
define i32 @add(i32 %a, i32 %b) {
entry:
%sum = add i32 %a, %b
ret i32 %sum
}