changeset 344:1378c4b027a0

Merge devel branch
author Windel Bouwman
date Sat, 01 Mar 2014 16:32:27 +0100
parents 6ee17c4dd6b8 (current diff) 11c5a8a70c02 (diff)
children b4882ff0ed06
files python/outstream.py python/target/__init__.py python/target/arm.brg python/target/armframe.py python/target/arminstructions.py python/target/arminstructionselector.py python/target/armtarget.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 test/gui/testhexedit.py
diffstat 88 files changed, 2837 insertions(+), 2524 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Fri Feb 21 13:35:07 2014 +0100
+++ b/.hgignore	Sat Mar 01 16:32:27 2014 +0100
@@ -4,6 +4,7 @@
 *.pyc
 *.o
 *.bin
+*.elf
 
 cos/bootdisk.img
 cos/lcfosinitrd.img
--- a/examples/c3/recipe.yaml	Fri Feb 21 13:35:07 2014 +0100
+++ b/examples/c3/recipe.yaml	Sat Mar 01 16:32:27 2014 +0100
@@ -3,11 +3,11 @@
   inputs:
     - assemble:
        source: startup_stm32f4.asm
-       machine: arm
+       machine: thumb
     - compile:
        sources: [burn2.c3]
        includes: [stm32f4xx.c3]
-       machine: arm
+       machine: thumb
        output: burn.elf2
   output: burn2.bin
   layout:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/experiments/qemu_vexpress_a9/debug.sh	Sat Mar 01 16:32:27 2014 +0100
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+qemu-system-arm -M vexpress-a9 -m 128M  -kernel test.bin \
+    -serial file:output.txt -s -S
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/experiments/qemu_vexpress_a9/display.c	Sat Mar 01 16:32:27 2014 +0100
@@ -0,0 +1,75 @@
+
+
+#define PL110_CR_EN             0x001
+#define PL110_CR_16BPP          0x008
+#define PL110_CR_MONO           0x010
+#define PL110_CR_TFT            0x020
+#define PL110_CR_MONO_8B        0x040
+#define PL110_CR_DUAL_LCD       0x080
+#define PL110_CR_BGR            0x100
+#define PL110_CR_BEBO           0x200
+#define PL110_CR_BEPO           0x400
+#define PL110_CR_PWR            0x800
+
+
+
+
+#define PL110_IOBASE            0x10020000
+#define FB_BASE                 0x60050000
+
+
+typedef unsigned int            uint32;
+typedef unsigned char           uint8;
+typedef unsigned short          uint16;
+
+typedef struct
+{
+    uint32          volatile tim0;          //0
+    uint32          volatile tim1;          //4
+    uint32          volatile tim2;          //8
+    uint32          volatile tim3;          //c
+    uint32          volatile upbase;        //10
+    uint32          volatile lpbase;        //14
+    uint32          volatile control;       //18
+} PL111MMIO;
+
+void print_uart0(const char *s);
+
+extern uint16* image_data;
+extern int image_width;
+extern int image_height;
+
+void do_display(void)
+{
+    uint16          volatile *fb;
+    PL111MMIO       *plio;
+    int             x, y;
+
+    plio = (PL111MMIO*)PL110_IOBASE;
+
+    plio->tim0 = 0x3f1f3f9c;
+    plio->tim1 = 0x080b61df;
+    plio->upbase = FB_BASE;
+
+    /* 16-bit color */
+    plio->control = PL110_CR_EN | (0xC) | PL110_CR_TFT | PL110_CR_PWR;
+
+    fb = (uint16*)FB_BASE;
+
+    for (x = 0; x < (640 * 480) - 10; ++x)
+        {
+                fb[x] = 0x1f << (5 + 6) | 0xf << 5;
+        }
+
+    print_uart0("Cleared disp\n");
+
+    for (x = 0; x < image_width; x++)
+    {
+        for (y = 0; y < image_height; y++)
+        {
+            fb[x + 640 * y] = image_data[x + image_width * y];
+        }
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/experiments/qemu_vexpress_a9/layout.ld	Sat Mar 01 16:32:27 2014 +0100
@@ -0,0 +1,14 @@
+
+ENTRY(_Reset)
+
+SECTIONS
+{
+ . = 0x60010000;
+ .startup . : { startup.o(.text) }
+ .text : {*(.text)}
+ .data : {*(.data)}
+ .bss : {*(.bss)}
+ . = . + 0x1000;
+ stack_top = .;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/experiments/qemu_vexpress_a9/main.c	Sat Mar 01 16:32:27 2014 +0100
@@ -0,0 +1,23 @@
+
+
+volatile unsigned int * const UART0_DR = (unsigned int *)0x10009000;
+
+
+void print_uart0(const char *s)
+{
+  while(*s != '\0') { /* Loop until end of string */
+    *UART0_DR = (unsigned int)(*s); /* Transmit char */
+    s++; /* Next char */
+  }
+}
+
+void do_display(void);
+
+void start(void)
+{
+    print_uart0("Hello world\n");
+    do_display();
+    for (;;);
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/experiments/qemu_vexpress_a9/make.sh	Sat Mar 01 16:32:27 2014 +0100
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+
+TARGET=arm-none-eabi
+MCPU=arm926ej-s
+
+python make_image.py
+$TARGET-as -mcpu=$MCPU -g startup.s -o startup.o
+$TARGET-gcc -c -g -mcpu=$MCPU -marm main.c -nostdlib -o main.o
+$TARGET-gcc -c -g -mcpu=$MCPU -marm display.c -nostdlib -o disp.o
+$TARGET-gcc -c -g -mcpu=$MCPU -marm image.c -nostdlib -o img.o
+$TARGET-ld -g -T layout.ld main.o startup.o disp.o img.o -o test.elf
+$TARGET-objcopy -O binary test.elf test.bin
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/experiments/qemu_vexpress_a9/make_image.py	Sat Mar 01 16:32:27 2014 +0100
@@ -0,0 +1,26 @@
+
+from PyQt5.QtGui import QImage, QGuiApplication, qRed, qBlue, qGreen
+
+app = QGuiApplication([])
+img = QImage('../../python/ide/icons/hardware.png')
+#print(img)
+
+f = open('image.c', 'w')
+print('typedef unsigned short uint16;',file=f)
+print('uint16 image_width = {};'.format(img.width()), file=f)
+print('uint16 image_height = {};'.format(img.height()), file=f)
+print('uint16 image_data[{}] = {{'.format(img.width()*img.height()+1), file=f)
+for y in range(img.height()):
+    for x in range(img.width()):
+        pix = img.pixel(x, y)
+        #print(qRed(pix))
+        r = qRed(pix) >> 3
+        g = qGreen(pix) >> 2
+        b = qBlue(pix) >> 3
+        u16 = (r << 11) | (g << 6) | b
+        assert u16 in range(2**16)
+        print('  {},'.format(hex(u16)),file=f)
+
+print('0x0};', file=f)
+f.close()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/experiments/qemu_vexpress_a9/run.sh	Sat Mar 01 16:32:27 2014 +0100
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+qemu-system-arm -M vexpress-a9 -m 128M  -kernel test.bin \
+    -serial file:output.txt
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/experiments/qemu_vexpress_a9/startup.s	Sat Mar 01 16:32:27 2014 +0100
@@ -0,0 +1,8 @@
+
+
+.global _Reset;
+_Reset:
+ LDR sp, =stack_top
+ BL start
+ B .
+
--- a/kernel/kernel.c3	Fri Feb 21 13:35:07 2014 +0100
+++ b/kernel/kernel.c3	Sat Mar 01 16:32:27 2014 +0100
@@ -8,6 +8,10 @@
 // Main entry point of the kernel:
 function void start()
 {
+   var int* UART0DR;
+   UART0DR = cast<int*>(0x10009000); // UART0 Data register
+   *UART0DR = 72;
+
     process.init();
     //memory:init();
 
@@ -15,6 +19,7 @@
     //Process proc = new process:Process();
 
     //scheduler:queue(proc);
+    while(true) {}
 }
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/make.sh	Sat Mar 01 16:32:27 2014 +0100
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+../python/zcc.py recipe recipe.yaml
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/monitor.sh	Sat Mar 01 16:32:27 2014 +0100
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+socat stdio UNIX-CONNECT:vm.sock
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/qemutst.sh	Sat Mar 01 16:32:27 2014 +0100
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+
+set -e
+
+echo "quit" | socat stdio stdio
+
+echo "Trying to run test on stellaris qemu machine"
+
+# -S means halt at start:
+qemu-system-arm -M vexpress-a9 -m 128M -kernel kernel.bin \
+    -monitor unix:vm.sock,server -serial file:output.txt -S -s
+
+#sleep 1
+
+# Send quit to the monitor application
+#echo "quit" | socat stdio UNIX-CONNECT:vm.sock
+
+#echo "Output from terminal:"
+#cat output.txt
+#echo ""
+
--- a/kernel/recipe.yaml	Fri Feb 21 13:35:07 2014 +0100
+++ b/kernel/recipe.yaml	Sat Mar 01 16:32:27 2014 +0100
@@ -2,15 +2,15 @@
 link:
   inputs:
     - assemble:
-       source: startup_m3.asm
-       machine: arm
+       source: startup_a9.asm
+       machine: thumb
     - compile:
        sources: [memory.c3, kernel.c3, syscall.c3, process.c3, schedule.c3, arch_arm.c3]
        includes: []
-       machine: arm
+       machine: thumb
        output: kernel.elf2
   layout:
-     code: 0x0
+     code: 0x10000
      data: 0x20000000
   output: kernel.bin
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/startup_a9.asm	Sat Mar 01 16:32:27 2014 +0100
@@ -0,0 +1,6 @@
+
+; DCD 0x20000678  ; Setup stack pointer
+DCD 0x06daa0e3 ; mov sp, #0x60 << 8
+DCD 0x60010009  ; Reset vector, jump to address 8
+B kernel_start          ; Branch to main (this is actually in the interrupt vector)
+
--- a/python/ide/hexedit.py	Fri Feb 21 13:35:07 2014 +0100
+++ b/python/ide/hexedit.py	Sat Mar 01 16:32:27 2014 +0100
@@ -1,20 +1,19 @@
 #!/usr/bin/python
 
 import sys
-import os
-from qtwrapper import QtGui, QtCore, QtWidgets, Qt
+from qtwrapper import QtGui, QtCore, QtWidgets, Qt, abspath, uic
 
 
 BYTES_PER_LINE, GAP = 8, 12
 
 def clamp(minimum, x, maximum):
-   return max(minimum, min(x, maximum))
+    return max(minimum, min(x, maximum))
 
 def asciiChar(v):
-   if v < 0x20 or v > 0x7e:
-      return '.'
-   else:
-      return chr(v)
+    if v < 0x20 or v > 0x7e:
+        return '.'
+    else:
+        return chr(v)
 
 class BinViewer(QtWidgets.QWidget):
    """ The view has an address, hex byte and ascii column """
@@ -99,18 +98,18 @@
          painter.fillRect(self.cursorX, self.cursorY + chh - 2, chw, 2, Qt.black)
 
    def keyPressEvent(self, event):
-      if event.matches(QKeySequence.MoveToNextChar):
+      if event.matches(QtGui.QKeySequence.MoveToNextChar):
          self.CursorPosition += 1
-      if event.matches(QKeySequence.MoveToPreviousChar):
+      if event.matches(QtGui.QKeySequence.MoveToPreviousChar):
          self.CursorPosition -= 1
-      if event.matches(QKeySequence.MoveToNextLine):
+      if event.matches(QtGui.QKeySequence.MoveToNextLine):
          self.CursorPosition += 2 * BYTES_PER_LINE
-      if event.matches(QKeySequence.MoveToPreviousLine):
+      if event.matches(QtGui.QKeySequence.MoveToPreviousLine):
          self.CursorPosition -= 2 * BYTES_PER_LINE
-      if event.matches(QKeySequence.MoveToNextPage):
+      if event.matches(QtGui.QKeySequence.MoveToNextPage):
          rows = int(self.scrollArea.viewport().height() / self.charHeight)
          self.CursorPosition += (rows - 1) * 2 * BYTES_PER_LINE
-      if event.matches(QKeySequence.MoveToPreviousPage):
+      if event.matches(QtGui.QKeySequence.MoveToPreviousPage):
          rows = int(self.scrollArea.viewport().height() / self.charHeight)
          self.CursorPosition -= (rows - 1) * 2 * BYTES_PER_LINE
       char = event.text().lower()
@@ -177,10 +176,9 @@
 
 
 class HexEditor(QtWidgets.QMainWindow):
-   def __init__(self):
+    def __init__(self):
       super().__init__()
-      basedir = os.path.dirname(__file__)
-      uic.loadUi(os.path.join(basedir, 'hexeditor.ui'), baseinstance=self)
+      uic.loadUi(abspath('hexeditor.ui'), baseinstance=self)
       self.he = HexEdit()
       self.setCentralWidget(self.he)
       self.actionOpen.triggered.connect(self.doOpen)
@@ -188,20 +186,24 @@
       self.actionSaveAs.triggered.connect(self.doSaveAs)
       self.fileName = None
       self.updateControls()
-   def updateControls(self):
+
+    def updateControls(self):
       s = True if self.fileName else False
       self.actionSave.setEnabled(s)
       self.actionSaveAs.setEnabled(s)
-   def doOpen(self):
-      filename = QFileDialog.getOpenFileName(self)
+
+    def doOpen(self):
+      filename = QtWidgets.QFileDialog.getOpenFileName(self)
       if filename:
          with open(filename, 'rb') as f:
             self.he.bv.Data = f.read()
          self.fileName = filename
       self.updateControls()
-   def doSave(self):
+
+    def doSave(self):
       self.updateControls()
-   def doSaveAs(self):
+
+    def doSaveAs(self):
       filename = QFileDialog.getSaveFileName(self)
       if filename:
          with open(filename, 'wb') as f:
@@ -211,8 +213,8 @@
 
 
 if __name__ == '__main__':
-   app = QApplication(sys.argv)
-   he = HexEditor()
-   he.show()
-   #he.bv.Data = bytearray(range(100)) * 8 + b'x'
-   app.exec()
+    app = QtWidgets.QApplication(sys.argv)
+    he = HexEditor()
+    he.show()
+    #he.bv.Data = bytearray(range(100)) * 8 + b'x'
+    app.exec()
--- a/python/ide/ide.py	Fri Feb 21 13:35:07 2014 +0100
+++ b/python/ide/ide.py	Sat Mar 01 16:32:27 2014 +0100
@@ -6,12 +6,14 @@
 import traceback
 import io
 
-from qtwrapper import QtGui, QtCore, QtWidgets, pyqtSignal, get_icon, abspath, Qt
+from qtwrapper import QtGui, QtCore, QtWidgets, pyqtSignal, get_icon
+from qtwrapper import abspath, Qt
 
 # Compiler imports:
 p = os.path.join(os.path.dirname(__file__), '..')
 sys.path.insert(0, p)
 sys.path.insert(0, os.path.join(p, 'utils'))
+
 import ppci
 from astviewer import AstViewer
 from codeedit import CodeEdit
@@ -19,8 +21,8 @@
 from disasm import Disassembly
 stutil = __import__('st-util')
 import zcc
-import outstream
-from target import armtarget
+from ppci.outstream import BinaryOutputStream
+from ppci.target.target_list import thumb_target
 
 
 def handle_exception(tp, v, tb):
@@ -279,9 +281,9 @@
             return
         fn = ce.FileName
         self.diag.clear()
-        outs = outstream.TextOutputStream()
+        outs = BinaryOutputStream()
         imps = [open(ce.FileName, 'r') for ce in self.allChildren() if ce.FileName and ce.FileName != fn]
-        if not zcc.zcc([open(fn, 'r')], imps, armtarget, outs, self.diag):
+        if not zcc.zcc([open(fn, 'r')], imps, thumb_target, outs, self.diag):
             # Set errors:
             self.builderrors.setErrorList(self.diag.diags)
             ce.setErrors(self.diag.diags)
--- a/python/ide/qtwrapper.py	Fri Feb 21 13:35:07 2014 +0100
+++ b/python/ide/qtwrapper.py	Sat Mar 01 16:32:27 2014 +0100
@@ -1,5 +1,5 @@
 import os
-from PyQt5 import QtCore, QtGui, QtWidgets
+from PyQt5 import QtCore, QtGui, QtWidgets, uic
 from PyQt5.QtCore import pyqtSignal, Qt
 
 def abspath(filename):
--- a/python/outstream.py	Fri Feb 21 13:35:07 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)
-        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 21 13:35:07 2014 +0100
+++ b/python/ppci/assembler.py	Sat Mar 01 16:32:27 2014 +0100
@@ -2,10 +2,20 @@
 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
 
-def tokenize(s):
+
+def bit_type(value):
+    assert value < (2**31)
+    assert value >= 0
+    t = 'val32'
+    for n in [16, 8, 5, 3]:
+        if value < (2**n):
+            t = 'val{}'.format(n)
+    return t
+
+def tokenize(s, kws):
     """
        Tokenizer, generates an iterator that
        returns tokens!
@@ -45,8 +55,13 @@
            val = float(val)
          elif typ == 'STRING':
            val = val[1:-1]
+         elif typ == 'ID':
+            if val.lower() in kws: # ['r3', 'sp', 'add', 'yield', 'r4', 'r0', 'r1', 'sub', 'r5', 'r6', 'r2']:
+                typ = val.lower()
          col = mo.start() - line_start
          loc = SourceLocation('', line, col, 0)   # TODO retrieve length?
+         if typ == 'NUMBER':
+            typ = bit_type(val)
          yield Token(typ, val, loc)
        pos = mo.end()
        mo = gettok(s, pos)
@@ -58,8 +73,8 @@
 
 
 class Lexer:
-    def __init__(self, src):
-        self.tokens = tokenize(src)
+    def __init__(self, src, kws):
+        self.tokens = tokenize(src, kws)
         self.curTok = self.tokens.__next__()
 
     def next_token(self):
@@ -70,11 +85,27 @@
 
 
 class Parser:
-    def __init__(self):
+    def add_rule(self, prod, rhs, f):
+        """ Helper function to add a rule, why this is required? """
+        if prod == 'instruction':
+            def f_wrap(*args):
+                i = f(args)
+                self.emit(i)
+        else:
+            def f_wrap(*rhs):
+                return f(rhs)
+        self.g.add_production(prod, rhs, f_wrap)
+
+    def __init__(self, kws, instruction_rules, emit):
         # Construct a parser given a grammar:
-        ident = lambda x: x   # Identity helper function
-        g = pyyacc.Grammar(['ID', 'NUMBER', ',', '[', ']', ':', '+', '-', '*', pyyacc.EPS, 'COMMENT', '{', '}',
-            pyyacc.EOF])
+        tokens2 = ['ID', 'NUMBER', ',', '[', ']', ':', '+', '-', '*',
+                   pyyacc.EPS, 'COMMENT', '{', '}',
+                   pyyacc.EOF, 'val32', 'val16', 'val8', 'val5', 'val3']
+        tokens2.extend(kws)
+        self.kws = kws
+        g = pyyacc.Grammar(tokens2)
+        self.g = g
+        # Global structure of assembly line:
         g.add_production('asmline', ['asmline2'])
         g.add_production('asmline', ['asmline2', 'COMMENT'])
         g.add_production('asmline2', ['label', 'instruction'])
@@ -83,28 +114,25 @@
         g.add_production('asmline2', [])
         g.add_production('label', ['ID', ':'], self.p_label)
         #g.add_production('label', [])
-        g.add_production('instruction', ['opcode', 'operands'], self.p_ins_1)
-        g.add_production('instruction', ['opcode'], self.p_ins_2)
+
+        # Add instruction rules for the target in question:
+        for prod, rhs, f in instruction_rules:
+            self.add_rule(prod, rhs, f)
+
         #g.add_production('instruction', [])
-        g.add_production('opcode', ['ID'], lambda x: x.val)
-        g.add_production('operands', ['operand'], self.p_operands_1)
-        g.add_production('operands', ['operands', ',', 'operand'], self.p_operands_2)
-        g.add_production('operand', ['expression'], ident)
-        g.add_production('operand', ['[', 'expression', ']'], self.p_mem_op)
-        g.add_production('operand', ['{', 'listitems', '}'], self.p_list_op)
-        g.add_production('listitems', ['expression'], self.p_listitems_1)
-        g.add_production('listitems', ['listitems', ',', 'expression'], self.p_listitems_2)
-        g.add_production('expression', ['term'], ident)
+        g.add_production('expression', ['term'], lambda x: x)
         g.add_production('expression', ['expression', 'addop', 'term'], self.p_binop)
         g.add_production('addop', ['-'], lambda x: x.val)
         g.add_production('addop', ['+'], lambda x: x.val)
         g.add_production('mulop', ['*'], lambda x: x.val)
-        g.add_production('term', ['factor'], ident)
+        g.add_production('term', ['factor'], lambda x: x)
         g.add_production('term', ['term', 'mulop', 'factor'], self.p_binop)
         g.add_production('factor', ['ID'], lambda name: ASymbol(name.val))
         g.add_production('factor', ['NUMBER'], lambda num: ANumber(int(num.val)))
         g.start_symbol = 'asmline'
-        self.p = g.genParser()
+        self.emit = emit
+        self.p = g.generate_parser()
+        # print('length of table:', len(self.p.action_table))
 
     # Parser handlers:
     def p_ins_1(self, opc, ops):
@@ -137,66 +165,40 @@
         return AUnop('[]', exp)
 
     def p_label(self, lname, cn):
-        lab = ALabel(lname.val)
+        lab = Label(lname.val)
         self.emit(lab)
 
     def p_binop(self, exp1, op, exp2):
         return ABinop(op, exp1, exp2)
 
-    def parse(self, lexer, emitter):
-        self.emit = emitter
+    def parse(self, lexer):
         self.p.parse(lexer)
 
-# Pre construct parser to save time:
-asmParser = Parser()
 
 class Assembler:
     def __init__(self, target, stream):
         self.target = target
-        assert isinstance(target,Target)
+        assert isinstance(target, Target)
         self.stream = stream
-        self.restart()
-        self.p = asmParser
+        self.parser = Parser(target.asm_keywords, target.assembler_rules, self.stream.emit)
 
     # Top level interface:
-    def restart(self):
-        self.stack = []
-
-    def emit(self, a):
-        """ Emit a parsed instruction """
-        self.stack.append(a)
-
     def parse_line(self, line):
-        """ Parse line into asm AST """
-        tokens = Lexer(line)
-        self.p.parse(tokens, self.emit)
+        """ Parse line into assembly instructions """
+        tokens = Lexer(line, self.target.asm_keywords)
+        self.parser.parse(tokens)
 
     def assemble(self, asmsrc):
         """ Assemble this source snippet """
-        if type(asmsrc) is not str:
+        if hasattr(asmsrc, 'read'):
             asmsrc2 = asmsrc.read()
             asmsrc.close()
             asmsrc = asmsrc2
+        # TODO: use generic newline??
+        # TODO: the bothersome newline ...
         for line in asmsrc.split('\n'):
-            self.assemble_line(line)
+            self.parse_line(line)
 
     def assemble_line(self, line):
-        """
-            Assemble a single source line.
-            Do not take newlines into account
-        """
+        """ Assemble a single assembly line. """
         self.parse_line(line)
-        self.assemble_aast()
-
-    def assemble_aast(self):
-        """ Assemble a parsed asm line """
-        while self.stack:
-            vi = self.stack.pop(0)
-            if type(vi) is AInstruction:
-                mi = self.target.mapInstruction(vi)
-            elif type(vi) is ALabel:
-                mi = Label(vi.name)
-            else:
-                raise NotImplementedError('{}'.format(vi))
-            if self.stream:
-                self.stream.emit(mi)
--- a/python/ppci/buildtasks.py	Fri Feb 21 13:35:07 2014 +0100
+++ b/python/ppci/buildtasks.py	Sat Mar 01 16:32:27 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 21 13:35:07 2014 +0100
+++ b/python/ppci/codegen/codegen.py	Sat Mar 01 16:32:27 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 21 13:35:07 2014 +0100
+++ b/python/ppci/irmach.py	Sat Mar 01 16:32:27 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 21 13:35:07 2014 +0100
+++ b/python/ppci/objectfile.py	Sat Mar 01 16:32:27 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 16:32:27 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 16:32:27 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 21 13:35:07 2014 +0100
+++ b/python/ppci/report.py	Sat Mar 01 16:32:27 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 16:32:27 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 16:32:27 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 16:32:27 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 16:32:27 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 16:32:27 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 16:32:27 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 16:32:27 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 16:32:27 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 16:32:27 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 16:32:27 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 16:32:27 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 16:32:27 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 16:32:27 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 16:32:27 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 16:32:27 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 16:32:27 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 16:32:27 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 16:32:27 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 16:32:27 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 16:32:27 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 16:32:27 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 16:32:27 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 16:32:27 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 21 13:35:07 2014 +0100
+++ b/python/ppci/tasks.py	Sat Mar 01 16:32:27 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/pyyacc.py	Fri Feb 21 13:35:07 2014 +0100
+++ b/python/pyyacc.py	Sat Mar 01 16:32:27 2014 +0100
@@ -201,14 +201,15 @@
                 if symbol not in self.Symbols:
                     raise ParserGenerationException('Symbol {0} undefined'.format(symbol))
 
-    def genParser(self):
-        """ Generates a parser from the grammar (using a caching algorithm) """
-        action_table, goto_table = self.doGenerate()
+    def generate_parser(self):
+        """ Generates a parser from the grammar """
+        action_table, goto_table = self.generate_tables()
         p = LRParser(action_table, goto_table, self.start_symbol)
         p.grammar = self
         return p
 
-    def doGenerate(self):
+    def generate_tables(self):
+        """ Generate parsing tables """
         if not self.start_symbol:
             self.start_symbol = self.productions[0].name
         self.checkSymbols()
@@ -265,7 +266,7 @@
 
 class Production:
     """ Production rule for a grammar """
-    def __init__(self, name, symbols, f=None):
+    def __init__(self, name, symbols, f):
         self.name = name
         self.symbols = symbols
         self.f = f
@@ -308,7 +309,7 @@
     @property
     def IsShift(self):
         """ Check if this item is a shift item, i.e. the dot can proceed """
-        return not self.IsReduce
+        return self.dotpos < len(self.production.symbols)
 
     @property
     def Next(self):
--- a/python/target/__init__.py	Fri Feb 21 13:35:07 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 21 13:35:07 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 Add, 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(Add, 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 21 13:35:07 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 .arminstructions 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(SP, SP, Imm7(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(SP, SP, Imm7(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 21 13:35:07 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,839 +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
-
-
-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):
-    getter = lambda s: s[b:e]
-    def setter(s, v):
-        s[b:e] = v
-    return property(getter, setter)
-
-class ArmToken:
-    def __init__(self):
-        self.bit_value = 0
-
-    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()
-
-    rd = bit_range(0, 3)
-
-    def encode(self):
-        return u16(self.bit_value)
-
-
-# Operands:
-
-class ArmRegister(Register):
-    def __init__(self, num, name):
-        super().__init__(name)
-        self.num = num
-
-    def __repr__(self):
-        return self.name
-
-    @classmethod
-    def Create(cls, vop):
-        if type(vop) is ASymbol:
-            name = vop.name
-            regs = {}
-            for r in registers:
-                regs[r.name] = r
-            if name in regs:
-                r = regs[name]
-                if isinstance(r, cls):
-                    return r
-
-
-class Reg8Op(ArmRegister):
-    pass
-
-
-class Reg16Op(ArmRegister):
-    pass
-
-
-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')
-# 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]
-
-
-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
-    
-
-class MemRegXRel:
-    def __init__(self, offset):
-        assert offset % 4 == 0
-        self.offset = offset
-
-    def __repr__(self):
-        return '[{}, #{}]'.format(self.regname, self.offset)
-
-    @classmethod
-    def Create(cls, vop):
-        if type(vop) is AUnop and vop.operation == '[]' and type(vop.arg) is ABinop and vop.arg.op == '+':
-            vop = vop.arg # descent
-            offset = isRegOffset(cls.regname, vop.arg1, vop.arg2)
-            if type(offset) is int:
-                if offset % 4 == 0:
-                    offset = vop.arg2.number
-                    return cls(offset)
-            elif type(vop) is ASymbol and vop.name.upper() == self.regname:
-                return cls(0)
-
-
-class MemSpRel(MemRegXRel):
-    regname = 'SP'
-
-
-class MemR8Rel:
-    def __init__(self, basereg, offset):
-        assert type(basereg) is Reg8Op
-        assert type(offset) is int
-        self.basereg = basereg
-        self.offset = offset
-
-    def __repr__(self):
-        return '[{}, #{}]'.format(self.basereg, self.offset)
-
-    @classmethod
-    def Create(cls, vop):
-        if type(vop) is AUnop and vop.operation == '[]':
-            vop = vop.arg # descent
-            if type(vop) is ABinop:
-                if vop.op == '+' and type(vop.arg1) is ASymbol and type(vop.arg2) is ANumber:
-                    offset = vop.arg2.number
-                    if offset > 120:
-                        return
-                    basereg = Reg8Op.Create(vop.arg1)
-                    if not basereg:
-                        return
-                else:
-                    return
-            elif type(vop) is ASymbol:
-                offset = 0
-                basereg = Reg8Op.Create(vop)
-                if not basereg:
-                    return
-            else:
-                return
-            return cls(getRegNum(basereg.num), offset)
-
-
-class RegisterSet:
-    def __init__(self, regs):
-        assert type(regs) is set
-        self.regs = regs
-
-    def __repr__(self):
-        return ','.join([str(r) for r in self.regs])
-
-    @classmethod
-    def Create(cls, vop):
-        assert type(vop) is AUnop and vop.operation == '{}'
-        assert type(vop.arg) is list
-        regs = set()
-        for arg in vop.arg:
-            if type(arg) is ASymbol:
-                reg = ArmRegister.Create(arg)
-                if not reg:
-                    return
-                regs.add(reg)
-            elif type(arg) is ABinop and arg.op == '-':
-                reg1 = ArmRegister.Create(arg.arg1)
-                reg2 = ArmRegister.Create(arg.arg2)
-                if not reg1:
-                    return
-                if not reg2:
-                    return
-                for r in getRegisterRange(reg1, reg2):
-                    regs.add(r)
-            else:
-                raise Exception('Cannot be')
-        return cls(regs)
-
-    def registerNumbers(self):
-        return [r.num for r in self.regs]
-
-
-
-# Instructions:
-
-class ArmInstruction(Instruction):
-    pass
-
-
-allins = []
-
-
-def instruction(i):
-    allins.append(i)
-    return i
-
-
-@instruction
-class Dcd(ArmInstruction):
-    mnemonic = 'dcd'
-    operands = (Imm32,)
-    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)
-
-
-@instruction
-class nop_ins(ArmInstruction):
-    mnemonic = 'nop'
-    operands = tuple()
-
-    def encode(self):
-        return bytes()
-
-    def __repr__(self):
-        return 'NOP'
-
-
-# Memory related
-
-class LS_imm5_base(ArmInstruction):
-    """ ??? Rt, [Rn, imm5] """
-    operands = (Reg8Op, MemR8Rel)
-    def __init__(self, rt, memop):
-        assert memop.offset % 4 == 0
-        self.imm5 = memop.offset >> 2
-        self.rn = memop.basereg.num
-        self.rt = rt
-        self.memloc = memop
-        assert self.rn < 8
-        assert self.rt.num < 8
-
-    def encode(self):
-        Rn = self.rn
-        Rt = self.rt.num
-        imm5 = self.imm5
-
-        h = (self.opcode << 11) | (imm5 << 6) | (Rn << 3) | Rt
-        return u16(h)
-
-
-    def __repr__(self):
-        return '{} {}, {}'.format(self.mnemonic, self.rt, self.memloc)
-
-
-@instruction
-class Str2(LS_imm5_base):
-    mnemonic = 'STR'
-    opcode = 0xC
-
-    @classmethod
-    def fromim(cls, im):
-        mem = MemR8Rel(im.src[0], im.others[0])
-        return cls(im.src[1], mem)
-
-
-@instruction
-class Ldr2(LS_imm5_base):
-    mnemonic = 'LDR'
-    opcode = 0xD
-
-    @classmethod
-    def fromim(cls, im):
-        mem = MemR8Rel(im.src[0], im.others[0])
-        return cls(im.dst[0], mem)
-
-class ls_sp_base_imm8(ArmInstruction):
-    operands = (Reg8Op, MemSpRel)
-    def __init__(self, rt, memop):
-        self.rt = rt
-        self.offset = memop.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):
-        return '{} {}, [sp,#{}]'.format(self.mnemonic, self.rt, self.offset)
-
-def align(x, m):
-    while ((x % m) != 0):
-        x = x + 1
-    return x
-
-
-@instruction
-class Ldr3(ArmInstruction):
-    """ ldr Rt, LABEL, load value from pc relative position """
-    mnemonic = 'ldr'
-    operands = (Reg8Op, LabelRef)
-    def __init__(self, rt, label):
-        assert isinstance(label, LabelRef)
-        self.rt = rt
-        self.label = label
-        self.offset = 0
-
-    @classmethod
-    def fromim(cls, im):
-        return cls(im.dst[0], im.others[0])
-
-    def relocations(self):
-        return [(self.label.name, 'lit_add_8')]
-
-    def encode(self):
-        rt = self.rt.num
-        assert rt < 8
-        assert self.offset % 4 == 0
-        imm8 = self.offset >> 2
-        assert imm8 < 256
-        assert imm8 >= 0
-        h = (0x9 << 11) | (rt << 8) | imm8
-        return u16(h)
-
-    def __repr__(self):
-        return 'LDR {}, {}'.format(self.rt, self.label.name)
-
-
-@instruction
-class Ldr1(ls_sp_base_imm8):
-    """ ldr Rt, [SP, imm8] """
-    mnemonic = 'LDR'
-    opcode = 0x98
-
-
-@instruction
-class Str1(ls_sp_base_imm8):
-    """ str Rt, [SP, imm8] """
-    mnemonic = 'STR'
-    opcode = 0x90
-
-
-@instruction
-class Mov3(ArmInstruction):
-    """ mov Rd, imm8, move immediate value into register """
-    mnemonic = 'mov'
-    opcode = 4 # 00100 Rd(3) imm8
-    operands = (Reg8Op, Imm8)
-    def __init__(self, rd, imm):
-        if type(imm) is int:
-            imm = Imm8(imm)
-        assert type(imm) is Imm8
-        self.imm = imm.imm
-        assert type(rd) is Reg8Op, str(type(rd))
-        self.rd = rd
-
-    @classmethod
-    def fromim(cls, im):
-        return cls(im.dst[0], im.others[0])
-
-    def encode(self):
-        rd = self.rd.num
-        opcode = self.opcode
-        imm8 = self.imm
-        h = (opcode << 11) | (rd << 8) | imm8
-        return u16(h)
-
-    def __repr__(self):
-        return 'MOV {}, {}'.format(self.rd, self.imm)
-
-
-
-# Arithmatics:
-
-
-
-class regregimm3_base(ArmInstruction):
-    operands = (Reg8Op, Reg8Op, Imm3)
-    def __init__(self, rd, rn, imm3):
-        self.rd = rd
-        self.rn = rn
-        assert type(imm3) is Imm3
-        self.imm3 = imm3
-
-    @classmethod
-    def fromim(cls, im):
-        return cls(im.dst[0], im.src[0], im.others[0])
-
-    def encode(self):
-        rd = self.rd.num
-        rn = self.rn.num
-        imm3 = self.imm3.imm
-        opcode = self.opcode
-        h = (self.opcode << 9) | (imm3 << 6) | (rn << 3) | rd
-        return u16(h)
-
-    def __repr__(self):
-        return '{} {}, {}, {}'.format(self.mnemonic, self.rd, self.rn, self.imm3.imm)
-
-@instruction
-class Add2(regregimm3_base):
-    """ add Rd, Rn, imm3 """
-    mnemonic = 'add'
-    opcode = 0b0001110
-
-
-@instruction
-class Sub2(regregimm3_base):
-    """ sub Rd, Rn, imm3 """
-    mnemonic = 'sub'
-    opcode = 0b0001111
-
-
-class regregreg_base(ArmInstruction):
-    """ ??? Rd, Rn, Rm """
-    operands = (Reg8Op, Reg8Op, Reg8Op)
-    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 = ArmToken()
-        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
-        #h = (self.opcode << 9) | (rm << 6) | (rn << 3) | rd
-        #return u16(h)
-        return at.encode()
-
-    def __repr__(self):
-        return '{} {}, {}, {}'.format(self.mnemonic, self.rd, self.rn, self.rm)
-
-
-@instruction
-class Add(regregreg_base):
-    mnemonic = 'ADD'
-    opcode = 0b0001100
-
-
-@instruction
-class Sub(regregreg_base):
-    mnemonic = 'SUB'
-    opcode = 0b0001101
-
-
-@instruction
-class Mov2(ArmInstruction):
-    """ mov rd, rm """
-    operands = (ArmRegister, ArmRegister)
-    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 = ArmToken()
-        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() # u16((opcode << 8) | (D << 7) |(Rm << 3) | Rd)
-
-    def __repr__(self):
-        return '{} {}, {}'.format(self.mnemonic, self.rd, self.rm)
-
-
-@instruction
-class Mul(ArmInstruction):
-    """ mul Rn, Rdm """
-    operands = (Reg8Op, Reg8Op)
-    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 = ArmToken()
-        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(ArmInstruction):
-    """ ??? Rdn, Rm """
-    operands = (Reg8Op, Reg8Op)
-    # TODO: integrate with the code gen interface:
-    src = (0, 1)
-    dst = (0,)
-    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 = ArmToken()
-        at.rd = self.rdn.num
-        rm = self.rm.num
-        at[3:6] = rm
-        at[6:16] = self.opcode
-        return at.encode()
-
-    def __repr__(self):
-        return '{} {}, {}'.format(self.mnemonic, self.rdn, self.rm)
-
-
-@instruction
-class movregreg_ins(regreg_base):
-    """ mov Rd, Rm (reg8 operands) """
-    mnemonic = 'mov'
-    opcode = 0
-
-
-@instruction
-class And(regreg_base):
-    mnemonic = 'AND'
-    opcode = 0b0100000000
-
-
-@instruction
-class Orr(regreg_base):
-    mnemonic = 'ORR'
-    opcode = 0b0100001100
-
-
-@instruction
-class Cmp(regreg_base):
-    mnemonic = 'CMP'
-    opcode = 0b0100001010
-
-
-@instruction
-class Lsl(regreg_base):
-    mnemonic = 'LSL'
-    opcode = 0b0100000010
-
-
-@instruction
-class cmpregimm8_ins(ArmInstruction):
-    """ cmp Rn, imm8 """
-    mnemonic = 'cmp'
-    opcode = 5 # 00101
-    operands = (Reg8Op, Imm8)
-    def __init__(self, rn, imm):
-        self.rn = rn
-        self.imm = imm
-
-    def encode(self):
-        rn = self.rn.num
-        imm = self.imm.imm
-        opcode = self.opcode
-        h = (opcode << 11) | (rn << 8) | imm
-        return u16(h)
-
-
-# Jumping:
-
-def wrap_negative(x, bits):
-    b = struct.unpack('<I', struct.pack('<i', x))[0]
-    mask = (1 << bits) - 1
-    return b & mask
-
-class jumpBase_ins(ArmInstruction):
-    operands = (LabelRef,)
-    def __init__(self, target_label):
-        assert type(target_label) is LabelRef
-        self.target = target_label
-        self.offset = 0
-
-    def __repr__(self):
-        return '{} {}'.format(self.mnemonic, self.target.name)
-
-
-class Imm11Reloc:
-    def apply(self, P, S):
-        pass
-
-
-@instruction
-class B(jumpBase_ins):
-    mnemonic = 'B'
-    def encode(self):
-        imm11 = wrap_negative(self.offset >> 1, 11)
-        h = (0b11100 << 11) | imm11 # | 1 # 1 to enable thumb mode
-        return u16(h)
-
-    def relocations(self):
-        return [(self.target.name, 'wrap_new11')]
-
-@instruction
-class Bl(jumpBase_ins):
-    mnemonic = 'BL'
-    def encode(self):
-        imm32 = wrap_negative(self.offset >> 1, 32)
-        imm11 = imm32 & 0x7FF
-        imm10 = (imm32 >> 11) & 0x3FF
-        j1 = 1 # TODO: what do these mean?
-        j2 = 1
-        s = (imm32 >> 24) & 0x1
-        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.name, 'bl_imm11_imm10')]
-
-
-class cond_base_ins(jumpBase_ins):
-    def encode(self):
-        imm8 = wrap_negative(self.offset >> 1, 8)
-        h = (0b1101 << 12) | (self.cond << 8) | imm8
-        return u16(h)
-
-    def relocations(self):
-        return [(self.target.name, '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.name, 'b_imm11_imm6')]
-
-
-@instruction
-class Beq(cond_base_ins):
-    mnemonic = 'beq'
-    cond = 0
-
-
-@instruction
-class Bne(cond_base_ins):
-    mnemonic = 'bne'
-    cond = 1
-
-
-@instruction
-class Blt(cond_base_ins):
-    mnemonic = 'blt'
-    cond = 0b1011
-
-
-@instruction
-class Bgt(cond_base_ins):
-    mnemonic = 'bgt'
-    cond = 0b1100
-
-
-@instruction
-class Push(ArmInstruction):
-    operands = (RegisterSet,)
-    mnemonic = 'push'
-
-    def __init__(self, regs):
-        if type(regs) is set:
-            regs = RegisterSet(regs)
-        assert (type(regs),) == self.operands, (type(regs),)
-        self.regs = regs
-
-    def __repr__(self):
-        return '{0} {{{1}}}'.format(self.mnemonic, self.regs)
-
-    def encode(self):
-        reg_list = 0
-        M = 0
-        for n in self.regs.registerNumbers():
-            if n < 8:
-                reg_list |= (1 << n)
-            elif n == 14:
-                M = 1
-            else:
-                raise NotImplementedError('not implemented for this register')
-        h = (0x5a << 9) | (M << 8) | reg_list
-        return u16(h)
-
-
-@instruction
-class Pop(ArmInstruction):
-    operands = (RegisterSet,)
-    mnemonic = 'pop'
-
-    def __init__(self, regs):
-        if type(regs) is set:
-            regs = RegisterSet(regs)
-        assert (type(regs),) == self.operands, (type(regs),)
-        self.regs = regs
-
-    def __repr__(self):
-        return '{0} {{{1}}}'.format(self.mnemonic, self.regs)
-
-    def encode(self):
-        reg_list = 0
-        P = 0
-        for n in self.regs.registerNumbers():
-            if n < 8:
-                reg_list |= (1 << n)
-            elif n == 15:
-                P = 1
-            else:
-                raise NotImplementedError('not implemented for this register')
-        h = (0x5E << 9) | (P << 8) | reg_list
-        return u16(h)
-
-
-@instruction
-class Yield(ArmInstruction):
-    operands = ()
-    mnemonic = 'yield'
-
-    def encode(self):
-        return u16(0xbf10)
-
-# misc:
-
-# add/sub SP:
-class addspsp_base(ArmInstruction):
-    operands = (RegSpOp, RegSpOp, Imm7)
-    def __init__(self, _sp, _sp2, imm7):
-        self.imm7 = imm7.imm
-        assert self.imm7 % 4 == 0
-        self.imm7 >>= 2
-
-    def encode(self):
-        return u16((self.opcode << 7) |self.imm7)
-
-    def __repr__(self):
-        return '{} sp, sp, {}'.format(self.mnemonic, self.imm7 << 2)
-
-
-@instruction
-class AddSp(addspsp_base):
-    mnemonic = 'add'
-    opcode = 0b101100000
-
-
-@instruction
-class SubSp(addspsp_base):
-    mnemonic = 'sub'
-    opcode = 0b101100001
--- a/python/target/arminstructionselector.py	Fri Feb 21 13:35:07 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 Add, Sub, Cmp, Sub2, Add2, 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/armtarget.py	Fri Feb 21 13:35:07 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-import struct
-from .basetarget import Register, Instruction, Target, Label, LabelRef
-from .basetarget import Imm32, Imm8, Imm7, Imm3
-from .arminstructions import allins, Reg8Op, ArmRegister
-from .arminstructions import Dcd, B
-from .arminstructions import R0, R1, R2, R3, R4, R5, R6, R7, LR, PC, SP
-
-from .armframe import ArmFrame
-from .arminstructionselector import ArmInstructionSelector
-
-""" ARM target description. """
-
-# TODO: encode this in DSL (domain specific language)
-# TBD: is this required?
-# TODO: make a difference between armv7 and armv5?
-
-
-class ArmTarget(Target):
-    def __init__(self):
-        super().__init__('arm')
-        for i in allins:
-            self.addInstruction(i)
-            # TODO: fix this nicer?
-            #setattr(self, i.__name__, i)
-        self.check()
-        self.ins_sel = ArmInstructionSelector()
-        self.FrameClass = ArmFrame
--- a/python/target/armv7.lidl	Fri Feb 21 13:35:07 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 21 13:35:07 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,191 +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.instructions = []
-        self.byte_sizes = {'int':4}  # For front end!
-
-    def instruction(self, cls):
-        """ Decorator function that registers an instruction to this target """
-        self.addInstruction(cls)
-        return cls
-
-    def check(self):
-        """ Check target """
-        for i in self.instructions:
-            assert hasattr(i, 'mnemonic')
-            assert hasattr(i, 'operands'), str(i)
-            assert type(i.mnemonic) is str
-            assert type(i.operands) is tuple, str(i)
-
-    def addInstruction(self, ins_class):
-        self.instructions.append(ins_class)
-
-    def mapOperand(self, operand):
-        """ Try to map an operand to a target type """
-        if type(operand) is ASymbol:
-            # Try to map to register:
-            regs = {}
-            for r in self.registers:
-                regs[r.name] = r
-            if operand.name in regs:
-                return regs[operand.name]
-        raise CompilerError('Cannot map {0}'.format(operand))
-
-    def mapInstruction(self, vi):
-        assert type(vi) is AInstruction
-        """ Map ast tree to real instruction for this target """
-
-        # map to real operands:
-        if vi.mnemonic.upper() == 'ALIGN' and len(vi.operands) == 1:
-            if type(vi.operands[0]) == ANumber:
-                return Alignment(vi.operands[0].number)
-
-        # look for a suitable instruction
-        for ic in self.instructions:
-            if ic.mnemonic.upper() == vi.mnemonic.upper() and len(ic.operands) == len(vi.operands):
-                # Try to map operands to the correct operand types:
-                rops = [roptype.Create(vop) for roptype, vop in zip(ic.operands, vi.operands)]
-
-                # Check if we succeeded:
-                if all(isinstance(rop, optype) for rop, optype in zip(rops, ic.operands)):
-                    return ic(*rops)
-        raise CompilerError('No suitable instruction found for "{0}"'.format(vi))
--- a/python/target/instructionselector.py	Fri Feb 21 13:35:07 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 21 13:35:07 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,247 +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):
-msp430target = Target("MSP430")
-
-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:
-#########################
-
-@msp430target.instruction
-class reti_ins(MSP430Instruction):
-    mnemonic = 'reti'
-    operands = ()
-    def encode(self):
-        h = 0x1300
-        return pack_ins(h)
-
-class OneOpArith(MSP430Instruction):
-    operands = (MSP430Reg, )
-    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)
-
-@msp430target.instruction
-class jnz_ins(JumpInstruction):
-    mnemonic = 'jnz'
-    condition = 0
-
-@msp430target.instruction
-class jz_ins(JumpInstruction):
-    mnemonic = 'jz'
-    condition = 1
-
-@msp430target.instruction
-class jnc_ins(JumpInstruction):
-    mnemonic = 'jnc'
-    condition = 2
-
-@msp430target.instruction
-class jc_ins(JumpInstruction):
-    mnemonic = 'jc'
-    condition = 3
-
-@msp430target.instruction
-class jn_ins(JumpInstruction):
-    mnemonic = 'jn'
-    condition = 4
-
-@msp430target.instruction
-class jge_ins(JumpInstruction):
-    mnemonic = 'jge'
-    condition = 5
-
-@msp430target.instruction
-class jl_ins(JumpInstruction):
-    mnemonic = 'jl'
-    condition = 6
-
-@msp430target.instruction
-class jmp_ins(JumpInstruction):
-    mnemonic = 'jmp'
-    condition = 7
-
-#########################
-# Two operand arithmatic instructions:
-#########################
-
-
-class TwoOpArith(MSP430Instruction):
-    operands = (MSP430Operand, MSP430Operand)
-    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)
-    msp430target.addInstruction(ins_cls)
-
-twoOpIns('mov', 4)
-
-# This is equivalent to the helper function twoOpIns:
-@msp430target.instruction
-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 21 13:35:07 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 21 13:35:07 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 21 13:35:07 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-
-from .armtarget import ArmTarget
-from .msp430 import msp430target
-
-# Instance:
-armtarget = ArmTarget()
-
-target_list = [armtarget]
--- a/python/target/target_x86.py	Fri Feb 21 13:35:07 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 21 13:35:07 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 21 13:35:07 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 21 13:35:07 2014 +0100
+++ b/python/yacc.py	Sat Mar 01 16:32:27 2014 +0100
@@ -209,7 +209,7 @@
         self.grammar = grammar
         self.headers = headers
         self.logger.info('Generating parser for grammar {}'.format(grammar))
-        self.action_table, self.goto_table = grammar.doGenerate()
+        self.action_table, self.goto_table = grammar.generate_tables()
         self.generate_python_script()
 
     def print(self, *args):
@@ -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 21 13:35:07 2014 +0100
+++ b/python/zcc.py	Sat Mar 01 16:32:27 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/gui/testhexedit.py	Fri Feb 21 13:35:07 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-import unittest
-import hexedit
-from PyQt4.QtGui import QApplication
-from PyQt4.QtTest import QTest
-from PyQt4.QtCore import Qt
-import sys
-
-
-class HexTest(unittest.TestCase):
-    def setUp(self):
-        self.app = QApplication(sys.argv)
-        self.ui = hexedit.HexEditor()
-        self.bv = self.ui.he.bv
-        # Provide some random data:
-        self.bv.Data = bytearray(range(10)) * 8 + b'x'
-
-    def tearDown(self):
-        self.app.processEvents()
-        self.app.quit()
-
-    def testOpenButton(self):
-        self.assertEqual(0, self.bv.CursorPosition)
-        #QTest.mouseClick(self.bv, Qt.LeftButton)
-        self.assertEqual(161, self.bv.CursorPosition)
-        QTest.keyClick(self.bv, Qt.Key_Left)
-        self.assertEqual(160, self.bv.CursorPosition)
-        QTest.keyClick(self.bv, Qt.Key_Up)
-        self.assertEqual(128, self.bv.CursorPosition)
-
-
-if __name__ == '__main__':
-    unittest.main()
--- a/test/runtests.sh	Fri Feb 21 13:35:07 2014 +0100
+++ b/test/runtests.sh	Sat Mar 01 16:32:27 2014 +0100
@@ -1,15 +1,13 @@
 #!/usr/bin/env bash
 
-export PYTHONPATH=$PYTHONPATH:`pwd`/../python
+export PYTHONPATH=$PYTHONPATH:`pwd`/../python:`pwd`/../python/ide
 
 if [ "$1" == "loop" ]
 then
   DIR=..
   while :; do
     python -m unittest
-    cd gui
     #python -m unittest -v
-    cd ..
     echo "Awaiting changes in $DIR"
     inotifywait -r -e modify $DIR
   done
--- a/test/testarmasm.py	Fri Feb 21 13:35:07 2014 +0100
+++ b/test/testarmasm.py	Sat Mar 01 16:32:27 2014 +0100
@@ -1,22 +1,19 @@
 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 armtarget
+from ppci.target.target_list import arm_target, thumb_target
 
 
-class AssemblerARMTestCase(AsmTestCaseBase):
+class ThumbAssemblerTestCase(AsmTestCaseBase):
     def setUp(self):
-        self.t = armtarget
+        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)
 
-    def testMapOperand(self):
-        pass
-
     def testMovImm8(self):
         self.feed('mov r4, 100')
         self.check('6424')
@@ -149,3 +146,17 @@
         self.feed('bne henkie')
         self.feed('b henkie')
         self.check('32b41519 94420198 049332bc a340ab42 f6d0f5d1 f4e7')
+
+
+class AssemblerArmTestCase(AsmTestCaseBase):
+    """ ARM-mode (not thumb-mode) instruction assembly test case """
+    def setUp(self):
+        self.t = arm_target
+        self.obj = ObjectFile()
+        self.o = BinaryOutputStream(self.obj)
+        self.o.selectSection('.text')
+        self.a = Assembler(target=self.t, stream=self.o)
+
+    def testMovImm(self):
+        self.feed('mov r4, 100')
+        self.check('6440a0e3')
--- a/test/testasm.py	Fri Feb 21 13:35:07 2014 +0100
+++ b/test/testasm.py	Sat Mar 01 16:32:27 2014 +0100
@@ -3,11 +3,11 @@
 import unittest, cProfile
 from ppci import CompilerError
 from ppci.asmnodes import AInstruction, ABinop, AUnop, ASymbol, ALabel, ANumber
-from ppci.assembler import tokenize, Assembler, asmParser, Lexer
+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):
@@ -16,23 +16,23 @@
     def testLex0(self):
         """ Check if the lexer is OK """
         asmline, toks = 'mov rax, rbx ', ['ID', 'ID', ',', 'ID', 'EOF']
-        self.assertSequenceEqual([tok.typ for tok in tokenize(asmline)], toks)
+        self.assertSequenceEqual([tok.typ for tok in tokenize(asmline, [])], toks)
 
     def testLex1(self):
         """ Test if lexer correctly maps some tokens """
         asmline, toks = 'lab1: mov rax, rbx ', ['ID', ':', 'ID', 'ID', ',', 'ID', 'EOF']
-        self.assertSequenceEqual([tok.typ for tok in tokenize(asmline)], toks)
+        self.assertSequenceEqual([tok.typ for tok in tokenize(asmline, [])], toks)
 
     def testLex2(self):
         """ Test if lexer correctly maps some tokens """
-        asmline, toks = 'mov 3.13 0xC 13', ['ID', 'REAL', 'NUMBER', 'NUMBER', 'EOF']
-        self.assertSequenceEqual([tok.typ for tok in tokenize(asmline)], toks)
+        asmline, toks = 'mov 3.13 0xC 13', ['ID', 'REAL', 'val5', 'val5', 'EOF']
+        self.assertSequenceEqual([tok.typ for tok in tokenize(asmline, [])], toks)
 
     def testLex3(self):
         """ Test if lexer fails on a token that is invalid """
         asmline = '0z4: mov rax, rbx $ '
         with self.assertRaises(CompilerError):
-            list(tokenize(asmline))
+            list(tokenize(asmline, []))
 
 
 class AssemblerParsingTestCase(unittest.TestCase):
@@ -40,6 +40,7 @@
         Tests the assembler parts
     """
     def setUp(self):
+        self.skipTest('refactoring asm parser')
         self.parser = asmParser
         self.stack = []
 
@@ -95,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 21 13:35:07 2014 +0100
+++ b/test/testbintools.py	Sat Mar 01 16:32:27 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 21 13:35:07 2014 +0100
+++ b/test/testc3.py	Sat Mar 01 16:32:27 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 21 13:35:07 2014 +0100
+++ b/test/testcg.py	Sat Mar 01 16:32:27 2014 +0100
@@ -2,8 +2,8 @@
 import ppci
 from ppci.codegen import CodeGenerator
 from ppci import ir
-from target.target_list import armtarget
-import outstream
+from ppci.target.target_list import thumb_target
+from ppci.outstream import BinaryOutputStream
 
 
 def genTestFunction():
@@ -15,10 +15,10 @@
 
 class testCodeGeneration(unittest.TestCase):
     def setUp(self):
-        self.cg = CodeGenerator(armtarget)
+        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,8 +28,8 @@
 
 class testArmCodeGeneration(unittest.TestCase):
     def testStack(self):
-        s = outstream.BinaryOutputStream(ppci.objectfile.ObjectFile())
-        cg = CodeGenerator(armtarget)
+        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)))
         bb.addInstruction(ir.Jump(f.epiloog))
--- a/test/testemulation.py	Fri Feb 21 13:35:07 2014 +0100
+++ b/test/testemulation.py	Sat Mar 01 16:32:27 2014 +0100
@@ -21,7 +21,7 @@
     def tearDown(self):
         os.chdir(testdir)
 
-    def runQemu(self, kernel, timespan=2):
+    def runQemu(self, kernel):
         args = ['qemu-system-arm', '-M', 'lm3s811evb', '-m', '16M', 
             '-nographic', '-kernel', kernel, '-monitor',
             'unix:qemucontrol.sock,server',
@@ -35,7 +35,7 @@
         qemu_control = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
         qemu_control.connect('qemucontrol.sock')
 
-        time.sleep(2.5)
+        time.sleep(0.5)
 
         # Now connect to the serial output:
         qemu_serial = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
@@ -47,9 +47,7 @@
 
         # Send quit command:
         qemu_control.send("quit\n".encode('ascii'))
-
-        p.wait(timeout=timespan)
-
+        p.wait(timeout=3)
         qemu_control.close()
         qemu_serial.close()
 
--- a/test/testgraph.py	Fri Feb 21 13:35:07 2014 +0100
+++ b/test/testgraph.py	Sat Mar 01 16:32:27 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):
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testhexedit.py	Sat Mar 01 16:32:27 2014 +0100
@@ -0,0 +1,42 @@
+import sys
+import unittest
+
+import hexedit
+#import ide
+
+from PyQt5.QtWidgets import QApplication
+from PyQt5.QtTest import QTest
+from PyQt5.QtCore import Qt
+
+
+class HexEditorTest(unittest.TestCase):
+    def setUp(self):
+        self.app = QApplication(sys.argv)
+        self.ui = hexedit.HexEditor()
+        self.bv = self.ui.he.bv
+        # Provide some random data:
+        self.bv.Data = bytearray(range(10)) * 8 + b'x'
+
+    def tearDown(self):
+        self.app.processEvents()
+        self.app.quit()
+
+    def tstOpenFile(self):
+        pass
+        #self.ui.actionOpen.trigger()
+        #w = self.app.activeWindow()
+        #print(w)
+        #QTest.keyClick(self.ui, Qt.Key_Escape)
+
+    def tstDataInView(self):
+        self.assertEqual(0, self.bv.CursorPosition)
+        QTest.mouseClick(self.bv, Qt.LeftButton)
+        self.assertEqual(154, self.bv.CursorPosition)
+        QTest.keyClick(self.bv, Qt.Key_Left)
+        self.assertEqual(153, self.bv.CursorPosition)
+        QTest.keyClick(self.bv, Qt.Key_Up)
+        self.assertEqual(137, self.bv.CursorPosition)
+
+
+if __name__ == '__main__':
+    unittest.main()
--- a/test/testir.py	Fri Feb 21 13:35:07 2014 +0100
+++ b/test/testir.py	Sat Mar 01 16:32:27 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 21 13:35:07 2014 +0100
+++ b/test/testmsp430asm.py	Sat Mar 01 16:32:27 2014 +0100
@@ -4,28 +4,20 @@
 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)
 
-    def testMapMovInstruction(self):
-        i = AInstruction('mov', [ASymbol('r14'), ASymbol('r15')])
-        ri = self.t.mapInstruction(i)
-
-    def testMapRetiInstruction(self):
-        i = AInstruction('reti', [])
-        ri = self.t.mapInstruction(i)
-
     def testMov(self):
         self.feed("mov r14, r15")
         self.check('0F4E')
@@ -42,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/testpyy.py	Fri Feb 21 13:35:07 2014 +0100
+++ b/test/testpyy.py	Sat Mar 01 16:32:27 2014 +0100
@@ -37,7 +37,7 @@
         # 2. define input:
         tokens = genTokens(['identifier', '+', 'identifier', '+', 'identifier'])
         # 3. build parser:
-        p = g.genParser()
+        p = g.generate_parser()
         # 4. feed input:
         p.parse(tokens)
 
@@ -52,7 +52,7 @@
         g.add_production('c', ['id'])
         g.start_symbol = 'goal'
         with self.assertRaises(ParserGenerationException):
-            p = g.genParser()
+            p = g.generate_parser()
 
     def testShiftReduceConflict(self):
         """ Must be handled automatically by doing shift """
@@ -63,7 +63,7 @@
         g.add_production('stmt', ['if_stmt'])
         g.add_production('stmt', ['ass'])
         g.start_symbol = 'stmt'
-        p = g.genParser()
+        p = g.generate_parser()
         # Ambiguous program:
         tokens = genTokens(['if', 'then','if', 'then', 'ass', 'else', 'ass'])
         p.parse(tokens)
@@ -76,7 +76,7 @@
         g.add_production('a', ['c'])
         g.start_symbol = 'goal'
         with self.assertRaises(ParserGenerationException):
-            g.genParser()
+            g.generate_parser()
 
     def testRedefineTerminal(self):
         """ Test correct behavior when a terminal is redefined """
@@ -86,14 +86,14 @@
             g.add_production('b', ['c']) # Not allowed
         g.add_production('a', ['c'])
         g.start_symbol = 'goal'
-        g.genParser()
+        g.generate_parser()
 
     def testEmpty(self):
         """ Test empty token stream """
         g = Grammar([','])
         g.add_production('input', [','])
         g.start_symbol = 'input'
-        p = g.genParser()
+        p = g.generate_parser()
         tokens = genTokens([])
         with self.assertRaises(ParserException):
             p.parse(tokens)
@@ -105,7 +105,7 @@
         g.add_production('optional_a', ['a'])
         g.add_production('optional_a', [])
         g.start_symbol = 'input'
-        p = g.genParser()
+        p = g.generate_parser()
         tokens = genTokens(['b'])
         p.parse(tokens)
 
@@ -117,7 +117,7 @@
         g.add_production('ins', ['id'])
         g.add_production('op1', ['id'])
         g.start_symbol = 'input'
-        p = g.genParser()
+        p = g.generate_parser()
         tokens = genTokens(['id', ':', 'id', 'id'])   # i.e. "lab_0: inc rax" 
         p.parse(tokens)
         tokens = genTokens(['id', 'id'])   # i.e. "inc rax"
@@ -129,7 +129,7 @@
         g.add_production('aas', [])
         g.add_production('aas', ['aas', 'a'])
         g.start_symbol = 'aas'
-        p = g.genParser()
+        p = g.generate_parser()
         tokens = genTokens(['a', 'a', 'a'])
         p.parse(tokens)
         tokens = genTokens([])
@@ -146,7 +146,7 @@
         g = Grammar(['a', 'b', 'c'])
         g.add_production('goal', ['a', 'c', 'b'], cb)
         g.start_symbol = 'goal'
-        p = g.genParser()
+        p = g.generate_parser()
         tokens = genTokens(['a', 'c', 'b'])
         p.parse(tokens)
         self.assertTrue(self.cb_called)
@@ -239,7 +239,7 @@
     def testParser(self):
         tokens = ['(', '(', ')', ')', '(', ')']
         # 3. build parser:
-        p = self.g.genParser()
+        p = self.g.generate_parser()
         self.assertEqual(len(p.goto_table), 5)
         self.assertEqual(len(p.action_table), 19)
 
--- a/test/testregalloc.py	Fri Feb 21 13:35:07 2014 +0100
+++ b/test/testregalloc.py	Sat Mar 01 16:32:27 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 21 13:35:07 2014 +0100
+++ b/test/testzcc.py	Sat Mar 01 16:32:27 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__))
@@ -40,7 +40,7 @@
             arg_list.append('-i')
             arg_list.append(os.path.join(basedir, fn))
         arg_list.append('--target')
-        arg_list.append('arm')
+        arg_list.append('thumb')
         arg_list += extra_args
         self.callZcc(arg_list)
 
@@ -49,7 +49,7 @@
         basedir = os.path.join('..', 'examples', 'c3', 'comments.c3')
         arg_list = ['compile', basedir]
         arg_list.append('--target')
-        arg_list.append('arm')
+        arg_list.append('thumb')
         self.callZcc(arg_list)
 
     def testKernel(self):
@@ -82,7 +82,7 @@
         recipe = os.path.join(testdir, '..', 'examples', 'c3', 'recipe.yaml')
         self.buildRecipe(recipe)
 
-    #@unittest.skip('s')
+    @unittest.skip('Skip because of logfile')
     def testBurn2WithLogging(self):
         self.do(['burn2.c3'], ['stm32f4xx.c3'], extra_args=['--report', 'x.rst'])
 
@@ -95,13 +95,14 @@
     def testFunctions(self):
         self.do(['functions.c3'])
 
+    @unittest.skip('Revise this test')
     def testSectionAddress(self):
         src = """module tst;
             function void t2() {var int t3; t3 = 2;}
         """
         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()
--- a/user/recipe.yaml	Fri Feb 21 13:35:07 2014 +0100
+++ b/user/recipe.yaml	Sat Mar 01 16:32:27 2014 +0100
@@ -5,7 +5,7 @@
      - compile:
         sources: [lib.c3, ipc.c3, hello.c3]
         includes: []
-        machine: arm
+        machine: thumb
         output: kernel.elf2
     layout:
          code: 0x0
--- a/util/serve_arm_as.py	Fri Feb 21 13:35:07 2014 +0100
+++ b/util/serve_arm_as.py	Sat Mar 01 16:32:27 2014 +0100
@@ -10,7 +10,7 @@
 
 def mangle(inp, outstream):
     print('assembling...', file=outstream)
-    p_as = subprocess.Popen(['arm-elf-as', '-mthumb'], stdin=subprocess.PIPE)
+    p_as = subprocess.Popen(['arm-elf-as'], stdin=subprocess.PIPE)
     p_as.communicate(input=inp.encode('ascii'))
 
     p_objdump = subprocess.Popen(['arm-elf-objdump', '-d'], stdout=subprocess.PIPE)