[lab3] add middle-end and backend with bugs to fix
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
@@ -1,5 +0,0 @@
|
||||
define i32 @add(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%sum = add i32 %a, %b
|
||||
ret i32 %sum
|
||||
}
|
||||
Reference in New Issue
Block a user