Introduce middle-end

This commit is contained in:
Lixuanwang
2025-05-24 16:27:48 +08:00
parent ec8deeeebf
commit 338e5ef9a4
7 changed files with 97 additions and 1 deletions

6
.gitignore vendored
View File

@@ -44,4 +44,8 @@ tmp
GPATH GPATH
GRTAGS GRTAGS
GTAGS GTAGS
__init__.py
*.pyc

View File

@@ -0,0 +1 @@
llvmlite==0.41.0

View File

@@ -0,0 +1,27 @@
class X86Emitter:
def __init__(self):
self.reg_pool = ["eax", "ebx", "ecx", "edx"] # 简化寄存器分配
def emit_function(self, func: MiddleFunction) -> str:
asm = [f".globl {func.name}", f"{func.name}:"]
for block in func.basic_blocks:
asm.append(f".{block.name}:")
for instr in block.instructions:
asm.append(self.emit_instruction(instr))
return "\n".join(asm)
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)}"
elif op == "ret":
return " ret"
else:
raise NotImplementedError(f"Unsupported opcode: {op}")
def map_operand(self, operand: str) -> str:
"""将虚拟寄存器映射到物理寄存器(简化版)"""
if operand.startswith('%'):
return self.reg_pool[int(operand[1:]) % len(self.reg_pool)]
return operand

View File

@@ -0,0 +1,14 @@
class MiddleFunction:
def __init__(self, name: str):
self.name = name
self.basic_blocks = [] # List[MiddleBasicBlock]
class MiddleBasicBlock:
def __init__(self, name: str):
self.name = name
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']

View File

@@ -0,0 +1,22 @@
from llvmlite import ir
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

23
src/pysrc/sysyc.py Normal file
View File

@@ -0,0 +1,23 @@
import sys
from sysy.utils.ir_parser import parse_llvm_ir
from sysy.backend.x86_emitter import X86Emitter
def main():
if len(sys.argv) != 3:
print("Usage: sysyc.py <input.ll> <output.s>")
sys.exit(1)
# 读取 LLVM IR
with open(sys.argv[1], 'r') as f:
ir_text = f.read()
# 解析并生成汇编
func = parse_llvm_ir(ir_text)
asm = X86Emitter().emit_function(func)
# 写入文件
with open(sys.argv[2], 'w') as f:
f.write(asm)
if __name__ == "__main__":
main()

View File

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