[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 SysYIRGenerator::getNextTemp() {
|
||||||
std::string ret = "%" + std::to_string(tempCounter++);
|
std::string ret = "%." + std::to_string(tempCounter++);
|
||||||
tmpTable[ret] = "void";
|
tmpTable[ret] = "void";
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
from ..middle_ir import *
|
||||||
|
|
||||||
class X86Emitter:
|
class X86Emitter:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.reg_pool = ["eax", "ebx", "ecx", "edx"] # 简化寄存器分配
|
self.reg_pool = ["eax", "ebx", "ecx", "edx"] # 简化寄存器分配
|
||||||
@@ -13,8 +15,13 @@ class X86Emitter:
|
|||||||
def emit_instruction(self, instr: MiddleInstruction) -> str:
|
def emit_instruction(self, instr: MiddleInstruction) -> str:
|
||||||
op = instr.opcode
|
op = instr.opcode
|
||||||
if op == "add":
|
if op == "add":
|
||||||
dest, src1, src2 = instr.operands
|
src1, src2 = instr.operands
|
||||||
return f" addl {self.map_operand(src2)}, {self.map_operand(dest)}"
|
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":
|
elif op == "ret":
|
||||||
return " ret"
|
return " ret"
|
||||||
else:
|
else:
|
||||||
@@ -22,6 +29,6 @@ class X86Emitter:
|
|||||||
|
|
||||||
def map_operand(self, operand: str) -> str:
|
def map_operand(self, operand: str) -> str:
|
||||||
"""将虚拟寄存器映射到物理寄存器(简化版)"""
|
"""将虚拟寄存器映射到物理寄存器(简化版)"""
|
||||||
if operand.startswith('%'):
|
if operand.startswith('%.'):
|
||||||
return self.reg_pool[int(operand[1:]) % len(self.reg_pool)]
|
return self.reg_pool[int(operand[2:]) % len(self.reg_pool)]
|
||||||
return operand
|
return operand
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ class MiddleBasicBlock:
|
|||||||
self.instructions = [] # List[MiddleInstruction]
|
self.instructions = [] # List[MiddleInstruction]
|
||||||
|
|
||||||
class MiddleInstruction:
|
class MiddleInstruction:
|
||||||
def __init__(self, opcode: str, operands: list):
|
def __init__(self, opcode: str, operands: list, dest=None):
|
||||||
self.opcode = opcode # e.g., 'add', 'ret'
|
self.opcode = opcode # e.g., 'add'
|
||||||
self.operands = operands # e.g., ['%0', '%1', '%2']
|
self.operands = operands # e.g., ['5', '7']
|
||||||
|
self.dest = dest # e.g., '%0'
|
||||||
|
|||||||
@@ -1,22 +1,32 @@
|
|||||||
from llvmlite import ir
|
from llvmlite import ir
|
||||||
|
from ..middle_ir import *
|
||||||
|
|
||||||
|
|
||||||
def parse_llvm_ir(ir_text: str) -> MiddleFunction:
|
def parse_llvm_ir(ir_text: str) -> MiddleFunction:
|
||||||
"""将 LLVM IR 文本转换为 MiddleIR 结构(简化版)"""
|
"""将 LLVM IR 文本转换为 MiddleIR 结构(简化版)"""
|
||||||
module = ir.Module()
|
from llvmlite.binding import parse_assembly
|
||||||
module.parse(ir_text)
|
|
||||||
|
|
||||||
# 提取第一个函数
|
# 使用 binding 模块解析 LLVM IR 文本
|
||||||
func = list(module.functions)[0]
|
with parse_assembly(ir_text) as module:
|
||||||
middle_func = MiddleFunction(func.name)
|
# 获取第一个函数
|
||||||
|
func = list(module.functions)[0]
|
||||||
|
middle_func = MiddleFunction(func.name)
|
||||||
|
|
||||||
# 转换基本块和指令
|
# 转换基本块和指令
|
||||||
for block in func.blocks:
|
for block in func.blocks:
|
||||||
mid_block = MiddleBasicBlock(block.name)
|
mid_block = MiddleBasicBlock(block.name)
|
||||||
for instr in block.instructions:
|
for instr in block.instructions:
|
||||||
opcode = instr.opcode
|
opcode = instr.opcode
|
||||||
operands = [str(op) for op in instr.operands]
|
operands = [str(op) for op in instr.operands]
|
||||||
mid_instr = MiddleInstruction(opcode, operands)
|
# 调试输出
|
||||||
mid_block.instructions.append(mid_instr)
|
print(f"Instruction: {instr}, Opcode: {opcode}, Operands: {operands}")
|
||||||
middle_func.basic_blocks.append(mid_block)
|
# 如果是有返回值的指令(如 add),第一个操作数是 dest
|
||||||
|
dest = None
|
||||||
|
if hasattr(instr, 'name') and instr.name:
|
||||||
|
dest = f"%{instr.name}" # 获取 LLVM IR 中的目标寄存器名
|
||||||
|
|
||||||
return middle_func
|
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