Mercurial > lcfOS
diff python/x86.py @ 180:25a0753da4cf
Re-organized files
author | Windel Bouwman |
---|---|
date | Thu, 09 May 2013 17:35:19 +0200 |
parents | c694ec551f34 |
children | 6b2bec5653f1 |
line wrap: on
line diff
--- a/python/x86.py Sat May 04 18:50:36 2013 +0200 +++ b/python/x86.py Thu May 09 17:35:19 2013 +0200 @@ -1,111 +1,16 @@ import ppci import ir -import registerallocator -# Instruction selection with DAG (Directed Acyclic Graph) -class DagLeaf: - def __init__(self, v): - self.v = v - -class DagNode: - def __init__(self, name): - self.name = name - self.children = [] - def __repr__(self): - return str(self.name) - -class Dag: - def __init__(self, bb): - self.mapping = {} - self.buildFromBB(bb) - def buildFromBB(self, bb): - for ins in bb.Instructions: - if type(ins) is ir.BinaryOperator: - if not ins.value1 in self.mapping: - self.mapping[ins.value1] = DagNode(ins.value1) - if not ins.value2 in self.mapping: - self.mapping[ins.value2] = DagNode(ins.value2) - # look for op with left and right operand the same: - N = None - lnode = self.mapping[ins.value1] - rnode = self.mapping[ins.value2] - for node in self.mapping.values(): - if node.name == ins.operation: - if node.children[0] == lnode and node.children[1] == rnode: - N = node - break - if not N: - # Create a node. - N = DagNode(ins.operation) - N.children.append(lnode) - N.children.append(rnode) - self.mapping[ins.result] = N - else: - pass - def dumpgv(self, outf): - outf.write('subgraph {0} {{\n'.format(id(self))) - for node in self.mapping.values(): - outf.write('{0} [label="{1}"];\n'.format(id(node), node.name)) - for c in node.children: - outf.write('{0} -> {1};\n'.format(id(node), id(c))) - outf.write('label="dag"}\n') - -def insSelect(mod): - """ Create DAG from ir-code """ - for bb in mod.BasicBlocks: - print(bb) - dag = Dag(bb) - print(dag.mapping) - bb.dag = dag - -# Machine code interface: -class MachineOperand: - """ Single machine operand """ - pass - -class MachineInstruction: - def __init__(self, opcode): - self.opcode = opcode - self.operands = [] - - -# x86 specific: -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: +class X86CodeGenSimple: + """ Inefficient code generation, assume stack machine """ 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: - insSelect(ir) - ra = registerallocator.RegisterAllocator() - # TODO: do not register allocate on intermediate code: - ra.registerAllocate(ir, self.regs) self.genModule(ir) return self.asm @@ -114,43 +19,46 @@ self.genFunction(f) def genFunction(self, f): self.emit('global {0}'.format(f.name)) - self.emit(AsmLabel(f.name)) - self.emit(Jmp('jmp', f.entry.name)) + self.emit('{0}:'.format(f.name)) + self.emit('jmp {0}'.format(f.entry.name)) for bb in f.BasicBlocks: self.genBB(bb) def genBB(self, bb): - self.emit(AsmLabel(bb.name)) + self.emit('{0}:'.format(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)) + i.result.reg = 'rax' + i.value1.reg = 'rbx' + i.value2.reg = 'rbx' + self.emit('mov {0}, {1}'.format(i.result.reg, i.value1.reg)) + self.emit('{0} {1}, {2}'.format(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.location))) + self.emit('mov {0}, [{1}]'.format(i.value, i.location)) 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)) + self.emit('mov {0}, {1}'.format(i.target, i.value)) elif type(i) is ir.Store: - self.emit(Op('mov', '[{0}]'.format(i.location), i.value)) + self.emit('mov [{0}], {1}'.format(i.location, i.value)) elif type(i) is ir.ConditionalBranch: - self.emit(Op('cmp', i.a, i.b)) + self.emit('cmp {0}, {1}'.format(i.a, i.b)) jmps = {'>':'jg', '<':'jl', '==':'je'} if i.cond in jmps: j = jmps[i.cond] - self.emit(Jmp(j, i.lab1.name)) + self.emit('{0} {1}'.format(j, i.lab1.name)) else: raise NotImplementedError('condition {0}'.format(i.cond)) - self.emit(Jmp('jmp', i.lab2.name)) + self.emit('jmp {0}'.format(i.lab2.name)) elif type(i) is ir.Branch: - self.emit(Jmp('jmp', i.target.name)) + self.emit('jmp {0}'.format(i.target.name)) elif type(i) is ir.Alloc: pass else: