Introduce middle-end
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -45,3 +45,7 @@ tmp
|
|||||||
GPATH
|
GPATH
|
||||||
GRTAGS
|
GRTAGS
|
||||||
GTAGS
|
GTAGS
|
||||||
|
|
||||||
|
__init__.py
|
||||||
|
|
||||||
|
*.pyc
|
||||||
1
src/pysrc/requirements.txt
Normal file
1
src/pysrc/requirements.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
llvmlite==0.41.0
|
||||||
27
src/pysrc/sysy/backend/x86_emitter.py
Normal file
27
src/pysrc/sysy/backend/x86_emitter.py
Normal 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
|
||||||
14
src/pysrc/sysy/middle_ir.py
Normal file
14
src/pysrc/sysy/middle_ir.py
Normal 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']
|
||||||
22
src/pysrc/sysy/utils/ir_parser.py
Normal file
22
src/pysrc/sysy/utils/ir_parser.py
Normal 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
23
src/pysrc/sysyc.py
Normal 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()
|
||||||
5
src/pysrc/tests/test_add.ll
Normal file
5
src/pysrc/tests/test_add.ll
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
define i32 @add(i32 %a, i32 %b) {
|
||||||
|
entry:
|
||||||
|
%sum = add i32 %a, %b
|
||||||
|
ret i32 %sum
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user