changeset 342:86b02c98a717 devel

Moved target directory
author Windel Bouwman
date Sat, 01 Mar 2014 15:40:31 +0100
parents 4d204f6f7d4e
children 11c5a8a70c02
files python/outstream.py python/ppci/assembler.py python/ppci/buildtasks.py python/ppci/codegen/codegen.py python/ppci/irmach.py python/ppci/objectfile.py python/ppci/outstream.py python/ppci/recipe.py python/ppci/report.py python/ppci/target/__init__.py python/ppci/target/arm/__init__.py python/ppci/target/arm/armv7.lidl python/ppci/target/arm/instructions.py python/ppci/target/arm/registers.py python/ppci/target/arm/token.py python/ppci/target/basetarget.py python/ppci/target/instructionselector.py python/ppci/target/msp430/instructions.py python/ppci/target/msp430/msp430.py python/ppci/target/msp430/registers.py python/ppci/target/target_list.py python/ppci/target/thumb/__init__.py python/ppci/target/thumb/arm.brg python/ppci/target/thumb/armframe.py python/ppci/target/thumb/arminstructionselector.py python/ppci/target/thumb/armtarget.py python/ppci/target/thumb/armtoken.py python/ppci/target/thumb/instructions.py python/ppci/target/token.py python/ppci/target/x86/target_x86.py python/ppci/target/x86/x86.py python/ppci/target/x86/x86_2.py python/ppci/tasks.py python/target/__init__.py python/target/arm.brg python/target/armframe.py python/target/arminstructions.py python/target/arminstructionselector.py python/target/armregisters.py python/target/armtarget.py python/target/armtoken.py python/target/armv7.lidl python/target/basetarget.py python/target/instructionselector.py python/target/msp430.py python/target/openrisc.lidl python/target/openrisc.py python/target/target_list.py python/target/target_x86.py python/target/x86.py python/target/x86_2.py python/yacc.py python/zcc.py test/testarmasm.py test/testasm.py test/testbintools.py test/testc3.py test/testcg.py test/testgraph.py test/testir.py test/testmsp430asm.py test/testregalloc.py test/testzcc.py
diffstat 63 files changed, 2434 insertions(+), 2344 deletions(-) [+]
line wrap: on
line diff
--- a/python/outstream.py	Fri Feb 28 18:07:14 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-import binascii
-from target import Instruction, DebugInfo, Alignment
-from ppci.objectfile import ObjectFile
-
-"""
- The output stream is a stream of instructions that can be output
- to a file or binary or hexfile.
-"""
-
-
-class OutputStream:
-    def emit(self, item):
-        raise NotImplementedError('Abstract base class')
-
-    def selectSection(self, sname):
-        raise NotImplementedError('Abstract base class')
-
-
-class OutputStreamWriter:
-    def __init__(self, extra_indent=''):
-        self.extra_indent = extra_indent
-
-    def dump(self, stream, f):
-        for s in sorted(stream.sections.keys()):
-            # print('.section '+ s)
-            self.dumpSection(stream.sections[s], f)
-
-    def dumpSection(self, s, f):
-        for i in s.instructions:
-            if type(i) is DebugInfo:
-                continue
-            addr = i.address
-            insword = i.encode()
-            assert type(insword) is bytes
-            insword = binascii.hexlify(bytes(reversed(insword))).decode('ascii')
-            asm = str(i)
-            if len(insword) == 0:
-                print('        {}'.format(asm), file=f)
-            else:
-                print('    0x{0:08x} 0x{1} {2}'.format(addr, insword, asm), file=f)
-
-
-class BinaryOutputStream(OutputStream):
-    """ Output stream that writes to object file """
-    def __init__(self, obj_file):
-        super().__init__()
-        self.obj_file = obj_file
-
-    def emit(self, item):
-        """ Encode instruction and add symbol and relocation information """
-        assert isinstance(item, Instruction), str(item) + str(type(item))
-        assert self.currentSection
-        section = self.currentSection
-        address = self.currentSection.Size
-        b = item.encode()
-        syms = item.symbols()
-        relocs = item.relocations()
-        section.add_data(b)
-        for sym in syms:
-            self.obj_file.add_symbol(sym, address, section.name)
-        for sym, typ in relocs:
-            self.obj_file.add_relocation(sym, address, typ, section.name)
-        # Special case for align, TODO do this different?
-        if type(item) is Alignment:
-            while section.Size % item.align != 0:
-                section.add_data(bytes([0]))
-
-    def selectSection(self, sname):
-        self.currentSection = self.obj_file.get_section(sname)
-
-
-class DummyOutputStream(OutputStream):
-    def emit(self, item):
-        pass
-
-    def selectSection(self, sname):
-        pass
--- a/python/ppci/assembler.py	Fri Feb 28 18:07:14 2014 +0100
+++ b/python/ppci/assembler.py	Sat Mar 01 15:40:31 2014 +0100
@@ -2,7 +2,7 @@
 import re
 import pyyacc
 from . import Token, CompilerError, SourceLocation
-from target import Target, Label
+from .target import Target, Label
 from .asmnodes import ALabel, AInstruction, ABinop, AUnop, ASymbol, ANumber
 
 
@@ -10,7 +10,7 @@
     assert value < (2**31)
     assert value >= 0
     t = 'val32'
-    for n in [8, 5, 3]:
+    for n in [16, 8, 5, 3]:
         if value < (2**n):
             t = 'val{}'.format(n)
     return t
@@ -100,7 +100,7 @@
         # Construct a parser given a grammar:
         tokens2 = ['ID', 'NUMBER', ',', '[', ']', ':', '+', '-', '*',
                    pyyacc.EPS, 'COMMENT', '{', '}',
-                   pyyacc.EOF, 'val32', 'val8', 'val5', 'val3']
+                   pyyacc.EOF, 'val32', 'val16', 'val8', 'val5', 'val3']
         tokens2.extend(kws)
         self.kws = kws
         g = pyyacc.Grammar(tokens2)
@@ -132,7 +132,7 @@
         g.start_symbol = 'asmline'
         self.emit = emit
         self.p = g.generate_parser()
-        print('length of table:', len(self.p.action_table))
+        # print('length of table:', len(self.p.action_table))
 
     # Parser handlers:
     def p_ins_1(self, opc, ops):
--- a/python/ppci/buildtasks.py	Fri Feb 28 18:07:14 2014 +0100
+++ b/python/ppci/buildtasks.py	Sat Mar 01 15:40:31 2014 +0100
@@ -15,7 +15,7 @@
 from .assembler import Assembler
 from .objectfile import ObjectFile
 from .linker import Linker
-import outstream
+from .outstream import BinaryOutputStream
 
 
 class BuildTask(Task):
@@ -32,7 +32,7 @@
         super().__init__('Assemble')
         self.source = source
         self.output = output_object
-        self.ostream = outstream.BinaryOutputStream(self.output)
+        self.ostream = BinaryOutputStream(self.output)
         self.assembler = Assembler(target, self.ostream)
 
     def run(self):
@@ -74,7 +74,7 @@
             # Code generation:
             d = {'ircode':ircode}
             self.logger.debug('Starting code generation for {}'.format(ircode), extra=d)
-            o = outstream.BinaryOutputStream(self.output)
+            o = BinaryOutputStream(self.output)
             cg.generate(ircode, o)
 
         if not c3b.ok:
--- a/python/ppci/codegen/codegen.py	Fri Feb 28 18:07:14 2014 +0100
+++ b/python/ppci/codegen/codegen.py	Sat Mar 01 15:40:31 2014 +0100
@@ -1,6 +1,6 @@
 from .. import ir
 from ..irutils import Verifier
-from target import Target
+from ..target import Target
 from ppci import CompilerError
 from .canon import make as canonicalize
 from .registerallocator import RegisterAllocator
--- a/python/ppci/irmach.py	Fri Feb 28 18:07:14 2014 +0100
+++ b/python/ppci/irmach.py	Sat Mar 01 15:40:31 2014 +0100
@@ -7,7 +7,7 @@
   Instructions are selected and scheduled at this stage.
 """
 
-from target import Instruction
+from .target import Instruction
 
 
 class Frame:
@@ -38,7 +38,7 @@
         abstraction of machine instructions.
     """
     def __init__(self, cls, ops=(), src=(), dst=(), jumps=(), others=(), ismove=False):
-        assert type(cls) is type or isinstance(cls, Instruction)
+        assert type(cls) is type or isinstance(cls, Instruction), str(cls)
         self.assem = cls
         self.ops = tuple(ops)
         self.src = tuple(src)
--- a/python/ppci/objectfile.py	Fri Feb 28 18:07:14 2014 +0100
+++ b/python/ppci/objectfile.py	Sat Mar 01 15:40:31 2014 +0100
@@ -17,6 +17,8 @@
 
 
 class Relocation:
+    """ Represents a relocation entry. A relocation always has a symbol to refer to
+     and a relocation type """
     def __init__(self, sym, offset, typ, section):
         self.sym = sym
         self.offset = offset
@@ -64,6 +66,7 @@
         return sym
 
     def add_relocation(self, sym_name, offset, typ, section):
+        assert type(sym_name) is str, str(sym_name)
         assert section in self.sections
         reloc = Relocation(sym_name, offset, typ, section)
         self.relocations.append(reloc)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/outstream.py	Sat Mar 01 15:40:31 2014 +0100
@@ -0,0 +1,77 @@
+import binascii
+from ppci.target import Instruction, DebugInfo, Alignment
+from ppci.objectfile import ObjectFile
+
+"""
+ The output stream is a stream of instructions that can be output
+ to a file or binary or hexfile.
+"""
+
+
+class OutputStream:
+    def emit(self, item):
+        raise NotImplementedError('Abstract base class')
+
+    def selectSection(self, sname):
+        raise NotImplementedError('Abstract base class')
+
+
+class OutputStreamWriter:
+    def __init__(self, extra_indent=''):
+        self.extra_indent = extra_indent
+
+    def dump(self, stream, f):
+        for s in sorted(stream.sections.keys()):
+            # print('.section '+ s)
+            self.dumpSection(stream.sections[s], f)
+
+    def dumpSection(self, s, f):
+        for i in s.instructions:
+            if type(i) is DebugInfo:
+                continue
+            addr = i.address
+            insword = i.encode()
+            assert type(insword) is bytes
+            insword = binascii.hexlify(bytes(reversed(insword))).decode('ascii')
+            asm = str(i)
+            if len(insword) == 0:
+                print('        {}'.format(asm), file=f)
+            else:
+                print('    0x{0:08x} 0x{1} {2}'.format(addr, insword, asm), file=f)
+
+
+class BinaryOutputStream(OutputStream):
+    """ Output stream that writes to object file """
+    def __init__(self, obj_file):
+        super().__init__()
+        self.obj_file = obj_file
+
+    def emit(self, item):
+        """ Encode instruction and add symbol and relocation information """
+        assert isinstance(item, Instruction), str(item) + str(type(item))
+        assert self.currentSection
+        section = self.currentSection
+        address = self.currentSection.Size
+        b = item.encode()
+        syms = item.symbols()
+        relocs = item.relocations()
+        section.add_data(b)
+        for sym in syms:
+            self.obj_file.add_symbol(sym, address, section.name)
+        for sym, typ in relocs:
+            self.obj_file.add_relocation(sym, address, typ, section.name)
+        # Special case for align, TODO do this different?
+        if type(item) is Alignment:
+            while section.Size % item.align != 0:
+                section.add_data(bytes([0]))
+
+    def selectSection(self, sname):
+        self.currentSection = self.obj_file.get_section(sname)
+
+
+class DummyOutputStream(OutputStream):
+    def emit(self, item):
+        pass
+
+    def selectSection(self, sname):
+        pass
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/recipe.py	Sat Mar 01 15:40:31 2014 +0100
@@ -0,0 +1,71 @@
+import os
+import yaml
+
+from .buildtasks import Compile, Assemble, Link
+from .objectfile import ObjectFile
+from .target.target_list import target_list
+
+
+targets = {t.name: t for t in target_list}
+targetnames = list(targets.keys())
+
+class RecipeLoader:
+    """ Loads a recipe into a runner from a dictionary or file """
+    def __init__(self):
+        self.directive_handlers = {}
+        for a in dir(self):
+            if a.startswith('handle_'):
+                f = getattr(self, a)
+                self.directive_handlers[a[7:]] = f
+
+    def load_file(self, recipe_file, runner):
+        """ Loads a recipe dictionary into a task runner """
+        self.recipe_dir = os.path.abspath(os.path.dirname(recipe_file))
+        with open(recipe_file, 'r') as f:
+            recipe = yaml.load(f)
+        self.runner = runner
+        self.load_dict(recipe)
+
+    def relpath(self, filename):
+        return os.path.join(self.recipe_dir, filename)
+
+    def openfile(self, filename):
+        return open(self.relpath(filename), 'r')
+
+    def handle_compile(self, value):
+        sources = [self.openfile(s) for s in value['sources']]
+        includes = [self.openfile(i) for i in value['includes']]
+        target = targets[value['machine']]
+        output = ObjectFile()
+        task = Compile(sources, includes, target, output)
+        self.runner.add_task(task)
+        return task
+
+    def handle_assemble(self, value):
+        asm_src = self.openfile(value['source'])
+        target = targets[value['machine']]
+        output = ObjectFile()
+        task = Assemble(asm_src, target, output)
+        self.runner.add_task(task)
+        return task
+
+    def handle_link(self, value):
+        inputs = value['inputs']
+        objs = []
+        for i in inputs:
+            task = self.load_dict(i)
+            objs.append(task.output)
+        layout = value['layout']
+        output = self.relpath(value['output'])
+        self.runner.add_task(Link(objs, layout, output))
+
+    def handle_apps(self, value):
+        for a in value:
+            self.load_dict(a)
+
+    def load_dict(self, recipe):
+        for command, value in recipe.items():
+            return self.directive_handlers[command](value)
+
+
+
--- a/python/ppci/report.py	Fri Feb 28 18:07:14 2014 +0100
+++ b/python/ppci/report.py	Sat Mar 01 15:40:31 2014 +0100
@@ -2,7 +2,7 @@
 import logging
 import io
 
-import outstream
+from . import outstream
 from .c3 import AstPrinter
 from . import logformat
 from .irutils import Writer
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/target/__init__.py	Sat Mar 01 15:40:31 2014 +0100
@@ -0,0 +1,9 @@
+#!/usr/bin/env python
+
+from .basetarget import Nop, Instruction, Label, Target, Comment, Alignment
+from .basetarget import Imm32, DebugInfo
+
+
+class SimpleTarget(Target):
+    def __init__(self):
+        super().__init__('SimpleTarget')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/target/arm/__init__.py	Sat Mar 01 15:40:31 2014 +0100
@@ -0,0 +1,42 @@
+
+from ..basetarget import Target
+from ..arm.registers import R0, R1, R2, R3, R4, R5, R6, R7, SP, LR, PC
+from ..arm.registers import register_range
+
+from .instructions import Mov
+
+class ArmArmTarget(Target):
+    def __init__(self):
+        super().__init__('arm_arm')
+
+        # Assembly grammar:
+        self.add_keyword('mov')
+        self.add_keyword('r0')
+        self.add_keyword('r1')
+        self.add_keyword('r2')
+        self.add_keyword('r3')
+        self.add_keyword('r4')
+        self.add_keyword('r5')
+        self.add_keyword('r6')
+        self.add_keyword('r7')
+
+        self.add_rule('reg', ['r0'], lambda rhs: R0)
+        self.add_rule('reg', ['r1'], lambda rhs: R1)
+        self.add_rule('reg', ['r2'], lambda rhs: R2)
+        self.add_rule('reg', ['r3'], lambda rhs: R3)
+        self.add_rule('reg', ['r4'], lambda rhs: R4)
+        self.add_rule('reg', ['r5'], lambda rhs: R5)
+        self.add_rule('reg', ['r6'], lambda rhs: R6)
+        self.add_rule('reg', ['r7'], lambda rhs: R7)
+
+
+        self.add_instruction(['mov', 'reg', ',', 'imm8'],
+                lambda rhs: Mov(rhs[1], rhs[3]))
+
+        self.add_rule('imm32', ['val32'], lambda x: x[0].val)
+        self.add_rule('imm32', ['imm8'], lambda x: x[0])
+        self.add_rule('imm8', ['val8'], lambda x: x[0].val)
+        self.add_rule('imm8', ['imm5'], lambda x: x[0])
+        self.add_rule('imm5', ['val5'], lambda x: x[0].val)
+        self.add_rule('imm5', ['imm3'], lambda x: x[0])
+        self.add_rule('imm3', ['val3'], lambda x: x[0].val)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/target/arm/armv7.lidl	Sat Mar 01 15:40:31 2014 +0100
@@ -0,0 +1,36 @@
+
+#  This file specifies the encoding of the arm instruction set.
+
+fields {
+    word16 16 {
+        opcode 15:12
+        top2 15:14
+        top6 15:10
+        data_opcode 9..6
+        opB 11:9
+        Rm 8:6
+        Rn 5:3
+        Rt 2:0
+    }
+}
+
+patterns {
+ add = 0
+ sub, mul = 1..2
+ [r1, r2, r3, r4, r5] is todo = 1..5
+ [STR, STRH, STRB, LDRSB, LDR, LDRH, LDRB, LDRSH] is opcode = 0b0101 & opB = {0 to 7}
+
+ EQ, NE, CS, CC, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE, AL = 0..14
+ [AND, EOR, LSL, LSR, ASR, ADC, SBC, ROR, TST, RSB, CMP, CMN, ORR, MUL, BIC, MVN] is  0..15
+
+ memop is STR | STRH | STRB | LDRSB | LDR | LDR | LDRH | LDRB | LDRSH
+}
+
+
+constructors
+{
+ alu rs1, reg_or_imm, rd
+ memop Rt, [Rn, Rm] is memop & Rt & Rn & Rm
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/target/arm/instructions.py	Sat Mar 01 15:40:31 2014 +0100
@@ -0,0 +1,37 @@
+
+
+from ..basetarget import Instruction
+
+from .token import ArmToken
+from .registers import R0, SP
+
+
+# Instructions:
+
+class ArmInstruction(Instruction):
+    def __init__(self):
+        self.token = ArmToken()
+
+
+class Mov(ArmInstruction):
+    """ Mov Rd, imm16 """
+    def __init__(self, reg, imm):
+        super().__init__()
+        self.reg = reg
+        self.imm = imm
+
+    def encode(self):
+        self.token[0:12] = self.imm
+        self.token[12:16] = self.reg.num
+        self.token[16:20] = 0
+        self.token[20] = 0
+        self.token[21:28] = 0b0011101
+        self.token.cond = 0xE # Always!
+        return self.token.encode()
+
+    def relocations(self):
+        return []
+
+    def __repr__(self):
+        return 'DCD 0x{0:X}'.format(self.expr)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/target/arm/registers.py	Sat Mar 01 15:40:31 2014 +0100
@@ -0,0 +1,49 @@
+
+from ..basetarget import Register
+
+class ArmRegister(Register):
+    def __init__(self, num, name):
+        super().__init__(name)
+        self.num = num
+
+    def __repr__(self):
+        return self.name
+
+
+class Reg8Op(ArmRegister):
+    pass
+
+
+def get_register(n):
+    for x in registers:
+        if x.num == n:
+            return x
+    raise Exception('No register found with this number')
+
+def register_range(a, b):
+    """ Return set of registers from a to b """
+    assert a.num < b.num
+    return {get_register(n) for n in range(a.num, b.num + 1)}
+
+
+R0 = Reg8Op(0, 'r0')
+R1 = Reg8Op(1, 'r1')
+R2 = Reg8Op(2, 'r2')
+R3 = Reg8Op(3, 'r3')
+R4 = Reg8Op(4, 'r4')
+R5 = Reg8Op(5, 'r5')
+R6 = Reg8Op(6, 'r6')
+R7 = Reg8Op(7, 'r7')
+R8 = ArmRegister(8, 'r8')
+R9 = ArmRegister(9, 'r9')
+R10 = ArmRegister(10, 'r10')
+R11 = ArmRegister(11, 'r11')
+R12 = ArmRegister(12, 'r12')
+
+# Other registers:
+# TODO
+SP = ArmRegister(13, 'sp')
+LR = ArmRegister(14, 'lr')
+PC = ArmRegister(15, 'pc')
+
+registers = [R0, R1, R2, R3, R4, R5, R6, R7, SP, LR, PC]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/target/arm/token.py	Sat Mar 01 15:40:31 2014 +0100
@@ -0,0 +1,12 @@
+
+from ..token import Token, u32, bit_range
+
+
+class ArmToken(Token):
+    def __init__(self):
+        super().__init__(32)
+
+    cond = bit_range(28, 32)
+
+    def encode(self):
+        return u32(self.bit_value)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/target/basetarget.py	Sat Mar 01 15:40:31 2014 +0100
@@ -0,0 +1,154 @@
+from ppci.asmnodes import ASymbol, AInstruction, ANumber
+from ppci import CompilerError
+
+"""
+  Base classes for defining a target
+"""
+
+# Machine code interface:
+class Operand:
+   """ Single machine operand """
+   pass
+
+# standard immediates:
+
+class ImmBase:
+    def __init__(self, imm):
+        assert type(imm) is int
+        assert imm < self.Max()
+        self.imm = imm
+
+    @classmethod
+    def Max(cls):
+        return 2**cls.bits
+
+    @classmethod
+    def Create(cls, vop):
+        if type(vop) is ANumber and vop.number < cls.Max():
+            return cls(vop.number)
+
+
+class Imm3(ImmBase):
+    bits = 3
+
+
+class Imm7(ImmBase):
+    bits = 7
+
+
+class Imm8(ImmBase):
+    bits = 8
+
+
+class Imm32(ImmBase):
+    bits = 32
+
+
+class Instruction:
+    """ Base instruction class """
+    def encode(self):
+        return bytes()
+
+    def relocations(self):
+        return []
+
+    def symbols(self):
+        return []
+
+
+class Nop(Instruction):
+    """ Instruction that does nothing and has zero size """
+    def encode(self):
+        return bytes()
+
+
+class PseudoInstruction(Instruction):
+    pass
+
+
+class Label(PseudoInstruction):
+    def __init__(self, name):
+        self.name = name
+
+    def __repr__(self):
+        return '{}:'.format(self.name)
+
+    def symbols(self):
+        return [self.name]
+
+    @classmethod
+    def Create(cls, vop):
+        if type(vop) is ASymbol:
+            name = vop.name
+            return cls(name)
+
+
+class Comment(PseudoInstruction):
+    def __init__(self, txt):
+        self.txt = txt
+
+    def encode(self):
+        return bytes()
+
+    def __repr__(self):
+        return '; {}'.format(self.txt)
+
+
+class Alignment(PseudoInstruction):
+    def __init__(self, a):
+        self.align = a
+
+    def __repr__(self):
+        return 'ALIGN({})'.format(self.align)
+
+    def encode(self):
+        pad = []
+        # TODO
+        address = 0
+        while (address % self.align) != 0:
+            address += 1
+            pad.append(0)
+        return bytes(pad)
+
+
+class DebugInfo(PseudoInstruction):
+    def __init__(self, i):
+        self.info = i
+
+    def __repr__(self):
+        return 'DebugInfo: {}'.format(self.info)
+
+
+class Register(Operand):
+    def __init__(self, name):
+        self.name = name
+
+
+class Target:
+    def __init__(self, name, desc=''):
+        self.name = name
+        self.desc = desc
+        self.registers = []
+        self.byte_sizes = {'int' : 4}  # For front end!
+
+        # For assembler:
+        self.assembler_rules = []
+        self.asm_keywords = []
+
+    def add_keyword(self, kw):
+        self.asm_keywords.append(kw)
+
+    def add_instruction(self, rhs, f):
+        self.add_rule('instruction', rhs, f)
+
+    def add_rule(self, lhs, rhs, f):
+        self.assembler_rules.append((lhs, rhs, f))
+
+    def instruction(self, cls):
+        """ Decorator function that registers an instruction to this target """
+        self.addInstruction(cls)
+        return cls
+
+    def addInstruction(self, i):
+        pass
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/target/instructionselector.py	Sat Mar 01 15:40:31 2014 +0100
@@ -0,0 +1,60 @@
+from ppci import ir
+from ppci import irmach
+from ppci.irmach import AbstractInstruction as makeIns
+from .basetarget import Label
+
+def genTemps():
+    n = 900
+    while True:
+        yield ir.Temp('t{}'.format(n))
+        n = n + 1
+
+
+class InstructionSelector:
+    """
+        Base instruction selector. This class must be overridden by
+        backends.
+    """
+    def __init__(self):
+        self.temps = genTemps()
+
+    def newTmp(self):
+        return self.temps.__next__()
+
+
+    def munchFunction(self, f, frame):
+        # Entry point for instruction selection
+        assert isinstance(f, ir.Function)
+        self.targets = {}
+        # Enter a frame per function:
+        self.frame = frame
+        # First define labels:
+        for bb in f.Blocks:
+            itgt = makeIns(Label(ir.label_name(bb)))
+            self.targets[bb] = itgt
+        # Generate code for all blocks:
+        for bb in f.Blocks:
+            self.emit2(self.targets[bb])
+            for i in bb.Instructions:
+                self.munchStm(i)
+        self.munchStm(ir.Move(self.frame.rv, f.return_value))
+
+    def move(self, dst, src):
+        raise NotImplementedError('Not target implemented')
+
+    def emit(self, *args, **kwargs):
+        """ Abstract instruction emitter """
+        i = makeIns(*args, **kwargs)
+        return self.emit2(i)
+
+    def emit2(self, i):
+        self.frame.instructions.append(i)
+        return i
+
+    def munchStm(self, s):
+        """ Implement this in the target specific back-end """
+        raise NotImplementedError()
+
+    def munchExpr(self, e):
+        """ Implement this in the target specific back-end """
+        raise NotImplementedError()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/target/msp430/instructions.py	Sat Mar 01 15:40:31 2014 +0100
@@ -0,0 +1,211 @@
+
+from ..basetarget import Register, Instruction, Target
+from ..token import Token, u16, bit_range
+from .registers import Msp430Register
+
+
+class Msp430Token(Token):
+    def __init__(self):
+        super().__init__(16)
+
+    condition = bit_range(10, 13)
+    opcode = bit_range(12, 16)
+    register = bit_range(0, 4)
+    destination = bit_range(0, 4)
+    source = bit_range(8, 12)
+    bw = bit_range(6, 7)  # TODO: actually a single bit!
+    Ad = bit_range(7, 8)  # TODO: actually a single bit!
+    As = bit_range(4, 6)
+
+    def encode(self):
+        return u16(self.bit_value)
+
+REGISTER_MODE = 1
+SYMBOLIC_MODE = 3
+ABSOLUTE_MODE = 4
+#TODO: add more modes!
+IMMEDIATE_MODE = 7
+
+class Msp430Operand:
+    pass
+
+class Msp430DestinationOperand(Msp430Operand):
+    def __init__(self, param):
+        if isinstance(param, Msp430Register):
+            self.reg = param.num
+            self.Ad = 0
+        else:
+            raise Exception()
+
+
+class Msp430SourceOperand(Msp430Operand):
+    def __init__(self, param):
+        if isinstance(param, Msp430Register):
+            self.reg = param.num
+            self.As = 0
+            self.extra_bytes = bytes()
+        elif isinstance(param, int):
+            self.reg = 0
+            self.As = 3
+            self.extra_bytes = u16(param)
+        else:
+            raise Exception()
+
+
+class Msp430Instruction(Instruction):
+    b = 0
+    def __init__(self):
+        self.token = Msp430Token()
+
+
+class Reti(Msp430Instruction):
+    def encode(self):
+        self.token[0:16] = 0x1300
+        return self.token.encode()
+
+
+#########################
+# Jump instructions:
+#########################
+
+class JumpInstruction(Msp430Instruction):
+    def __init__(self, target):
+        super().__init__()
+        self.target = target
+
+    def encode(self):
+        self.token.condition = self.condition
+        self.token.offset = 0
+        self.token[13] = 1
+        return self.token.encode()
+
+    def relocations(self):
+        return [(self.target, 'msp_reloc')]
+
+
+class Jnz(JumpInstruction):
+    condition = 0
+
+
+class Jz(JumpInstruction):
+    condition = 1
+
+
+class Jnc(JumpInstruction):
+    condition = 2
+
+
+class Jc(JumpInstruction):
+    condition = 3
+
+
+class Jn(JumpInstruction):
+    condition = 4
+
+
+class Jge(JumpInstruction):
+    condition = 5
+
+
+class Jl(JumpInstruction):
+    condition = 6
+
+
+class Jmp(JumpInstruction):
+    condition = 7
+
+
+#########################
+# Single operand arithmatic:
+#########################
+
+
+class OneOpArith(Msp430Instruction):
+    def __init__(self, op1):
+        self.op1 = op1
+
+    def encode(self):
+        # TODO:
+        bits[15:10] = '00100'
+        h1 = (self.opcode << 4)
+        return pack_ins(h1)
+
+
+def oneOpIns(mne, opc):
+    """ Helper function to define a one operand arithmetic instruction """
+    members = {'opcode': opc}
+    ins_cls = type(mne + '_ins', (OneOpArith,), members)
+
+
+oneOpIns('rrc', 0)
+oneOpIns('swpb', 1)
+oneOpIns('rra', 2)
+oneOpIns('sxt', 3)
+oneOpIns('push', 4)
+oneOpIns('call', 5)
+
+
+#########################
+# Two operand arithmatic instructions:
+#########################
+
+
+class TwoOpArith(Msp430Instruction):
+    def __init__(self, src, dst):
+        super().__init__()
+        self.src = Msp430SourceOperand(src)
+        self.dst = Msp430DestinationOperand(dst)
+
+    def encode(self):
+        """
+            Smart things have been done by MSP430 designers.
+            As (2 bits) is the source addressing mode selector.
+            Ad (1 bit) is the destination adressing mode selector.
+            For the source there are 7 different addressing mode.
+            For the destination there are 4.
+            The trick is to use also the register to distuingish the
+            different modes.
+        """
+        # TODO: Make memory also possible
+        self.token.bw = self.b # When b=1, the operation is byte mode
+        self.token.As = self.src.As
+        self.token.Ad = self.dst.Ad
+        self.token.destination = self.dst.reg
+        self.token.source = self.src.reg
+        self.token.opcode = self.opcode
+        return self.token.encode() + self.src.extra_bytes
+
+
+def twoOpIns(mne, opc):
+    """ Helper function to define a two operand arithmetic instruction """
+    members = {'opcode': opc}
+    ins_cls = type(mne + '_ins', (TwoOpArith,), members)
+
+
+class Mov(TwoOpArith):
+    """ Moves the source to the destination """
+    opcode = 4
+
+
+# This is equivalent to the helper function twoOpIns:
+class Add(TwoOpArith):
+    """ Adds the source to the destination """
+    mnemonic = 'add'
+    opcode = 5
+
+
+twoOpIns('addc', 6)
+twoOpIns('subc', 7)
+twoOpIns('sub', 8)
+
+
+class Cmp(TwoOpArith):
+    opcode = 9
+
+
+twoOpIns('dadd', 10)
+twoOpIns('bit', 11)
+twoOpIns('bic', 12)
+twoOpIns('bis', 13)
+twoOpIns('xor', 14)
+twoOpIns('and', 15)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/target/msp430/msp430.py	Sat Mar 01 15:40:31 2014 +0100
@@ -0,0 +1,67 @@
+import struct
+import types
+from ..basetarget import Register, Instruction, Target
+from ppci.asmnodes import ASymbol, ANumber
+from ppci import CompilerError
+from .registers import r10, r11, r12, r13, r14, r15
+from .instructions import Reti, Mov, Add
+
+# Create the target class (singleton):
+
+class Msp430Target(Target):
+    def __init__(self):
+        super().__init__('msp430')
+
+        # Registers:
+        self.add_keyword('r10')
+        self.add_keyword('r11')
+        self.add_keyword('r12')
+        self.add_keyword('r13')
+        self.add_keyword('r14')
+        self.add_keyword('r15')
+        self.add_rule('reg', ['r10'], lambda rhs: r10)
+        self.add_rule('reg', ['r11'], lambda rhs: r11)
+        self.add_rule('reg', ['r12'], lambda rhs: r12)
+        self.add_rule('reg', ['r13'], lambda rhs: r13)
+        self.add_rule('reg', ['r14'], lambda rhs: r14)
+        self.add_rule('reg', ['r15'], lambda rhs: r15)
+
+        # Instructions rules:
+        self.add_keyword('mov')
+        self.add_instruction(['mov', 'reg', ',', 'reg'],
+            lambda rhs: Mov(rhs[1], rhs[3]))
+        self.add_instruction(['mov', 'imm16', ',', 'reg'],
+            lambda rhs: Mov(rhs[1], rhs[3]))
+
+        self.add_keyword('add')
+        self.add_instruction(['add', 'reg', ',', 'reg'],
+            lambda rhs: Add(rhs[1], rhs[3]))
+
+        self.add_keyword('reti')
+        self.add_instruction(['reti'], lambda rhs: Reti())
+
+        # Constants:
+        self.add_rule('imm32', ['val32'], lambda x: x[0].val)
+        self.add_rule('imm32', ['imm16'], lambda x: x[0])
+        self.add_rule('imm16', ['val16'], lambda x: x[0].val)
+        self.add_rule('imm16', ['imm8'], lambda x: x[0])
+        self.add_rule('imm8', ['val8'], lambda x: x[0].val)
+        self.add_rule('imm8', ['imm5'], lambda x: x[0])
+        self.add_rule('imm5', ['val5'], lambda x: x[0].val)
+        self.add_rule('imm5', ['imm3'], lambda x: x[0])
+        self.add_rule('imm3', ['val3'], lambda x: x[0].val)
+
+
+msp430target = Msp430Target()
+
+
+# Target description for the MSP430 processor
+
+
+msp430target.registers.append(r10)
+msp430target.registers.append(r11)
+msp430target.registers.append(r12)
+msp430target.registers.append(r13)
+msp430target.registers.append(r14)
+msp430target.registers.append(r15)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/target/msp430/registers.py	Sat Mar 01 15:40:31 2014 +0100
@@ -0,0 +1,18 @@
+
+from ..basetarget import Register
+
+class Msp430Register(Register):
+    def __init__(self, num, name):
+        super().__init__(name)
+        self.num = num
+
+# 8 bit registers:
+PCB = Msp430Register(0, 'r0')
+rpc = PCB
+r10 = Msp430Register(10, 'r10')
+r11 = Msp430Register(11, 'r11')
+r12 = Msp430Register(12, 'r12')
+r13 = Msp430Register(13, 'r13')
+r14 = Msp430Register(14, 'r14')
+r15 = Msp430Register(15, 'r15')
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/target/target_list.py	Sat Mar 01 15:40:31 2014 +0100
@@ -0,0 +1,10 @@
+
+from .arm import ArmArmTarget
+from .thumb import ThumbTarget
+from .msp430.msp430 import msp430target
+
+# Instance:
+arm_target = ArmArmTarget()
+thumb_target = ThumbTarget()
+
+target_list = [arm_target, thumb_target]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/target/thumb/__init__.py	Sat Mar 01 15:40:31 2014 +0100
@@ -0,0 +1,4 @@
+
+
+from .armtarget import ThumbTarget
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/target/thumb/arm.brg	Sat Mar 01 15:40:31 2014 +0100
@@ -0,0 +1,31 @@
+
+from ppci.target.thumb.instructions import Orr, Lsl, Str2, Ldr2, Ldr3
+from ppci.target.thumb.instructions import B, Bl, Bgt, Blt, Beq, Bne
+from ppci.target.thumb.instructions import Mov2, Mov3, Sub3
+from ppci.target.thumb.instructions import Add3, Sub, Cmp, Sub2, Add2, Mul
+
+%%
+
+%terminal ADDI32 SUBI32 MULI32
+%terminal ORI32 SHLI32
+%terminal CONSTI32 MEMI32 REGI32 CALL
+%terminal MOVI32
+
+%%
+
+
+reg: ADDI32(reg, reg) 2 (. d = self.newTmp(); self.emit(Add3, dst=[d], src=[$1, $2]); return d .)
+reg: SUBI32(reg, reg) 2 (. d = self.newTmp(); self.emit(Sub3, dst=[d], src=[$1, $2]); return d .)
+reg: ORI32(reg, reg)  2 (. d = self.newTmp(); self.selector.move(d, $1); self.emit(Orr, dst=[], src=[d, $2]); return d .)
+reg: SHLI32(reg, reg) 2 (. d = self.newTmp(); self.selector.move(d, $1); self.emit(Lsl, dst=[], src=[d, $2]); return d .)
+reg: MULI32(reg, reg) 2 (. d = self.newTmp(); self.selector.move(d, $1); self.emit(Mul, dst=[d], src=[$2, d]); return d .)
+
+reg: CONSTI32         3 (. d = self.newTmp(); ln = self.selector.frame.addConstant($$.value); self.emit(Ldr3, dst=[d], others=[ln]); return d .)
+reg: MEMI32(reg)      4 (. d = self.newTmp(); self.emit(Ldr2, dst=[d], src=[$1], others=[0]); return d .)
+reg: REGI32           1 (. return $$.value .)
+reg: CALL             1 (. return self.selector.munchCall($$.value) .)
+
+
+stmt: MOVI32(MEMI32(addr), reg) 3 (. self.emit(Str2, src=[$1, $2]) .)
+
+addr: reg 2 (. .)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/target/thumb/armframe.py	Sat Mar 01 15:40:31 2014 +0100
@@ -0,0 +1,96 @@
+from ... import ir
+from ..basetarget import Label, Alignment
+from ...irmach import makeIns, Frame
+from .instructions import Dcd, AddSp, SubSp, Push, Pop, Mov2
+from ..arm.registers import R0, R1, R2, R3, R4, R5, R6, R7, LR, PC, SP
+
+
+class ArmFrame(Frame):
+    """ Arm specific frame for functions. """
+    def __init__(self, name):
+        # We use r7 as frame pointer.
+        super().__init__(name)
+        self.regs = [R0, R1, R2, R3, R4, R5, R6]
+        self.rv = ir.Temp('special_RV')
+        self.p1 = ir.Temp('special_P1')
+        self.p2 = ir.Temp('special_P2')
+        self.p3 = ir.Temp('special_P3')
+        self.p4 = ir.Temp('special_P4')
+        self.fp = ir.Temp('special_FP')
+        # Pre-colored registers:
+        self.tempMap = {}
+        self.tempMap[self.rv] = R0
+        self.tempMap[self.p1] = R1
+        self.tempMap[self.p2] = R2
+        self.tempMap[self.p3] = R3
+        self.tempMap[self.p4] = R4
+        self.tempMap[self.fp] = R7
+        self.locVars = {}
+        self.parMap = {}
+        # Literal pool:
+        self.constants = []
+
+    def argLoc(self, pos):
+        """
+            Gets the function parameter location in IR-code format.
+        """
+        if pos == 0:
+            return self.p1
+        elif pos == 1:
+            return self.p2
+        elif pos == 2:
+            return self.p3
+        elif pos == 3:
+            return self.p4
+        else:
+            raise NotImplementedError('No more than 4 parameters implemented')
+
+    def allocVar(self, lvar):
+        if lvar not in self.locVars:
+            self.locVars[lvar] = self.stacksize
+            self.stacksize = self.stacksize + 4
+        return self.locVars[lvar]
+
+    def addConstant(self, value):
+        lab_name = '{}_literal_{}'.format(self.name, len(self.constants))
+        self.constants.append((lab_name, value))
+        return lab_name
+
+    def prologue(self):
+        """ Returns prologue instruction sequence """
+        pre = [
+            Label(self.name),                     # Label indication function
+            Push({LR, R7})
+            ]
+        if self.stacksize > 0:
+            pre.append(SubSp(self.stacksize))  # Reserve stack space
+        pre += [
+            Mov2(R7, SP)                          # Setup frame pointer
+            ]
+        return pre
+
+    def epilogue(self):
+        """ Return epilogue sequence for a frame. Adjust frame pointer and add constant pool """
+        post = []
+        if self.stacksize > 0:
+            post.append(AddSp(self.stacksize))
+        post += [
+            Pop({PC, R7}),
+            Alignment(4)   # Align at 4 bytes
+            ]
+        # Add constant literals:
+        for ln, v in self.constants:
+            post.extend([Label(ln), Dcd(v)])
+        return post
+
+    def EntryExitGlue3(self):
+        """
+            Add code for the prologue and the epilogue. Add a label, the
+            return instruction and the stack pointer adjustment for the frame.
+        """
+        for index, ins in enumerate(self.prologue()):
+            self.instructions.insert(index, makeIns(ins))
+
+        # Postfix code:
+        for ins in self.epilogue():
+            self.instructions.append(makeIns(ins))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/target/thumb/arminstructionselector.py	Sat Mar 01 15:40:31 2014 +0100
@@ -0,0 +1,92 @@
+from ... import ir, same_dir
+from ppci.irmach import AbstractInstruction as makeIns
+from ppci.ir2tree import makeTree
+import pyburg
+from ..basetarget import Nop
+from ..instructionselector import InstructionSelector
+from .instructions import Orr, Lsl, Str2, Ldr2, Ldr3
+from .instructions import B, Bl, Bgt, Blt, Beq, Bne
+from .instructions import Mov2, Mov3
+from .instructions import Cmp, Sub2, Mul
+
+# Import BURG spec for arm:
+spec_file = same_dir(__file__, 'arm.brg')
+arm_matcher = pyburg.load_as_module(spec_file)
+
+
+class ArmMatcher(arm_matcher.Matcher):
+    """ Matcher that derives from a burg spec generated matcher """
+    def __init__(self, selector):
+        super().__init__()
+        self.newTmp = selector.newTmp
+        self.emit = selector.emit
+        self.selector = selector
+
+
+class ArmInstructionSelector(InstructionSelector):
+    """ Instruction selector for the arm architecture """
+    def __init__(self):
+        super().__init__()
+        self.matcher = ArmMatcher(self)
+
+    def munchExpr(self, e):
+        # Use BURG system here:
+        t = makeTree(e)
+        return self.matcher.gen(t)
+
+    def munchCall(self, e):
+        """ Generate code for call sequence """
+        # Move arguments into proper locations:
+        reguses = []
+        for i, a in enumerate(e.arguments):
+            loc = self.frame.argLoc(i)
+            m = ir.Move(loc, a)
+            self.munchStm(m)
+            if isinstance(loc, ir.Temp):
+                reguses.append(loc)
+        self.emit(Bl(e.f), src=reguses, dst=[self.frame.rv])
+        d = self.newTmp()
+        self.move(d, self.frame.rv)
+        return d
+
+    def munchStm(self, s):
+        if isinstance(s, ir.Terminator):
+            pass
+        elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem) and \
+            isinstance(s.dst.e, ir.Binop) and s.dst.e.operation == '+' and \
+            isinstance(s.dst.e.b, ir.Const):
+            a = self.munchExpr(s.dst.e.a)
+            val = self.munchExpr(s.src)
+            c = s.dst.e.b.value
+            self.emit(Str2, others=[c], src=[a, val])
+        elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem):
+            memloc = self.munchExpr(s.dst.e)
+            val = self.munchExpr(s.src)
+            self.emit(Str2, others=[0], src=[memloc, val])
+        elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Temp):
+            val = self.munchExpr(s.src)
+            dreg = s.dst
+            self.move(dreg, val)
+        elif isinstance(s, ir.Exp):
+            # Generate expression code and discard the result.
+            x = self.munchExpr(s.e)
+            self.emit(Nop(), src=[x])
+        elif isinstance(s, ir.Jump):
+            tgt = self.targets[s.target]
+            self.emit(B(ir.label_name(s.target)), jumps=[tgt])
+        elif isinstance(s, ir.CJump):
+            a = self.munchExpr(s.a)
+            b = self.munchExpr(s.b)
+            self.emit(Cmp, src=[a, b])
+            ntgt = self.targets[s.lab_no]
+            ytgt = self.targets[s.lab_yes]
+            jmp_ins = makeIns(B(ir.label_name(s.lab_no)), jumps=[ntgt])
+            opnames = {'<': Blt, '>':Bgt, '==':Beq, '!=':Bne}
+            op = opnames[s.cond](ir.label_name(s.lab_yes))
+            self.emit(op, jumps=[ytgt, jmp_ins])  # Explicitely add fallthrough
+            self.emit2(jmp_ins)
+        else:
+            raise NotImplementedError('Stmt --> {}'.format(s))
+
+    def move(self, dst, src):
+        self.emit(Mov2, src=[src], dst=[dst], ismove=True)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/target/thumb/armtarget.py	Sat Mar 01 15:40:31 2014 +0100
@@ -0,0 +1,157 @@
+import struct
+from ..basetarget import Register, Instruction, Target, Label, Alignment
+from ..basetarget import Imm32, Imm8, Imm7, Imm3
+from .instructions import Add2, Sub, Add3, Cmp, Lsl, Orr, Add, Cmp2
+from .instructions import Dcd, Pop, Push, Yield, Mov2, Mov3
+from .instructions import B, Bl, Bne, Beq, Blt, Bgt
+from .instructions import Ldr, Str2, Ldr2, Str1, Ldr1
+
+from .armframe import ArmFrame
+from .arminstructionselector import ArmInstructionSelector
+from ..arm.registers import R0, R1, R2, R3, R4, R5, R6, R7, SP, LR, PC
+from ..arm.registers import register_range
+
+
+""" ARM target description. """
+
+# TODO: encode this in DSL (domain specific language)
+# TBD: is this required?
+# TODO: make a difference between armv7 and armv5?
+
+thumb_assembly_rules = []
+def add_rule(rhs, f):
+    thumb_assembly_rules.append(('instruction', rhs, f))
+
+
+class ThumbTarget(Target):
+    def __init__(self):
+        super().__init__('thumb')
+        self.ins_sel = ArmInstructionSelector()
+        self.FrameClass = ArmFrame
+        self.add_rules()
+
+    def add_rules(self):
+
+        # Add instructions:
+        self.add_keyword('dcd')
+        self.add_instruction(['dcd', 'imm32'], lambda rhs: Dcd(rhs[1]))
+
+        self.add_keyword('mov')
+        self.add_instruction(['mov', 'reg8', ',', 'reg8'],
+                lambda rhs: Mov2(rhs[1], rhs[3]))
+
+        self.add_instruction(['mov', 'reg8', ',', 'imm8'],
+                lambda rhs: Mov3(rhs[1], rhs[3]))
+
+        self.add_keyword('add')
+        self.add_instruction(['add', 'reg8', ',', 'reg8', ',', 'imm3'],
+                lambda rhs: Add2(rhs[1], rhs[3], rhs[5]))
+
+        self.add_instruction(['add', 'reg8', ',', 'reg8', ',', 'reg8'],
+                lambda rhs: Add3(rhs[1], rhs[3], rhs[5]))
+
+        self.add_keyword('sub')
+        self.add_instruction(['sub', 'reg8', ',', 'reg8', ',', 'imm3'],
+                lambda rhs: Sub(rhs[1], rhs[3], rhs[5]))
+
+        self.add_instruction(['sub', 'sp', ',', 'sp', ',', 'imm8'],
+                lambda rhs: Sub(SP, SP, rhs[5]))
+
+        self.add_instruction(['add', 'sp', ',', 'sp', ',', 'imm8'],
+                lambda rhs: Add(SP, SP, rhs[5]))
+
+        self.add_keyword('cmp')
+        self.add_instruction(['cmp', 'reg8', ',', 'reg8'],
+                lambda rhs: Cmp(rhs[1], rhs[3]))
+        self.add_instruction(['cmp', 'reg8', ',', 'imm8'],
+                lambda rhs: Cmp2(rhs[1], rhs[3]))
+
+        self.add_keyword('lsl')
+        self.add_instruction(['lsl', 'reg8', ',', 'reg8'],
+                lambda rhs: Lsl(rhs[1], rhs[3]))
+
+        self.add_keyword('str')
+        self.add_instruction(['str', 'reg8', ',', '[', 'reg8', '+', 'imm5', ']'],
+                lambda rhs: Str2(rhs[1], rhs[4], rhs[6]))
+
+        self.add_keyword('ldr')
+        self.add_instruction(['ldr', 'reg8', ',', '[', 'reg8', '+', 'imm5', ']'],
+                lambda rhs: Ldr2(rhs[1], rhs[4], rhs[6]))
+
+        self.add_instruction(['str', 'reg8', ',', '[', 'sp', '+', 'imm8', ']'],
+                lambda rhs: Str1(rhs[1], rhs[6]))
+
+        self.add_instruction(['ldr', 'reg8', ',', '[', 'sp', '+', 'imm8', ']'],
+                lambda rhs: Ldr1(rhs[1], rhs[6]))
+
+        self.add_keyword('pop')
+        self.add_instruction(['pop', 'reg_list'], lambda rhs: Pop(rhs[1]))
+        self.add_keyword('push')
+        self.add_instruction(['push', 'reg_list'], lambda rhs: Push(rhs[1]))
+
+        self.add_keyword('yield')
+        self.add_instruction(['yield'], lambda rhs: Yield())
+
+        self.add_keyword('b')
+        self.add_keyword('bl')
+        self.add_instruction(['b', 'ID'], lambda rhs: B(rhs[1].val))
+        self.add_instruction(['bl', 'ID'], lambda rhs: Bl(rhs[1].val))
+        self.add_keyword('beq')
+        self.add_keyword('bne')
+        self.add_keyword('blt')
+        self.add_keyword('bgt')
+        self.add_instruction(['beq', 'ID'], lambda rhs: Beq(rhs[1].val))
+        self.add_instruction(['bne', 'ID'], lambda rhs: Bne(rhs[1].val))
+        self.add_instruction(['blt', 'ID'], lambda rhs: Blt(rhs[1].val))
+        self.add_instruction(['bgt', 'ID'], lambda rhs: Bgt(rhs[1].val))
+
+        self.add_keyword('align')
+        self.add_instruction(['align', 'imm8'], lambda rhs: Alignment(rhs[1]))
+
+        self.add_instruction(['ldr', 'reg8', ',', 'ID'],
+                lambda rhs: Ldr(rhs[1], rhs[3].val))
+
+        # Additional rules:
+
+        # Register list grammar:
+        self.add_rule('reg_list', ['{', 'reg_list_inner', '}'],
+            lambda rhs: rhs[1])
+        self.add_rule('reg_list_inner', ['reg_or_range'],
+            lambda rhs: rhs[0])
+        self.add_rule('reg_list_inner', ['reg_or_range', ',', 'reg_list_inner'],
+            lambda rhs: rhs[0] | rhs[2])
+        self.add_rule('reg_or_range', ['reg8'], lambda rhs: {rhs[0]})
+        self.add_rule('reg_or_range', ['lr'], lambda rhs: {LR})
+        self.add_rule('reg_or_range', ['pc'], lambda rhs: {PC})
+
+        self.add_rule('reg_or_range', ['reg8', '-', 'reg8'],
+            lambda rhs: register_range(rhs[0], rhs[2]))
+
+        self.add_keyword('r0')
+        self.add_keyword('r1')
+        self.add_keyword('r2')
+        self.add_keyword('r3')
+        self.add_keyword('r4')
+        self.add_keyword('r5')
+        self.add_keyword('r6')
+        self.add_keyword('r7')
+        self.add_keyword('sp')
+        self.add_keyword('lr')
+        self.add_keyword('pc')
+        self.add_rule('reg8', ['r0'], lambda rhs: R0)
+        self.add_rule('reg8', ['r1'], lambda rhs: R1)
+        self.add_rule('reg8', ['r2'], lambda rhs: R2)
+        self.add_rule('reg8', ['r3'], lambda rhs: R3)
+        self.add_rule('reg8', ['r4'], lambda rhs: R4)
+        self.add_rule('reg8', ['r5'], lambda rhs: R5)
+        self.add_rule('reg8', ['r6'], lambda rhs: R6)
+        self.add_rule('reg8', ['r7'], lambda rhs: R7)
+        # Constants:
+        self.add_rule('imm32', ['val32'], lambda x: x[0].val)
+        self.add_rule('imm32', ['imm8'], lambda x: x[0])
+        self.add_rule('imm8', ['val8'], lambda x: x[0].val)
+        self.add_rule('imm8', ['imm5'], lambda x: x[0])
+        self.add_rule('imm5', ['val5'], lambda x: x[0].val)
+        self.add_rule('imm5', ['imm3'], lambda x: x[0])
+        self.add_rule('imm3', ['val3'], lambda x: x[0].val)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/target/thumb/armtoken.py	Sat Mar 01 15:40:31 2014 +0100
@@ -0,0 +1,12 @@
+
+from ..token import Token, u16, bit_range
+
+class ThumbToken(Token):
+    def __init__(self):
+        super().__init__(16)
+
+    rd = bit_range(0, 3)
+
+    def encode(self):
+        return u16(self.bit_value)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/target/thumb/instructions.py	Sat Mar 01 15:40:31 2014 +0100
@@ -0,0 +1,536 @@
+from ..basetarget import Register, Instruction, Target, Label
+from ..basetarget import Imm32, Imm8, Imm7, Imm3
+from ..token import u16, u32
+from .armtoken import ThumbToken
+from ..arm.registers import R0, ArmRegister, SP
+
+
+# Instructions:
+
+class ThumbInstruction(Instruction):
+    pass
+
+
+class Dcd(ThumbInstruction):
+    def __init__(self, expr):
+        if isinstance(expr, Imm32):
+            self.expr = expr.imm
+            self.label = None
+        elif isinstance(expr, int):
+            self.expr = expr
+            self.label = None
+        else:
+            raise NotImplementedError()
+
+    def encode(self):
+        return u32(self.expr)
+
+    def relocations(self):
+        return []
+
+    def __repr__(self):
+        return 'DCD 0x{0:X}'.format(self.expr)
+
+
+class nop_ins(ThumbInstruction):
+    def encode(self):
+        return bytes()
+
+    def __repr__(self):
+        return 'NOP'
+
+
+# Memory related
+
+class LS_imm5_base(ThumbInstruction):
+    """ ??? Rt, [Rn, imm5] """
+    def __init__(self, rt, rn, imm5):
+        assert imm5 % 4 == 0
+        self.imm5 = imm5 >> 2
+        self.rn = rn
+        self.rt = rt
+        assert self.rn.num < 8
+        assert self.rt.num < 8
+        self.token = ThumbToken()
+
+    def encode(self):
+        Rn = self.rn.num
+        Rt = self.rt.num
+        imm5 = self.imm5
+        self.token[0:3] = Rt
+        self.token[3:6] = Rn
+        self.token[6:11] = imm5
+        self.token[11:16] = self.opcode
+        return self.token.encode()
+
+    def __repr__(self):
+        mnemonic = "???"
+        return '{} {}, [{}, {}]'.format(mnemonic, self.rt, self.rn, self.imm5)
+
+
+class Str2(LS_imm5_base):
+    opcode = 0xC
+
+    @classmethod
+    def fromim(cls, im):
+        return cls(im.src[1], im.src[0], im.others[0])
+
+
+class Ldr2(LS_imm5_base):
+    opcode = 0xD
+
+    @classmethod
+    def fromim(cls, im):
+        return cls(im.dst[0], im.src[0], im.others[0])
+
+class ls_sp_base_imm8(ThumbInstruction):
+    def __init__(self, rt, offset):
+        self.rt = rt
+        self.offset = offset
+
+    def encode(self):
+        rt = self.rt.num
+        assert rt < 8
+        imm8 = self.offset >> 2
+        assert imm8 < 256
+        h = (self.opcode << 8) | (rt << 8) | imm8
+        return u16(h)
+
+    def __repr__(self):
+        mnemonic = self.__class__.__name__
+        return '{} {}, [sp,#{}]'.format(mnemonic, self.rt, self.offset)
+
+def align(x, m):
+    while ((x % m) != 0):
+        x = x + 1
+    return x
+
+def Ldr(*args):
+    if len(args) == 2 and isinstance(args[0], ArmRegister) \
+            and isinstance(args[1], str):
+        return Ldr3(*args)
+    else:
+        raise Exception()
+
+
+class Ldr3(ThumbInstruction):
+    """ ldr Rt, LABEL, load value from pc relative position """
+    mnemonic = 'ldr'
+    def __init__(self, rt, label):
+        self.rt = rt
+        self.label = label
+
+    @classmethod
+    def fromim(cls, im):
+        return cls(im.dst[0], im.others[0])
+
+    def relocations(self):
+        return [(self.label, 'lit_add_8')]
+
+    def encode(self):
+        rt = self.rt.num
+        assert rt < 8
+        imm8 = 0
+        h = (0x9 << 11) | (rt << 8) | imm8
+        return u16(h)
+
+    def __repr__(self):
+        return 'LDR {}, {}'.format(self.rt, self.label)
+
+
+class Ldr1(ls_sp_base_imm8):
+    """ ldr Rt, [SP, imm8] """
+    opcode = 0x98
+
+
+class Str1(ls_sp_base_imm8):
+    """ str Rt, [SP, imm8] """
+    opcode = 0x90
+
+
+class Mov3(ThumbInstruction):
+    """ mov Rd, imm8, move immediate value into register """
+    opcode = 4 # 00100 Rd(3) imm8
+    def __init__(self, rd, imm):
+        assert imm < 256
+        self.imm = imm
+        self.rd = rd
+        self.token = ThumbToken()
+
+    @classmethod
+    def fromim(cls, im):
+        return cls(im.dst[0], im.others[0])
+
+    def encode(self):
+        rd = self.rd.num
+        self.token[8:11] = rd
+        self.token[0:8] = self.imm
+        self.token[11:16] = self.opcode
+        return self.token.encode()
+
+    def __repr__(self):
+        return 'MOV {}, {}'.format(self.rd, self.imm)
+
+
+
+# Arithmatics:
+
+
+
+class regregimm3_base(ThumbInstruction):
+    def __init__(self, rd, rn, imm3):
+        self.rd = rd
+        self.rn = rn
+        assert imm3 < 8
+        self.imm3 = imm3
+        self.token = ThumbToken()
+
+    @classmethod
+    def fromim(cls, im):
+        return cls(im.dst[0], im.src[0], im.others[0])
+
+    def encode(self):
+        rd = self.rd.num
+        self.token[0:3] = rd
+        self.token[3:6] = self.rn.num
+        self.token[6:9] = self.imm3
+        self.token[9:16] = self.opcode
+        return self.token.encode()
+
+    def __repr__(self):
+        mnemonic = self.__class__.__name__
+        return '{} {}, {}, {}'.format(mnemonic, self.rd, self.rn, self.imm3)
+
+
+
+class Add2(regregimm3_base):
+    """ add Rd, Rn, imm3 """
+    opcode = 0b0001110
+
+
+class Sub2(regregimm3_base):
+    """ sub Rd, Rn, imm3 """
+    opcode = 0b0001111
+
+
+def Sub(*args):
+    if len(args) == 3 and args[0] is SP and args[1] is SP and \
+            isinstance(args[2], int) and args[2] < 256:
+        return SubSp(args[2])
+    elif len(args) == 3 and isinstance(args[0], ArmRegister) and \
+            isinstance(args[1], ArmRegister) and isinstance(args[2], int) and \
+            args[2] < 8:
+        return Sub2(args[0], args[1], args[2])
+    else:
+        raise Exception()
+
+
+def Add(*args):
+    if len(args) == 3 and args[0] is SP and args[1] is SP and \
+            isinstance(args[2], int) and args[2] < 256:
+        return AddSp(args[2])
+    elif len(args) == 3 and isinstance(args[0], ArmRegister) and \
+            isinstance(args[1], ArmRegister) and isinstance(args[2], int) and \
+            args[2] < 8:
+        return Add2(args[0], args[1], args[2])
+    else:
+        raise Exception()
+
+
+class regregreg_base(ThumbInstruction):
+    """ ??? Rd, Rn, Rm """
+    def __init__(self, rd, rn, rm):
+        self.rd = rd
+        self.rn = rn
+        self.rm = rm
+
+    @classmethod
+    def fromim(cls, im):
+        return cls(im.dst[0], im.src[0], im.src[1])
+
+    def encode(self):
+        at = ThumbToken()
+        at.rd = self.rd.num
+        rn = self.rn.num
+        rm = self.rm.num
+        at[3:6] = rn
+        at[6:9] = rm
+        at[9:16] = self.opcode
+        return at.encode()
+
+    def __repr__(self):
+        return '{} {}, {}, {}'.format(self.mnemonic, self.rd, self.rn, self.rm)
+
+
+class Add3(regregreg_base):
+    mnemonic = 'ADD'
+    opcode = 0b0001100
+
+
+class Sub3(regregreg_base):
+    mnemonic = 'SUB'
+    opcode = 0b0001101
+
+
+class Mov2(ThumbInstruction):
+    """ mov rd, rm """
+    mnemonic = 'MOV'
+    def __init__(self, rd, rm):
+        self.rd = rd
+        self.rm = rm
+
+    @classmethod
+    def fromim(cls, im):
+        return cls(im.dst[0], im.src[0])
+
+    def encode(self):
+        at = ThumbToken()
+        at.rd = self.rd.num & 0x7
+        D = (self.rd.num >> 3) & 0x1
+        Rm = self.rm.num
+        opcode = 0b01000110
+        at[8:16] = opcode
+        at[3:7] = Rm
+        at[7] = D
+        return at.encode()
+
+    def __repr__(self):
+        return '{} {}, {}'.format(self.mnemonic, self.rd, self.rm)
+
+
+class Mul(ThumbInstruction):
+    """ mul Rn, Rdm """
+    mnemonic = 'MUL'
+    def __init__(self, rn, rdm):
+        self.rn = rn
+        self.rdm = rdm
+
+    @classmethod
+    def fromim(cls, im):
+        assert im.src[1] is im.dst[0]
+        return cls(im.src[0], im.dst[0])
+
+    def encode(self):
+        at = ThumbToken()
+        rn = self.rn.num
+        at.rd = self.rdm.num
+        opcode = 0b0100001101
+        #h = (opcode << 6) | (rn << 3) | rdm
+        at[6:16] = opcode
+        at[3:6] = rn
+        return at.encode()
+
+    def __repr__(self):
+        return '{} {}, {}'.format(self.mnemonic, self.rn, self.rdm)
+
+
+class regreg_base(ThumbInstruction):
+    """ ??? Rdn, Rm """
+    def __init__(self, rdn, rm):
+        self.rdn = rdn
+        self.rm = rm
+
+    @classmethod
+    def fromim(cls, im):
+        return cls(im.src[0], im.src[1])
+
+    def encode(self):
+        at = ThumbToken()
+        at.rd = self.rdn.num
+        rm = self.rm.num
+        at[3:6] = rm
+        at[6:16] = self.opcode
+        return at.encode()
+
+    def __repr__(self):
+        mnemonic = self.__class__.__name__
+        return '{} {}, {}'.format(mnemonic, self.rdn, self.rm)
+
+
+class movregreg_ins(regreg_base):
+    """ mov Rd, Rm (reg8 operands) """
+    opcode = 0
+
+
+class And(regreg_base):
+    opcode = 0b0100000000
+
+
+class Orr(regreg_base):
+    opcode = 0b0100001100
+
+
+class Cmp(regreg_base):
+    opcode = 0b0100001010
+
+
+class Lsl(regreg_base):
+    opcode = 0b0100000010
+
+
+class Cmp2(ThumbInstruction):
+    """ cmp Rn, imm8 """
+    opcode = 5 # 00101
+    def __init__(self, rn, imm):
+        self.rn = rn
+        self.imm = imm
+
+    def encode(self):
+        at = ThumbToken()
+        at[0:8] = self.imm
+        at[8:11] = self.rn.num
+        at[11:16] = self.opcode
+        return at.encode()
+
+
+# Jumping:
+
+class jumpBase_ins(ThumbInstruction):
+    def __init__(self, target_label):
+        assert type(target_label) is str
+        self.target = target_label
+        self.offset = 0
+
+    def __repr__(self):
+        mnemonic = self.__class__.__name__
+        return '{} {}'.format(mnemonic, self.target)
+
+
+class B(jumpBase_ins):
+    def encode(self):
+        h = (0b11100 << 11) | 0
+        # | 1 # 1 to enable thumb mode
+        return u16(h)
+
+    def relocations(self):
+        return [(self.target, 'wrap_new11')]
+
+class Bl(jumpBase_ins):
+    def encode(self):
+        imm11 = 0
+        imm10 = 0
+        j1 = 1 # TODO: what do these mean?
+        j2 = 1
+        s = 0
+        h1 = (0b11110 << 11) | (s << 10) | imm10 
+        h2 = (0b1101 << 12) | (j1 << 13) | (j2 << 11) | imm11
+        return u16(h1) + u16(h2)
+
+    def relocations(self):
+        return [(self.target, 'bl_imm11_imm10')]
+
+
+class cond_base_ins(jumpBase_ins):
+    def encode(self):
+        imm8 = 0
+        h = (0b1101 << 12) | (self.cond << 8) | imm8
+        return u16(h)
+
+    def relocations(self):
+        return [(self.target, 'rel8')]
+
+
+class cond_base_ins_long(jumpBase_ins):
+    """ Encoding T3 """
+    def encode(self):
+        j1 = 1 # TODO: what do these mean?
+        j2 = 1
+        h1 = (0b11110 << 11) | (self.cond << 6)
+        h2 = (0b1101 << 12) | (j1 << 13) | (j2 << 11)
+        return u16(h1) + u16(h2)
+
+    def relocations(self):
+        return [(self.target, 'b_imm11_imm6')]
+
+
+class Beq(cond_base_ins):
+    cond = 0
+
+
+class Bne(cond_base_ins):
+    cond = 1
+
+
+class Blt(cond_base_ins):
+    cond = 0b1011
+
+
+class Bgt(cond_base_ins):
+    cond = 0b1100
+
+
+class Push(ThumbInstruction):
+    def __init__(self, regs):
+        assert type(regs) is set
+        self.regs = regs
+
+    def __repr__(self):
+        return 'Push {{{}}}'.format(self.regs)
+
+    def encode(self):
+        at = ThumbToken()
+        for n in register_numbers(self.regs):
+            if n < 8:
+                at[n] = 1
+            elif n == 14:
+                at[8] = 1
+            else:
+                raise NotImplementedError('not implemented for {}'.format(n))
+        at[9:16] = 0x5a
+        return at.encode()
+
+
+
+def register_numbers(regs):
+    for r in regs:
+        yield r.num
+
+class Pop(ThumbInstruction):
+    def __init__(self, regs):
+        assert type(regs) is set
+        self.regs = regs
+        self.token = ThumbToken()
+
+    def __repr__(self):
+        return 'Pop {{{}}}'.format(self.regs)
+
+    def encode(self):
+        for n in register_numbers(self.regs):
+            if n < 8:
+                self.token[n] = 1
+            elif n == 15:
+                self.token[8] = 1
+            else:
+                raise NotImplementedError('not implemented for this register')
+        self.token[9:16] = 0x5E
+        return self.token.encode()
+
+
+
+class Yield(ThumbInstruction):
+    def encode(self):
+        return u16(0xbf10)
+
+# misc:
+
+# add/sub SP:
+class addspsp_base(ThumbInstruction):
+    def __init__(self, imm7):
+        self.imm7 = imm7
+        assert self.imm7 % 4 == 0
+        self.imm7 >>= 2
+
+    def encode(self):
+        return u16((self.opcode << 7) | self.imm7)
+
+    def __repr__(self):
+        mnemonic = self.__class__.__name__
+        return '{} sp, sp, {}'.format(mnemonic, self.imm7 << 2)
+
+
+class AddSp(addspsp_base):
+    opcode = 0b101100000
+
+
+class SubSp(addspsp_base):
+    opcode = 0b101100001
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/target/token.py	Sat Mar 01 15:40:31 2014 +0100
@@ -0,0 +1,56 @@
+
+import struct
+
+def u16(h):
+    return struct.pack('<H', h)
+
+
+def u32(x):
+    return struct.pack('<I', x)
+
+
+def val2bit(v, bits):
+    b = []
+    for i in range(bits):
+        b.append(bool((1<<i) & v))
+    #b.reverse()
+    return b
+
+
+def bit_range(b, e):
+    """ Property generator function """
+    getter = lambda s: s[b:e]
+    def setter(s, v):
+        s[b:e] = v
+    return property(getter, setter)
+
+
+class Token:
+    def __init__(self, bitsize):
+        self.bitsize = bitsize
+        self.bit_value = 0
+
+    def set_bit(self, i, value):
+        value = bool(value)
+        assert i in range(0, self.bitsize)
+        mask = 1 << i
+        if value:
+            self.bit_value |= mask
+        else:
+            self.bit_value &= (~mask)
+
+    def __getitem__(self, key):
+        return False
+
+    def __setitem__(self, key, value):
+        if type(key) is int:
+            self.set_bit(key, value)
+        elif type(key) is slice:
+            assert key.step is None
+            bits = key.stop - key.start
+            value_bits = val2bit(value, bits)
+            for i in range(key.start, key.stop):
+                self.set_bit(i, value_bits[i - key.start])
+        else:
+            raise KeyError()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/target/x86/target_x86.py	Sat Mar 01 15:40:31 2014 +0100
@@ -0,0 +1,66 @@
+from target import Register, Instruction, Target
+
+class x86Register(Register):
+   def __init__(self, name):
+      self.name = name
+
+class REG16(x86Register):
+   pass
+
+def addRegs(cls, names):
+   for name in names:
+      r = cls(name)
+      globals()[name] = r
+
+addRegs(REG16, ['ax', 'bx', 'cx'])
+
+regs = """
+ax; reg16
+"""
+
+class MO:
+   def __init__(self):
+      pass
+
+instrs = """
+add; 0x0; mem8/reg8; reg8
+"""
+
+# machine op table:
+mot = []
+
+for i in instrs.split('\n'):
+   i = i.strip()
+   if i:
+      print('INS:', i)
+      mnemonic, opcode, op1, op2 = [a.strip() for a in i.split(';')]
+      print(op1.split('/'), op2.split('/'))
+
+
+print(mot)
+
+# Test first with these 3 instructions:
+"""
+mov reg64, reg64 : opcode=0x89
+xor reg64, reg64 : opcode=0x31
+inc reg64 : opcode=0xff
+"""
+
+class x86Machine:
+   def __init__(self):
+      self.table = []
+      self.table.append((0x0, 'add', 'reg8/mem8, reg8'))
+      self.table.append((0x1, 'add', 'reg16/mem16/reg32/mem32, reg16/reg32'))
+      self.table.append((0x2, 'add', 'reg8, reg8/mem8'))
+   def forMnemonic(self, m):
+      return [i for i in self.table if i[1] == m]
+   def emit(self, m, ops):
+      print(m, ops)
+      ops = self.forMnemonic(m)
+      print(ops)
+
+
+if __name__ == '__main__':
+   m = x86Machine()
+   m.emit('add', [ax, cx])
+   m.emit('mov', [bx, 1337])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/target/x86/x86.py	Sat Mar 01 15:40:31 2014 +0100
@@ -0,0 +1,69 @@
+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))
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/target/x86/x86_2.py	Sat Mar 01 15:40:31 2014 +0100
@@ -0,0 +1,356 @@
+"""
+    X86 target descriptions and encodings.
+
+"""
+
+from target import Register, Instruction, Target, Imm8, Label, Imm3, LabelRef
+
+
+modrm = {'rax': 0, 'rbx': 1}
+
+# Table 3.1 of the intel manual:
+# use REX.W on the table below:
+regs64 = {'rax': 0,'rcx':1,'rdx':2,'rbx':3,'rsp':4,'rbp':5,'rsi':6,'rdi':7,'r8':0,'r9':1,'r10':2,'r11':3,'r12':4,'r13':5,'r14':6,'r15':7}
+regs32 = {'eax': 0, 'ecx':1, 'edx':2, 'ebx': 3, 'esp': 4, 'ebp': 5, 'esi':6, 'edi':7}
+regs8 = {'al':0,'cl':1,'dl':2,'bl':3,'ah':4,'ch':5,'dh':6,'bh':7}
+
+# Calculation of the rexb bit:
+rexbit = {'rax': 0, 'rcx':0, 'rdx':0, 'rbx': 0, 'rsp': 0, 'rbp': 0, 'rsi':0, 'rdi':0,'r8':1,'r9':1,'r10':1,'r11':1,'r12':1,'r13':1,'r14':1,'r15':1}
+
+# Helper functions:
+def imm64(x):
+   """ represent 64 bits integer in little endian 8 bytes"""
+   if x < 0:
+      x = x + (1 << 64)
+   x = x & 0xFFFFFFFFFFFFFFFF
+   return [ (x >> (p*8)) & 0xFF for p in range(8) ]
+
+def imm32(x):
+   """ represent 32 bits integer in little endian 4 bytes"""
+   if x < 0:
+      x = x + (1 << 32)
+   x = x & 0xFFFFFFFF
+   return [ (x >> (p*8)) & 0xFF for p in range(4) ]
+
+def imm8(x):
+   if x < 0:
+      x = x + (1 << 8)
+   x = x & 0xFF
+   return [ x ]
+
+def modrm(mod=0, rm=0, reg=0):
+   """ Construct the modrm byte from its components """
+   assert(mod <= 3)
+   assert(rm <= 7)
+   assert(reg <= 7)
+   return (mod << 6) | (reg << 3) | rm
+
+def rex(w=0, r=0, x=0, b=0):
+   """ Create a REX prefix byte """
+   assert(w <= 1)
+   assert(r <= 1)
+   assert(x <= 1)
+   assert(b <= 1)
+   return 0x40 | (w<<3) | (r<<2) | (x<<1) | b
+
+def sib(ss=0, index=0, base=0):
+   assert(ss <= 3)
+   assert(index <= 7)
+   assert(base <= 7)
+   return (ss << 6) | (index << 3) | base
+
+tttn = {'L':0xc,'G':0xf,'NE':0x5,'GE':0xd,'LE':0xe, 'E':0x4}
+
+# Actual instructions:
+def nearjump(distance, condition=None):
+   """ jmp imm32 """
+   lim = (1<<30)
+   if abs(distance) > lim:
+      Error('near jump cannot jump over more than {0} bytes'.format(lim))
+   if condition:
+      if distance < 0:
+         distance -= 6 # Skip own instruction
+      opcode = 0x80 | tttn[condition] # Jcc imm32
+      return [0x0F, opcode] + imm32(distance)
+   else:
+      if distance < 0:
+         distance -= 5 # Skip own instruction
+      return [ 0xE9 ] + imm32(distance)
+
+def shortjump(distance, condition=None):
+   """ jmp imm8 """
+   lim = 118
+   if abs(distance) > lim:
+      Error('short jump cannot jump over more than {0} bytes'.format(lim))
+   if distance < 0:
+      distance -= 2 # Skip own instruction
+   if condition:
+      opcode = 0x70 | tttn[condition] # Jcc rel8
+   else:
+      opcode = 0xeb # jmp rel8
+   return [opcode] + imm8(distance)
+
+# Helper that determines jump type:
+def reljump(distance):
+   if abs(distance) < 110:
+      return shortjump(distance)
+   else:
+      return nearjump(distance)
+
+def push(reg):
+   if reg in regs64:
+      if rexbit[reg] == 1:
+         return [0x41, 0x50 + regs64[reg]]
+      else:
+         return [0x50 + regs64[reg]]
+   else:
+      Error('push for {0} not implemented'.format(reg))
+
+def pop(reg):
+   if reg in regs64:
+      if rexbit[reg] == 1:
+         rexprefix = rex(b=1)
+         opcode = 0x58 + regs64[reg]
+         return [rexprefix, opcode]
+      else:
+         opcode = 0x58 + regs64[reg]
+         return [ opcode ]
+   else:
+      Error('pop for {0} not implemented'.format(reg))
+
+def INT(number):
+   opcode = 0xcd
+   return [opcode] + imm8(number)
+
+def syscall():
+   return [0x0F, 0x05]
+
+def call(distance):
+   if type(distance) is int:
+      return [0xe8]+imm32(distance)
+   elif type(distance) is str and distance in regs64:
+      reg = distance
+      opcode = 0xFF # 0xFF /2 == call r/m64
+      mod_rm = modrm(mod=3, reg=2, rm=regs64[reg])
+      if rexbit[reg] == 1:
+         rexprefix = rex(b=rexbit[reg])
+         return [rexprefix, opcode, mod_rm]
+      else:
+         return [opcode, mod_rm]
+   else:
+      Error('Cannot call to {0}'.format(distance))
+
+def ret():
+   return [ 0xc3 ]
+
+def increg64(reg):
+   assert(reg in regs64)
+   rexprefix = rex(w=1, b=rexbit[reg])
+   opcode = 0xff
+   mod_rm = modrm(mod=3, rm=regs64[reg])
+   return [rexprefix, opcode, mod_rm]
+
+def prepost8(r8, rm8):
+   assert(r8 in regs8)
+   pre = []
+   if type(rm8) is list:
+      # TODO: merge mem access with prepost for 64 bits
+      if len(rm8) == 1:
+         base, = rm8
+         if type(base) is str and base in regs64:
+            assert(not base in ['rbp', 'rsp', 'r12', 'r13'])
+            mod_rm = modrm(mod=0, rm=regs64[base], reg=regs8[r8])
+            if rexbit[base] == 1:
+               pre.append(rex(b=1))
+            post = [mod_rm]
+         else:
+            Error('One arg of type {0} not implemented'.format(base))
+      elif len(rm8) == 2:
+         base, offset = rm8
+         assert(type(offset) is int)
+         assert(base in regs64)
+
+         if base == 'rsp' or base == 'r12':
+            Error('Cannot use rsp or r12 as base yet')
+         if rexbit[base] == 1:
+            pre.append( rex(b=1) )
+         mod_rm = modrm(mod=1, rm=regs64[base], reg=regs8[r8])
+         post = [mod_rm] + imm8(offset)
+      else:
+         Error('not supporting prepost8 with list len {0}'.format(len(rm8)))
+   else:
+      Error('Not supporting move with reg8 {0}'.format(r8))
+   return pre, post
+
+def prepost(r64, rm64):
+   assert(r64 in regs64)
+   if type(rm64) is list:
+      if len(rm64) == 3:
+            base, index, disp = rm64
+            assert(base in regs64)
+            assert(index in regs64)
+            assert(type(disp) is int)
+            # Assert that no special cases are used:
+            # TODO: swap base and index to avoid special cases
+            # TODO: exploit special cases and make better code
+            assert(index != 'rsp')
+
+            rexprefix = rex(w=1, r=rexbit[r64], x=rexbit[index], b=rexbit[base])
+            # mod=1 and rm=4 indicates a SIB byte: [--][--]+imm8
+            mod_rm = modrm(mod=1, rm=4, reg=regs64[r64])
+            si_b = sib(ss=0, index=regs64[index], base=regs64[base])
+            return [rexprefix], [mod_rm, si_b] + imm8(disp)
+      elif len(rm64) == 2:
+         base, offset = rm64
+         assert(type(offset) is int)
+         if base == 'RIP':
+            # RIP pointer relative addressing mode!
+            rexprefix = rex(w=1, r=rexbit[r64])
+            mod_rm = modrm(mod=0, rm=5, reg=regs64[r64])
+            return [rexprefix], [mod_rm] + imm32(offset)
+         else:
+            assert(base in regs64)
+
+            if base == 'rsp' or base == 'r12':
+               # extended function that uses SIB byte
+               rexprefix = rex(w=1, r=rexbit[r64], b=rexbit[base])
+               # rm=4 indicates a SIB byte follows
+               mod_rm = modrm(mod=1, rm=4, reg=regs64[r64])
+               # index=4 indicates that index is not used
+               si_b = sib(ss=0, index=4, base=regs64[base])
+               return [rexprefix], [mod_rm, si_b] + imm8(offset)
+            else:
+               rexprefix = rex(w=1, r=rexbit[r64], b=rexbit[base])
+               mod_rm = modrm(mod=1, rm=regs64[base], reg=regs64[r64])
+               return [rexprefix], [mod_rm] + imm8(offset)
+      elif len(rm64) == 1:
+         offset = rm64[0]
+         if type(offset) is int:
+            rexprefix = rex(w=1, r=rexbit[r64])
+            mod_rm = modrm(mod=0, rm=4,reg=regs64[r64])
+            si_b = sib(ss=0, index=4,base=5) # 0x25
+            return [rexprefix], [mod_rm, si_b] + imm32(offset)
+         else:
+            Error('Memory reference of type {0} not implemented'.format(offset))
+      else:
+         Error('Memory reference not implemented')
+   elif rm64 in regs64:
+      rexprefix = rex(w=1, r=rexbit[r64], b=rexbit[rm64])
+      mod_rm = modrm(3, rm=regs64[rm64], reg=regs64[r64])
+      return [rexprefix], [mod_rm]
+
+def leareg64(rega, m):
+   opcode = 0x8d # lea r64, m
+   pre, post = prepost(rega, m)
+   return pre + [opcode] + post
+
+def mov(rega, regb):
+   if type(regb) is int:
+      pre = [rex(w=1, b=rexbit[rega])]
+      opcode = 0xb8 + regs64[rega]
+      post = imm64(regb)
+   elif type(regb) is str:
+      if regb in regs64:
+         opcode = 0x89 # mov r/m64, r64
+         pre, post = prepost(regb, rega)
+      elif regb in regs8:
+         opcode = 0x88 # mov r/m8, r8
+         pre, post = prepost8(regb, rega)
+      else:
+         Error('Unknown register {0}'.format(regb))
+   elif type(rega) is str:
+      if rega in regs64:
+         opcode = 0x8b # mov r64, r/m64
+         pre, post = prepost(rega, regb)
+      else:
+         Error('Unknown register {0}'.format(rega))
+   else:
+      Error('Move of this kind {0}, {1} not implemented'.format(rega, regb))
+   return pre + [opcode] + post
+
+def xorreg64(rega, regb):
+   rexprefix = rex(w=1, r=rexbit[regb], b=rexbit[rega])
+   opcode = 0x31 # XOR r/m64, r64
+   # Alternative is 0x33 XOR r64, r/m64
+   mod_rm = modrm(3, rm=regs64[rega], reg=regs64[regb])
+   return [rexprefix, opcode, mod_rm]
+
+# integer arithmatic:
+def addreg64(rega, regb):
+   if regb in regs64:
+      pre, post = prepost(regb, rega)
+      opcode = 0x01 # ADD r/m64, r64
+      return pre + [opcode] + post
+   elif type(regb) is int:
+      if regb < 100:
+         rexprefix = rex(w=1, b=rexbit[rega])
+         opcode = 0x83 # add r/m, imm8
+         mod_rm = modrm(3, rm=regs64[rega], reg=0)
+         return [rexprefix, opcode, mod_rm]+imm8(regb)
+      elif regb < (1<<31):
+         rexprefix = rex(w=1, b=rexbit[rega])
+         opcode = 0x81 # add r/m64, imm32
+         mod_rm = modrm(3, rm=regs64[rega], reg=0)
+         return [rexprefix, opcode, mod_rm]+imm32(regb)
+      else:
+         Error('Constant value too large!')
+   else:
+      Error('unknown second operand!'.format(regb))
+
+def subreg64(rega, regb):
+   if regb in regs64:
+      pre, post = prepost(regb, rega)
+      opcode = 0x29 # SUB r/m64, r64
+      return pre + [opcode] + post
+   elif type(regb) is int:
+      if regb < 100:
+         rexprefix = rex(w=1, b=rexbit[rega])
+         opcode = 0x83 # sub r/m, imm8
+         mod_rm = modrm(3, rm=regs64[rega], reg=5)
+         return [rexprefix, opcode, mod_rm]+imm8(regb)
+      elif regb < (1<<31):
+         rexprefix = rex(w=1, b=rexbit[rega])
+         opcode = 0x81 # sub r/m64, imm32
+         mod_rm = modrm(3, rm=regs64[rega], reg=5)
+         return [rexprefix, opcode, mod_rm]+imm32(regb)
+      else:
+         Error('Constant value too large!')
+
+   else:
+      Error('unknown second operand!'.format(regb))
+
+def idivreg64(reg):
+   rexprefix = rex(w=1, b=rexbit[reg])
+   opcode = 0xf7 # IDIV r/m64
+   mod_rm = modrm(3, rm=regs64[reg], reg=7)
+   return [rexprefix, opcode, mod_rm]
+
+def imulreg64_rax(reg):
+   rexprefix = rex(w=1, b=rexbit[reg])
+   opcode = 0xf7 # IMUL r/m64
+   mod_rm = modrm(3, rm=regs64[reg], reg=5)
+   return [rexprefix, opcode, mod_rm]
+
+def imulreg64(rega, regb):
+   pre, post = prepost(rega, regb)
+   opcode = 0x0f # IMUL r64, r/m64
+   opcode2 = 0xaf
+   return pre + [opcode, opcode2] + post
+
+def cmpreg64(rega, regb):
+   if regb in regs64:
+      pre, post = prepost(regb, rega)
+      opcode = 0x39 # CMP r/m64, r64
+      return pre + [opcode] + post
+   elif type(regb) is int:
+      rexprefix = rex(w=1, b=rexbit[rega])
+      opcode = 0x83 # CMP r/m64, imm8
+      mod_rm = modrm(3, rm=regs64[rega], reg=7)
+      return [rexprefix, opcode, mod_rm] + imm8(regb)
+      
+   else:
+      Error('not implemented cmp64')
+
+# Mapping that maps string names to the right functions:
+opcodes = {'mov':(mov,2), 'lea':(leareg64,2), 'int':(INT,1), 'syscall':(syscall,0)}
+
--- a/python/ppci/tasks.py	Fri Feb 28 18:07:14 2014 +0100
+++ b/python/ppci/tasks.py	Sat Mar 01 15:40:31 2014 +0100
@@ -1,3 +1,7 @@
+"""
+    This module defines tasks and a runner for these tasks. Tasks can
+    have dependencies and it can be determined if they need to be run.
+"""
 
 import logging
 
@@ -9,31 +13,49 @@
     """ Task that can run, and depend on other tasks """
     def __init__(self, name):
         self.name = name
-        self.subtasks = []
         self.completed = False
-        self.dependencies = []
+        self.dependencies = set()
         self.duration = 1
 
     def run(self):
         raise NotImplementedError("Implement this abstract method!")
 
     def fire(self):
+        """ Wrapper around run that marks the task as done """
         assert all(t.completed for t in self.dependencies)
         self.run()
         self.completed = True
 
-    def addSubTask(self, tsk):
-        self.subtasks.append(tsk)
-        return tsk
+    def add_dependency(self, task):
+        """ Add another task as a dependency for this task """
+        if task is self:
+            raise TaskError('Can not add dependency on task itself!')
+        if self in task.down_stream_tasks:
+            raise TaskError('Can not introduce circular task')
+        self.dependencies.add(task)
+        return task
 
-    def addDependency(self, task):
-        self.dependencies.append(task)
-        return task
+    @property
+    def down_stream_tasks(self):
+        """ Return a set of all tasks that follow this task """
+        # TODO: is this upstream or downstream???
+        cdst = list(dep.down_stream_tasks for dep in self.dependencies)
+        cdst.append(self.dependencies)
+        return set.union(*cdst)
+
+    def __gt__(self, other):
+        return other in self.down_stream_tasks
 
     def __repr__(self):
         return 'Task "{}"'.format(self.name)
 
 
+class EmptyTask(Task):
+    """ Basic task that does nothing """
+    def run(self):
+        pass
+
+
 class TaskRunner:
     """ Basic task runner that can run some tasks in sequence """
     def __init__(self):
@@ -48,6 +70,10 @@
         return sum(t.duration for t in self.task_list)
 
     def run_tasks(self):
+        # First sort tasks:
+        self.task_list.sort()
+
+        # Run tasks:
         passed_time = 0.0
         total_time = self.total_duration
         try:
@@ -56,7 +82,7 @@
                 t.fire()
                 passed_time += t.duration
         except TaskError as e:
-            print('Error: {}'.format(e))
+            self.logger.error(str(e.msg))
             return 1
         self.report_progress(1, 'OK')
         return 0
--- a/python/target/__init__.py	Fri Feb 28 18:07:14 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-#!/usr/bin/env python
-
-from .basetarget import Nop, Instruction, Label, Target, Comment, Alignment
-from .basetarget import Imm32, DebugInfo
-
-
-class SimpleTarget(Target):
-    def __init__(self):
-        super().__init__('SimpleTarget')
--- a/python/target/arm.brg	Fri Feb 28 18:07:14 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-
-from target.basetarget import Label, Comment, Alignment, LabelRef, DebugInfo, Nop
-from target.arminstructions import Orr, Lsl, Str2, Ldr2, Ldr3
-from target.arminstructions import B, Bl, Bgt, Blt, Beq, Bne
-from target.arminstructions import Mov2, Mov3
-from target.arminstructions import Add3, Sub, Cmp, Sub2, Add2, Mul
-from ppci import ir
-
-%%
-
-%terminal ADDI32 SUBI32 MULI32
-%terminal ORI32 SHLI32
-%terminal CONSTI32 MEMI32 REGI32 CALL
-%terminal MOVI32
-
-%%
-
-
-reg: ADDI32(reg, reg) 2 (. d = self.newTmp(); self.emit(Add3, dst=[d], src=[$1, $2]); return d .)
-reg: SUBI32(reg, reg) 2 (. d = self.newTmp(); self.emit(Sub, dst=[d], src=[$1, $2]); return d .)
-reg: ORI32(reg, reg)  2 (. d = self.newTmp(); self.selector.move(d, $1); self.emit(Orr, dst=[], src=[d, $2]); return d .)
-reg: SHLI32(reg, reg) 2 (. d = self.newTmp(); self.selector.move(d, $1); self.emit(Lsl, dst=[], src=[d, $2]); return d .)
-reg: MULI32(reg, reg) 2 (. d = self.newTmp(); self.selector.move(d, $1); self.emit(Mul, dst=[d], src=[$2, d]); return d .)
-
-reg: CONSTI32         3 (. d = self.newTmp(); ln = LabelRef(self.selector.frame.addConstant($$.value)); self.emit(Ldr3, dst=[d], others=[ln]); return d .)
-reg: MEMI32(reg)      4 (. d = self.newTmp(); self.emit(Ldr2, dst=[d], src=[$1], others=[0]); return d .)
-reg: REGI32           1 (. return $$.value .)
-reg: CALL             1 (. return self.selector.munchCall($$.value) .)
-
-
-stmt: MOVI32(MEMI32(addr), reg) 3 (. self.emit(Str2, src=[$1, $2]) .)
-
-addr: reg 2 (. .)
--- a/python/target/armframe.py	Fri Feb 28 18:07:14 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-from ppci import ir
-from .basetarget import Label, Comment, Alignment, LabelRef, DebugInfo, Nop
-from .basetarget import Imm7
-from ppci.irmach import makeIns, Frame
-from .arminstructions import Dcd, AddSp, SubSp, Push, Pop, Mov2
-from .armregisters import R0, R1, R2, R3, R4, R5, R6, R7, LR, PC, SP
-
-
-class ArmFrame(Frame):
-    """ Arm specific frame for functions. """
-    def __init__(self, name):
-        # We use r7 as frame pointer.
-        super().__init__(name)
-        self.regs = [R0, R1, R2, R3, R4, R5, R6]
-        self.rv = ir.Temp('special_RV')
-        self.p1 = ir.Temp('special_P1')
-        self.p2 = ir.Temp('special_P2')
-        self.p3 = ir.Temp('special_P3')
-        self.p4 = ir.Temp('special_P4')
-        self.fp = ir.Temp('special_FP')
-        # Pre-colored registers:
-        self.tempMap = {}
-        self.tempMap[self.rv] = R0
-        self.tempMap[self.p1] = R1
-        self.tempMap[self.p2] = R2
-        self.tempMap[self.p3] = R3
-        self.tempMap[self.p4] = R4
-        self.tempMap[self.fp] = R7
-        self.locVars = {}
-        self.parMap = {}
-        # Literal pool:
-        self.constants = []
-
-    def argLoc(self, pos):
-        """
-            Gets the function parameter location in IR-code format.
-        """
-        if pos == 0:
-            return self.p1
-        elif pos == 1:
-            return self.p2
-        elif pos == 2:
-            return self.p3
-        elif pos == 3:
-            return self.p4
-        else:
-            raise NotImplementedError('No more than 4 parameters implemented')
-
-    def allocVar(self, lvar):
-        if lvar not in self.locVars:
-            self.locVars[lvar] = self.stacksize
-            self.stacksize = self.stacksize + 4
-        return self.locVars[lvar]
-
-    def addConstant(self, value):
-        lab_name = '{}_literal_{}'.format(self.name, len(self.constants))
-        self.constants.append((lab_name, value))
-        return lab_name
-
-    def prologue(self):
-        """ Returns prologue instruction sequence """
-        pre = [
-            Label(self.name),                     # Label indication function
-            Push({LR, R7})
-            ]
-        if self.stacksize > 0:
-            pre.append(SubSp(self.stacksize))  # Reserve stack space
-        pre += [
-            Mov2(R7, SP)                          # Setup frame pointer
-            ]
-        return pre
-
-    def epilogue(self):
-        """ Return epilogue sequence for a frame. Adjust frame pointer and add constant pool """
-        post = []
-        if self.stacksize > 0:
-            post.append(AddSp(self.stacksize))
-        post += [
-            Pop({PC, R7}),
-            Alignment(4)   # Align at 4 bytes
-            ]
-        # Add constant literals:
-        for ln, v in self.constants:
-            post.extend([Label(ln), Dcd(v)])
-        return post
-
-    def EntryExitGlue3(self):
-        """
-            Add code for the prologue and the epilogue. Add a label, the
-            return instruction and the stack pointer adjustment for the frame.
-        """
-        for index, ins in enumerate(self.prologue()):
-            self.instructions.insert(index, makeIns(ins))
-
-        # Postfix code:
-        for ins in self.epilogue():
-            self.instructions.append(makeIns(ins))
--- a/python/target/arminstructions.py	Fri Feb 28 18:07:14 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,576 +0,0 @@
-import struct
-from ppci.asmnodes import ASymbol, AInstruction, ANumber, AUnop, ABinop
-from .basetarget import Register, Instruction, Target, Label, LabelRef
-from .basetarget import Imm32, Imm8, Imm7, Imm3
-
-from .armtoken import ThumbToken, ArmToken
-from .armregisters import R0, ArmRegister, SP
-
-
-
-def u16(h):
-    return struct.pack('<H', h)
-
-def u32(x):
-    return struct.pack('<I', x)
-
-
-arm_assembly_rules = []
-
-
-# Operands:
-
-
-
-class RegSpOp:
-    @classmethod
-    def Create(cls, vop):
-        if type(vop) is ASymbol:
-            if vop.name.lower() == 'sp':
-                return cls()
-
-
-def getRegNum(n):
-    for r in registers:
-        if r.num == n:
-            return r
-
-
-def getRegisterRange(n1, n2):
-    regs = []
-    if n1.num < n2.num:
-        for n in range(n1.num, n2.num + 1):
-            r = getRegNum(n)
-            assert r
-            regs.append(r)
-    return regs
-
-
-def isRegOffset(regname, x, y):
-    if type(x) is ASymbol and type(y) is ANumber and x.name.upper() == regname:
-        return y.number
-    elif type(y) is ASymbol and type(x) is ANumber and y.name.upper() == regname:
-        return x.number
-
-
-
-# Instructions:
-
-class ThumbInstruction(Instruction):
-    pass
-
-
-
-class Dcd(ThumbInstruction):
-    def __init__(self, expr):
-        if isinstance(expr, Imm32):
-            self.expr = expr.imm
-            self.label = None
-        elif isinstance(expr, LabelRef):
-            self.expr = 0
-            self.label = expr
-        elif isinstance(expr, int):
-            self.expr = expr
-            self.label = None
-        else:
-            raise NotImplementedError()
-
-    def encode(self):
-        return u32(self.expr)
-
-    def relocations(self):
-        assert not isinstance(self.expr, LabelRef)
-        return []
-
-    def __repr__(self):
-        return 'DCD 0x{0:X}'.format(self.expr)
-
-
-class nop_ins(ThumbInstruction):
-    def encode(self):
-        return bytes()
-
-    def __repr__(self):
-        return 'NOP'
-
-
-# Memory related
-
-class LS_imm5_base(ThumbInstruction):
-    """ ??? Rt, [Rn, imm5] """
-    def __init__(self, rt, rn, imm5):
-        assert imm5 % 4 == 0
-        self.imm5 = imm5 >> 2
-        self.rn = rn
-        self.rt = rt
-        assert self.rn.num < 8
-        assert self.rt.num < 8
-        self.token = ThumbToken()
-
-    def encode(self):
-        Rn = self.rn.num
-        Rt = self.rt.num
-        imm5 = self.imm5
-        self.token[0:3] = Rt
-        self.token[3:6] = Rn
-        self.token[6:11] = imm5
-        self.token[11:16] = self.opcode
-        return self.token.encode()
-
-    def __repr__(self):
-        mnemonic = "???"
-        return '{} {}, [{}, {}]'.format(mnemonic, self.rt, self.rn, self.imm5)
-
-
-class Str2(LS_imm5_base):
-    opcode = 0xC
-
-    @classmethod
-    def fromim(cls, im):
-        return cls(im.src[1], im.src[0], im.others[0])
-
-
-class Ldr2(LS_imm5_base):
-    opcode = 0xD
-
-    @classmethod
-    def fromim(cls, im):
-        return cls(im.dst[0], im.src[0], im.others[0])
-
-class ls_sp_base_imm8(ThumbInstruction):
-    def __init__(self, rt, offset):
-        self.rt = rt
-        self.offset = offset
-
-    def encode(self):
-        rt = self.rt.num
-        assert rt < 8
-        imm8 = self.offset >> 2
-        assert imm8 < 256
-        h = (self.opcode << 8) | (rt << 8) | imm8
-        return u16(h)
-
-    def __repr__(self):
-        mnemonic = self.__class__.__name__
-        return '{} {}, [sp,#{}]'.format(mnemonic, self.rt, self.offset)
-
-def align(x, m):
-    while ((x % m) != 0):
-        x = x + 1
-    return x
-
-def Ldr(*args):
-    if len(args) == 2 and isinstance(args[0], ArmRegister) \
-            and isinstance(args[1], str):
-        return Ldr3(*args)
-    else:
-        raise Exception()
-
-
-class Ldr3(ThumbInstruction):
-    """ ldr Rt, LABEL, load value from pc relative position """
-    mnemonic = 'ldr'
-    def __init__(self, rt, label):
-        self.rt = rt
-        self.label = label
-
-    @classmethod
-    def fromim(cls, im):
-        return cls(im.dst[0], im.others[0])
-
-    def relocations(self):
-        return [(self.label, 'lit_add_8')]
-
-    def encode(self):
-        rt = self.rt.num
-        assert rt < 8
-        imm8 = 0
-        h = (0x9 << 11) | (rt << 8) | imm8
-        return u16(h)
-
-    def __repr__(self):
-        return 'LDR {}, {}'.format(self.rt, self.label)
-
-
-class Ldr1(ls_sp_base_imm8):
-    """ ldr Rt, [SP, imm8] """
-    opcode = 0x98
-
-
-class Str1(ls_sp_base_imm8):
-    """ str Rt, [SP, imm8] """
-    opcode = 0x90
-
-
-class Mov3(ThumbInstruction):
-    """ mov Rd, imm8, move immediate value into register """
-    opcode = 4 # 00100 Rd(3) imm8
-    def __init__(self, rd, imm):
-        assert imm < 256
-        self.imm = imm
-        self.rd = rd
-        self.token = ThumbToken()
-
-    @classmethod
-    def fromim(cls, im):
-        return cls(im.dst[0], im.others[0])
-
-    def encode(self):
-        rd = self.rd.num
-        self.token[8:11] = rd
-        self.token[0:8] = self.imm
-        self.token[11:16] = self.opcode
-        return self.token.encode()
-
-    def __repr__(self):
-        return 'MOV {}, {}'.format(self.rd, self.imm)
-
-
-
-# Arithmatics:
-
-
-
-class regregimm3_base(ThumbInstruction):
-    def __init__(self, rd, rn, imm3):
-        self.rd = rd
-        self.rn = rn
-        assert imm3 < 8
-        self.imm3 = imm3
-        self.token = ThumbToken()
-
-    @classmethod
-    def fromim(cls, im):
-        return cls(im.dst[0], im.src[0], im.others[0])
-
-    def encode(self):
-        rd = self.rd.num
-        self.token[0:3] = rd
-        self.token[3:6] = self.rn.num
-        self.token[6:9] = self.imm3
-        self.token[9:16] = self.opcode
-        return self.token.encode()
-
-    def __repr__(self):
-        mnemonic = self.__class__.__name__
-        return '{} {}, {}, {}'.format(mnemonic, self.rd, self.rn, self.imm3)
-
-
-
-class Add2(regregimm3_base):
-    """ add Rd, Rn, imm3 """
-    opcode = 0b0001110
-
-
-class Sub2(regregimm3_base):
-    """ sub Rd, Rn, imm3 """
-    opcode = 0b0001111
-
-
-def Sub(*args):
-    if len(args) == 3 and args[0] is SP and args[1] is SP and \
-            isinstance(args[2], int) and args[2] < 256:
-        return SubSp(args[2])
-    elif len(args) == 3 and isinstance(args[0], ArmRegister) and \
-            isinstance(args[1], ArmRegister) and isinstance(args[2], int) and \
-            args[2] < 8:
-        return Sub2(args[0], args[1], args[2])
-    else:
-        raise Exception()
-
-class regregreg_base(ThumbInstruction):
-    """ ??? Rd, Rn, Rm """
-    def __init__(self, rd, rn, rm):
-        self.rd = rd
-        self.rn = rn
-        self.rm = rm
-
-    @classmethod
-    def fromim(cls, im):
-        return cls(im.dst[0], im.src[0], im.src[1])
-
-    def encode(self):
-        at = ThumbToken()
-        at.rd = self.rd.num
-        rn = self.rn.num
-        rm = self.rm.num
-        at[3:6] = rn
-        at[6:9] = rm
-        at[9:16] = self.opcode
-        return at.encode()
-
-    def __repr__(self):
-        return '{} {}, {}, {}'.format(self.mnemonic, self.rd, self.rn, self.rm)
-
-
-class Add3(regregreg_base):
-    mnemonic = 'ADD'
-    opcode = 0b0001100
-
-
-class Sub3(regregreg_base):
-    mnemonic = 'SUB'
-    opcode = 0b0001101
-
-
-class Mov2(ThumbInstruction):
-    """ mov rd, rm """
-    mnemonic = 'MOV'
-    def __init__(self, rd, rm):
-        self.rd = rd
-        self.rm = rm
-
-    @classmethod
-    def fromim(cls, im):
-        return cls(im.dst[0], im.src[0])
-
-    def encode(self):
-        at = ThumbToken()
-        at.rd = self.rd.num & 0x7
-        D = (self.rd.num >> 3) & 0x1
-        Rm = self.rm.num
-        opcode = 0b01000110
-        at[8:16] = opcode
-        at[3:7] = Rm
-        at[7] = D
-        return at.encode()
-
-    def __repr__(self):
-        return '{} {}, {}'.format(self.mnemonic, self.rd, self.rm)
-
-
-class Mul(ThumbInstruction):
-    """ mul Rn, Rdm """
-    mnemonic = 'MUL'
-    def __init__(self, rn, rdm):
-        self.rn = rn
-        self.rdm = rdm
-
-    @classmethod
-    def fromim(cls, im):
-        assert im.src[1] is im.dst[0]
-        return cls(im.src[0], im.dst[0])
-
-    def encode(self):
-        at = ThumbToken()
-        rn = self.rn.num
-        at.rd = self.rdm.num
-        opcode = 0b0100001101
-        #h = (opcode << 6) | (rn << 3) | rdm
-        at[6:16] = opcode
-        at[3:6] = rn
-        return at.encode()
-
-    def __repr__(self):
-        return '{} {}, {}'.format(self.mnemonic, self.rn, self.rdm)
-
-
-class regreg_base(ThumbInstruction):
-    """ ??? Rdn, Rm """
-    def __init__(self, rdn, rm):
-        self.rdn = rdn
-        self.rm = rm
-
-    @classmethod
-    def fromim(cls, im):
-        return cls(im.src[0], im.src[1])
-
-    def encode(self):
-        at = ThumbToken()
-        at.rd = self.rdn.num
-        rm = self.rm.num
-        at[3:6] = rm
-        at[6:16] = self.opcode
-        return at.encode()
-
-    def __repr__(self):
-        mnemonic = self.__class__.__name__
-        return '{} {}, {}'.format(mnemonic, self.rdn, self.rm)
-
-
-class movregreg_ins(regreg_base):
-    """ mov Rd, Rm (reg8 operands) """
-    opcode = 0
-
-
-class And(regreg_base):
-    opcode = 0b0100000000
-
-
-class Orr(regreg_base):
-    opcode = 0b0100001100
-
-
-class Cmp(regreg_base):
-    opcode = 0b0100001010
-
-
-class Lsl(regreg_base):
-    opcode = 0b0100000010
-
-
-class cmpregimm8_ins(ThumbInstruction):
-    """ cmp Rn, imm8 """
-    opcode = 5 # 00101
-    def __init__(self, rn, imm):
-        self.rn = rn
-        self.imm = imm
-
-    def encode(self):
-        at = ThumbToken()
-        at[0:8] = self.imm.imm
-        at[8:11] = self.rn.num
-        at[11:16] = self.opcode
-        return at.encode()
-
-
-# Jumping:
-
-class jumpBase_ins(ThumbInstruction):
-    def __init__(self, target_label):
-        self.target = target_label
-        self.offset = 0
-
-    def __repr__(self):
-        mnemonic = self.__class__.__name__
-        return '{} {}'.format(mnemonic, self.target)
-
-
-class B(jumpBase_ins):
-    def encode(self):
-        h = (0b11100 << 11) | 0
-        # | 1 # 1 to enable thumb mode
-        return u16(h)
-
-    def relocations(self):
-        return [(self.target, 'wrap_new11')]
-
-class Bl(jumpBase_ins):
-    def encode(self):
-        imm11 = 0
-        imm10 = 0
-        j1 = 1 # TODO: what do these mean?
-        j2 = 1
-        s = 0
-        h1 = (0b11110 << 11) | (s << 10) | imm10 
-        h2 = (0b1101 << 12) | (j1 << 13) | (j2 << 11) | imm11
-        return u16(h1) + u16(h2)
-
-    def relocations(self):
-        return [(self.target, 'bl_imm11_imm10')]
-
-
-class cond_base_ins(jumpBase_ins):
-    def encode(self):
-        imm8 = 0
-        h = (0b1101 << 12) | (self.cond << 8) | imm8
-        return u16(h)
-
-    def relocations(self):
-        return [(self.target, 'rel8')]
-
-
-class cond_base_ins_long(jumpBase_ins):
-    """ Encoding T3 """
-    def encode(self):
-        j1 = 1 # TODO: what do these mean?
-        j2 = 1
-        h1 = (0b11110 << 11) | (self.cond << 6)
-        h2 = (0b1101 << 12) | (j1 << 13) | (j2 << 11)
-        return u16(h1) + u16(h2)
-
-    def relocations(self):
-        return [(self.target, 'b_imm11_imm6')]
-
-
-class Beq(cond_base_ins):
-    cond = 0
-
-
-class Bne(cond_base_ins):
-    cond = 1
-
-
-class Blt(cond_base_ins):
-    cond = 0b1011
-
-
-class Bgt(cond_base_ins):
-    cond = 0b1100
-
-
-class Push(ThumbInstruction):
-    def __init__(self, regs):
-        assert type(regs) is set
-        self.regs = regs
-
-    def __repr__(self):
-        return 'Push {{{}}}'.format(self.regs)
-
-    def encode(self):
-        at = ThumbToken()
-        for n in register_numbers(self.regs):
-            if n < 8:
-                at[n] = 1
-            elif n == 14:
-                at[8] = 1
-            else:
-                raise NotImplementedError('not implemented for {}'.format(n))
-        at[9:16] = 0x5a
-        return at.encode()
-
-
-
-def register_numbers(regs):
-    for r in regs:
-        yield r.num
-
-class Pop(ThumbInstruction):
-    def __init__(self, regs):
-        assert type(regs) is set
-        self.regs = regs
-        self.token = ThumbToken()
-
-    def __repr__(self):
-        return 'Pop {{{}}}'.format(self.regs)
-
-    def encode(self):
-        for n in register_numbers(self.regs):
-            if n < 8:
-                self.token[n] = 1
-            elif n == 15:
-                self.token[8] = 1
-            else:
-                raise NotImplementedError('not implemented for this register')
-        self.token[9:16] = 0x5E
-        return self.token.encode()
-
-
-
-class Yield(ThumbInstruction):
-    def encode(self):
-        return u16(0xbf10)
-
-# misc:
-
-# add/sub SP:
-class addspsp_base(ThumbInstruction):
-    def __init__(self, imm7):
-        self.imm7 = imm7
-        assert self.imm7 % 4 == 0
-        self.imm7 >>= 2
-
-    def encode(self):
-        return u16((self.opcode << 7) | self.imm7)
-
-    def __repr__(self):
-        mnemonic = self.__class__.__name__
-        return '{} sp, sp, {}'.format(mnemonic, self.imm7 << 2)
-
-
-class AddSp(addspsp_base):
-    opcode = 0b101100000
-
-
-class SubSp(addspsp_base):
-    opcode = 0b101100001
--- a/python/target/arminstructionselector.py	Fri Feb 28 18:07:14 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-import os
-from ppci import ir, same_dir
-from ppci.irmach import AbstractInstruction as makeIns
-from ppci.ir2tree import makeTree
-import pyburg
-from .basetarget import Label, Comment, Alignment, LabelRef, DebugInfo, Nop
-from .instructionselector import InstructionSelector
-from .arminstructions import Orr, Lsl, Str2, Ldr2, Ldr3
-from .arminstructions import B, Bl, Bgt, Blt, Beq, Bne
-from .arminstructions import Mov2, Mov3
-from .arminstructions import Cmp, Sub2, Mul
-from .basetarget import Imm8, Imm7, Imm3
-
-# Import BURG spec for arm:
-spec_file = same_dir(__file__, 'arm.brg')
-arm_matcher = pyburg.load_as_module(spec_file)
-
-
-class ArmMatcher(arm_matcher.Matcher):
-    """ Matcher that derives from a burg spec generated matcher """
-    def __init__(self, selector):
-        super().__init__()
-        self.newTmp = selector.newTmp
-        self.emit = selector.emit
-        self.selector = selector
-
-
-class ArmInstructionSelector(InstructionSelector):
-    """ Instruction selector for the arm architecture """
-    def __init__(self):
-        super().__init__()
-        self.matcher = ArmMatcher(self)
-
-    def munchExpr(self, e):
-        # Use BURG system here:
-        t = makeTree(e)
-        return self.matcher.gen(t)
-
-    def munchCall(self, e):
-        """ Generate code for call sequence """
-        # Move arguments into proper locations:
-        reguses = []
-        for i, a in enumerate(e.arguments):
-            loc = self.frame.argLoc(i)
-            m = ir.Move(loc, a)
-            self.munchStm(m)
-            if isinstance(loc, ir.Temp):
-                reguses.append(loc)
-        self.emit(Bl(LabelRef(e.f)), src=reguses, dst=[self.frame.rv])
-        d = self.newTmp()
-        self.move(d, self.frame.rv)
-        return d
-
-    def munchStm(self, s):
-        if isinstance(s, ir.Terminator):
-            pass
-        elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem) and \
-            isinstance(s.dst.e, ir.Binop) and s.dst.e.operation == '+' and \
-            isinstance(s.dst.e.b, ir.Const):
-            a = self.munchExpr(s.dst.e.a)
-            val = self.munchExpr(s.src)
-            c = s.dst.e.b.value
-            self.emit(Str2, others=[c], src=[a, val])
-        elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem):
-            memloc = self.munchExpr(s.dst.e)
-            val = self.munchExpr(s.src)
-            self.emit(Str2, others=[0], src=[memloc, val])
-        elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Temp):
-            val = self.munchExpr(s.src)
-            dreg = s.dst
-            self.move(dreg, val)
-        elif isinstance(s, ir.Exp):
-            # Generate expression code and discard the result.
-            x = self.munchExpr(s.e)
-            self.emit(Nop(), src=[x])
-        elif isinstance(s, ir.Jump):
-            tgt = self.targets[s.target]
-            self.emit(B(LabelRef(ir.label_name(s.target))), jumps=[tgt])
-        elif isinstance(s, ir.CJump):
-            a = self.munchExpr(s.a)
-            b = self.munchExpr(s.b)
-            self.emit(Cmp, src=[a, b])
-            ntgt = self.targets[s.lab_no]
-            ytgt = self.targets[s.lab_yes]
-            jmp_ins = makeIns(B(LabelRef(ir.label_name(s.lab_no))), jumps=[ntgt])
-            opnames = {'<': Blt, '>':Bgt, '==':Beq, '!=':Bne}
-            op = opnames[s.cond](LabelRef(ir.label_name(s.lab_yes)))
-            self.emit(op, jumps=[ytgt, jmp_ins])  # Explicitely add fallthrough
-            self.emit2(jmp_ins)
-        else:
-            raise NotImplementedError('Stmt --> {}'.format(s))
-
-    def move(self, dst, src):
-        self.emit(Mov2, src=[src], dst=[dst], ismove=True)
--- a/python/target/armregisters.py	Fri Feb 28 18:07:14 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-
-from .basetarget import Register
-
-class ArmRegister(Register):
-    def __init__(self, num, name):
-        super().__init__(name)
-        self.num = num
-
-    def __repr__(self):
-        return self.name
-
-
-class Reg8Op(ArmRegister):
-    pass
-
-
-class Reg16Op(ArmRegister):
-    pass
-
-def get_register(n):
-    for x in registers:
-        if x.num == n:
-            return x
-    raise Exception()
-
-def register_range(a, b):
-    """ Return set of registers from a to b """
-    assert a.num < b.num
-    return {get_register(n) for n in range(a.num, b.num + 1)}
-
-
-R0 = Reg8Op(0, 'r0')
-R1 = Reg8Op(1, 'r1')
-R2 = Reg8Op(2, 'r2')
-R3 = Reg8Op(3, 'r3')
-R4 = Reg8Op(4, 'r4')
-R5 = Reg8Op(5, 'r5')
-R6 = Reg8Op(6, 'r6')
-R7 = Reg8Op(7, 'r7')
-R8 = Reg8Op(8, 'r8')
-R9 = Reg8Op(9, 'r9')
-R10 = Reg8Op(10, 'r10')
-R11 = Reg8Op(11, 'r11')
-R12 = Reg8Op(12, 'r12')
-
-# Other registers:
-# TODO
-SP = ArmRegister(13, 'sp')
-LR = ArmRegister(14, 'lr')
-PC = ArmRegister(15, 'pc')
-
-registers = [R0, R1, R2, R3, R4, R5, R6, R7, SP, LR, PC]
--- a/python/target/armtarget.py	Fri Feb 28 18:07:14 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,188 +0,0 @@
-import struct
-from .basetarget import Register, Instruction, Target, Label, Alignment
-from .basetarget import Imm32, Imm8, Imm7, Imm3
-from .arminstructions import Add2, Sub, Add3, Cmp, Lsl, Orr
-from .arminstructions import Dcd, Pop, Push, Yield, Mov2, Mov3
-from .arminstructions import B, Bl, Bne, Beq, Blt, Bgt
-from .arminstructions import Ldr, Str2, Ldr2, Str1, Ldr1
-
-from .armframe import ArmFrame
-from .arminstructionselector import ArmInstructionSelector
-from .armregisters import R0, R1, R2, R3, R4, R5, R6, R7, SP, LR, PC
-from .armregisters import register_range
-
-
-""" ARM target description. """
-
-# TODO: encode this in DSL (domain specific language)
-# TBD: is this required?
-# TODO: make a difference between armv7 and armv5?
-
-thumb_assembly_rules = []
-def add_rule(rhs, f):
-    thumb_assembly_rules.append(('instruction', rhs, f))
-
-
-class ThumbTarget(Target):
-    def __init__(self):
-        super().__init__('thumb')
-        self.ins_sel = ArmInstructionSelector()
-        self.FrameClass = ArmFrame
-        self.add_rules()
-
-    def add_rules(self):
-
-        # Add instructions:
-        self.add_keyword('dcd')
-        self.add_instruction(['dcd', 'imm32'], lambda rhs: Dcd(rhs[1]))
-
-        self.add_keyword('mov')
-        self.add_instruction(['mov', 'reg8', ',', 'reg8'],
-                lambda rhs: Mov2(rhs[1], rhs[3]))
-
-        self.add_instruction(['mov', 'reg8', ',', 'imm8'],
-                lambda rhs: Mov3(rhs[1], rhs[3]))
-
-        self.add_keyword('add')
-        self.add_instruction(['add', 'reg8', ',', 'reg8', ',', 'imm3'],
-                lambda rhs: Add2(rhs[1], rhs[3], rhs[5]))
-
-        self.add_instruction(['add', 'reg8', ',', 'reg8', ',', 'reg8'],
-                lambda rhs: Add3(rhs[1], rhs[3], rhs[5]))
-
-        self.add_keyword('sub')
-        self.add_instruction(['sub', 'reg8', ',', 'reg8', ',', 'imm3'],
-                lambda rhs: Sub(rhs[1], rhs[3], rhs[5]))
-
-        self.add_instruction(['sub', 'sp', ',', 'sp', ',', 'imm8'],
-                lambda rhs: Sub(SP, SP, rhs[5]))
-
-        self.add_instruction(['add', 'sp', ',', 'sp', ',', 'imm8'],
-                lambda rhs: Sub(SP, SP, rhs[5]))
-
-        self.add_keyword('cmp')
-        self.add_instruction(['cmp', 'reg8', ',', 'reg8'],
-                lambda rhs: Cmp(rhs[1], rhs[3]))
-
-        self.add_keyword('lsl')
-        self.add_instruction(['lsl', 'reg8', ',', 'reg8'],
-                lambda rhs: Lsl(rhs[1], rhs[3]))
-
-        self.add_keyword('str')
-        self.add_instruction(['str', 'reg8', ',', '[', 'reg8', '+', 'imm5', ']'],
-                lambda rhs: Str2(rhs[1], rhs[4], rhs[6]))
-
-        self.add_keyword('ldr')
-        self.add_instruction(['ldr', 'reg8', ',', '[', 'reg8', '+', 'imm5', ']'],
-                lambda rhs: Ldr2(rhs[1], rhs[4], rhs[6]))
-
-        self.add_instruction(['str', 'reg8', ',', '[', 'sp', '+', 'imm8', ']'],
-                lambda rhs: Str1(rhs[1], rhs[6]))
-
-        self.add_instruction(['ldr', 'reg8', ',', '[', 'sp', '+', 'imm8', ']'],
-                lambda rhs: Ldr1(rhs[1], rhs[6]))
-
-        self.add_keyword('pop')
-        self.add_instruction(['pop', 'reg_list'], lambda rhs: Pop(rhs[1]))
-        self.add_keyword('push')
-        self.add_instruction(['push', 'reg_list'], lambda rhs: Push(rhs[1]))
-
-        self.add_keyword('yield')
-        self.add_instruction(['yield'], lambda rhs: Yield())
-
-        self.add_keyword('b')
-        self.add_keyword('bl')
-        self.add_instruction(['b', 'ID'], lambda rhs: B(rhs[1].val))
-        self.add_instruction(['bl', 'ID'], lambda rhs: Bl(rhs[1].val))
-        self.add_keyword('beq')
-        self.add_keyword('bne')
-        self.add_keyword('blt')
-        self.add_keyword('bgt')
-        self.add_instruction(['beq', 'ID'], lambda rhs: Beq(rhs[1].val))
-        self.add_instruction(['bne', 'ID'], lambda rhs: Bne(rhs[1].val))
-        self.add_instruction(['blt', 'ID'], lambda rhs: Blt(rhs[1].val))
-        self.add_instruction(['bgt', 'ID'], lambda rhs: Bgt(rhs[1].val))
-
-        self.add_keyword('align')
-        self.add_instruction(['align', 'imm8'], lambda rhs: Alignment(rhs[1]))
-
-        self.add_instruction(['ldr', 'reg8', ',', 'ID'],
-                lambda rhs: Ldr(rhs[1], rhs[3].val))
-
-        # Additional rules:
-
-        # Register list grammar:
-        self.add_rule('reg_list', ['{', 'reg_list_inner', '}'],
-            lambda rhs: rhs[1])
-        self.add_rule('reg_list_inner', ['reg_or_range'],
-            lambda rhs: rhs[0])
-        self.add_rule('reg_list_inner', ['reg_or_range', ',', 'reg_list_inner'],
-            lambda rhs: rhs[0] | rhs[2])
-        self.add_rule('reg_or_range', ['reg8'], lambda rhs: {rhs[0]})
-        self.add_rule('reg_or_range', ['lr'], lambda rhs: {LR})
-        self.add_rule('reg_or_range', ['pc'], lambda rhs: {PC})
-
-        self.add_rule('reg_or_range', ['reg8', '-', 'reg8'],
-            lambda rhs: register_range(rhs[0], rhs[2]))
-
-        self.add_keyword('r0')
-        self.add_keyword('r1')
-        self.add_keyword('r2')
-        self.add_keyword('r3')
-        self.add_keyword('r4')
-        self.add_keyword('r5')
-        self.add_keyword('r6')
-        self.add_keyword('r7')
-        self.add_keyword('sp')
-        self.add_keyword('lr')
-        self.add_keyword('pc')
-        self.add_rule('reg8', ['r0'], lambda rhs: R0)
-        self.add_rule('reg8', ['r1'], lambda rhs: R1)
-        self.add_rule('reg8', ['r2'], lambda rhs: R2)
-        self.add_rule('reg8', ['r3'], lambda rhs: R3)
-        self.add_rule('reg8', ['r4'], lambda rhs: R4)
-        self.add_rule('reg8', ['r5'], lambda rhs: R5)
-        self.add_rule('reg8', ['r6'], lambda rhs: R6)
-        self.add_rule('reg8', ['r7'], lambda rhs: R7)
-        # Constants:
-        self.add_rule('imm32', ['val32'], lambda x: x[0].val)
-        self.add_rule('imm32', ['imm8'], lambda x: x[0])
-        self.add_rule('imm8', ['val8'], lambda x: x[0].val)
-        self.add_rule('imm8', ['imm5'], lambda x: x[0])
-        self.add_rule('imm5', ['val5'], lambda x: x[0].val)
-        self.add_rule('imm5', ['imm3'], lambda x: x[0])
-        self.add_rule('imm3', ['val3'], lambda x: x[0].val)
-
-
-
-class ArmArmTarget(Target):
-    def __init__(self):
-        super().__init__('arm_arm')
-
-        # Assembly grammar:
-        self.add_keyword('mov')
-        self.add_keyword('r0')
-        self.add_keyword('r1')
-        self.add_keyword('r2')
-        self.add_keyword('r3')
-        self.add_keyword('r4')
-        self.add_keyword('r5')
-
-        self.add_rule('reg', ['r0'], lambda rhs: R0)
-        self.add_rule('reg', ['r1'], lambda rhs: R1)
-        self.add_rule('reg', ['r2'], lambda rhs: R2)
-        self.add_rule('reg', ['r3'], lambda rhs: R3)
-        self.add_rule('reg', ['r4'], lambda rhs: R4)
-        self.add_rule('reg', ['r5'], lambda rhs: R5)
-
-
-        self.add_instruction(['mov', 'reg', ',', 'imm8'],
-                lambda rhs: Yield())
-
-        self.add_rule('imm32', ['val32'], lambda x: x[0].val)
-        self.add_rule('imm32', ['imm8'], lambda x: x[0])
-        self.add_rule('imm8', ['val8'], lambda x: x[0].val)
-        self.add_rule('imm8', ['imm5'], lambda x: x[0])
-        self.add_rule('imm5', ['val5'], lambda x: x[0].val)
-        self.add_rule('imm5', ['imm3'], lambda x: x[0])
-        self.add_rule('imm3', ['val3'], lambda x: x[0].val)
--- a/python/target/armtoken.py	Fri Feb 28 18:07:14 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-
-import struct
-
-def u16(h):
-    return struct.pack('<H', h)
-
-def val2bit(v, bits):
-    b = []
-    for i in range(bits):
-        b.append(bool((1<<i) & v))
-    #b.reverse()
-    return b
-
-
-def bit_range(b, e):
-    getter = lambda s: s[b:e]
-    def setter(s, v):
-        s[b:e] = v
-    return property(getter, setter)
-
-
-class Token:
-    def set_bit(self, i, value):
-        value = bool(value)
-        assert i in range(0, 16)
-        mask = 1 << i
-        if value:
-            self.bit_value |= mask
-        else:
-            self.bit_value &= (~mask)
-
-    def __getitem__(self, key):
-        return False
-
-    def __setitem__(self, key, value):
-        if type(key) is int:
-            self.set_bit(key, value)
-        elif type(key) is slice:
-            assert key.step is None
-            bits = key.stop - key.start
-            value_bits = val2bit(value, bits)
-            for i in range(key.start, key.stop):
-                self.set_bit(i, value_bits[i - key.start])
-        else:
-            raise KeyError()
-
-class ThumbToken(Token):
-    def __init__(self):
-        self.bit_value = 0
-
-
-    rd = bit_range(0, 3)
-
-    def encode(self):
-        return u16(self.bit_value)
-
-
-class ArmToken(Token):
-    def __init__(self):
-        self.bit_value = 0
-
--- a/python/target/armv7.lidl	Fri Feb 28 18:07:14 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-
-#  This file specifies the encoding of the arm instruction set.
-
-fields {
-    word16 16 {
-        opcode 15:12
-        top2 15:14
-        top6 15:10
-        data_opcode 9..6
-        opB 11:9
-        Rm 8:6
-        Rn 5:3
-        Rt 2:0
-    }
-}
-
-patterns {
- add = 0
- sub, mul = 1..2
- [r1, r2, r3, r4, r5] is todo = 1..5
- [STR, STRH, STRB, LDRSB, LDR, LDRH, LDRB, LDRSH] is opcode = 0b0101 & opB = {0 to 7}
-
- EQ, NE, CS, CC, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE, AL = 0..14
- [AND, EOR, LSL, LSR, ASR, ADC, SBC, ROR, TST, RSB, CMP, CMN, ORR, MUL, BIC, MVN] is  0..15
-
- memop is STR | STRH | STRB | LDRSB | LDR | LDR | LDRH | LDRB | LDRSH
-}
-
-
-constructors
-{
- alu rs1, reg_or_imm, rd
- memop Rt, [Rn, Rm] is memop & Rt & Rn & Rm
-}
-
-
--- a/python/target/basetarget.py	Fri Feb 28 18:07:14 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,165 +0,0 @@
-from ppci.asmnodes import ASymbol, AInstruction, ANumber
-from ppci import CompilerError
-
-"""
-  Base classes for defining a target
-"""
-
-# Machine code interface:
-class Operand:
-   """ Single machine operand """
-   pass
-
-# standard immediates:
-
-class ImmBase:
-    def __init__(self, imm):
-        assert type(imm) is int
-        assert imm < self.Max()
-        self.imm = imm
-
-    @classmethod
-    def Max(cls):
-        return 2**cls.bits
-
-    @classmethod
-    def Create(cls, vop):
-        if type(vop) is ANumber and vop.number < cls.Max():
-            return cls(vop.number)
-
-
-class Imm3(ImmBase):
-    bits = 3
-
-
-class Imm7(ImmBase):
-    bits = 7
-
-
-class Imm8(ImmBase):
-    bits = 8
-
-
-class Imm32(ImmBase):
-    bits = 32
-
-
-class LabelRef:
-    def __init__(self, name):
-        assert type(name) is str
-        self.name = name
-
-    @classmethod
-    def Create(cls, vop):
-        if type(vop) is ASymbol:
-            return cls(vop.name)
-
-
-class Instruction:
-    """ Base instruction class """
-    def encode(self):
-        return bytes()
-
-    def relocations(self):
-        return []
-
-    def symbols(self):
-        return []
-
-
-class Nop(Instruction):
-    """ Instruction that does nothing and has zero size """
-    def encode(self):
-        return bytes()
-
-
-class PseudoInstruction(Instruction):
-    pass
-
-
-class Label(PseudoInstruction):
-    def __init__(self, name):
-        self.name = name
-
-    def __repr__(self):
-        return '{}:'.format(self.name)
-
-    def symbols(self):
-        return [self.name]
-
-    @classmethod
-    def Create(cls, vop):
-        if type(vop) is ASymbol:
-            name = vop.name
-            return cls(name)
-
-
-class Comment(PseudoInstruction):
-    def __init__(self, txt):
-        self.txt = txt
-
-    def encode(self):
-        return bytes()
-
-    def __repr__(self):
-        return '; {}'.format(self.txt)
-
-
-class Alignment(PseudoInstruction):
-    def __init__(self, a):
-        self.align = a
-
-    def __repr__(self):
-        return 'ALIGN({})'.format(self.align)
-
-    def encode(self):
-        pad = []
-        # TODO
-        address = 0
-        while (address % self.align) != 0:
-            address += 1
-            pad.append(0)
-        return bytes(pad)
-
-
-class DebugInfo(PseudoInstruction):
-    def __init__(self, i):
-        self.info = i
-
-    def __repr__(self):
-        return 'DebugInfo: {}'.format(self.info)
-
-
-class Register(Operand):
-    def __init__(self, name):
-        self.name = name
-
-
-class Target:
-    def __init__(self, name, desc=''):
-        self.name = name
-        self.desc = desc
-        self.registers = []
-        self.byte_sizes = {'int' : 4}  # For front end!
-
-        # For assembler:
-        self.assembler_rules = []
-        self.asm_keywords = []
-
-    def add_keyword(self, kw):
-        self.asm_keywords.append(kw)
-
-    def add_instruction(self, rhs, f):
-        self.add_rule('instruction', rhs, f)
-
-    def add_rule(self, lhs, rhs, f):
-        self.assembler_rules.append((lhs, rhs, f))
-
-    def instruction(self, cls):
-        """ Decorator function that registers an instruction to this target """
-        self.addInstruction(cls)
-        return cls
-
-    def addInstruction(self, i):
-        pass
-
--- a/python/target/instructionselector.py	Fri Feb 28 18:07:14 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-from ppci import ir
-from ppci import irmach
-from ppci.irmach import AbstractInstruction as makeIns
-import target
-
-def genTemps():
-    n = 900
-    while True:
-        yield ir.Temp('t{}'.format(n))
-        n = n + 1
-
-
-class InstructionSelector:
-    """
-        Base instruction selector. This class must be overridden by
-        backends.
-    """
-    def __init__(self):
-        self.temps = genTemps()
-
-    def newTmp(self):
-        return self.temps.__next__()
-
-
-    def munchFunction(self, f, frame):
-        # Entry point for instruction selection
-        assert isinstance(f, ir.Function)
-        self.targets = {}
-        # Enter a frame per function:
-        self.frame = frame
-        # First define labels:
-        for bb in f.Blocks:
-            itgt = makeIns(target.Label(ir.label_name(bb)))
-            self.targets[bb] = itgt
-        # Generate code for all blocks:
-        for bb in f.Blocks:
-            self.emit2(self.targets[bb])
-            for i in bb.Instructions:
-                self.munchStm(i)
-        self.munchStm(ir.Move(self.frame.rv, f.return_value))
-
-    def move(self, dst, src):
-        raise NotImplementedError('Not target implemented')
-
-    def emit(self, *args, **kwargs):
-        """ Abstract instruction emitter """
-        i = makeIns(*args, **kwargs)
-        return self.emit2(i)
-
-    def emit2(self, i):
-        self.frame.instructions.append(i)
-        return i
-
-    def munchStm(self, s):
-        """ Implement this in the target specific back-end """
-        raise NotImplementedError()
-
-    def munchExpr(self, e):
-        """ Implement this in the target specific back-end """
-        raise NotImplementedError()
--- a/python/target/msp430.py	Fri Feb 28 18:07:14 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,257 +0,0 @@
-from .basetarget import Register, Instruction, Target
-from ppci.asmnodes import ASymbol, ANumber
-from ppci import CompilerError
-import struct
-import types
-
-# Create the target class (singleton):
-
-class Msp430T(Target):
-    def __init__(self):
-        super().__init__('msp430')
-        self.asm_keywords = []
-        self.assembler_rules = []
-        self.add_keyword('mov')
-        self.add_keyword('r13')
-        self.add_keyword('r14')
-        self.add_keyword('r15')
-        R0 = None # TODO
-        self.add_rule('reg', ['r13'], lambda rhs: r13)
-        self.add_rule('reg', ['r14'], lambda rhs: r14)
-        self.add_rule('reg', ['r15'], lambda rhs: r15)
-        self.add_instruction(['mov', 'reg', ',', 'reg'],
-            lambda rhs: Mov(rhs[1], rhs[3]))
-        
-        self.add_keyword('reti')
-        self.add_instruction(['reti'], lambda rhs: reti_ins())
-
-msp430target = Msp430T()
-
-REGISTER_MODE = 1
-SYMBOLIC_MODE = 3
-ABSOLUTE_MODE = 4
-#TODO: add more modes!
-IMMEDIATE_MODE = 7
-
-# Target description for the MSP430 processor
-
-class MSP430Reg(Register):
-    def __init__(self, num, name):
-        super().__init__(name)
-        self.num = num
-
-# 8 bit registers:
-PCB = MSP430Reg(0, 'r0')
-rpc = PCB
-r11 = MSP430Reg(11, 'r11')
-r12 = MSP430Reg(12, 'r12')
-r13 = MSP430Reg(13, 'r13')
-r14 = MSP430Reg(14, 'r14')
-r15 = MSP430Reg(15, 'r15')
-
-class MSP430Mem:
-    pass
-
-msp430target.registers.append(r11)
-msp430target.registers.append(r12)
-msp430target.registers.append(r13)
-msp430target.registers.append(r14)
-msp430target.registers.append(r15)
-
-# .. etc
-
-#GR8 = RegisterClass((PCB, R15B))
-
-class MSP430Operand:
-    def __init__(self, mode, param):
-        self.mode = mode
-        self.param = param
-    def regField(self):
-        if self.mode == REGISTER_MODE:
-            return self.param
-        elif self.mode == IMMEDIATE_MODE:
-            return rpc.num
-    def asField(self):
-        if self.mode == REGISTER_MODE:
-            return 0
-        elif self.mode == IMMEDIATE_MODE:
-            return 3
-    def adField(self):
-        if self.mode == REGISTER_MODE:
-            return 0
-        elif self.mode == IMMEDIATE_MODE:
-            raise CompilerError('Cannot use immediate mode for destination operand')
-    def extraBytes(self):
-        if self.mode == IMMEDIATE_MODE:
-            return pack_ins(self.param)
-        return bytes()
-    
-    @classmethod
-    def Create(cls, vop):
-        if type(vop) is ASymbol:
-            # try to map to register:
-            regs = {}
-            for r in msp430target.registers:
-                regs[r.name] = r
-            if vop.name in regs:
-                reg = regs[vop.name]
-                return cls(REGISTER_MODE, reg.num)
-        elif type(vop) is ANumber:
-            # Immediate mode:
-            return cls(IMMEDIATE_MODE, vop.number)
-
-def pack_ins(h):
-    return struct.pack('<H', h)
-
-class MSP430Instruction(Instruction):
-    b = 0
-
-class BInstruction:
-    pass
-
-class MSP430CoreInstruction(Instruction):
-    pass
-
-#########################
-# Single operand arithmatic:
-#########################
-
-class reti_ins(MSP430Instruction):
-    mnemonic = 'reti'
-    def encode(self):
-        h = 0x1300
-        return pack_ins(h)
-
-class OneOpArith(MSP430Instruction):
-    def __init__(self, op1):
-        self.op1 = op1
-
-    def encode(self):
-        # TODO:
-        bits[15:10] = '00100'
-        h1 = (self.opcode << 4)
-        return pack_ins(h1)
-
-def oneOpIns(mne, opc):
-    """ Helper function to define a one operand arithmetic instruction """
-    members = {'mnemonic': mne, 'opcode': opc}
-    ins_cls = type(mne + '_ins', (OneOpArith,), members)
-    msp430target.addInstruction(ins_cls)
-
-oneOpIns('rrc', 0)
-oneOpIns('swpb', 1)
-oneOpIns('rra', 2)
-oneOpIns('sxt', 3)
-oneOpIns('push', 4)
-oneOpIns('call', 5)
-
-#########################
-# Jump instructions:
-#########################
-
-class JumpInstruction(Instruction):
-    def __init__(self, offset):
-        self.offset = offset
-
-    def encode(self):
-        h = (1 << 13) | (self.condition << 10) | (self.offset)
-        return pack_ins(h)
-
-class jnz_ins(JumpInstruction):
-    mnemonic = 'jnz'
-    condition = 0
-
-class jz_ins(JumpInstruction):
-    mnemonic = 'jz'
-    condition = 1
-
-class jnc_ins(JumpInstruction):
-    mnemonic = 'jnc'
-    condition = 2
-
-class jc_ins(JumpInstruction):
-    mnemonic = 'jc'
-    condition = 3
-
-class jn_ins(JumpInstruction):
-    mnemonic = 'jn'
-    condition = 4
-
-class jge_ins(JumpInstruction):
-    mnemonic = 'jge'
-    condition = 5
-
-class jl_ins(JumpInstruction):
-    mnemonic = 'jl'
-    condition = 6
-
-class jmp_ins(JumpInstruction):
-    mnemonic = 'jmp'
-    condition = 7
-
-#########################
-# Two operand arithmatic instructions:
-#########################
-
-
-class TwoOpArith(MSP430Instruction):
-    def __init__(self, src, dst):
-        self.op1 = src
-        self.op2 = dst
-
-    def encode(self):
-        """
-            Smart things have been done by MSP430 designers.
-            As (2 bits) is the source addressing mode selector.
-            Ad (1 bit) is the destination adressing mode selector.
-            For the source there are 7 different addressing mode.
-            For the destination there are 4.
-            The trick is to use also the register to distuingish the
-            different modes.
-        """
-        # TODO: Make memory also possible
-
-        As = self.op1.asField() # addressing mode for the source
-        Ad = self.op2.adField() # Addressing mode for dst
-        b = self.b # When b=1, the operation is byte mode
-        source = self.op1.regField()
-        destination = self.op2.regField()
-        h = (self.opcode << 12) | (source << 8)
-        h |= (self.b << 6) | (As << 4) | (Ad << 7) | destination
-        additions = self.op1.extraBytes() + self.op2.extraBytes()
-        return pack_ins(h) + additions
-
-    def decode(self, data):
-        pass
-
-
-def twoOpIns(mne, opc):
-    """ Helper function to define a two operand arithmetic instruction """
-    members = {'mnemonic': mne, 'opcode': opc}
-    ins_cls = type(mne + '_ins', (TwoOpArith,), members)
-
-class Mov(TwoOpArith):
-    """ Adds the source to the destination """
-    mnemonic = 'mov'
-    opcode = 4
-
-# This is equivalent to the helper function twoOpIns:
-class add_ins(TwoOpArith):
-    """ Adds the source to the destination """
-    mnemonic = 'add'
-    opcode = 5
-
-    def operate(self):
-        dst.value = dst.value + src.value
-        setFlags()
-
-twoOpIns('addc', 6)
-twoOpIns('subc', 7)
-twoOpIns('sub', 8)
-twoOpIns('cmp', 9)
-twoOpIns('dadd', 10)
-twoOpIns('bit', 11)
-twoOpIns('bic', 12)
-twoOpIns('bis', 13)
-twoOpIns('xor', 14)
-twoOpIns('and', 15)
--- a/python/target/openrisc.lidl	Fri Feb 28 18:07:14 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-
-// Openrisc description in LIDL (lcfos isa description language)
-
-// Register storage:
-storage r {
-  width: 32
-  size: 32
-}
-
-
-instruction add {
-  encoding: '111111111DDDDDDAAAAAABBBBBB'
-  semantics: D = A + B
-}
-
-
-// ...
-
-instruction push {
-  encoding: ''
-  semantics: {
-    sp = X
-    sp  = sp - 4
-  }
-}
-
--- a/python/target/openrisc.py	Fri Feb 28 18:07:14 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-
-
-import target
-
--- a/python/target/target_list.py	Fri Feb 28 18:07:14 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-
-from .armtarget import ArmArmTarget, ThumbTarget
-from .msp430 import msp430target
-
-# Instance:
-arm_target = ArmArmTarget()
-thumb_target = ThumbTarget()
-
-target_list = [arm_target, thumb_target]
--- a/python/target/target_x86.py	Fri Feb 28 18:07:14 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-from target import Register, Instruction, Target
-
-class x86Register(Register):
-   def __init__(self, name):
-      self.name = name
-
-class REG16(x86Register):
-   pass
-
-def addRegs(cls, names):
-   for name in names:
-      r = cls(name)
-      globals()[name] = r
-
-addRegs(REG16, ['ax', 'bx', 'cx'])
-
-regs = """
-ax; reg16
-"""
-
-class MO:
-   def __init__(self):
-      pass
-
-instrs = """
-add; 0x0; mem8/reg8; reg8
-"""
-
-# machine op table:
-mot = []
-
-for i in instrs.split('\n'):
-   i = i.strip()
-   if i:
-      print('INS:', i)
-      mnemonic, opcode, op1, op2 = [a.strip() for a in i.split(';')]
-      print(op1.split('/'), op2.split('/'))
-
-
-print(mot)
-
-# Test first with these 3 instructions:
-"""
-mov reg64, reg64 : opcode=0x89
-xor reg64, reg64 : opcode=0x31
-inc reg64 : opcode=0xff
-"""
-
-class x86Machine:
-   def __init__(self):
-      self.table = []
-      self.table.append((0x0, 'add', 'reg8/mem8, reg8'))
-      self.table.append((0x1, 'add', 'reg16/mem16/reg32/mem32, reg16/reg32'))
-      self.table.append((0x2, 'add', 'reg8, reg8/mem8'))
-   def forMnemonic(self, m):
-      return [i for i in self.table if i[1] == m]
-   def emit(self, m, ops):
-      print(m, ops)
-      ops = self.forMnemonic(m)
-      print(ops)
-
-
-if __name__ == '__main__':
-   m = x86Machine()
-   m.emit('add', [ax, cx])
-   m.emit('mov', [bx, 1337])
--- a/python/target/x86.py	Fri Feb 28 18:07:14 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-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))
-
--- a/python/target/x86_2.py	Fri Feb 28 18:07:14 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,356 +0,0 @@
-"""
-    X86 target descriptions and encodings.
-
-"""
-
-from target import Register, Instruction, Target, Imm8, Label, Imm3, LabelRef
-
-
-modrm = {'rax': 0, 'rbx': 1}
-
-# Table 3.1 of the intel manual:
-# use REX.W on the table below:
-regs64 = {'rax': 0,'rcx':1,'rdx':2,'rbx':3,'rsp':4,'rbp':5,'rsi':6,'rdi':7,'r8':0,'r9':1,'r10':2,'r11':3,'r12':4,'r13':5,'r14':6,'r15':7}
-regs32 = {'eax': 0, 'ecx':1, 'edx':2, 'ebx': 3, 'esp': 4, 'ebp': 5, 'esi':6, 'edi':7}
-regs8 = {'al':0,'cl':1,'dl':2,'bl':3,'ah':4,'ch':5,'dh':6,'bh':7}
-
-# Calculation of the rexb bit:
-rexbit = {'rax': 0, 'rcx':0, 'rdx':0, 'rbx': 0, 'rsp': 0, 'rbp': 0, 'rsi':0, 'rdi':0,'r8':1,'r9':1,'r10':1,'r11':1,'r12':1,'r13':1,'r14':1,'r15':1}
-
-# Helper functions:
-def imm64(x):
-   """ represent 64 bits integer in little endian 8 bytes"""
-   if x < 0:
-      x = x + (1 << 64)
-   x = x & 0xFFFFFFFFFFFFFFFF
-   return [ (x >> (p*8)) & 0xFF for p in range(8) ]
-
-def imm32(x):
-   """ represent 32 bits integer in little endian 4 bytes"""
-   if x < 0:
-      x = x + (1 << 32)
-   x = x & 0xFFFFFFFF
-   return [ (x >> (p*8)) & 0xFF for p in range(4) ]
-
-def imm8(x):
-   if x < 0:
-      x = x + (1 << 8)
-   x = x & 0xFF
-   return [ x ]
-
-def modrm(mod=0, rm=0, reg=0):
-   """ Construct the modrm byte from its components """
-   assert(mod <= 3)
-   assert(rm <= 7)
-   assert(reg <= 7)
-   return (mod << 6) | (reg << 3) | rm
-
-def rex(w=0, r=0, x=0, b=0):
-   """ Create a REX prefix byte """
-   assert(w <= 1)
-   assert(r <= 1)
-   assert(x <= 1)
-   assert(b <= 1)
-   return 0x40 | (w<<3) | (r<<2) | (x<<1) | b
-
-def sib(ss=0, index=0, base=0):
-   assert(ss <= 3)
-   assert(index <= 7)
-   assert(base <= 7)
-   return (ss << 6) | (index << 3) | base
-
-tttn = {'L':0xc,'G':0xf,'NE':0x5,'GE':0xd,'LE':0xe, 'E':0x4}
-
-# Actual instructions:
-def nearjump(distance, condition=None):
-   """ jmp imm32 """
-   lim = (1<<30)
-   if abs(distance) > lim:
-      Error('near jump cannot jump over more than {0} bytes'.format(lim))
-   if condition:
-      if distance < 0:
-         distance -= 6 # Skip own instruction
-      opcode = 0x80 | tttn[condition] # Jcc imm32
-      return [0x0F, opcode] + imm32(distance)
-   else:
-      if distance < 0:
-         distance -= 5 # Skip own instruction
-      return [ 0xE9 ] + imm32(distance)
-
-def shortjump(distance, condition=None):
-   """ jmp imm8 """
-   lim = 118
-   if abs(distance) > lim:
-      Error('short jump cannot jump over more than {0} bytes'.format(lim))
-   if distance < 0:
-      distance -= 2 # Skip own instruction
-   if condition:
-      opcode = 0x70 | tttn[condition] # Jcc rel8
-   else:
-      opcode = 0xeb # jmp rel8
-   return [opcode] + imm8(distance)
-
-# Helper that determines jump type:
-def reljump(distance):
-   if abs(distance) < 110:
-      return shortjump(distance)
-   else:
-      return nearjump(distance)
-
-def push(reg):
-   if reg in regs64:
-      if rexbit[reg] == 1:
-         return [0x41, 0x50 + regs64[reg]]
-      else:
-         return [0x50 + regs64[reg]]
-   else:
-      Error('push for {0} not implemented'.format(reg))
-
-def pop(reg):
-   if reg in regs64:
-      if rexbit[reg] == 1:
-         rexprefix = rex(b=1)
-         opcode = 0x58 + regs64[reg]
-         return [rexprefix, opcode]
-      else:
-         opcode = 0x58 + regs64[reg]
-         return [ opcode ]
-   else:
-      Error('pop for {0} not implemented'.format(reg))
-
-def INT(number):
-   opcode = 0xcd
-   return [opcode] + imm8(number)
-
-def syscall():
-   return [0x0F, 0x05]
-
-def call(distance):
-   if type(distance) is int:
-      return [0xe8]+imm32(distance)
-   elif type(distance) is str and distance in regs64:
-      reg = distance
-      opcode = 0xFF # 0xFF /2 == call r/m64
-      mod_rm = modrm(mod=3, reg=2, rm=regs64[reg])
-      if rexbit[reg] == 1:
-         rexprefix = rex(b=rexbit[reg])
-         return [rexprefix, opcode, mod_rm]
-      else:
-         return [opcode, mod_rm]
-   else:
-      Error('Cannot call to {0}'.format(distance))
-
-def ret():
-   return [ 0xc3 ]
-
-def increg64(reg):
-   assert(reg in regs64)
-   rexprefix = rex(w=1, b=rexbit[reg])
-   opcode = 0xff
-   mod_rm = modrm(mod=3, rm=regs64[reg])
-   return [rexprefix, opcode, mod_rm]
-
-def prepost8(r8, rm8):
-   assert(r8 in regs8)
-   pre = []
-   if type(rm8) is list:
-      # TODO: merge mem access with prepost for 64 bits
-      if len(rm8) == 1:
-         base, = rm8
-         if type(base) is str and base in regs64:
-            assert(not base in ['rbp', 'rsp', 'r12', 'r13'])
-            mod_rm = modrm(mod=0, rm=regs64[base], reg=regs8[r8])
-            if rexbit[base] == 1:
-               pre.append(rex(b=1))
-            post = [mod_rm]
-         else:
-            Error('One arg of type {0} not implemented'.format(base))
-      elif len(rm8) == 2:
-         base, offset = rm8
-         assert(type(offset) is int)
-         assert(base in regs64)
-
-         if base == 'rsp' or base == 'r12':
-            Error('Cannot use rsp or r12 as base yet')
-         if rexbit[base] == 1:
-            pre.append( rex(b=1) )
-         mod_rm = modrm(mod=1, rm=regs64[base], reg=regs8[r8])
-         post = [mod_rm] + imm8(offset)
-      else:
-         Error('not supporting prepost8 with list len {0}'.format(len(rm8)))
-   else:
-      Error('Not supporting move with reg8 {0}'.format(r8))
-   return pre, post
-
-def prepost(r64, rm64):
-   assert(r64 in regs64)
-   if type(rm64) is list:
-      if len(rm64) == 3:
-            base, index, disp = rm64
-            assert(base in regs64)
-            assert(index in regs64)
-            assert(type(disp) is int)
-            # Assert that no special cases are used:
-            # TODO: swap base and index to avoid special cases
-            # TODO: exploit special cases and make better code
-            assert(index != 'rsp')
-
-            rexprefix = rex(w=1, r=rexbit[r64], x=rexbit[index], b=rexbit[base])
-            # mod=1 and rm=4 indicates a SIB byte: [--][--]+imm8
-            mod_rm = modrm(mod=1, rm=4, reg=regs64[r64])
-            si_b = sib(ss=0, index=regs64[index], base=regs64[base])
-            return [rexprefix], [mod_rm, si_b] + imm8(disp)
-      elif len(rm64) == 2:
-         base, offset = rm64
-         assert(type(offset) is int)
-         if base == 'RIP':
-            # RIP pointer relative addressing mode!
-            rexprefix = rex(w=1, r=rexbit[r64])
-            mod_rm = modrm(mod=0, rm=5, reg=regs64[r64])
-            return [rexprefix], [mod_rm] + imm32(offset)
-         else:
-            assert(base in regs64)
-
-            if base == 'rsp' or base == 'r12':
-               # extended function that uses SIB byte
-               rexprefix = rex(w=1, r=rexbit[r64], b=rexbit[base])
-               # rm=4 indicates a SIB byte follows
-               mod_rm = modrm(mod=1, rm=4, reg=regs64[r64])
-               # index=4 indicates that index is not used
-               si_b = sib(ss=0, index=4, base=regs64[base])
-               return [rexprefix], [mod_rm, si_b] + imm8(offset)
-            else:
-               rexprefix = rex(w=1, r=rexbit[r64], b=rexbit[base])
-               mod_rm = modrm(mod=1, rm=regs64[base], reg=regs64[r64])
-               return [rexprefix], [mod_rm] + imm8(offset)
-      elif len(rm64) == 1:
-         offset = rm64[0]
-         if type(offset) is int:
-            rexprefix = rex(w=1, r=rexbit[r64])
-            mod_rm = modrm(mod=0, rm=4,reg=regs64[r64])
-            si_b = sib(ss=0, index=4,base=5) # 0x25
-            return [rexprefix], [mod_rm, si_b] + imm32(offset)
-         else:
-            Error('Memory reference of type {0} not implemented'.format(offset))
-      else:
-         Error('Memory reference not implemented')
-   elif rm64 in regs64:
-      rexprefix = rex(w=1, r=rexbit[r64], b=rexbit[rm64])
-      mod_rm = modrm(3, rm=regs64[rm64], reg=regs64[r64])
-      return [rexprefix], [mod_rm]
-
-def leareg64(rega, m):
-   opcode = 0x8d # lea r64, m
-   pre, post = prepost(rega, m)
-   return pre + [opcode] + post
-
-def mov(rega, regb):
-   if type(regb) is int:
-      pre = [rex(w=1, b=rexbit[rega])]
-      opcode = 0xb8 + regs64[rega]
-      post = imm64(regb)
-   elif type(regb) is str:
-      if regb in regs64:
-         opcode = 0x89 # mov r/m64, r64
-         pre, post = prepost(regb, rega)
-      elif regb in regs8:
-         opcode = 0x88 # mov r/m8, r8
-         pre, post = prepost8(regb, rega)
-      else:
-         Error('Unknown register {0}'.format(regb))
-   elif type(rega) is str:
-      if rega in regs64:
-         opcode = 0x8b # mov r64, r/m64
-         pre, post = prepost(rega, regb)
-      else:
-         Error('Unknown register {0}'.format(rega))
-   else:
-      Error('Move of this kind {0}, {1} not implemented'.format(rega, regb))
-   return pre + [opcode] + post
-
-def xorreg64(rega, regb):
-   rexprefix = rex(w=1, r=rexbit[regb], b=rexbit[rega])
-   opcode = 0x31 # XOR r/m64, r64
-   # Alternative is 0x33 XOR r64, r/m64
-   mod_rm = modrm(3, rm=regs64[rega], reg=regs64[regb])
-   return [rexprefix, opcode, mod_rm]
-
-# integer arithmatic:
-def addreg64(rega, regb):
-   if regb in regs64:
-      pre, post = prepost(regb, rega)
-      opcode = 0x01 # ADD r/m64, r64
-      return pre + [opcode] + post
-   elif type(regb) is int:
-      if regb < 100:
-         rexprefix = rex(w=1, b=rexbit[rega])
-         opcode = 0x83 # add r/m, imm8
-         mod_rm = modrm(3, rm=regs64[rega], reg=0)
-         return [rexprefix, opcode, mod_rm]+imm8(regb)
-      elif regb < (1<<31):
-         rexprefix = rex(w=1, b=rexbit[rega])
-         opcode = 0x81 # add r/m64, imm32
-         mod_rm = modrm(3, rm=regs64[rega], reg=0)
-         return [rexprefix, opcode, mod_rm]+imm32(regb)
-      else:
-         Error('Constant value too large!')
-   else:
-      Error('unknown second operand!'.format(regb))
-
-def subreg64(rega, regb):
-   if regb in regs64:
-      pre, post = prepost(regb, rega)
-      opcode = 0x29 # SUB r/m64, r64
-      return pre + [opcode] + post
-   elif type(regb) is int:
-      if regb < 100:
-         rexprefix = rex(w=1, b=rexbit[rega])
-         opcode = 0x83 # sub r/m, imm8
-         mod_rm = modrm(3, rm=regs64[rega], reg=5)
-         return [rexprefix, opcode, mod_rm]+imm8(regb)
-      elif regb < (1<<31):
-         rexprefix = rex(w=1, b=rexbit[rega])
-         opcode = 0x81 # sub r/m64, imm32
-         mod_rm = modrm(3, rm=regs64[rega], reg=5)
-         return [rexprefix, opcode, mod_rm]+imm32(regb)
-      else:
-         Error('Constant value too large!')
-
-   else:
-      Error('unknown second operand!'.format(regb))
-
-def idivreg64(reg):
-   rexprefix = rex(w=1, b=rexbit[reg])
-   opcode = 0xf7 # IDIV r/m64
-   mod_rm = modrm(3, rm=regs64[reg], reg=7)
-   return [rexprefix, opcode, mod_rm]
-
-def imulreg64_rax(reg):
-   rexprefix = rex(w=1, b=rexbit[reg])
-   opcode = 0xf7 # IMUL r/m64
-   mod_rm = modrm(3, rm=regs64[reg], reg=5)
-   return [rexprefix, opcode, mod_rm]
-
-def imulreg64(rega, regb):
-   pre, post = prepost(rega, regb)
-   opcode = 0x0f # IMUL r64, r/m64
-   opcode2 = 0xaf
-   return pre + [opcode, opcode2] + post
-
-def cmpreg64(rega, regb):
-   if regb in regs64:
-      pre, post = prepost(regb, rega)
-      opcode = 0x39 # CMP r/m64, r64
-      return pre + [opcode] + post
-   elif type(regb) is int:
-      rexprefix = rex(w=1, b=rexbit[rega])
-      opcode = 0x83 # CMP r/m64, imm8
-      mod_rm = modrm(3, rm=regs64[rega], reg=7)
-      return [rexprefix, opcode, mod_rm] + imm8(regb)
-      
-   else:
-      Error('not implemented cmp64')
-
-# Mapping that maps string names to the right functions:
-opcodes = {'mov':(mov,2), 'lea':(leareg64,2), 'int':(INT,1), 'syscall':(syscall,0)}
-
--- a/python/yacc.py	Fri Feb 28 18:07:14 2014 +0100
+++ b/python/yacc.py	Sat Mar 01 15:40:31 2014 +0100
@@ -286,6 +286,7 @@
     exec(ob.getvalue(), parser_mod.__dict__)
     return parser_mod
 
+
 def main(args):
     src = args.source.read()
     args.source.close()
--- a/python/zcc.py	Fri Feb 28 18:07:14 2014 +0100
+++ b/python/zcc.py	Sat Mar 01 15:40:31 2014 +0100
@@ -4,13 +4,13 @@
 import os
 import argparse
 import logging
-import yaml
 
 from ppci.buildtasks import Compile, Assemble, Link
 from ppci.tasks import TaskRunner
 from ppci.report import RstFormatter
 from ppci.objectfile import ObjectFile
-from target.target_list import target_list
+from ppci.target.target_list import target_list
+from ppci.recipe import RecipeLoader
 import ppci
 
 
@@ -51,64 +51,6 @@
     return parser
 
 
-class RecipeLoader:
-    """ Loads a recipe into a runner from a dictionary or file """
-    def __init__(self):
-        self.directive_handlers = {}
-        for a in dir(self):
-            if a.startswith('handle_'):
-                f = getattr(self, a)
-                self.directive_handlers[a[7:]] = f
-
-    def load_file(self, recipe_file, runner):
-        """ Loads a recipe dictionary into a task runner """
-        self.recipe_dir = os.path.abspath(os.path.dirname(recipe_file))
-        with open(recipe_file, 'r') as f:
-            recipe = yaml.load(f)
-        self.runner = runner
-        self.load_dict(recipe)
-
-    def relpath(self, filename):
-        return os.path.join(self.recipe_dir, filename)
-
-    def openfile(self, filename):
-        return open(self.relpath(filename), 'r')
-
-    def handle_compile(self, value):
-        sources = [self.openfile(s) for s in value['sources']]
-        includes = [self.openfile(i) for i in value['includes']]
-        target = targets[value['machine']]
-        output = ObjectFile()
-        task = Compile(sources, includes, target, output)
-        self.runner.add_task(task)
-        return task
-
-    def handle_assemble(self, value):
-        asm_src = self.openfile(value['source'])
-        target = targets[value['machine']]
-        output = ObjectFile()
-        task = Assemble(asm_src, target, output)
-        self.runner.add_task(task)
-        return task
-
-    def handle_link(self, value):
-        inputs = value['inputs']
-        objs = []
-        for i in inputs:
-            task = self.load_dict(i)
-            objs.append(task.output)
-        layout = value['layout']
-        output = self.relpath(value['output'])
-        self.runner.add_task(Link(objs, layout, output))
-
-    def handle_apps(self, value):
-        for a in value:
-            self.load_dict(a)
-
-    def load_dict(self, recipe):
-        for command, value in recipe.items():
-            return self.directive_handlers[command](value)
-
 
 def main(args):
     # Configure some logging:
--- a/test/testarmasm.py	Fri Feb 28 18:07:14 2014 +0100
+++ b/test/testarmasm.py	Sat Mar 01 15:40:31 2014 +0100
@@ -1,16 +1,16 @@
 import unittest
-import outstream
+from ppci.outstream import BinaryOutputStream
 from ppci.objectfile import ObjectFile
 from asm import Assembler
 from testasm import AsmTestCaseBase
-from target.target_list import arm_target, thumb_target
+from ppci.target.target_list import arm_target, thumb_target
 
 
 class ThumbAssemblerTestCase(AsmTestCaseBase):
     def setUp(self):
         self.t = thumb_target
         self.obj = ObjectFile()
-        self.o = outstream.BinaryOutputStream(self.obj)
+        self.o = BinaryOutputStream(self.obj)
         self.o.selectSection('.text')
         self.a = Assembler(target=self.t, stream=self.o)
 
@@ -153,7 +153,7 @@
     def setUp(self):
         self.t = arm_target
         self.obj = ObjectFile()
-        self.o = outstream.BinaryOutputStream(self.obj)
+        self.o = BinaryOutputStream(self.obj)
         self.o.selectSection('.text')
         self.a = Assembler(target=self.t, stream=self.o)
 
--- a/test/testasm.py	Fri Feb 28 18:07:14 2014 +0100
+++ b/test/testasm.py	Sat Mar 01 15:40:31 2014 +0100
@@ -6,8 +6,8 @@
 from ppci.assembler import tokenize, Assembler, Lexer
 from ppci.objectfile import ObjectFile
 from ppci.linker import Linker
-import outstream
-from target import Label
+from ppci.outstream import BinaryOutputStream
+from ppci.target.basetarget import Label
 
 
 class AssemblerLexingCase(unittest.TestCase):
@@ -96,7 +96,7 @@
 class OustreamTestCase(unittest.TestCase):
     def test1(self):
         obj = ObjectFile()
-        o = outstream.BinaryOutputStream(obj)
+        o = BinaryOutputStream(obj)
         o.selectSection('.text')
         o.emit(Label('a'))
         self.assertSequenceEqual(bytes(), obj.get_section('.text').data)
--- a/test/testbintools.py	Fri Feb 28 18:07:14 2014 +0100
+++ b/test/testbintools.py	Sat Mar 01 15:40:31 2014 +0100
@@ -1,9 +1,37 @@
 import unittest
 import sys
-from target.arminstructions import ArmToken
+from ppci.target.arm.token import ArmToken
 from ppci.linker import Linker
 from ppci.objectfile import ObjectFile
 from ppci import CompilerError
+from ppci.tasks import EmptyTask, TaskRunner, TaskError
+
+
+class TaskTestCase(unittest.TestCase):
+    def testCircular(self):
+        t1 = EmptyTask('t1')
+        t2 = EmptyTask('t2')
+        t1.add_dependency(t2)
+        with self.assertRaises(TaskError):
+            t2.add_dependency(t1)
+
+    def testCircularDeeper(self):
+        t1 = EmptyTask('t1')
+        t2 = EmptyTask('t2')
+        t3 = EmptyTask('t3')
+        t1.add_dependency(t2)
+        t2.add_dependency(t3)
+        with self.assertRaises(TaskError):
+            t3.add_dependency(t1)
+
+    def testSort(self):
+        t1 = EmptyTask('t1')
+        t2 = EmptyTask('t2')
+        runner = TaskRunner()
+        t1.add_dependency(t2)
+        runner.add_task(t1)
+        runner.add_task(t2)
+        runner.run_tasks()
 
 
 class TokenTestCase(unittest.TestCase):
--- a/test/testc3.py	Fri Feb 28 18:07:14 2014 +0100
+++ b/test/testc3.py	Sat Mar 01 15:40:31 2014 +0100
@@ -1,8 +1,8 @@
-from ppci.c3 import Builder, Lexer
-from target import SimpleTarget
-import ppci
 import unittest
 import io
+from ppci.c3 import Builder, Lexer
+from ppci.target import SimpleTarget
+import ppci
 
 
 class testLexer(unittest.TestCase):
--- a/test/testcg.py	Fri Feb 28 18:07:14 2014 +0100
+++ b/test/testcg.py	Sat Mar 01 15:40:31 2014 +0100
@@ -2,8 +2,8 @@
 import ppci
 from ppci.codegen import CodeGenerator
 from ppci import ir
-from target.target_list import thumb_target
-import outstream
+from ppci.target.target_list import thumb_target
+from ppci.outstream import BinaryOutputStream
 
 
 def genTestFunction():
@@ -18,7 +18,7 @@
         self.cg = CodeGenerator(thumb_target)
 
     def testFunction(self):
-        s = outstream.BinaryOutputStream(ppci.objectfile.ObjectFile())
+        s = BinaryOutputStream(ppci.objectfile.ObjectFile())
         m, f, bb = genTestFunction()
         bb.addInstruction(ir.Exp(ir.Const(123)))
         bb.addInstruction(ir.Jump(f.epiloog))
@@ -28,7 +28,7 @@
 
 class testArmCodeGeneration(unittest.TestCase):
     def testStack(self):
-        s = outstream.BinaryOutputStream(ppci.objectfile.ObjectFile())
+        s = BinaryOutputStream(ppci.objectfile.ObjectFile())
         cg = CodeGenerator(thumb_target)
         m, f, bb = genTestFunction()
         bb.addInstruction(ir.Move(ir.Mem(ir.Const(1)), ir.Const(22)))
--- a/test/testgraph.py	Fri Feb 28 18:07:14 2014 +0100
+++ b/test/testgraph.py	Sat Mar 01 15:40:31 2014 +0100
@@ -6,7 +6,7 @@
 from ppci.codegen.flowgraph import FlowGraph
 from ppci import ir
 from ppci.irmach import AbstractInstruction as AI
-from target import Nop
+from ppci.target import Nop
 
 
 class GraphTestCase(unittest.TestCase):
--- a/test/testir.py	Fri Feb 28 18:07:14 2014 +0100
+++ b/test/testir.py	Sat Mar 01 15:40:31 2014 +0100
@@ -83,6 +83,7 @@
         v1 = ir.Const(0)
         v3 = ir.Add(v1, ir.Const(0))
 
+
 class TestWriter(unittest.TestCase):
     def testWrite(self):
         writer = irutils.Writer()
@@ -106,7 +107,7 @@
             m = reader.read(f)
             self.assertTrue(m)
             #print(m)
-        
+
 
 if __name__ == '__main__':
     unittest.main()
--- a/test/testmsp430asm.py	Fri Feb 28 18:07:14 2014 +0100
+++ b/test/testmsp430asm.py	Sat Mar 01 15:40:31 2014 +0100
@@ -4,17 +4,17 @@
 from ppci.asmnodes import AInstruction, ABinop, AUnop, ASymbol, ALabel, ANumber
 from ppci.assembler import tokenize, Assembler
 from ppci.objectfile import ObjectFile
-import outstream
-from target import Label
-from target.target_list import msp430target
+from ppci.outstream import BinaryOutputStream
+from ppci.target import Label
+from ppci.target.target_list import msp430target
 from testasm import AsmTestCaseBase
 
 
-class AssemblerMSP430TestCase(AsmTestCaseBase):
+class Msp430AssemblerTestCase(AsmTestCaseBase):
     def setUp(self):
         self.t = msp430target
         self.obj = ObjectFile()
-        self.o = outstream.BinaryOutputStream(self.obj)
+        self.o = BinaryOutputStream(self.obj)
         self.o.selectSection('.text')
         self.a = Assembler(target=self.t, stream=self.o)
 
@@ -34,10 +34,6 @@
         self.feed("reti")
         self.check('0013')
 
-    def testMSPinstructionCount(self):
-        """ Check that there are 27 instructions """
-        self.assertEqual(27, len(self.t.instructions))
-
 
 if __name__ == '__main__':
     unittest.main()
--- a/test/testregalloc.py	Fri Feb 28 18:07:14 2014 +0100
+++ b/test/testregalloc.py	Sat Mar 01 15:40:31 2014 +0100
@@ -4,7 +4,7 @@
 from ppci.irmach import makeIns, Frame
 from ppci.codegen.registerallocator import RegisterAllocator
 from ppci import ir
-from target import Nop
+from ppci.target import Nop
 
 
 class RegAllocTestCase(unittest.TestCase):
--- a/test/testzcc.py	Fri Feb 28 18:07:14 2014 +0100
+++ b/test/testzcc.py	Sat Mar 01 15:40:31 2014 +0100
@@ -6,7 +6,7 @@
 from ppci.objectfile import ObjectFile
 import ppci
 import io
-import target
+from ppci.target import target_list
 
 # Store testdir for safe switch back to directory:
 testdir = os.path.dirname(os.path.abspath(__file__))
@@ -102,7 +102,7 @@
         """
         f = io.StringIO(src)
         out = ObjectFile()
-        tg = target.target_list.armtarget
+        tg = target_list.armtarget
         tr = ppci.tasks.TaskRunner()
         tr.add_task(ppci.buildtasks.Compile([f], [], tg, out))
         tr.run_tasks()