diff 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 diff
--- a/python/x86.py	Fri Mar 29 17:33:17 2013 +0100
+++ b/python/x86.py	Wed Apr 03 22:20:20 2013 +0200
@@ -8,12 +8,19 @@
       return '{0}:'.format(self.lab)
 
 class Op:
-   def __init__(self, op, a, b):
+   def __init__(self, op, dst, src):
       self.op = op
-      self.a = a
-      self.b = b
+      self.src = src
+      self.dst = dst
    def __repr__(self):
-      return '{0} {1}, {2}'.format(self.op, self.a, self.b)
+      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):
@@ -22,42 +29,57 @@
 
    def emit(self, i):
       self.asm.append(i)
-   def allocateReg(self, typ):
-      return 'ax'
-   def deallocateReg(self, r):
-      pass
 
-   def genBin(self, i):
+   def genBin(self, ir):
       self.asm = []
-      self.genModule(i)
+      # Allocate registers:
+      ir.registerAllocate(self.regs)
+      self.genModule(ir)
+      return self.asm
 
-   def genModule(self, m):
-      for g in m.Globals:
-         self.emit(AsmLabel(g.name))
-         # Ignore types for now ..
-         self.emit('dw 0')
-      for f in m.Functions:
-         self.genFunction(f)
+   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:
-         if i.operation == 'fadd':
-            r = 'rax'
-            self.emit(Op('add', r, '11'))
-      elif type(i) is ir.LoadInstruction:
-         r = 'rbx'
-         self.emit(Op('mov', r, '{0}'.format(i.value)))
-      elif type(i) is ir.RetInstruction:
+         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.CallInstruction:
+      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:
-         print('Unknown ins', i)
+         raise NotImplementedError('{0}'.format(i))