view python/x86.py @ 262:ed14e077124c

Added conditional branch instructions
author Windel Bouwman
date Fri, 09 Aug 2013 11:30:11 +0200
parents 6b2bec5653f1
children
line wrap: on
line source

import ppci
import ir

class X86CodeGenSimple:
   """ 
    Inefficient code generation, assume stack machine 
    backend
   """
   def __init__(self, diag):
      self.diag = diag

   def emit(self, i):
      self.asm.append(i)

   def genBin(self, ir):
      self.asm = []
      self.genModule(ir)
      return self.asm

   def genModule(self, ir):
      for f in ir.Functions:
         self.genFunction(f)
   def genFunction(self, f):
      self.emit('global {0}'.format(f.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('{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:
            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('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('mov {0}, {1}'.format(i.target, i.value))
      elif type(i) is ir.Store:
         self.emit('mov [{0}], {1}'.format(i.location, i.value))
      elif type(i) is ir.ConditionalBranch:
         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('{0} {1}'.format(j, i.lab1.name))
         else:
            raise NotImplementedError('condition {0}'.format(i.cond))
         self.emit('jmp {0}'.format(i.lab2.name))
      elif type(i) is ir.Branch:
         self.emit('jmp {0}'.format(i.target.name))
      elif type(i) is ir.Alloc:
         pass
      else:
         raise NotImplementedError('{0}'.format(i))