# HG changeset patch # User Windel Bouwman # Date 1368113719 -7200 # Node ID 25a0753da4cfbe71dd480edda3c711366ade07ad # Parent 0f3b1adfd4167ca2e40df8abd0ac8885b002b12b Re-organized files diff -r 0f3b1adfd416 -r 25a0753da4cf python/pyyacc.py --- a/python/pyyacc.py Sat May 04 18:50:36 2013 +0200 +++ b/python/pyyacc.py Thu May 09 17:35:19 2013 +0200 @@ -13,6 +13,21 @@ @property def Symbols(self): return self.nonterminals + self.terminals + def calcFollow(self): + follow = {} + for nt in self.nonterminals: + follow[nt] = set() + while True: + change = False + # 1. + for p in self.productions: + pass + if not change: + break + return follow + def calcFirst(self): + first = {} + return first class Production: def __init__(self, name, symbols): diff -r 0f3b1adfd416 -r 25a0753da4cf python/testc3.py --- a/python/testc3.py Sat May 04 18:50:36 2013 +0200 +++ b/python/testc3.py Thu May 09 17:35:19 2013 +0200 @@ -179,9 +179,9 @@ def testIf(self): snippet = """ package tstIFF; - var int a; function void t(int b) { + var int a; a = 2; if (a > b) { diff -r 0f3b1adfd416 -r 25a0753da4cf python/testir.py --- a/python/testir.py Sat May 04 18:50:36 2013 +0200 +++ b/python/testir.py Thu May 09 17:35:19 2013 +0200 @@ -52,7 +52,7 @@ if __name__ == '__main__': diag = ppci.DiagnosticsManager() builder = c3.Builder(diag) - cgenx86 = x86.X86CodeGen(diag) + cgenx86 = x86.X86CodeGenSimple(diag) ir = builder.build(testsrc) diag.printErrors(testsrc) #ir.dump() @@ -65,8 +65,6 @@ dcd.run(ir) clr.run(ir) m2r.run(ir) - for bb in ir.BasicBlocks: - bb.dag = x86.Dag(bb) #ir.dump() # Dump a graphiz file: @@ -81,3 +79,5 @@ f.write('BITS 64\n') for a in asm: f.write(str(a) + '\n') + print(a) + diff -r 0f3b1adfd416 -r 25a0753da4cf python/x86.py --- 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: