Mercurial > lcfOS
view python/x86.py @ 171:3eb9b9e2958d
Improved IR code
author | Windel Bouwman |
---|---|
date | Wed, 03 Apr 2013 22:20:20 +0200 |
parents | 10330be89bc2 |
children | c1d2b6b9f9a7 |
line wrap: on
line source
import ppci import ir class AsmLabel: def __init__(self, lab): self.lab = lab def __repr__(self): return '{0}:'.format(self.lab) class Op: def __init__(self, op, dst, src): self.op = op self.src = src self.dst = dst def __repr__(self): return '{0} {1}, {2}'.format(self.op, self.dst, self.src) class Jmp: def __init__(self, j, target): self.j = j self.target = target def __repr__(self): return '{0} {1}'.format(self.j, self.target) class X86CodeGen: def __init__(self, diag): self.diag = diag self.regs = ['rax', 'rbx', 'rcx', 'rdx'] def emit(self, i): self.asm.append(i) def genBin(self, ir): self.asm = [] # Allocate registers: ir.registerAllocate(self.regs) self.genModule(ir) return self.asm def genModule(self, ir): #for f in ir.Functions: # self.genFunction(f) for bb in ir.BasicBlocks: self.genBB(bb) def genFunction(self, f): self.emit('global {0}'.format(f.name)) self.emit(AsmLabel(f.name)) for bb in f.BasicBlocks: self.genBB(bb) def genBB(self, bb): self.emit(AsmLabel(bb.name)) for i in bb.Instructions: self.genIns(i) def genIns(self, i): if type(i) is ir.BinaryOperator: ops = {'+':'add', '-':'sub', '*':'mul'} if i.operation in ops: self.emit(Op('mov', i.result.reg, i.value1.reg)) self.emit(Op(ops[i.operation], i.result.reg, i.value2.reg)) else: raise NotImplementedError('op {0}'.format(i.operation)) elif type(i) is ir.Load: self.emit(Op('mov', i.value, '[{0}]'.format(i.name))) elif type(i) is ir.Return: self.emit('ret') elif type(i) is ir.Call: self.emit('call') elif type(i) is ir.ImmLoad: self.emit(Op('mov', i.target, i.value)) elif type(i) is ir.Store: self.emit(Op('mov', '[{0}]'.format(i.name), i.value)) elif type(i) is ir.ConditionalBranch: self.emit(Op('cmp', i.a, i.b)) jmps = {'>':'jg', '<':'jl', '==':'je'} if i.cond in jmps: j = jmps[i.cond] self.emit(Jmp(j, i.lab1.name)) else: raise NotImplementedError('condition {0}'.format(i.cond)) self.emit(Jmp('jmp', i.lab2.name)) elif type(i) is ir.Branch: self.emit(Jmp('jmp', i.target.name)) else: raise NotImplementedError('{0}'.format(i))