about summary refs log tree commit diff stats
path: root/test
diff options
context:
space:
mode:
authorserpilliere <devnull@localhost>2014-06-03 10:27:56 +0200
committerserpilliere <devnull@localhost>2014-06-03 10:27:56 +0200
commited5c3668cc9f545b52674ad699fc2b0ed1ccb575 (patch)
tree07faf97d7e4d083173a1f7e1bfd249baed2d74f9 /test
parenta183e1ebd525453710306695daa8c410fd0cb2af (diff)
downloadmiasm-ed5c3668cc9f545b52674ad699fc2b0ed1ccb575.tar.gz
miasm-ed5c3668cc9f545b52674ad699fc2b0ed1ccb575.zip
Miasm v2
* API has changed, so old scripts need updates
* See example for API usage
* Use tcc or llvm for jit emulation
* Go to test and run test_all.py to check install

Enjoy !
Diffstat (limited to 'test')
-rw-r--r--test/arch/arm/arch.py517
-rw-r--r--test/arch/arm/sem.py321
-rw-r--r--test/arch/msp430/arch.py110
-rw-r--r--test/arch/msp430/sem.py143
-rw-r--r--test/arch/sh4/arch.py436
-rw-r--r--test/arch/x86/arch.py1779
-rw-r--r--test/core/graph.py18
-rw-r--r--test/core/interval.py156
-rw-r--r--test/core/parse_asm.py41
-rw-r--r--test/expression/modint.py59
-rw-r--r--test/expression/simplifications.py258
-rw-r--r--test/expression/stp.py35
-rw-r--r--test/ir/ir2C.py59
-rw-r--r--test/ir/symbexec.py59
-rw-r--r--test/test_all.py443
15 files changed, 4434 insertions, 0 deletions
diff --git a/test/arch/arm/arch.py b/test/arch/arm/arch.py
new file mode 100644
index 00000000..e6b3fdda
--- /dev/null
+++ b/test/arch/arm/arch.py
@@ -0,0 +1,517 @@
+import os
+import time
+from miasm2.arch.arm.arch import *
+
+filename = os.environ.get('PYTHONSTARTUP')
+if filename and os.path.isfile(filename):
+    execfile(filename)
+
+if 0:
+    a = bs('00')
+    b = bs('01')
+    c = bs(l=2)
+    d = bs(l=4, fname='rd')
+    e = bs_name(l=1, name={'ADD': 0, 'SUB': 1})
+    assert(isinstance(e, bs_divert))
+    scc = bs_mod_name(l=1, mn_mod=['', 'S'])
+    f = bs(l=1, cls=(arm_reg,))
+
+    class arm_mov(mn_arm):
+        fields = [bs('0000'), bs('0000'), bs('0000')]
+
+    class arm_DATA(mn_arm):
+        fields = [bs('1111'), e, scc, f, bs('0')]
+    mn = mn_arm.dis(0xF000000)
+
+
+if 0:
+    import cProfile
+    cProfile.run('mn_arm.dis("\xe1\xa0\xa0\x06", mode_arm)')
+    # l = mn_arm.dis(bin_stream("\xe1\xa0\xa0\x06"), mode_arm)
+    # print l
+    """
+    mode = 64
+    l = mn_x86.fromstring("ADC      DWORD PTR [RAX], 0x11223344", mode)
+    print 'xx'
+    #t= time.time()
+    import cProfile
+    def f():
+        x = l.asm(mode)
+        print x
+    cProfile.run('f()')
+    """
+
+
+def h2i(s):
+    return s.replace(' ', '').decode('hex')
+
+
+def u16swap(i):
+    return struct.unpack('<H', struct.pack('>H', i))[0]
+
+reg_tests_arm = [
+    ("001504F4    MOV        R1, LR",
+     "0e10a0e1"),
+    ("00150500    ADD        R2, R8, R0",
+     "002088e0"),
+    ("001504E8    MOV        LR, 0x3E8",
+     "faefa0e3"),
+    ("001504F0    RSB        R0, R0, R3",
+     "030060e0"),
+    ("000E6F50    MUL        R2, LR, R6",
+     "9e0602e0"),
+    ("000620D8    MLA        R12, R0, R5, R3",
+     "90352ce0"),
+    ("00026798    ADDS       R2, R4, R0",
+     "002094e0"),
+    ("0003EA9C    MVN        R7, R2",
+     "0270e0e1"),
+    ("C00CD4DC    BL         0x7C",
+     "1F0000EB"),
+    ("C00CF110    BL         0xFFFFFDEC",
+     "7BFFFFEB"),
+
+
+    ("000829b0    BLNE       0xFFF87110",
+     "441cfe1b"),
+
+    ("C00EC608    TEQ        R4, R5",
+     "050034e1"),
+    ("C00CD53C    CMP        R9, R8",
+     "080059e1"),
+    ("C00CD5D8    MOV        R1, 0x60000000",
+     "0612a0e3"),
+    ("C00CEC18    MOV        R2, R1 LSL 0x14",
+     "012aa0e1"),
+    ("C00CF828    ORR        R0, R2, R1 LSL R0",
+     "110082e1"),
+    ("C00D8A14    EOR        R7, R2, R7 LSR 0x8",
+     "277422e0"),
+    ("C00CD2E4    MRS        R1, CPSR_cxsf",
+     "00100fe1"),
+    ("C019BE2C    MRS        R5, SPSR_cxsf",
+     "00504fe1"),
+    ("C00CD2F0    MSR        CPSR_cf, R1",
+     "01f029e1"),
+    ("C00D8A24    LDRB       R2, [R3, 0xFFFFFFFF]",    # LDRB  R2, [R3, #-1]
+     "012053e5"),
+    ("C01E59F8    LDREQ      R0, [R1, R0 LSL 0x2]",  # LDREQ R0, [R1, R0, LSL 2]
+     "00019107"),
+    ("C046855C    LDR        R0, [R9, R0 LSL 0x4]",  #
+     "000299e7"),
+    ('c012a8d8    LDREQ      R0, [R0]',
+     '00009005'),
+    ("C00D8AA8    LDR        R0, [R2], 0x4",           # LDR   R0, [R2], 4
+     "040092e4"),
+    ("C00D8A9C    LDR        R0, [PC, 0x514]",
+     "14059fe5"),
+    ("C03C7A38    LDR        R5, [R0, 0xD4]!",
+     "d450b0e5"),
+    ("C00EA214    LDMIA      R0, {R0, R1}",               # LDMIA   R0, {R0, R1}
+     "030090e8"),
+    ("C0121D70    LDMGEIA    R1, {R0, R1}",
+     "030091a8"),
+    ("C0124E68    LDMIB      R1, {R4, R12}",
+     "101091e9"),
+    ("C012D2A0    LDMDA      R7, {R0, R2}",
+     "050017e8"),
+    ("C0130A64    LDMFD      SP, {R0, R1}",
+     "03009de8"),
+    ("C016AAD0    LDMFD      SP!, {R8}",
+     "0001bde8"),
+    ("C00E0F98    LDMED      SP, {R4, R6}",
+     "50009de9"),
+    ("C0161AC0    STMFD      SP!, {R8}",               # stmfd
+     "00012de9"),
+    ("C00E0710    STMIA      R5, {R8, R9}",
+     "000385e8"),
+    ("C0460580    STMFA      SP, {R8, R10}",
+     "00058de9"),
+    ("C04FFBD0    STMEA      SP, {R9, R10}",
+     "00068de8"),
+    ("C00CEB10    STMDB      R8, {SP, LR}^",
+     "006048e9"),
+    ("C0129534    STMIB      R6, {R0, R9}",
+     "010286e9"),
+    ("C01293BC    STMFD      SP!, {R4-R11, LR}",
+     "F04F2DE9"),
+    ("C02FA8B4    SVCEQ      0x196A0B",
+     "0B6a190f"),
+    ("C00EF814    SVCMI      0x495020",
+     "2050494F"),
+    ("C00ED5CC    CDPCS      p3, 0x2, c7, c14, c5, 0x3",
+     "65732e2e"),
+    ("C00EFE88    CDPVS      p13, 0x2, c6, c0, c15, 0x3",
+     "6F6D206e"),
+    ("C0148ED0    LDCVS      p11, c5, [R4], 0xFFFFFF94!",  # -0x6C TODO XXX no wb !
+     "1B5B346C"),
+    ("C00ED374    MRCHI      p15, 0x5, LR, c14, c9, 0x7",
+     "f9efbe8e"),
+    ("C00F3D24    MCRVS      p0, 0x3, R2, c9, c4, 0x3",
+     "7420696e"),
+    ("xxxxxxxx    UND        0x0, 0x0",
+     "100000e6"),
+    ("xxxxxxxx    BKPT       0x0, 0x0",
+     "700020e1"),
+    ("c00d153c    LDRH       R2, [R4, 0xCA]",
+     "ba2cd4e1"),
+    ("c00d18a8    LDRH       R6, [R12]",
+     "b060dce1"),
+    ("c00d8134    STRH       R3, [R6, 0x2]",
+     "b230c6e1"),
+    ("c00d80c4    STRH       R3, [R6]",
+     "b030c6e1"),
+
+    ("00031F40    LDRD       R8, [R7]",
+     "D080C7E1"),
+
+    ("c0104a34    LDRD       R0, [SP, 0x8]",
+     "D800CDE1"),
+    ("C013DC68    LDRD       R6, [R0, 0xFFFFFFF8]",
+     "D86040E1"),
+
+    ("C0120CC0    LDRSB      R1, [SP, 0x8]",
+     "D810DDE1"),
+
+    ("C0105C28    LDRSH      R0, [R8, 0xA]",
+     "FA00D8E1"),
+
+    ("C00D8FF4    LDRH       R3, [R12, R3]",
+     "B3309CE1"),
+    ("C012D1A4    LDRSB      R2, [R2, R1]",
+     "D12092E1"),
+
+    ("c0115a84    STRD       R0, [SP, 0x18]",
+     "F801CDE1"),
+    ("c0124a18    STRD       R2, [R0, 0xFFFFFFF8]",
+     "F82040E1"),
+
+    ("0002F5A8    MOV        R2, 0x2710",
+     "102702E3"),
+
+    ("0002F5B0    UMULL      R2, R3, R3, R2",
+     "932283E0"),
+    ("C045D260    SMULL      R3, R2, LR, R2",
+     "9E32C2E0"),
+    ("C03E6440    SMLAL      R2, R0, R1, R0",
+     "9120E0E0"),
+
+    ("C00CFA40    BLX        R12",
+     "3CFF2FE1"),
+    ("C010DE1C    BLX        0x1ECCEA",
+     "3AB307FB"),
+
+    ("00013028    MOV        R9, 0x6E75",
+     "759E06E3"),
+
+    ("0001302C    MOVT       R9, 0x64",
+     "649040E3"),
+
+    ("0004A38C    CLZ        R3, R2",
+     "123F6FE1"),
+
+    ("C0132564    BLX        0xFFFCF06C",
+     "1B3CFFFA"),
+
+    ("C0297028    QADD       R7, R6, R6",
+     "567006E1"),
+
+    ("6330A0E1    MOV        R3, R3 RRX",
+     "6330A0E1"),
+
+]
+ts = time.time()
+
+for s, l in reg_tests_arm:
+    print "-" * 80
+    s = s[12:]
+    b = h2i((l))
+    mn = mn_arm.dis(b, mode_arm)
+    print [str(x) for x in mn.args]
+    print s
+    print mn
+    assert(str(mn) == s)
+    # print hex(b)
+    # print [str(x.get()) for x in mn.args]
+    l = mn_arm.fromstring(s, mode_arm)
+    # print l
+    assert(str(l) == s)
+    a = mn_arm.asm(l)
+    print [x for x in a]
+    print repr(b)
+    # print mn.args
+    assert(b in a)
+
+reg_tests_armt = [
+    ("0006ff5c    LSLS       R2, R0, 0x1A",
+     "8206"),
+    ("0006fe06    LSRS       R3, R3, 0x7",
+     "db09"),
+    ("0006af9c    ASRS       R0, R2, 0x1",
+     "5010"),
+    ("0006b1ea    ADDS       R1, R4, R5",
+     "6119"),
+    ("0006b304    ADDS       R2, R0, 0x1",
+     "421c"),
+    ("0006bc80    SUBS       R3, R1, 0x1",
+     "4b1e"),
+    ("0006f1d0    SUBS       R2, R6, R3",
+     "f21a"),
+    ("0006af30    MOVS       R3, 0x1",
+     "0123"),
+    ("0006b0ee    CMP        R3, 0x1",
+     "012b"),
+    ("C0100242    CMP        R2, 0x0",
+     "002A"),
+    ("0006b0f2    SUBS       R3, 0x1",
+     "013b"),
+    ("0006b12c    ADDS       R0, 0x4",
+     "0430"),
+
+    ("0006b944    ANDS       R2, R5",
+     "2a40"),
+    ("0014df06    EORS       R2, R0",
+     "4240"),
+    ("0008b66e    LSLS       R7, R1",
+     "8f40"),
+    ("002e7e0c    LSRS       R4, R0",
+     "c440"),
+    ("003258b6    ASRS       R2, R3",
+     "1a41"),
+    # adcs
+    # sbcs
+    # rors
+    ("0017b754    TST        R0, R2",
+     "1042"),
+    ("0006e3fc    NEGS       R5, R5",
+     "6d42"),
+    ("0006b1fc    CMP        R6, R7",
+     "be42"),
+    ("001845ea    CMN        R3, R0",
+     "c342"),
+    ("001845ea    ORRS       R0, R4",
+     "2043"),
+    # muls
+    # bic
+    ("0006b90e    MVNS       R0, R3",
+     "d843"),
+
+    ("0006bcac    CMP        R6, R9",
+     "4e45"),
+    ("0006bcf0    CMP        R3, R1",
+     "8b42"),
+    ("0006c26c    CMP        R12, LR",
+     "f445"),
+    ("0006c8e4    CMP        R8, R2",
+     "9045"),
+    ("0006af70    MOV        R1, R0",
+     "0146"),
+    ("0006b3d0    MOV        R1, SP",
+     "6946"),
+    ("0006b47c    MOV        R8, R0",
+     "8046"),
+    ("0006bc8e    MOV        R8, SP",
+     "e846"),
+    ("0006aee0    BX         LR",
+     "7047"),
+    ("000a9d30    BX         R2",
+     "1047"),
+
+    ("0006b2dc    LDR        R0, [PC]",
+     "0048"),
+    ("00078798    LDR        R3, [PC, 0x1]",
+     "014b"),
+
+    ("00072dc2    LDR        R3, [R3, R0]",
+     "1b58"),
+    ("0008e5d4    LDR        R2, [R4, R0]",
+     "2258"),
+    ("0018e8ce    LDRB       R3, [R0, R4]",
+     "035d"),
+    ("0007b976    STR        R6, [R5, R4]",
+     "2e51"),
+    ("000b5b42    STRB       R7, [R1, R4]",
+     "0f55"),
+
+    ("002b02ae    STRH       R1, [R0, R3]",
+     "c152"),
+    ("002ea7de    LDRH       R5, [R6, R4]",
+     "355b"),
+    # ldsb
+    # ldsh
+
+    ("000a65c6    LDR        R7, [R0, 0x10]",
+     "0769"),
+    ("0006b308    LDRB       R5, [R1, 0x4]",
+     "0d79"),
+    ("0006b014    STR        R4, [R4, 0x38]",
+     "a463"),
+    ("0006b006    STRB       R5, [R0, 0x10]",
+     "0574"),
+
+    ("0009b598    STRH       R3, [R4, 0x2]",
+     "6380"),
+    ("000748da    LDRH       R2, [R6, 0x30]",
+     "328E"),
+
+    ("0006aed2    STR        R3, [SP, 0x24]",
+     "0993"),
+    ("0006ae6c    LDR        R3, [SP, 0x4]",
+     "019b"),
+
+    ("0006aed0    ADD        R1, SP, 0x20",
+     "08a9"),
+    ("000xxxxx    ADD        R1, PC, 0x20",
+     "08a1"),
+
+    ("0006aed8    ADD        SP, 0x30",
+     "0cb0"),
+    ("0006c1b0    SUB        SP, 0x18",
+     "86b0"),
+
+
+    ("0006aeee    POP        {R4, PC}",
+     "10bd"),
+    ("0006b03a    POP        {R4-R6, PC}",
+     "70bd"),
+    ("0006aee4    PUSH       {R4, LR}",
+     "10b5"),
+    ("0006b084    PUSH       {R0, R1, R4-R6, LR}",
+     "73b5"),
+    ("003139a0    PUSH       {LR}",
+     "00b5"),
+    ("00220f44    PUSH       {R2, R3}",
+     "0cb4"),
+
+    ("00076c54    LDMIA      R1!, {R0, R1}",
+     "03c9"),
+    ("000a1c16    STMIA      R6!, {R0-R3}",
+     "0fc6"),
+
+    ("0006af78    BEQ        0x6",
+     "03d0"),
+    ("000747b4    BCC        0xFFFFFFE6",
+     "f3d3"),
+    # swi
+
+    ("0007479c    B          0xE",
+     "07e0"),
+    ("0006b946    B          0xFFFFFFE4",
+     "f2e7"),
+    ("C010163C    BLX        0x1F916C",
+     "F9F1B6E8"),
+    ("C01015E8    BL         0x1F8D5C",
+     "F8F1AEFE"),
+
+
+    #("000xxxxx    BL       0x0",
+    # "00F8"),
+    #("000xxxxx    BL       0x4000",
+    # "04F0"),
+    #("000xxxxx    BL       0xFFFFF000",
+    # "FFF7"),
+
+
+    #("0006aea4    MOV      R5, R1",
+    # "460d"),
+
+    # adc
+    # adc
+    ("00000000    UND        ",
+     "01de"),
+
+    ("00000000    BLX        R7",
+     "B847"),
+
+    ("00000000    CBZ        R4, 0x2E",
+     "bcb1"),
+    ("00000000    CBNZ       R0, 0x2A",
+     "a8b9"),
+
+
+]
+print "#" * 40, 'armthumb', '#' * 40
+
+for s, l in reg_tests_armt:
+    print "-" * 80
+    s = s[12:]
+    b = h2i((l))
+    print b.encode('hex')
+    mn = mn_armt.dis(b, mode_armthumb)
+    print [str(x) for x in mn.args]
+    print s
+    print mn
+    assert(str(mn) == s)
+    # print hex(b)
+    # print [str(x.get()) for x in mn.args]
+    l = mn_armt.fromstring(s, mode_armthumb)
+    # print l
+    assert(str(l) == s)
+    a = mn_armt.asm(l)
+    print [x for x in a]
+    print repr(b)
+    # print mn.args
+    assert(b in a)
+
+"""
+print "*"*30, "START SPECIAL PARSING", "*"*30
+parse_tests = [
+    "MOV      LR, toto",
+    "MOV      LR, 1+toto",
+    "MOV      LR, (lend-lstart)^toto<<<R1",
+    "MOV      LR, R1 LSL (l_end-l_start)^toto<<<R1",
+    "MOV      LR, R1 LSL (l_end-l_start)^toto<<<R1",
+    "EOR      R0, R1, toto^titi+1",
+    ]
+
+for l in parse_tests:
+    print "-"*80
+    l = mn_arm.fromstring(l, mode_arm)
+    print l.name, ", ".join([str(a) for a in l.args])
+"""
+
+
+print 'TEST time', time.time() - ts
+
+# speed test arm
+o = ""
+for s, l in reg_tests_arm:
+    s = s[12:]
+    b = h2i((l))
+    o += b
+
+while len(o) < 1000:
+    o += o
+bs = bin_stream_str(o)
+off = 0
+instr_num = 0
+ts = time.time()
+while off < bs.getlen():
+    mn = mn_arm.dis(bs, mode_arm, off)
+    instr_num += 1
+    off += 4
+print 'instr per sec:', instr_num / (time.time() - ts)
+
+
+# speed test thumb
+o = ""
+for s, l in reg_tests_armt:
+    s = s[12:]
+    b = h2i((l))
+    o += b
+
+while len(o) < 1000:
+    o += o
+bs = bin_stream_str(o)
+off = 0
+instr_num = 0
+ts = time.time()
+while off < bs.getlen():
+    mn = mn_armt.dis(bs, mode_armthumb, off)
+    # print instr_num, off, str(mn)
+    instr_num += 1
+    off += mn.l
+print 'instr per sec:', instr_num / (time.time() - ts)
+
+import cProfile
+cProfile.run(r'mn_arm.dis("\xe1\xa0\xa0\x06", mode_arm)')
diff --git a/test/arch/arm/sem.py b/test/arch/arm/sem.py
new file mode 100644
index 00000000..be36e90b
--- /dev/null
+++ b/test/arch/arm/sem.py
@@ -0,0 +1,321 @@
+#!/usr/bin/env python
+#-*- coding:utf-8 -*-
+
+import unittest
+import logging
+
+from miasm2.ir.symbexec import symbexec
+from miasm2.arch.arm.arch import mn_arm as mn, mode_arm as mode
+from miasm2.arch.arm.sem import ir_arm as ir
+from miasm2.arch.arm.regs import *
+from miasm2.expression.expression import *
+
+logging.getLogger('cpuhelper').setLevel(logging.ERROR)
+EXCLUDE_REGS = set()
+
+
+def M(addr):
+    return ExprMem(ExprInt_fromsize(16, addr), 16)
+
+
+def compute(asm, inputstate={}, debug=False):
+    sympool = dict(regs_init)
+    sympool.update({k: ExprInt_from(k, v) for k, v in inputstate.iteritems()})
+    symexec = symbexec(mn, sympool)
+    instr = mn.fromstring(asm, mode)
+    code = mn.asm(instr)[0]
+    instr = mn.dis(code, mode)
+    instr.offset = inputstate.get(PC, 0)
+    interm = ir()
+    interm.add_instr(instr)
+    symexec.emul_ir_blocs(interm, instr.offset)
+    if debug:
+        for k, v in symexec.symbols.items():
+            if regs_init.get(k, None) != v:
+                print k, v
+    return {k: v.arg.arg for k, v in symexec.symbols.items()
+            if k not in EXCLUDE_REGS and regs_init.get(k, None) != v}
+
+
+class TestARMSemantic(unittest.TestCase):
+
+    # def test_condition(self):
+    # §A8.3:                   Conditional execution
+    #    pass
+
+    def test_shift(self):
+        # §A8.4:                   Shifts applied to a register
+        self.assertEqual(
+            compute('MOV R4, R4       ', {R4: 0xDEADBEEF, }), {R4: 0xDEADBEEF, })
+        self.assertRaises(ValueError, compute, 'MOV R4, R4 LSL  0')
+        self.assertEqual(
+            compute('MOV R4, R4 LSL  1', {R4: 0xDEADBEEF, }), {R4: 0xBD5B7DDE, })
+        self.assertEqual(
+            compute('MOV R4, R4 LSL 16', {R4: 0xDEADBEEF, }), {R4: 0xBEEF0000, })
+        self.assertEqual(
+            compute('MOV R4, R4 LSL 31', {R4: 0xDEADBEEF, }), {R4: 0x80000000, })
+        self.assertRaises(ValueError, compute, 'MOV R4, R4 LSL 32')
+        self.assertEqual(
+            compute('MOV R4, R4 LSL R5', {R4: 0xDEADBEEF, R5: 0xBADBAD01, }), {R4: 0xBD5B7DDE, R5: 0xBADBAD01, })
+        self.assertRaises(ValueError, compute, 'MOV R4, R4 LSR  0')
+        self.assertEqual(
+            compute('MOV R4, R4 LSR  1', {R4: 0xDEADBEEF, }), {R4: 0x6F56DF77, })
+        self.assertEqual(
+            compute('MOV R4, R4 LSR 16', {R4: 0xDEADBEEF, }), {R4: 0x0000DEAD, })
+        self.assertEqual(
+            compute('MOV R4, R4 LSR 31', {R4: 0xDEADBEEF, }), {R4: 0x00000001, })
+        self.assertEqual(
+            compute('MOV R4, R4 LSR 32', {R4: 0xDEADBEEF, }), {R4: 0xDEADBEEF, })
+        self.assertRaises(ValueError, compute, 'MOV R4, R4 LSR 33')
+        self.assertEqual(
+            compute('MOV R4, R4 LSR R5', {R4: 0xDEADBEEF, R5: 0xBADBAD01, }), {R4: 0x6F56DF77, R5: 0xBADBAD01, })
+        self.assertRaises(ValueError, compute, 'MOV R4, R4 ASR  0')
+        self.assertEqual(
+            compute('MOV R4, R4 ASR  1', {R4: 0xDEADBEEF, }), {R4: 0xEF56DF77, })
+        self.assertEqual(
+            compute('MOV R4, R4 ASR 16', {R4: 0xDEADBEEF, }), {R4: 0xFFFFDEAD, })
+        self.assertEqual(
+            compute('MOV R4, R4 ASR 31', {R4: 0xDEADBEEF, }), {R4: 0xFFFFFFFF, })
+        self.assertEqual(
+            compute('MOV R4, R4 ASR 32', {R4: 0xDEADBEEF, }), {R4: 0xDEADBEEF, })
+        self.assertRaises(ValueError, compute, 'MOV R4, R4 ASR 33')
+        self.assertEqual(
+            compute('MOV R4, R4 ASR R5', {R4: 0xDEADBEEF, R5: 0xBADBAD01, }), {R4: 0xEF56DF77, R5: 0xBADBAD01, })
+        self.assertRaises(ValueError, compute, 'MOV R4, R4 ROR  0')
+        self.assertEqual(
+            compute('MOV R4, R4 ROR  1', {R4: 0xDEADBEEF, }), {R4: 0xEF56DF77, })
+        self.assertEqual(
+            compute('MOV R4, R4 ROR 16', {R4: 0xDEADBEEF, }), {R4: 0xBEEFDEAD, })
+        self.assertEqual(
+            compute('MOV R4, R4 ROR 31', {R4: 0xDEADBEEF, }), {R4: 0xBD5B7DDF, })
+        self.assertRaises(ValueError, compute, 'MOV R4, R4 ROR 32')
+        self.assertEqual(
+            compute('MOV R4, R4 ROR R5', {R4: 0xDEADBEEF, R5: 0xBADBAD01, }), {R4: 0xEF56DF77, R5: 0xBADBAD01, })
+        self.assertEqual(compute('MOV R4, R4 RRX   ', {cf: 0, R4: 0xDEADBEEF, }), {
+                         cf: 0, R4: 0x6F56DF77, })
+        self.assertEqual(compute('MOV R4, R4 RRX   ', {cf: 1, R4: 0xDEADBEEF, }), {
+                         cf: 1, R4: 0xEF56DF77, })
+
+    def test_ADC(self):
+        # §A8.8.1:                 ADC{S}{<c>}{<q>} {<Rd>,} <Rn>, #<const>
+        self.assertRaises(
+            ValueError, compute, 'ADC          R4,   0x00000001 ')
+        self.assertEqual(compute('ADC                R4,    R4,   0x00000001 ',   {
+                                 cf: 0, R4: 0x00000000, }), {cf: 0,     R4: 0x00000001, })
+        self.assertEqual(compute('ADC                R4,    R4,   0x00000000 ',   {
+                                 cf: 1, R4: 0x00000000, }), {cf: 1,     R4: 0x00000001, })
+        self.assertEqual(compute('ADC                PC,    R4,   0x00000001 ',   {
+                                 cf: 0, R4: 0xFFFFFFFF, PC: 0x55555555, }), {cf: 0,     R4: 0xFFFFFFFF, PC: 0x00000000, })
+        self.assertEqual(compute('ADC                PC,    R4,   0x00000000 ',   {
+                                 cf: 1, R4: 0xFFFFFFFF, PC: 0x55555555, }), {cf: 1,     R4: 0xFFFFFFFF, PC: 0x00000000, })
+        self.assertEqual(compute('ADCS               R4,    R4,   0x80000000 ',   {cf: 0, R4: 0x80000000, }), {
+                         nf: 0, zf: 1, cf: 0, of: 1, R4: 0x00000000, })
+        self.assertEqual(compute('ADCS               R4,    R4,   0xFF000000 ',   {cf: 1, R4: 0x00FFFFFE, }), {
+                         nf: 1, zf: 0, cf: 1, of: 0, R4: 0xFFFFFFFF, })
+        self.assertEqual(compute('ADCS               PC,    R4,   0x00000000 ',   {
+                                 cf: 0, R4: 0x00000000, PC: 0x55555555, }), {cf: 0,     R4: 0x00000000, PC: 0x00000000, })
+        self.assertEqual(compute('ADCS               PC,    R4,   0xFF000000 ',   {
+                                 cf: 1, R4: 0x01000000, PC: 0x55555555, }), {cf: 1,     R4: 0x01000000, PC: 0x00000001, })
+
+        # §A8.8.2:                 ADC{S}{<c>}{<q>} {<Rd>,} <Rn>, <Rm> {,<shift>}
+        self.assertRaises(
+            ValueError, compute, 'ADC          R4,   R5          ')
+        self.assertEqual(compute('ADC                R4,    R4,   R5          ',  {
+                                 cf: 1, R4: 0xFFFFFFFF, R5: 0x00000000, }), {cf: 1,     R4: 0x00000000, R5: 0x00000000, })
+        self.assertEqual(compute('ADC                R4,    R4,   R5    LSL 1 ',  {
+                                 cf: 0, R4: 0x00000001, R5: 0x00000008, }), {cf: 0,     R4: 0x00000011, R5: 0x00000008, })
+        self.assertEqual(compute('ADC                R4,    R4,   R5    LSR 2 ',  {
+                                 cf: 1, R4: 0x00000000, R5: 0x80000041, }), {cf: 1,     R4: 0x20000011, R5: 0x80000041, })
+        self.assertEqual(compute('ADC                R4,    R4,   R5    ASR 3 ',  {
+                                 cf: 0, R4: 0x00000001, R5: 0x80000081, }), {cf: 0,     R4: 0xF0000011, R5: 0x80000081, })
+        self.assertEqual(compute('ADC                R4,    R4,   R5    ROR 4 ',  {
+                                 cf: 1, R4: 0xFFFFFFFF, R5: 0x0000010F, }), {cf: 1,     R4: 0xF0000010, R5: 0x0000010F, })
+        self.assertEqual(compute('ADC                R4,    R4,   R5    RRX   ',  {
+                                 cf: 1, R4: 0xFFFFFFFF, R5: 0x00000101, }), {cf: 1,     R4: 0x80000080, R5: 0x00000101, })
+        self.assertEqual(compute('ADCS               R4,    R4,   R5          ',  {cf: 1, R4: 0xFFFFFFFF, R5: 0x00000000, }), {
+                         nf: 0, zf: 1, cf: 0, of: 0, R4: 0x00000000, R5: 0x00000000, })
+        self.assertEqual(compute('ADCS               R4,    R4,   R5    LSL 1 ',  {cf: 0, R4: 0x00000001, R5: 0x00000008, }), {
+                         nf: 0, zf: 0, cf: 1, of: 0, R4: 0x00000011, R5: 0x00000008, })
+        self.assertEqual(compute('ADCS               R4,    R4,   R5    LSR 2 ',  {cf: 1, R4: 0x00000000, R5: 0x80000041, }), {
+                         nf: 0, zf: 0, cf: 1, of: 0, R4: 0x20000011, R5: 0x80000041, })
+        self.assertEqual(compute('ADCS               R4,    R4,   R5    ASR 3 ',  {cf: 0, R4: 0x00000001, R5: 0x80000081, }), {
+                         nf: 1, zf: 0, cf: 1, of: 0, R4: 0xF0000011, R5: 0x80000081, })
+        self.assertEqual(compute('ADCS               R4,    R4,   R5    ROR 4 ',  {cf: 1, R4: 0xFFFFFFFF, R5: 0x0000010F, }), {
+                         nf: 1, zf: 0, cf: 0, of: 0, R4: 0xF0000010, R5: 0x0000010F, })
+        self.assertEqual(compute('ADCS               R4,    R4,   R5    RRX   ',  {cf: 1, R4: 0xFFFFFFFF, R5: 0x00000101, }), {
+                         nf: 1, zf: 0, cf: 0, of: 0, R4: 0x80000080, R5: 0x00000101, })
+
+        # §A8.8.3:                 ADC{S}{<c>}{<q>} {<Rd>,} <Rn>, <Rm>, <type> <Rs>
+        self.assertEqual(compute('ADC                R4,    R6,   R4    LSL R5',  {
+                                 cf: 0, R4: 0x00000001, R5: 0x00000004, R6: 0, }), {cf: 0,     R4: 0x00000010, R5: 0x00000004, R6: 0, })
+        self.assertEqual(compute('ADC                R4,    R6,   R4    LSR R5',  {
+                                 cf: 1, R4: 0x00000110, R5: 0x80000004, R6: 0, }), {cf: 1,     R4: 0x00000012, R5: 0x80000004, R6: 0, })
+        self.assertEqual(compute('ADC                R4,    R6,   R4    ASR R5',  {
+                                 cf: 0, R4: 0x80000010, R5: 0xF0000001, R6: 0, }), {cf: 0,     R4: 0xC0000008, R5: 0xF0000001, R6: 0, })
+        self.assertEqual(compute('ADC                R4,    R6,   R4    ROR R5',  {
+                                 cf: 1, R4: 0x000000FF, R5: 0x00000F04, R6: 0, }), {cf: 1,     R4: 0xF0000010, R5: 0x00000F04, R6: 0, })
+        self.assertEqual(compute('ADCS               R4,    R6,   R4    LSL R5',  {cf: 0, R4: 0x00000001, R5: 0x00000004, R6: 0, }), {
+                         nf: 0, zf: 0, cf: 1, of: 0, R4: 0x00000010, R5: 0x00000004, R6: 0, })
+        self.assertEqual(compute('ADCS               R4,    R6,   R4    LSR R5',  {cf: 1, R4: 0x00000110, R5: 0x80000004, R6: 0, }), {
+                         nf: 0, zf: 0, cf: 1, of: 0, R4: 0x00000012, R5: 0x80000004, R6: 0, })
+        self.assertEqual(compute('ADCS               R4,    R6,   R4    ASR R5',  {cf: 0, R4: 0x80000010, R5: 0xF0000001, R6: 0, }), {
+                         nf: 1, zf: 0, cf: 1, of: 0, R4: 0xC0000008, R5: 0xF0000001, R6: 0, })
+        self.assertEqual(compute('ADCS               R4,    R6,   R4    ROR R5',  {cf: 1, R4: 0x000000FF, R5: 0x00000F04, R6: 0, }), {
+                         nf: 1, zf: 0, cf: 1, of: 0, R4: 0xF0000010, R5: 0x00000F04, R6: 0, })
+
+    def test_ADD(self):
+        # §A8.8.{5,9}:             ADD{S}{<c>}{<q>} {<Rd>,} <Rn>, #<const>
+        self.assertRaises(
+            ValueError, compute, 'ADD          R4,   0x00000001 ')
+        self.assertEqual(compute('ADD                R4,    R4,   0x00000001 ',   {
+                                 R4: 0x00000000, }), {R4: 0x00000001, })
+        self.assertEqual(compute('ADD                R4,    R4,   0x00000000 ',   {
+                                 R4: 0x00000000, }), {R4: 0x00000000, })
+        self.assertEqual(compute('ADD                PC,    R4,   0x00000001 ',   {
+                                 R4: 0xFFFFFFFF, PC: 0x55555555, }), {R4: 0xFFFFFFFF, PC: 0x00000000, })
+        self.assertEqual(compute('ADD                PC,    R4,   0x00000000 ',   {
+                                 R4: 0xFFFFFFFF, PC: 0x55555555, }), {R4: 0xFFFFFFFF, PC: 0xFFFFFFFF, })
+        self.assertEqual(compute('ADDS               R4,    R4,   0x80000000 ',   {R4: 0x80000000, }), {
+                         nf: 0, zf: 1, cf: 0, of: 1, R4: 0x00000000, })
+        self.assertEqual(compute('ADDS               R4,    R4,   0xFF000000 ',   {R4: 0x00FFFFFE, }), {
+                         nf: 1, zf: 0, cf: 1, of: 0, R4: 0xFFFFFFFE, })
+        self.assertEqual(compute('ADDS               PC,    R4,   0x00000000 ',   {
+                                 R4: 0x00000000, PC: 0x55555555, }), {R4: 0x00000000, PC: 0x00000000, })
+        self.assertEqual(compute('ADDS               PC,    R4,   0xFF000000 ',   {
+                                 R4: 0x01000000, PC: 0x55555555, }), {R4: 0x01000000, PC: 0x00000000, })
+        # SP special part
+        self.assertEqual(compute('ADD                R4,    SP,   0x00000001 ',   {
+                                 R4: 0x00000000, SP: 0x00000000, }), {R4: 0x00000001, SP: 0x00000000, })
+
+        # §A8.8.{7,11}:            ADD{S}{<c>}{<q>} {<Rd>,} <Rn>, <Rm> {,<shift>}
+        self.assertRaises(
+            ValueError, compute, 'ADD          R4,   R5          ')
+        self.assertEqual(compute('ADD                R4,    R4,   R5          ',  {
+                                 R4: 0xFFFFFFFF, R5: 0x00000001, }), {R4: 0x00000000, R5: 0x00000001, })
+        self.assertEqual(compute('ADD                R4,    R4,   R5    LSL 1 ',  {
+                                 R4: 0x00000001, R5: 0x00000008, }), {R4: 0x00000011, R5: 0x00000008, })
+        self.assertEqual(compute('ADD                R4,    R4,   R5    LSR 2 ',  {
+                                 R4: 0x00000000, R5: 0x80000041, }), {R4: 0x20000010, R5: 0x80000041, })
+        self.assertEqual(compute('ADD                R4,    R4,   R5    ASR 3 ',  {
+                                 R4: 0x00000001, R5: 0x80000081, }), {R4: 0xF0000011, R5: 0x80000081, })
+        self.assertEqual(compute('ADD                R4,    R4,   R5    ROR 4 ',  {
+                                 R4: 0xFFFFFFFF, R5: 0x0000010F, }), {R4: 0xF000000F, R5: 0x0000010F, })
+        self.assertEqual(compute('ADD                R4,    R4,   R5    RRX   ',  {
+                                 cf: 1, R4: 0xFFFFFFFF, R5: 0x00000101, }), {cf: 1,     R4: 0x8000007F, R5: 0x00000101, })
+        self.assertEqual(compute('ADDS               R4,    R4,   R5          ',  {R4: 0xFFFFFFFF, R5: 0x00000001, }), {
+                         nf: 0, zf: 1, cf: 0, of: 0, R4: 0x00000000, R5: 0x00000001, })
+        self.assertEqual(compute('ADDS               R4,    R4,   R5    LSL 1 ',  {R4: 0x00000001, R5: 0x00000008, }), {
+                         nf: 0, zf: 0, cf: 1, of: 0, R4: 0x00000011, R5: 0x00000008, })
+        self.assertEqual(compute('ADDS               R4,    R4,   R5    LSR 2 ',  {R4: 0x00000000, R5: 0x80000041, }), {
+                         nf: 0, zf: 0, cf: 1, of: 0, R4: 0x20000010, R5: 0x80000041, })
+        self.assertEqual(compute('ADDS               R4,    R4,   R5    ASR 3 ',  {R4: 0x00000001, R5: 0x80000081, }), {
+                         nf: 1, zf: 0, cf: 1, of: 0, R4: 0xF0000011, R5: 0x80000081, })
+        self.assertEqual(compute('ADDS               R4,    R4,   R5    ROR 4 ',  {R4: 0xFFFFFFFF, R5: 0x0000010F, }), {
+                         nf: 1, zf: 0, cf: 0, of: 0, R4: 0xF000000F, R5: 0x0000010F, })
+        self.assertEqual(compute('ADDS               R4,    R4,   R5    RRX   ',  {cf: 1, R4: 0xFFFFFFFF, R5: 0x00000101, }), {
+                         nf: 1, zf: 0, cf: 0, of: 0, R4: 0x8000007F, R5: 0x00000101, })
+        # SP special part
+        self.assertEqual(compute('ADD                R4,    SP,   R4    LSR 1 ',  {
+                                 R4: 0x00000002, SP: 0x00000000, }), {R4: 0x00000001, SP: 0x00000000, })
+
+        # §A8.8.8:                 ADD{S}{<c>}{<q>} {<Rd>,} <Rn>, <Rm>, <type> <Rs>
+        self.assertEqual(compute('ADD                R4,    R6,   R4    LSL R5',  {
+                                 R4: 0x00000001, R5: 0x00000004, R6: 0, }), {R4: 0x00000010, R5: 0x00000004, R6: 0, })
+        self.assertEqual(compute('ADD                R4,    R6,   R4    LSR R5',  {
+                                 R4: 0x00000110, R5: 0x80000004, R6: 0, }), {R4: 0x00000011, R5: 0x80000004, R6: 0, })
+        self.assertEqual(compute('ADD                R4,    R6,   R4    ASR R5',  {
+                                 R4: 0x80000010, R5: 0xF0000001, R6: 0, }), {R4: 0xC0000008, R5: 0xF0000001, R6: 0, })
+        self.assertEqual(compute('ADD                R4,    R6,   R4    ROR R5',  {
+                                 R4: 0x000000FF, R5: 0x00000F04, R6: 0, }), {R4: 0xF000000F, R5: 0x00000F04, R6: 0, })
+        self.assertEqual(compute('ADDS               R4,    R6,   R4    LSL R5',  {R4: 0x00000001, R5: 0x00000004, R6: 0, }), {
+                         nf: 0, zf: 0, cf: 1, of: 0, R4: 0x00000010, R5: 0x00000004, R6: 0, })
+        self.assertEqual(compute('ADDS               R4,    R6,   R4    LSR R5',  {R4: 0x00000110, R5: 0x80000004, R6: 0, }), {
+                         nf: 0, zf: 0, cf: 1, of: 0, R4: 0x00000011, R5: 0x80000004, R6: 0, })
+        self.assertEqual(compute('ADDS               R4,    R6,   R4    ASR R5',  {R4: 0x80000010, R5: 0xF0000001, R6: 0, }), {
+                         nf: 1, zf: 0, cf: 1, of: 0, R4: 0xC0000008, R5: 0xF0000001, R6: 0, })
+        self.assertEqual(compute('ADDS               R4,    R6,   R4    ROR R5',  {R4: 0x000000FF, R5: 0x00000F04, R6: 0, }), {
+                         nf: 1, zf: 0, cf: 1, of: 0, R4: 0xF000000F, R5: 0x00000F04, R6: 0, })
+
+    def test_ADR(self):
+        # §A8.8.12:                ADR{<c>}{<q>} <Rd>, <label>    <==>    ADD{<c>}{<q>} <Rd>, PC, #<const>
+        pass
+
+    def test_AND(self):
+        # §A8.8.13:                AND{S}{<c>}{<q>} {<Rd>,} <Rn>, #<const>
+        self.assertRaises(
+            ValueError, compute, 'AND          R4,   0x00000001 ')
+        self.assertEqual(compute('AND                R4,    R4,   0x00000001 ',   {
+                                 R4: 0xDEADBEEF, }), {R4: 0x00000001, })
+        self.assertEqual(compute('AND                R4,    R4,   0x00000000 ',   {
+                                 R4: 0x00000000, }), {R4: 0x00000000, })
+        self.assertEqual(compute('AND                PC,    R4,   0x00000001 ',   {
+                                 R4: 0xFFFFFFFF, PC: 0x55555555, }), {R4: 0xFFFFFFFF, PC: 0x00000001, })
+        self.assertEqual(compute('AND                PC,    R4,   0x00000000 ',   {
+                                 R4: 0xFFFFFFFF, PC: 0x55555555, }), {R4: 0xFFFFFFFF, PC: 0x00000000, })
+        self.assertEqual(compute('ANDS               R4,    R4,   0x000000FF ',   {R4: 0xFFFFFF00, }), {
+                         nf: 0, zf: 1, cf: 0,     R4: 0x00000000, })
+        self.assertEqual(compute('ANDS               R4,    R4,   0xFF000000 ',   {R4: 0xFF000000, }), {
+                         nf: 1, zf: 0, cf: 0,     R4: 0xFF000000, })
+        self.assertEqual(compute('ANDS               PC,    R4,   0x000000FF ',   {
+                                 R4: 0xFFFFFF00, PC: 0x55555555, }), {R4: 0xFFFFFF00, PC: 0x00000000, })
+        self.assertEqual(compute('ANDS               PC,    R4,   0xFF000000 ',   {
+                                 R4: 0xFF000000, PC: 0x55555555, }), {R4: 0xFF000000, PC: 0xFF000000, })
+
+        # §A8.8.14:                AND{S}{<c>}{<q>} {<Rd>,} <Rn>, <Rm> {,<shift>}
+        self.assertRaises(
+            ValueError, compute, 'AND          R4,   R5          ')
+        self.assertEqual(compute('AND                R4,    R4,   R5          ',  {
+                                 R4: 0xFFFFFFFE, R5: 0x00000001, }), {R4: 0x00000000, R5: 0x00000001, })
+        self.assertEqual(compute('AND                R4,    R4,   R5    LSL 1 ',  {
+                                 R4: 0x00000011, R5: 0x00000008, }), {R4: 0x00000010, R5: 0x00000008, })
+        self.assertEqual(compute('AND                R4,    R4,   R5    LSR 2 ',  {
+                                 R4: 0xFFFFFFFF, R5: 0x80000041, }), {R4: 0x20000010, R5: 0x80000041, })
+        self.assertEqual(compute('AND                R4,    R4,   R5    ASR 3 ',  {
+                                 R4: 0xF00000FF, R5: 0x80000081, }), {R4: 0xF0000010, R5: 0x80000081, })
+        self.assertEqual(compute('AND                R4,    R4,   R5    ROR 4 ',  {
+                                 R4: 0xFFFFFFFF, R5: 0x000000FF, }), {R4: 0xF000000F, R5: 0x000000FF, })
+        self.assertEqual(compute('AND                R4,    R4,   R5    RRX   ',  {
+                                 cf: 1, R4: 0xFFFFFFFF, R5: 0x00000101, }), {cf: 1,     R4: 0x80000080, R5: 0x00000101, })
+        self.assertEqual(compute('ANDS               R4,    R4,   R5          ',  {R4: 0xFFFFFFFE, R5: 0x00000001, }), {
+                         nf: 0, zf: 1, cf: 0,     R4: 0x00000000, R5: 0x00000001, })
+        self.assertEqual(compute('ANDS               R4,    R4,   R5    LSL 1 ',  {R4: 0x00000011, R5: 0x00000008, }), {
+                         nf: 0, zf: 0, cf: 0,     R4: 0x00000010, R5: 0x00000008, })
+        self.assertEqual(compute('ANDS               R4,    R4,   R5    LSR 2 ',  {R4: 0xFFFFFFFF, R5: 0x80000041, }), {
+                         nf: 0, zf: 0, cf: 0,     R4: 0x20000010, R5: 0x80000041, })
+        self.assertEqual(compute('ANDS               R4,    R4,   R5    ASR 3 ',  {R4: 0xF00000FF, R5: 0x80000081, }), {
+                         nf: 1, zf: 0, cf: 0,     R4: 0xF0000010, R5: 0x80000081, })
+        self.assertEqual(compute('ANDS               R4,    R4,   R5    ROR 4 ',  {R4: 0xFFFFFFFF, R5: 0x000000FF, }), {
+                         nf: 1, zf: 0, cf: 0,     R4: 0xF000000F, R5: 0x000000FF, })
+        self.assertEqual(compute('ANDS               R4,    R4,   R5    RRX   ',  {cf: 1, R4: 0xFFFFFFFF, R5: 0x00000101, }), {
+                         nf: 1, zf: 0, cf: 0,     R4: 0x80000080, R5: 0x00000101, })
+
+        # §A8.8.15:                AND{S}{<c>}{<q>} {<Rd>,} <Rn>, <Rm>, <type> <Rs>
+        self.assertEqual(compute('AND                R4,    R6,   R4    LSL R5',  {
+                                 R4: 0x00000001, R5: 0x00000004, R6: -1, }), {R4: 0x00000010, R5: 0x00000004, R6: 0xFFFFFFFF, })
+        self.assertEqual(compute('AND                R4,    R6,   R4    LSR R5',  {
+                                 R4: 0x00000110, R5: 0x80000004, R6: -1, }), {R4: 0x00000011, R5: 0x80000004, R6: 0xFFFFFFFF, })
+        self.assertEqual(compute('AND                R4,    R6,   R4    ASR R5',  {
+                                 R4: 0x80000010, R5: 0xF0000001, R6: -1, }), {R4: 0xC0000008, R5: 0xF0000001, R6: 0xFFFFFFFF, })
+        self.assertEqual(compute('AND                R4,    R6,   R4    ROR R5',  {
+                                 R4: 0x000000FF, R5: 0x00000F04, R6: -1, }), {R4: 0xF000000F, R5: 0x00000F04, R6: 0xFFFFFFFF, })
+        self.assertEqual(compute('ANDS               R4,    R6,   R4    LSL R5',  {R4: 0x00000001, R5: 0x00000004, R6: -1, }), {
+                         nf: 0, zf: 0, cf: 0,     R4: 0x00000010, R5: 0x00000004, R6: 0xFFFFFFFF, })
+        self.assertEqual(compute('ANDS               R4,    R6,   R4    LSR R5',  {R4: 0x00000110, R5: 0x80000004, R6: -1, }), {
+                         nf: 0, zf: 0, cf: 0,     R4: 0x00000011, R5: 0x80000004, R6: 0xFFFFFFFF, })
+        self.assertEqual(compute('ANDS               R4,    R6,   R4    ASR R5',  {R4: 0x80000010, R5: 0xF0000001, R6: -1, }), {
+                         nf: 1, zf: 0, cf: 0,     R4: 0xC0000008, R5: 0xF0000001, R6: 0xFFFFFFFF, })
+        self.assertEqual(compute('ANDS               R4,    R6,   R4    ROR R5',  {R4: 0x000000FF, R5: 0x00000F04, R6: -1, }), {
+                         nf: 1, zf: 0, cf: 0,     R4: 0xF000000F, R5: 0x00000F04, R6: 0xFFFFFFFF, })
+
+    def test_ASR(self):
+        # §A8.8.16:                ASR{S}{<c>}{<q>} {<Rd>,} <Rm>, #<imm>    <==>    MOV{S}{<c>}{<q>} {<Rd>,} <Rm>, ASR #<n>
+        pass
+
+        # §A8.8.17:                ASR{S}{<c>}{<q>} {<Rd>,} <Rn>, <Rm>      <==>    MOV{S}{<c>}{<q>} {<Rd>,} <Rn>, ASR <Rm>
+        pass
+
+
+if __name__ == '__main__':
+    testsuite = unittest.TestLoader().loadTestsFromTestCase(TestARMSemantic)
+    report = unittest.TextTestRunner(verbosity=2).run(testsuite)
+    exit(len(report.errors + report.failures))
diff --git a/test/arch/msp430/arch.py b/test/arch/msp430/arch.py
new file mode 100644
index 00000000..f3e82955
--- /dev/null
+++ b/test/arch/msp430/arch.py
@@ -0,0 +1,110 @@
+
+import os
+import time
+from miasm2.arch.msp430.arch import *
+
+filename = os.environ.get('PYTHONSTARTUP')
+if filename and os.path.isfile(filename):
+    execfile(filename)
+
+
+def h2i(s):
+    return s.replace(' ', '').decode('hex')
+
+
+def u16swap(i):
+    return struct.unpack('<H', struct.pack('>H', i))[0]
+
+
+reg_tests_msp = [
+    ("4456    mov.w      SP, R4",
+     "0441"),
+    ("4d4f    mov.b      R13, R15",
+     "4f4d"),
+    ("49fe    mov.w      @R13, R9",
+     "294d"),
+    ("4982    mov.w      0x10(R14), R13",
+     "1d4e1000"),
+    ("4972    mov.w      R14, 0x0(SP)",
+     "814e0000"),
+    ("46de    mov.w      0x2(R14), 0x2(R13)",
+     "9d4e02000200"),
+    ("469e    mov.w      @0x2400, R11",
+     "1b420024"),
+    ("4c14    mov.w      0x4A96, R15",
+     "3f40964a"),
+    ("47c0    mov.w      0x1, R8",
+     "1843"),
+    ("48fc    mov.w      0x2, R10",
+     "2a43"),
+    ("44fe    mov.w      0x4, R7",
+     "2742"),
+    ("4a28    mov.w      0xFFFF, R15",
+     "3f43"),
+    ("4416    mov.w      R5, @0x15C",
+     "82455c01"),
+
+    ("4a22    add.w      R11, R15",
+     "0f5b"),
+    ("448e    sub.w      R15, SP",
+     "018f"),
+    ("4474    cmp.b      @R15, R13",
+     "6d9f"),
+    ("46a8    bit.w      0x1, R13",
+     "1db3"),
+    ("440a    bis.w      0x5A08, R5",
+     "35d0085a"),
+    ("4c1a    xor.w      R15, R10",
+     "0aef"),
+    ("4408    and.b      0xFF, R5",
+     "75f3"),
+
+
+    ("4cf0    push.w     SR",
+     "0212"),
+    ("4d6e    push.w     0x0",
+     "0312"),
+    ("45dc    push.w     0x2(R11)",
+     "1b120200"),
+    ("49cc    push.w     R11",
+     "0b12"),
+
+    ("443a    call       0x4B66",
+     "b012664b"),
+
+    ("4442    jmp        0xFFFA",
+     "fd3f"),
+    ("4422    jnz        0xFFF2",
+     "f923"),
+
+    ("xxxx    mov.b      @R13+, 0x0(R14)",
+     "fe4d0000"),
+
+    ("4a36    mov.w      @SP+, PC",
+     "3041"),
+
+
+]
+
+ts = time.time()
+
+for s, l in reg_tests_msp:
+    print "-" * 80
+    s = s[8:]
+    b = h2i((l))
+    print repr(b)
+    mn = mn_msp430.dis(b, None)
+    print [str(x) for x in mn.args]
+    print s
+    print mn
+    assert(str(mn) == s)
+    # print hex(b)
+    # print [str(x.get()) for x in mn.args]
+    l = mn_msp430.fromstring(s, None)
+    # print l
+    assert(str(l) == s)
+    a = mn_msp430.asm(l)
+    print [x for x in a]
+    print repr(b)
+    # print mn.args
+    assert(b in a)
diff --git a/test/arch/msp430/sem.py b/test/arch/msp430/sem.py
new file mode 100644
index 00000000..55da5d56
--- /dev/null
+++ b/test/arch/msp430/sem.py
@@ -0,0 +1,143 @@
+#!/usr/bin/env python
+#-*- coding:utf-8 -*-
+
+import unittest
+import logging
+
+from miasm2.ir.symbexec import symbexec
+from miasm2.arch.msp430.arch import mn_msp430 as mn, mode_msp430 as mode
+from miasm2.arch.msp430.sem import ir_msp430 as ir
+from miasm2.arch.msp430.regs import *
+from miasm2.expression.expression import *
+
+logging.getLogger('cpuhelper').setLevel(logging.ERROR)
+EXCLUDE_REGS = set([res])
+
+
+def M(addr):
+    return ExprMem(ExprInt_fromsize(16, addr), 16)
+
+
+def compute(asm, inputstate={}, debug=False):
+    sympool = dict(regs_init)
+    sympool.update({k: ExprInt_from(k, v) for k, v in inputstate.iteritems()})
+    symexec = symbexec(mn, sympool)
+    instr = mn.fromstring(asm, mode)
+    code = mn.asm(instr)[0]
+    instr = mn.dis(code, mode)
+    instr.offset = inputstate.get(PC, 0)
+    interm = ir()
+    interm.add_instr(instr)
+    symexec.emul_ir_blocs(interm, instr.offset)
+    if debug:
+        for k, v in symexec.symbols.items():
+            if regs_init.get(k, None) != v:
+                print k, v
+    return {k: v.arg.arg for k, v in symexec.symbols.items()
+            if k not in EXCLUDE_REGS and regs_init.get(k, None) != v}
+
+
+class TestMSP430Semantic(unittest.TestCase):
+
+    def test_ADD_W(self):
+        # Testing status flags
+        self.assertEqual(compute('add.w  0x0000, R4', {R4: 0x0001, }), {
+                         R4: 0x0001, nf: 0, zf: 0, cf: 0, of: 0})
+        self.assertEqual(compute('add.w  0x0000, R4', {R4: 0xFFFF, }), {
+                         R4: 0xFFFF, nf: 1, zf: 0, cf: 0, of: 0})
+        self.assertEqual(compute('add.w  0x0000, R4', {R4: 0x0000, }), {
+                         R4: 0x0000, nf: 0, zf: 1, cf: 0, of: 0})
+        self.assertEqual(compute('add.w  0x0002, R4', {R4: 0xFFFF, }), {
+                         R4: 0x0001, nf: 0, zf: 0, cf: 1, of: 0})
+        self.assertEqual(compute('add.w  0x7FFF, R4', {R4: 0x7FFF, }), {
+                         R4: 0xFFFE, nf: 1, zf: 0, cf: 0, of: 1})
+        self.assertEqual(compute('add.w  0x8001, R4', {R4: 0x8001, }), {
+                         R4: 0x0002, nf: 0, zf: 0, cf: 1, of: 1})
+        # Testing addressing mode
+        self.assertEqual(compute('add.w     R5,  R4', {R4: 0x1F53, R5: 0x28C4, }), {
+                         R4: 0x4817, R5: 0x28C4,             nf: 0, zf: 0, cf: 0, of: 0})
+        self.assertEqual(compute('add.w    @R5,  R4', {R4: 0x1F53, R5: 0x28C4, M(0x28C4): 0, }), {
+                         R4: 0x1F53, R5: 0x28C4, M(0x28C4): 0, nf: 0, zf: 0, cf: 0, of: 0})
+        self.assertEqual(compute('add.w    @R5+, R4', {R4: 0x1F53, R5: 0x28C4, M(0x28C4): 0, }), {
+                         R4: 0x1F53, R5: 0x28C6, M(0x28C4): 0, nf: 0, zf: 0, cf: 0, of: 0})
+        self.assertEqual(compute('add.w   1(R5), R4', {R4: 0x1F53, R5: 0x28C4, M(0x28C5): 0, }), {
+                         R4: 0x1F53, R5: 0x28C4, M(0x28C5): 0, nf: 0, zf: 0, cf: 0, of: 0})
+        self.assertEqual(compute('add.w @0x0000, R4', {R4: 0x1F53,          M(0): 0x28C4, }), {
+                         R4: 0x4817,          M(0): 0x28C4, nf: 0, zf: 0, cf: 0, of: 0})
+        self.assertEqual(compute('add.w  0x0000, R4', {R4: 0x1F53, }), {
+                         R4: 0x1F53,                       nf: 0, zf: 0, cf: 0, of: 0})
+
+    def test_AND_B(self):
+        # Testing status flags
+        self.assertEqual(compute('and.b  0x0001, R4', {R4: 0x0001, }), {
+                         R4: 0x0001, nf: 0, zf: 0, cf: 1, of: 0})
+        self.assertEqual(compute('and.b  0xFFFF, R4', {R4: 0xFFFF, }), {
+                         R4: 0x00FF, nf: 1, zf: 0, cf: 1, of: 0})
+        self.assertEqual(compute('and.b  0x0000, R4', {R4: 0x0000, }), {
+                         R4: 0x0000, nf: 0, zf: 1, cf: 0, of: 0})
+        # Testing addressing mode
+        self.assertEqual(compute('and.b     R5,  R4', {R4: 0x1F53, R5: 0x38C4, }), {
+                         R4: 0x0040, R5: 0x38C4,             nf: 0, zf: 0, cf: 1, of: 0})
+        self.assertEqual(compute('and.b    @R5,  R4', {R4: 0x1F53, R5: 0x38C4, M(0x38C4): 0, }), {
+                         R4: 0x0000, R5: 0x38C4, M(0x38C4): 0, nf: 0, zf: 1, cf: 0, of: 0})
+        self.assertEqual(compute('and.b    @R5+, R4', {R4: 0x1F53, R5: 0x38C4, M(0x38C4): 0, }), {
+                         R4: 0x0000, R5: 0x38C5, M(0x38C4): 0, nf: 0, zf: 1, cf: 0, of: 0})
+        self.assertEqual(compute('and.b   1(R5), R4', {R4: 0x1F53, R5: 0x38C4, M(0x38C5): 1, }), {
+                         R4: 0x0001, R5: 0x38C4, M(0x38C5): 1, nf: 0, zf: 0, cf: 1, of: 0})
+        self.assertEqual(compute('and.b @0x0000, R4', {R4: 0x1F53,          M(0): 0x38C4, }), {
+                         R4: 0x0040,          M(0): 0x38C4, nf: 0, zf: 0, cf: 1, of: 0})
+        self.assertEqual(compute('and.b  0xFFFF, R4', {R4: 0x1F53, }), {
+                         R4: 0x0053,                       nf: 0, zf: 0, cf: 1, of: 0})
+
+    def test_AND_W(self):
+        # Testing status flags
+        self.assertEqual(compute('and.w  0x0001, R4', {R4: 0x0001, }), {
+                         R4: 0x0001, nf: 0, zf: 0, cf: 1, of: 0})
+        self.assertEqual(compute('and.w  0xFFFF, R4', {R4: 0xFFFF, }), {
+                         R4: 0xFFFF, nf: 1, zf: 0, cf: 1, of: 0})
+        self.assertEqual(compute('and.w  0x0000, R4', {R4: 0x0000, }), {
+                         R4: 0x0000, nf: 0, zf: 1, cf: 0, of: 0})
+        # Testing addressing mode
+        self.assertEqual(compute('and.w     R5,  R4', {R4: 0x1F53, R5: 0x38C4, }), {
+                         R4: 0x1840, R5: 0x38C4,             nf: 0, zf: 0, cf: 1, of: 0})
+        self.assertEqual(compute('and.w    @R5,  R4', {R4: 0x1F53, R5: 0x38C4, M(0x38C4): 0, }), {
+                         R4: 0x0000, R5: 0x38C4, M(0x38C4): 0, nf: 0, zf: 1, cf: 0, of: 0})
+        self.assertEqual(compute('and.w    @R5+, R4', {R4: 0x1F53, R5: 0x38C4, M(0x38C4): 0, }), {
+                         R4: 0x0000, R5: 0x38C6, M(0x38C4): 0, nf: 0, zf: 1, cf: 0, of: 0})
+        self.assertEqual(compute('and.w   1(R5), R4', {R4: 0x1F53, R5: 0x38C4, M(0x38C5): 1, }), {
+                         R4: 0x0001, R5: 0x38C4, M(0x38C5): 1, nf: 0, zf: 0, cf: 1, of: 0})
+        self.assertEqual(compute('and.w @0x0000, R4', {R4: 0x1F53,          M(0): 0x38C4, }), {
+                         R4: 0x1840,          M(0): 0x38C4, nf: 0, zf: 0, cf: 1, of: 0})
+        self.assertEqual(compute('and.w  0xFFFF, R4', {R4: 0x1F53, }), {
+                         R4: 0x1F53,                       nf: 0, zf: 0, cf: 1, of: 0})
+
+    def test_BIC_B(self):
+        # Testing addressing mode
+        self.assertEqual(
+            compute('bic.b 0x0000,     R4',  {R4: 0x1F53, }), {R4: 0x0053, })
+        # self.assertEqual(compute('bic.b 0x0000,    @R4',  {R4:0x1F53,M(0x1F53):0x569D, }), {R4:0x1F53,M(0x1F53):0x38C4, })
+        # self.assertEqual(compute('bic.b 0x38C4,    @R4+', {R4:0x1F53,M(0x1F53):0x569D, }), {R4:0x1F55,M(0x1F53):0x38C4, })
+        # self.assertEqual(compute('bic.b 0x38C4,   1(R4)', {R4:0x1F53,M(0x1F54):0x569D, }), {R4:0x1F53,M(0x1F54):0x5619, })
+        # self.assertEqual(compute('bic.b 0x0000, @0x0000', {          M(0x0000):0x569D, }), {          M(0x0000):0x38C4, })
+        # self.assertEqual(compute('bic.b 0x38C4,  0xFFFE', {
+        # }), {                            })
+
+    def test_CALL(self):
+        # Testing addressing mode
+        self.assertEqual(compute('call     R4',  {PC: 0x0100, SP: 0x0400, R4: 0x1F53, }), {
+                         PC: 0x1F53, SP: 0x03FE, R4: 0x1F53,                 M(0x03FE): 0x102, })
+        self.assertEqual(compute('call    @R4',  {PC: 0x0100, SP: 0x0400, R4: 0x1F53, M(0x1F53): 0x38C4, }), {
+                         PC: 0x38C4, SP: 0x03FE, R4: 0x1F53, M(0x1F53): 0x38C4, M(0x03FE): 0x102, })
+        self.assertEqual(compute('call    @R4+', {PC: 0x0100, SP: 0x0400, R4: 0x1F53, M(0x1F53): 0x38C4, }), {
+                         PC: 0x38C4, SP: 0x03FE, R4: 0x1F55, M(0x1F53): 0x38C4, M(0x03FE): 0x102, })
+        self.assertEqual(compute('call   1(R4)', {PC: 0x0100, SP: 0x0400, R4: 0x1F53, M(0x1F54): 0x38C4, }), {
+                         PC: 0x38C4, SP: 0x03FE, R4: 0x1F53, M(0x1F54): 0x38C4, M(0x03FE): 0x104, })
+        self.assertEqual(compute('call @0x0000', {PC: 0x0100, SP: 0x0400,          M(0x0000): 0x38C4, }), {
+                         PC: 0x38C4, SP: 0x03FE,          M(0x0000): 0x38C4, M(0x03FE): 0x104, })
+        self.assertEqual(compute('call  0xFFFE', {PC: 0x0100, SP: 0x0400, }), {
+                         PC: 0xFFFE, SP: 0x03FE,                           M(0x03FE): 0x104, })
+
+if __name__ == '__main__':
+    testsuite = unittest.TestLoader().loadTestsFromTestCase(TestMSP430Semantic)
+    report = unittest.TextTestRunner(verbosity=2).run(testsuite)
+    exit(len(report.errors + report.failures))
diff --git a/test/arch/sh4/arch.py b/test/arch/sh4/arch.py
new file mode 100644
index 00000000..b7e79d30
--- /dev/null
+++ b/test/arch/sh4/arch.py
@@ -0,0 +1,436 @@
+import os
+import time
+from sys import stderr
+from miasm2.arch.sh4.arch import *
+
+filename = os.environ.get('PYTHONSTARTUP')
+if filename and os.path.isfile(filename):
+    execfile(filename)
+
+
+def h2i(s):
+    return s.replace(' ', '').decode('hex')
+
+reg_tests_sh4 = [
+    # vxworks
+    ("c80022f2    MOV        0x10, R6",
+     "10e6"),
+    ("c8002250    MOV        0xFFFFFFFF, R0",
+     "ffe0"),
+    ("c800226a    MOV.W      @(PC,0xC0), R9",
+     "5e99"),
+    ("c8002006    MOV.L      @(PC&0xFFFFFFFC,0x10), R15",
+     "03df"),
+    ("c800cfc4    MOV        R4, R9",
+     "4369"),
+    ("C8005004    MOV.B      R1, @R2",
+     "1022"),
+    ("C8002E04    MOV.W      R0, @R8",
+     '0128'),
+    ("c800223e    MOV.L      R1, @R14",
+     "122E"),
+
+    ("c8002002    MOV.L      @R1, R0",
+     "1260"),
+    ("c8002E08    MOV.W      @R8, R1",
+     "8161"),
+    ("c800357c    MOV.B      @R4, R1",
+     "4061"),
+
+    ("c8002220    MOV.L      R8, @-R15",
+     "862f"),
+    ("c8022a66    MOV.B      R4, @-R0",
+     "4420"),
+    ("c8002310    MOV.L      @R15+, R14",
+     "f66e"),
+    ("c80038a4    MOV.W      @R8+, R5",
+     "8565"),
+    ("xxxxxxxx    MOV.B      R0, @(R8,0x2)",
+     "8280"),
+    ("xxxxxxxx    MOV.W      R0, @(R8,0x4)",
+     "8281"),
+    ("c8002274    MOV.L      R0, @(R9,0x8)",
+     "0219"),
+    ("xxxxxxxx    MOV.B      @(R8,0x8), R0",
+     "8884"),
+    ("xxxxxxxx    MOV.W      @(R8,0x10), R0",
+     "8885"),
+    ("c8002500    MOV.L      @(R14,0x4), R5",
+     "e155"),
+    ("xxxxxxxx    MOV.B      R4, @(R0,R8)",
+     "4408"),
+    ("xxxxxxxx    MOV.W      R4, @(R0,R8)",
+     "4508"),
+    ("xxxxxxxx    MOV.L      R4, @(R0,R8)",
+     "4608"),
+    ("xxxxxxxx    MOV.B      @(R0,R4), R8",
+     "4c08"),
+    ("xxxxxxxx    MOV.W      @(R0,R4), R8",
+     "4d08"),
+    ("xxxxxxxx    MOV.L      @(R0,R4), R8",
+     "4e08"),
+    ("xxxxxxxx    MOV.B      R0, @(GBR,0x4)",
+     "04c0"),
+    ("xxxxxxxx    MOV.W      R0, @(GBR,0x8)",
+     "04c1"),
+    ("xxxxxxxx    MOV.L      R0, @(GBR,0x10)",
+     "04c2"),
+    ("xxxxxxxx    MOV.B      @(GBR,0x4), R0",
+     "04c4"),
+    ("xxxxxxxx    MOV.W      @(GBR,0x8), R0",
+     "04c5"),
+    ("xxxxxxxx    MOV.L      @(GBR,0x10), R0",
+     "04c6"),
+    #("xxxxxxxx    MOV        PC&0xFFFFFFFC+0x14, R0",
+    # "04c7"),
+    ("xxxxxxxx    SWAPB      R2, R1",
+     "2861"),
+    ("c803f492    SWAPW      R4, R9",
+     "4969"),
+    ("xxxxxxxx    XTRCT      R4, R9",
+     "4d29"),
+    ("c8002270    ADD        R12, R9",
+     "cc39"),
+    ("c8002238    ADD        0xFFFFFFFC, R15",
+     "FC7F"),
+    ("c80164cc    ADDC       R0, R1",
+     "0e31"),
+    ("xxxxxxxx    ADDV       R0, R1",
+     "0f31"),
+    ("c8002994    CMPEQ      0x20, R0",
+     "2088"),
+    ("c80029d2    CMPEQ      R2, R1",
+     "2031"),
+    ("c8003964    CMPHS      R5, R3",
+     "5233"),
+    ("c8002df2    CMPGE      R0, R1",
+     "0331"),
+    ("c80029a4    CMPHI      R1, R0",
+     "1630"),
+    ("c8002bfe    CMPGT      R10, R8",
+     "a738"),
+    ("c8002bf8    CMPPZ      R0",
+     "1140"),
+    ("c8006294    CMPPL      R2",
+     "1542"),
+    ("c8033800    CMPSTR     R14, R4",
+     "ec24"),
+    ("xxxxxxxx    DIV1       R14, R4",
+     "e434"),
+    ("c8d960de    DIV0S      R0, R3",
+     "0723"),
+    ("xxxxxxxx    DIV0U      ",
+     "1900"),
+    ("c800dcd8    DMULS      R1, R0",
+     "1d30"),
+    ("c80164da    DMULU      R3, R8",
+     "3538"),
+    ("c80024e2    DT         R10",
+     "104a"),
+    ("c800343a    EXTSB      R1, R1",
+     "1e61"),
+    ("c8002bf6    EXTSW      R0, R0",
+     "0f60"),
+    ("c8002fba    EXTUB      R0, R0",
+     "0c60"),
+    ("c8002398    EXTUW      R0, R0",
+     "0d60"),
+    ("xxxxxxxx    MAC.L      @R5+, @R4+",
+     "5f04"),
+    ("xxxxxxxx    MAC.W      @R5+, @R4+",
+     "5f44"),
+    ("c8005112    MULL       R1, R3",
+     "1703"),
+    ("xxxxxxxx    MULSW      R1, R3",
+     "1F23"),
+    ("xxxxxxxx    MULUW      R1, R3",
+     "1e23"),
+    ("c8004856    NEG        R1, R8",
+     "1b68"),
+    ("c80054fc    NEGC       R9, R7",
+     "9a67"),
+    ("c8004b36    SUB        R1, R5",
+     "1835"),
+    ("c800a536    SUBC       R1, R0",
+     "1a30"),
+    ("xxxxxxxx    SUBV       R1, R0",
+     "1b30"),
+    ("c80023ca    AND        R0, R5",
+     "0925"),
+    ("c800257c    AND        0x2, R0",
+     "02c9"),
+    ("xxxxxxxx    AND.B      0x2, @(GBR,R0)",
+     "02cd"),
+    ("c80065fe    NOT        R5, R1",
+     "5761"),
+    ("c8002586    OR         R10, R1",
+     "ab21"),
+    ("c80023aa    OR         0x4, R0",
+     "04cb"),
+    ("xxxxxxxx    OR.B       0x4, @(GBR,R0)",
+     "04cf"),
+    ("xxxxxxxx    TAS.B      @R8",
+     "1b48"),
+    ("c8002368    TST        R10, R13",
+     "a82d"),
+    ("c8003430    TST        0x11, R0",
+     "11c8"),
+    ("xxxxxxxx    TST.B      0x4, @(GBR,R0)",
+     "04cc"),
+    ("c8003978    XOR        R1, R6",
+     "1a26"),
+    ("c8028270    XOR        0x1, R0",
+     "01ca"),
+    ("xxxxxxxx    XOR.B      0x4, @(GBR,R0)",
+     "04cE"),
+    ("xxxxxxxx    ROTL       R9",
+     "0449"),
+    ("xxxxxxxx    ROTR       R9",
+     "0549"),
+    ("xxxxxxxx    ROTCL      R9",
+     "2449"),
+    ("xxxxxxxx    ROTCR      R9",
+     "2549"),
+    ("xxxxxxxx    SHAL       R11",
+     "204b"),
+    ("xxxxxxxx    SHAR       R11",
+     "214b"),
+    ("c800236c    SHLD       R6, R10",
+     "6d4a"),
+    ("xxxxxxxx    SHLL       R11",
+     "004b"),
+    ("xxxxxxxx    SHLR       R11",
+     "014b"),
+    ("xxxxxxxx    SHLL2      R11",
+     "084b"),
+    ("xxxxxxxx    SHLR2      R11",
+     "094b"),
+    ("xxxxxxxx    SHLL8      R11",
+     "184b"),
+    ("xxxxxxxx    SHLR8      R11",
+     "194b"),
+    ("xxxxxxxx    SHLL16     R11",
+     "284b"),
+    ("xxxxxxxx    SHLR16     R11",
+     "294b"),
+    ("c8002c00    BF         0xFFFFFFF4",
+     "f48b"),
+    ("c80023c2    BFS        0xFFFFFFD8",
+     "d88f"),
+    ("c8002266    BT         0x5B",
+     "5b89"),
+    ("c8002266    BTS        0x5C",
+     "5c8d"),
+    ("c8002326    BRA        0xFFFFFFF0",
+     "f0af"),
+    ("c8004b4a    BRAF       R1",
+     "2301"),
+    ("c8055da4    BSR        0xFFFFFE48",
+     "48be"),
+    ("xxxxxxxx    BSRF       R1",
+     "0301"),
+    ("c80027b4    JMP.L      @R1",
+     "2b41"),
+    ("c800200c    JSR.L      @R0",
+     "0b40"),
+    ("c800231a    RTS        ",
+     "0b00"),
+    ("xxxxxxxx    CLRMAC     ",
+     "2800"),
+    ("xxxxxxxx    CLRS       ",
+     "4800"),
+    ("xxxxxxxx    CLRT       ",
+     "0800"),
+    ("c8002004    LDC        R0, SR",
+     "0e40"),
+    ("c800200e    LDC        R1, GBR",
+     "1e41"),
+    ("c8064bd4    LDC        R8, VBR",
+     "2e48"),
+    ("xxxxxxxx    LDC        R8, SSR",
+     "3e48"),
+    ("xxxxxxxx    LDC        R8, SPC",
+     "4e48"),
+    ("xxxxxxxx    LDC        R8, DBR",
+     "fa48"),
+    ("xxxxxxxx    LDC        R8, R0_BANK",
+     "8e48"),
+    ("xxxxxxxx    LDC.L      @R8+, SR",
+     "0748"),
+    ("xxxxxxxx    LDC.L      @R8+, GBR",
+     "1748"),
+    ("xxxxxxxx    LDC.L      @R8+, VBR",
+     "2748"),
+    ("xxxxxxxx    LDC.L      @R8+, SSR",
+     "3748"),
+    ("xxxxxxxx    LDC.L      @R8+, SPC",
+     "4748"),
+    ("xxxxxxxx    LDC.L      @R8+, DBR",
+     "f648"),
+    ("xxxxxxxx    LDC.L      @R8+, R2_BANK",
+     "a748"),
+    ("xxxxxxxx    LDS        R8, MACH",
+     "0a48"),
+    ("xxxxxxxx    LDS        R8, MACL",
+     "1a48"),
+    ("xxxxxxxx    LDS        R8, PR",
+     "2a48"),
+    ("xxxxxxxx    LDS.L      @R8+, MACH",
+     "0648"),
+    ("xxxxxxxx    LDS.L      @R8+, MACL",
+     "1648"),
+    ("xxxxxxxx    LDTLB      ",
+     "3800"),
+    ("xxxxxxxx    MOVCA.L    R0, @R8",
+     "c308"),
+    ("xxxxxxxx    NOP        ",
+     "0900"),
+    ("xxxxxxxx    OCBI.L     @R8",
+     "9308"),
+    ("xxxxxxxx    OCBP.L     @R8",
+     "a308"),
+    ("xxxxxxxx    OCBWB.L    @R8",
+     "b308"),
+    ("xxxxxxxx    PREF.L     @R8",
+     "8308"),
+    ("xxxxxxxx    STS        MACH, R8",
+     "0a08"),
+    ("xxxxxxxx    STS        MACL, R8",
+     "1a08"),
+    ("xxxxxxxx    STS        PR, R8",
+     "2a08"),
+    ("xxxxxxxx    STS.L      MACH, @-R8",
+     "0248"),
+    ("xxxxxxxx    STS.L      MACL, @-R8",
+     "1248"),
+    ("xxxxxxxx    STS.L      PR, @-R8",
+     "2248"),
+
+
+
+
+
+    ("c8004b50    STC        GBR, R0",
+     "1200"),
+    ("c8064516    STC        VBR, R1",
+     "2201"),
+    ("c8004b54    STC        SSR, R1",
+     "3201"),
+    ("c801ed6c    STC        SPC, R0",
+     "4200"),
+    ("xxxxxxxx    STC        SGR, R0",
+     "3a00"),
+    ("xxxxxxxx    STC        DBR, R0",
+     "fa00"),
+    ("c8004b56    STC        R3_BANK, R1",
+     "B201"),
+    ("xxxxxxxx    STC.L      SR, @-R8",
+     "0348"),
+    ("xxxxxxxx    STC.L      GBR, @-R8",
+     "1348"),
+    ("xxxxxxxx    STC.L      VBR, @-R8",
+     "2348"),
+    ("xxxxxxxx    STC.L      SSR, @-R8",
+     "3348"),
+    ("xxxxxxxx    STC.L      SPC, @-R8",
+     "4348"),
+    ("xxxxxxxx    STC.L      DBR, @-R8",
+     "f248"),
+    ("xxxxxxxx    STC.L      R7_BANK, @-R8",
+     "f348"),
+    ("c803b130    TRAPA      0xE0",
+     "e0c3"),
+
+    ("xxxxxxxx    FLDI0      FR8",
+     "8df8"),
+    ("xxxxxxxx    FLDI1      FR8",
+     "9df8"),
+    ("c8019ca8    FMOV       FR15, FR5",
+     "fcf5"),
+    ("c800affe    FMOV.S     @R1, FR4",
+     "18f4"),
+    ("c80283f6    FMOV.S     @(R0,R14), FR5",
+     "e6f5"),
+    ("c800aff8    FMOV.S     @R1+, FR5",
+     "19f5"),
+    ("c80cb692    FMOV.S     FR0, @R2",
+     "0af2"),
+    ("c80cb694    FMOV.S     FR1, @-R2",
+     "1bf2"),
+    ("c80283aa    FMOV.S     FR1, @(R0,R14)",
+     "17fe"),
+    ("c800ce16    FLDS       FR13, FPUL",
+     "1dfd"),
+    ("c800ce08    FSTS       FPUL, FR13",
+     "0dfd"),
+    ("xxxxxxxx    FABS       FR8",
+     "5df8"),
+    ("c800cf28    FADD       FR2, FR6",
+     "20f6"),
+    ("c805dacc    FCMPEQ     FR2, FR6",
+     "24f6"),
+    ("c8028406    FCMPGT     FR4, FR2",
+     "45f2"),
+    ("c8019ca4    FDIV       FR2, FR12",
+     "23fc"),
+    ("c800ce5e    FLOAT      FPUL, FR2",
+     "2df2"),
+    ("xxxxxxxx    FMAC       FR0, FR1, FR2",
+     "1ef2"),
+    ("c800b006    FMUL       FR2, FR4",
+     "22f4"),
+    ("c805e412    FNEG       FR14",
+     "4dfe"),
+    ("xxxxxxxx    FSQRT      FR14",
+     "6dfe"),
+    ("c8030400    FSUB       FR4, FR2",
+     "41f2"),
+    ("c80303ba    FTRC       FR2, FPUL",
+     "3df2"),
+
+]
+
+for s, l in reg_tests_sh4:
+    print "-" * 80
+    s = s[12:]
+    b = h2i((l))
+    print b.encode('hex')
+    mn = mn_sh4.dis(b, None)
+    print [str(x) for x in mn.args]
+    print s
+    print mn
+    assert(str(mn) == s)
+    # print hex(b)
+    # print [str(x.get()) for x in mn.args]
+    l = mn_sh4.fromstring(s, None)
+    # print l
+    assert(str(l) == s)
+    a = mn_sh4.asm(l)
+    print [x for x in a]
+    print repr(b)
+    # print mn.args
+    assert(b in a)
+
+
+# speed test
+o = ""
+for s, l, in reg_tests_sh4:
+    s = s[12:]
+    b = h2i((l))
+    o += b
+
+while len(o) < 1000:
+    o += o
+bs = bin_stream_str(o)
+off = 0
+instr_num = 0
+ts = time.time()
+while off < bs.getlen():
+    mn = mn_sh4.dis(bs, None, off)
+    print instr_num, off, mn.l, str(mn)
+    instr_num += 1
+    off += mn.l
+print 'instr per sec:', instr_num / (time.time() - ts)
+
+import cProfile
+cProfile.run(r'mn_sh4.dis("\x17\xfe", None)')
diff --git a/test/arch/x86/arch.py b/test/arch/x86/arch.py
new file mode 100644
index 00000000..98545b4f
--- /dev/null
+++ b/test/arch/x86/arch.py
@@ -0,0 +1,1779 @@
+import os
+import time
+from miasm2.arch.x86.arch import *
+
+filename = os.environ.get('PYTHONSTARTUP')
+if filename and os.path.isfile(filename):
+    execfile(filename)
+for s in ["[EAX]",
+          "[0x10]",
+          "[EBX + 0x10]",
+          "[EBX + ECX*0x10]",
+          "[EBX + ECX*0x10 + 0x1337]"]:
+    (e, a, b) = deref_mem_ad.scanString(s).next()
+    print 'expr', e[0]
+
+print '---'
+
+mylabel16 = ExprId('mylabel16', 16)
+mylabel32 = ExprId('mylabel32', 32)
+mylabel64 = ExprId('mylabel64', 64)
+
+reg_and_id = dict(mn_x86.regs.all_regs_ids_byname)
+reg_and_id.update({'mylabel16': mylabel16,
+                   'mylabel32': mylabel32,
+                   'mylabel64': mylabel64,
+                   })
+
+
+def my_ast_id2expr(t):
+    r = reg_and_id.get(t, ExprId(t, size=32))
+    return r
+
+my_var_parser = parse_ast(my_ast_id2expr, ast_int2expr)
+base_expr.setParseAction(my_var_parser)
+
+for s in ['EAX',
+          "BYTE PTR [EAX]",
+          "WORD PTR [EAX]",
+          "DWORD PTR [ECX+0x1337]",
+          "QWORD PTR [RAX+4*RCX + 0x1337]",
+          "DWORD PTR [EAX+EBX]",
+          "QWORD PTR [RAX+RBX+0x55667788]",
+          "BYTE PTR CS:[EAX]",
+          "QWORD PTR [RAX+RBX+mylabel64]",
+          "BYTE PTR [RAX+RBX+mylabel64]",
+          "BYTE PTR [AX+BX+mylabel16]",
+          "BYTE PTR [mylabel32]",
+          ]:
+    print '*' * 80
+    print s
+    (e, a, b) = rmarg.scanString(s).next()
+    print 'expr', e[0]
+    e[0].visit(print_size)
+
+
+def h2i(s):
+    return int(s.replace(' ', '').decode('hex')[::].encode('hex'), 16)
+
+
+m16 = 16  # (16, 16)
+m32 = 32  # (32, 32)
+m64 = 64  # (64, 64)
+reg_tests = [
+
+    (m32, "00000000    AAA",
+     "37"),
+    (m32, "00000000    AAS",
+     "3F"),
+    (m32, "00000000    AAD        0x11",
+     "d511"),
+    (m32, "00000000    AAM        0x11",
+     "d411"),
+    (m32, "00000000    ADC        AL, 0x11",
+     "1411"),
+    (m32, "00000000    ADC        EAX, 0x11223344",
+     "1544332211"),
+    (m16, "00000000    ADC        AX, 0x1122",
+     "152211"),
+    (m64, "00000000    ADC        EAX, 0x11223344",
+     "1544332211"),
+    (m64, "00000000    ADC        RAX, 0x11223344",
+     "481544332211"),
+    (m32, "00000000    ADC        EAX, 0xFFFFFFFC",
+     "83d0fc"),
+    (m64, "00000000    ADC        RAX, 0xFFFFFFFFFFFFFFFC",
+     "4883d0fc"),
+    (m16, "00000000    ADC        AX, 0xFFFC",
+     "83d0fc"),
+    (m64, "00000000    ADC        EAX, 0xFFFFFFFC",
+     "15fcffffff"),
+    (m64, "00000000    ADC        RAX, 0xFFFFFFFFFFFFFFFC",
+     "4815fcffffff"),
+    (m16, "00000000    ADC        WORD PTR [BX+SI], 0x1122",
+     "81102211"),
+    (m32, "00000000    ADC        DWORD PTR [EAX], 0x11223344",
+     "811044332211"),
+    (m32, "00000000    ADC        DWORD PTR [EAX+EBX+0xFFFFFFFE], 0x11223344",
+     "815418fe44332211"),
+    (m32, "00000000    ADC        DWORD PTR [EAX+EBX+0x55667788], 0x11223344",
+     "8194188877665544332211"),
+    (m64, "00000000    ADC        DWORD PTR [RAX], 0x11223344",
+     "811044332211"),
+    (m64, "00000000    ADC        QWORD PTR [RAX], 0x11223344",
+     "48811044332211"),
+    (m64, "00000000    ADC        QWORD PTR [RAX+RBX], 0x11223344",
+     "4881141844332211"),
+    (m64, "00000000    ADC        QWORD PTR [RAX+RBX+0x55667788], 0x11223344",
+     "488194188877665544332211"),
+    (m64, "00000000    ADC        QWORD PTR [RAX+RBX+0xFFFFFFFFFFFFFFFE], 0x11223344",
+     "48815403fe44332211"),
+    (m64, "00000000    ADC        QWORD PTR [EAX], 0x11223344",
+     "6748811044332211"),
+    (m32, "00000000    ADC        BYTE PTR [EAX], 0x11",
+     "801011"),
+    (m16, "00000000    ADC        DX, 0x1122",
+     "81d22211"),
+    (m32, "00000000    ADC        EDX, 0x11223344",
+     "81d244332211"),
+    (m64, "00000000    ADC        RDX, 0x11223344",
+     "4881d244332211"),
+    (m32, "00000000    ADC        DWORD PTR [EAX+EBX], 0x11223344",
+     "81141844332211"),
+    (m32, "00000000    ADC        DWORD PTR [EAX+EBX], EAX",
+     "110418"),
+    (m64, "00000000    ADC        QWORD PTR [RAX+RBX], RAX",
+     "48110418"),
+    (m32, "00000000    ADC        BYTE PTR [EAX+EBX], AL",
+     "100418"),
+    (m32, "00000000    ADC        AL, BYTE PTR [EAX+EBX]",
+     "120418"),
+    (m16, "00000000    ADC        WORD PTR [BX+SI], DX",
+     "1110"),
+    (m32, "00000000    ADC        WORD PTR [BX+SI], DX",
+     "66671110"),
+    (m16, "00000000    ADC        DWORD PTR [EBX+ESI], EDX",
+     "6667111433"),
+
+    # prefix test
+    (m32, "00000000    ADC        AX, 0x1122",
+     "66152211"),
+
+    (m32, "00000000    ADC        EAX, 0x11223344",
+     "1544332211"),
+
+    (m16, "00000000    ADC        WORD PTR [BX+DI], 0x1",
+     "831101"),
+    (m32, "00000000    ADC        DWORD PTR [EAX+EBX+0xFFFFFFFE], 0x1",
+     "835403fe01"),
+    (m32, "00000000    ADC        WORD PTR [EAX+EBX+0xFFFFFFFE], 0x1",
+     "66835403fe01"),
+    (m64, "00000000    ADC        DWORD PTR [RAX+RBX+0xFFFFFFFFFFFFFFFE], 0x1",
+     "835403fe01"),
+    #
+    (m32, "00000000    ADC        DWORD PTR [EAX+EBX*0x4+0xFFFFFFFE], 0x1",
+     "835498fe01"),
+
+    (m64, "00000000    ADC        QWORD PTR [RAX+RBX], R8",
+     "4c110418"),
+    (m64, "00000000    ADC        QWORD PTR [RAX+RBX], R15",
+     "4c113c18"),
+
+    (m64, "00000000    ADC        QWORD PTR [R8], RAX",
+     "491100"),
+    (m64, "00000000    ADC        QWORD PTR [R8+R9], RAX",
+     "4b110408"),
+    (m64, "00000000    ADC        QWORD PTR [R8+RBP], RAX",
+     "49110428"),
+    (m64, "00000000    ADC        QWORD PTR [RBP+R8*0x4], RAX",
+     "4a11448500"),
+    (m64, "00000000    ADC        QWORD PTR [RBP+R12*0x4], RAX",
+     "4a1144a500"),
+    (m64, "00000000    ADC        QWORD PTR [RSP+R12*0x4], RAX",
+     "4a1104a4"),
+    (m64, "00000000    ADC        QWORD PTR [R12*0x5], RAX",
+     "4b1104a4"),
+    (m64, "00000000    ADC        QWORD PTR [R12*0x5+0x11], RAX",
+     "4b1144a411"),
+    (m64, "00000000    ADC        QWORD PTR [RBP+R12*0x4+0x10], RAX",
+     "4a1144a510"),
+
+    (m32, "00000000    ADD        AL, 0x11",
+     "0411"),
+    (m32, "00000000    ADD        EAX, 0x11223344",
+     "0544332211"),
+
+
+    (m32, "00000000    AND        AL, 0x11",
+     "2411"),
+    (m32, "00000000    AND        EAX, 0x11223344",
+     "2544332211"),
+    (m64, "00000000    AND        CX, R14W",
+     "664123CE"),
+    (m64, "00000000    AND        R12W, R14W",
+     "664521f4"),
+
+
+
+    (m32, "00000000    BSF        EAX, DWORD PTR [EAX]",
+     "0fbc00"),
+
+    (m32, "00000000    BSR        EAX, DWORD PTR [EAX]",
+     "0fbd00"),
+
+    (m32, "00000000    BSWAP      EAX",
+     "0fc8"),
+
+    (m32, "00000000    BT         DWORD PTR [EAX], EAX",
+     "0fa300"),
+    (m32, "00000000    BT         DWORD PTR [EAX], 0x11",
+     "0fba2011"),
+    (m32, "00000000    BT         DWORD PTR [EAX], 0xFF",
+     "0fba20ff"),
+    (m64, "00000000    BT         R9D, 0x1E",
+     "410fbae11e"),
+
+    (m32, "00000000    BTC        DWORD PTR [EAX], EAX",
+     "0fbb00"),
+    (m32, "00000000    BTC        DWORD PTR [EAX], 0x42",
+     "0fba3842"),
+
+
+    (m32, "00000000    BTR        DWORD PTR [EAX], EAX",
+     "0fb300"),
+    (m32, "00000000    BTR        DWORD PTR [EAX], 0x42",
+     "0fba3042"),
+
+
+    (m32, "00000000    BTS        DWORD PTR [EAX], EAX",
+     "0fab00"),
+    (m32, "00000000    BTS        DWORD PTR [EAX], 0x42",
+     "0fba2842"),
+
+
+    (m32, "00000000    CALL       0x112233",
+     "e833221100"),
+    (m64, "00000000    CALL       0x112233",
+     "e833221100"),
+    (m32, "00000000    CALL       DWORD PTR [EAX]",
+     "ff10"),
+    (m64, "00000000    CALL       QWORD PTR [RAX]",
+     "ff10"),
+
+    (m32, "00000000    CALL       0x6655:0x44332211",
+     "9a112233445566"),
+    (m32, "00000000    CALL       0x6655:0xFF332211",
+     "9a112233FF5566"),
+
+
+    (m16, "00000000    CBW",
+     "98"),
+    (m16, "00000000    CWDE",
+     "6698"),
+    (m32, "00000000    CWDE",
+     "98"),
+    (m64, "00000000    CWDE",
+     "98"),
+    (m64, "00000000    CDQE",
+     "4898"),
+
+    (m32, "00000000    CMOVO      EAX, DWORD PTR [EAX]",
+     "0f4000"),
+    (m32, "00000000    CMOVNO     EAX, DWORD PTR [EAX]",
+     "0f4100"),
+    (m32, "00000000    CMOVB      EAX, DWORD PTR [EAX]",
+     "0f4200"),
+    (m32, "00000000    CMOVAE     EAX, DWORD PTR [EAX]",
+     "0f4300"),
+    (m32, "00000000    CMOVZ      EAX, DWORD PTR [EAX]",
+     "0f4400"),
+    (m32, "00000000    CMOVNZ     EAX, DWORD PTR [EAX]",
+     "0f4500"),
+    (m32, "00000000    CMOVBE     EAX, DWORD PTR [EAX]",
+     "0f4600"),
+    (m32, "00000000    CMOVA      EAX, DWORD PTR [EAX]",
+     "0f4700"),
+    (m32, "00000000    CMOVS      EAX, DWORD PTR [EAX]",
+     "0f4800"),
+    (m32, "00000000    CMOVNS     EAX, DWORD PTR [EAX]",
+     "0f4900"),
+    (m32, "00000000    CMOVPE     EAX, DWORD PTR [EAX]",
+     "0f4A00"),
+    (m32, "00000000    CMOVNP     EAX, DWORD PTR [EAX]",
+     "0f4B00"),
+    (m32, "00000000    CMOVL      EAX, DWORD PTR [EAX]",
+     "0f4C00"),
+    (m32, "00000000    CMOVGE     EAX, DWORD PTR [EAX]",
+     "0f4D00"),
+    (m32, "00000000    CMOVLE     EAX, DWORD PTR [EAX]",
+     "0f4E00"),
+    (m32, "00000000    CMOVG      EAX, DWORD PTR [EAX]",
+     "0f4F00"),
+
+    (m32, "00000000    CMP        EAX, DWORD PTR [EAX]",
+     "3b00"),
+
+    (m32, "00000000    CMPXCHG    BYTE PTR [EAX], AL",
+     "0fb000"),
+    (m32, "00000000    CMPXCHG    DWORD PTR [EAX], EAX",
+     "0fb100"),
+
+    (m32, "00000000    CDQ",
+     "99"),
+    (m64, "00000000    CQO",
+     "4899"),
+
+    (m32, "00000000    DEC        BYTE PTR [EAX]",
+     "fe08"),
+    (m32, "00000000    DEC        DWORD PTR [EAX]",
+     "ff08"),
+
+    (m32, "00000000    DEC        ECX",
+     "49"),
+
+    (m32, "00000000    DIV        BL",
+     "f6f3"),
+    (m32, "00000000    DIV        EBX",
+     "f7f3"),
+
+    (m32, "00000000    ENTER      0x12, 0x0",
+     "c8120000"),
+    (m32, "00000000    ENTER      0x12, 0x66",
+     "c8120066"),
+
+    (m32, "00000000    F2XM1",
+     "D9f0"),
+    (m32, "00000000    FABS",
+     "D9e1"),
+
+    (m16, "00000000    FADD       DWORD PTR [BX+SI]",
+     "D800"),
+    (m32, "00000000    FADD       DWORD PTR [EAX]",
+     "D800"),
+    (m32, "00000000    FADD       QWORD PTR [EAX]",
+     "DC00"),
+
+    (m32, "00000000    FADD       ST, ST(2)",
+     "D8C2"),
+    (m32, "00000000    FADD       ST(2), ST",
+     "DCC2"),
+
+    (m32, "00000000    FADDP      ST(2), ST",
+     "DEC2"),
+
+    (m16, "00000000    FIADD      DWORD PTR [BX+SI]",
+     "DA00"),
+    (m32, "00000000    FIADD      DWORD PTR [EAX]",
+     "DA00"),
+    (m32, "00000000    FIADD      WORD PTR [EAX]",
+     "DE00"),
+
+    (m32, "00000000    FBLD       TBYTE PTR [EAX]",
+     "DF20"),
+    (m64, "00000000    FBLD       TBYTE PTR [RAX]",
+     "DF20"),
+
+    (m32, "00000000    FBLDP      TBYTE PTR [EAX]",
+     "DF30"),
+    (m64, "00000000    FBLDP      TBYTE PTR [RAX]",
+     "DF30"),
+
+    (m16, "00000000    FCHS",
+     "d9e0"),
+    (m32, "00000000    FCHS",
+     "d9e0"),
+    (m64, "00000000    FCHS",
+     "d9e0"),
+
+
+    #(m32, "00000000    FCLEX",
+    # "9bdbe2"),
+    (m32, "00000000    FNCLEX",
+     "dbe2"),
+
+    (m32, "00000000    FCMOVB     ST, ST(2)",
+     "dac2"),
+
+    (m32, "00000000    FCOM       DWORD PTR [EAX]",
+     "d810"),
+    (m32, "00000000    FCOM       QWORD PTR [EAX]",
+     "dC10"),
+    (m32, "00000000    FCOMP      DWORD PTR [EAX]",
+     "d818"),
+    (m32, "00000000    FCOMP      QWORD PTR [EAX]",
+     "dC18"),
+    (m32, "00000000    FCOMPP",
+     "ded9"),
+
+    (m32, "00000000    FCOMI      ST, ST(2)",
+     "dbf2"),
+    (m32, "00000000    FCOMIP     ST, ST(2)",
+     "dff2"),
+
+    (m32, "00000000    FUCOMI     ST, ST(2)",
+     "dbea"),
+    (m32, "00000000    FUCOMIP    ST, ST(2)",
+     "dfea"),
+
+    (m32, "00000000    FCOS",
+     "d9ff"),
+
+    (m32, "00000000    FDECSTP",
+     "d9f6"),
+
+
+    (m16, "00000000    FDIV       DWORD PTR [BX+SI]",
+     "D830"),
+    (m32, "00000000    FDIV       DWORD PTR [EAX]",
+     "D830"),
+    (m32, "00000000    FDIV       QWORD PTR [EAX]",
+     "DC30"),
+
+    (m32, "00000000    FDIV       ST, ST(2)",
+     "D8F2"),
+    (m32, "00000000    FDIV       ST(2), ST",
+     "DCFA"),
+
+    (m32, "00000000    FDIVP      ST(2), ST",
+     "DEFA"),
+
+    (m16, "00000000    FIDIV      DWORD PTR [BX+SI]",
+     "DA30"),
+    (m32, "00000000    FIDIV      DWORD PTR [EAX]",
+     "DA30"),
+    (m32, "00000000    FIDIV      WORD PTR [EAX]",
+     "DE30"),
+
+
+
+    (m16, "00000000    FDIVR      DWORD PTR [BX+SI]",
+     "D838"),
+    (m32, "00000000    FDIVR      DWORD PTR [EAX]",
+     "D838"),
+    (m32, "00000000    FDIVR      QWORD PTR [EAX]",
+     "DC38"),
+
+    (m32, "00000000    FDIVR      ST, ST(2)",
+     "D8Fa"),
+    (m32, "00000000    FDIVR      ST(2), ST",
+     "DCF2"),
+
+    (m32, "00000000    FDIVRP     ST(2), ST",
+     "DEF2"),
+
+    (m16, "00000000    FIDIVR     DWORD PTR [BX+SI]",
+     "DA38"),
+    (m32, "00000000    FIDIVR     DWORD PTR [EAX]",
+     "DA38"),
+    (m32, "00000000    FIDIVR     WORD PTR [EAX]",
+     "DE38"),
+
+    (m32, "00000000    FFREE      ST(2)",
+     "DDC2"),
+
+    (m32, "00000000    FICOM      WORD PTR [EAX]",
+     "DE10"),
+    (m32, "00000000    FICOM      DWORD PTR [EAX]",
+     "DA10"),
+
+    (m32, "00000000    FICOMP     WORD PTR [EAX]",
+     "DE18"),
+    (m32, "00000000    FICOMP     DWORD PTR [EAX]",
+     "DA18"),
+
+    (m32, "00000000    FILD       WORD PTR [EAX]",
+     "DF00"),
+    (m32, "00000000    FILD       DWORD PTR [EAX]",
+     "DB00"),
+
+
+    (m32, "00000000    FILD       QWORD PTR [EAX]",
+     "DF28"),
+
+    (m32, "00000000    FINCSTP",
+     "d9f7"),
+
+    #(m32, "00000000    FINIT",
+    # "9bdbe3"),
+    (m32, "00000000    FNINIT",
+     "dbe3"),
+
+    (m32, "00000000    FIST       WORD PTR [EAX]",
+     "DF10"),
+    (m32, "00000000    FIST       DWORD PTR [EAX]",
+     "DB10"),
+
+    (m32, "00000000    FISTP      WORD PTR [EAX]",
+     "DF18"),
+    (m32, "00000000    FISTP      DWORD PTR [EAX]",
+     "DB18"),
+
+    (m32, "00000000    FISTP      QWORD PTR [EAX]",
+     "Df38"),
+
+    (m32, "00000000    FISTTP     WORD PTR [EAX]",
+     "DF08"),
+    (m32, "00000000    FISTTP     DWORD PTR [EAX]",
+     "DB08"),
+
+    (m32, "00000000    FISTTP     QWORD PTR [EAX]",
+     "Dd08"),
+
+    (m32, "00000000    FLD        DWORD PTR [EAX]",
+     "d900"),
+    (m32, "00000000    FLD        QWORD PTR [EAX]",
+     "dd00"),
+
+    (m32, "00000000    FLD        TBYTE PTR [EAX]",
+     "db28"),
+    (m32, "00000000    FLD        ST(2)",
+     "d9c2"),
+
+
+    (m32, "00000000    FLD1",
+     "d9e8"),
+    (m32, "00000000    FLDL2T",
+     "d9e9"),
+    (m32, "00000000    FLDL2E",
+     "d9eA"),
+    (m32, "00000000    FLDPI",
+     "d9eB"),
+    (m32, "00000000    FLDLG2",
+     "d9eC"),
+    (m32, "00000000    FLDLN2",
+     "d9eD"),
+    (m32, "00000000    FLDZ",
+     "d9eE"),
+
+    (m32, "00000000    FLDCW      WORD PTR [EAX]",
+     "d928"),
+
+
+
+    (m16, "00000000    FMUL       DWORD PTR [BX+SI]",
+     "D808"),
+    (m32, "00000000    FMUL       DWORD PTR [EAX]",
+     "D808"),
+    (m32, "00000000    FMUL       QWORD PTR [EAX]",
+     "DC08"),
+
+    (m32, "00000000    FMUL       ST, ST(2)",
+     "D8Ca"),
+    (m32, "00000000    FMUL       ST(2), ST",
+     "DCCa"),
+
+    (m32, "00000000    FMULP      ST(2), ST",
+     "DECa"),
+
+    (m16, "00000000    FIMUL      DWORD PTR [BX+SI]",
+     "DA08"),
+    (m32, "00000000    FIMUL      DWORD PTR [EAX]",
+     "DA08"),
+    (m32, "00000000    FIMUL      WORD PTR [EAX]",
+     "DE08"),
+
+    (m32, "00000000    FNOP",
+     "D9d0"),
+    (m32, "00000000    FPATAN",
+     "D9f3"),
+    (m32, "00000000    FPREM",
+     "D9f8"),
+    (m32, "00000000    FPREM1",
+     "D9f5"),
+    (m32, "00000000    FPTAN",
+     "D9f2"),
+    (m32, "00000000    FRNDINT",
+     "D9fc"),
+
+    (m32, "00000000    FRSTOR     TBYTE PTR [EAX]",
+     "dd20"),
+
+    #(m32, "00000000    FSAVE      TBYTE PTR [EAX]",
+    # "9bdd30"),
+    (m32, "00000000    FNSAVE     TBYTE PTR [EAX]",
+     "dd30"),
+
+    (m32, "00000000    FSCALE",
+     "d9fd"),
+
+    (m32, "00000000    FSIN",
+     "d9fe"),
+    (m32, "00000000    FSINCOS",
+     "d9fb"),
+    (m32, "00000000    FSQRT",
+     "d9fa"),
+
+
+
+    (m32, "00000000    FST        DWORD PTR [EAX]",
+     "D910"),
+    (m32, "00000000    FST        QWORD PTR [EAX]",
+     "DD10"),
+
+    (m32, "00000000    FST        ST(2)",
+     "ddd2"),
+
+    (m32, "00000000    FSTP       DWORD PTR [EAX]",
+     "D918"),
+    (m32, "00000000    FSTP       QWORD PTR [EAX]",
+     "Dd18"),
+    (m32, "00000000    FSTP       TBYTE PTR [EAX]",
+     "db38"),
+
+    #(m32, "00000000    FSTCW      WORD PTR [EAX]",
+    # "9bd938"),
+    (m32, "00000000    FNSTCW     WORD PTR [EAX]",
+     "d938"),
+
+    (m32, "00000000    FNSTENV    TBYTE PTR [EAX]",
+     "d930"),
+    #(m32, "00000000    FSTENV     TBYTE PTR [EAX]",
+    # "9bd930"),
+
+    (m32, "00000000    FNSTSW     WORD PTR [EAX]",
+     "dd38"),
+    #(m32, "00000000    FSTSW      WORD PTR [EAX]",
+    # "9bdd38"),
+
+    #(m32, "00000000    FSTSW      AX",
+    # "9bdfe0"),
+    (m32, "00000000    FNSTSW     AX",
+     "dfe0"),
+
+    (m16, "00000000    FSUB       DWORD PTR [BX+SI]",
+     "D820"),
+    (m32, "00000000    FSUB       DWORD PTR [EAX]",
+     "D820"),
+    (m32, "00000000    FSUB       QWORD PTR [EAX]",
+     "DC20"),
+
+    (m32, "00000000    FSUB       ST, ST(2)",
+     "D8E2"),
+    (m32, "00000000    FSUB       ST(2), ST",
+     "DCEA"),
+
+    (m32, "00000000    FSUBP      ST(2), ST",
+     "DEEA"),
+
+    (m16, "00000000    FISUB      DWORD PTR [BX+SI]",
+     "DA20"),
+    (m32, "00000000    FISUB      DWORD PTR [EAX]",
+     "DA20"),
+    (m32, "00000000    FISUB      WORD PTR [EAX]",
+     "DE20"),
+
+
+
+    (m16, "00000000    FSUBR      DWORD PTR [BX+SI]",
+     "D828"),
+    (m32, "00000000    FSUBR      DWORD PTR [EAX]",
+     "D828"),
+    (m32, "00000000    FSUBR      QWORD PTR [EAX]",
+     "DC28"),
+
+    (m32, "00000000    FSUBR      ST, ST(2)",
+     "D8EA"),
+    (m32, "00000000    FSUBR      ST(2), ST",
+     "DCE2"),
+
+    (m32, "00000000    FSUBRP     ST(2), ST",
+     "DEE2"),
+
+    (m16, "00000000    FISUBR     DWORD PTR [BX+SI]",
+     "DA28"),
+    (m32, "00000000    FISUBR     DWORD PTR [EAX]",
+     "DA28"),
+    (m32, "00000000    FISUBR     WORD PTR [EAX]",
+     "DE28"),
+
+    (m32, "00000000    FTST",
+     "d9e4"),
+
+    (m32, "00000000    FUCOM      ST(2)",
+     "dde2"),
+    (m32, "00000000    FUCOMP     ST(2)",
+     "DDEA"),
+    (m32, "00000000    FUCOMPP",
+     "DAe9"),
+
+    (m32, "00000000    FXAM",
+     "d9e5"),
+
+    (m32, "00000000    FXCH       ST(2)",
+     "d9ca"),
+
+    (m32, "00000000    FXRSTOR    TBYTE PTR [EAX]",
+     "0fae08"),
+    (m32, "00000000    FXSAVE     TBYTE PTR [EAX]",
+     "0fae00"),
+
+    (m32, "00000000    FXTRACT",
+     "d9f4"),
+    (m32, "00000000    FYL2X",
+     "d9f1"),
+    (m32, "00000000    FYL2XP1",
+     "d9f9"),
+
+    (m32, "00000000    HLT",
+     "f4"),
+    (m32, "00000000    ICEBP",
+     "f1"),
+
+    (m32, "00000000    IDIV       BYTE PTR [EAX]",
+     "f638"),
+    (m32, "00000000    IDIV       DWORD PTR [EAX]",
+     "f738"),
+
+    (m32, "00000000    IMUL       EAX, DWORD PTR [EAX]",
+     "0faf00"),
+
+
+    (m32, "00000000    IMUL       EAX, EBX, 0x8",
+     "6bc308"),
+    (m32, "00000000    IMUL       EAX, EBX, 0xFFFFFFFF",
+     "6bc3FF"),
+    (m32, "00000000    IMUL       EAX, DWORD PTR [EBX], 0x11223344",
+     "690344332211"),
+    (m64, "00000000    IMUL       RAX, QWORD PTR [RBX], 0x11223344",
+     "48690344332211"),
+    (m64, "00000000    IMUL       RAX, QWORD PTR [RBX], 0x11223344",
+     "48690344332211"),
+    (m64, "00000000    IMUL       RAX, QWORD PTR [RBX], 0xFFFFFFFFF1223344",
+     "486903443322F1"),
+    (m16, "00000000    IMUL       AX, BX, 0x8",
+     "6bc308"),
+    (m16, "00000000    IMUL       AX, BX, 0xFFF0",
+     "6bc3F0"),
+
+    (m32, "00000000    IN         AL, 0x12",
+     "e412"),
+    (m32, "00000000    IN         EAX, 0x12",
+     "e512"),
+    (m64, "00000000    IN         RAX, 0x12",
+     "48e512"),
+
+    (m32, "00000000    IN         AL, DL",
+     "EC"),
+    (m32, "00000000    IN         EAX, EDX",
+     "ED"),
+    (m32, "00000000    IN         AX, DX",
+     "66ED"),
+
+    (m32, "00000000    INC        DWORD PTR [EAX]",
+     "ff00"),
+    (m32, "00000000    INC        ECX",
+     "41"),
+
+    (m32, "00000000    INT        0x3",
+     "CC"),
+    (m32, "00000000    INT        0x21",
+     "CD21"),
+
+    (m16, "00000000    IRET",
+     "CF"),
+    (m32, "00000000    IRETD",
+     "CF"),
+    (m64, "00000000    IRETQ",
+     "48CF"),
+
+    (m32, "00000000    JA         0x12",
+     "7712"),
+    (m32, "00000000    JA         0xFFFFFFEE",
+     "77EE"),
+    (m64, "00000000    JA         0xFFFFFFFFFFFFFFEE",
+     "77EE"),
+
+    #(m32, "00000000    JA         0xFFEE",
+    # "6677EE"),
+    #(m64, "00000000    JA         0xFFEE",
+    # "6677EE"),
+
+
+    (m16, "00000000    JCXZ       0xFFEE",
+     "E3EE"),
+    (m16, "00000000    JECXZ      0xFFEE",
+     "67E3EE"),
+    (m32, "00000000    JECXZ      0xFFFFFFEE",
+     "E3EE"),
+    (m32, "00000000    JCXZ       0xFFFFFFEE",
+     "67E3EE"),
+    (m32, "00000000    JCXZ       0xFFEE",
+     "6667E3EE"),
+    (m64, "00000000    JRCXZ      0xFFFFFFFFFFFFFFEE",
+     "E3EE"),
+    (m64, "00000000    JECXZ      0xFFFFFFFFFFFFFFEE",
+     "67E3EE"),
+
+
+    (m32, "00000000    MOV        BYTE PTR [EAX], AL",
+     "8800"),
+    (m32, "00000000    MOV        AL, BYTE PTR [EAX]",
+     "8a00"),
+    (m32, "00000000    MOV        EAX, DWORD PTR [EAX]",
+     "8b00"),
+    (m32, "00000000    MOV        DWORD PTR [EAX], EAX",
+     "8900"),
+    (m64, "00000000    MOV        ECX, DWORD PTR [RCX]",
+     "8b09"),
+    (m64, "00000000    MOV        DWORD PTR [RCX], ECX",
+     "8909"),
+    (m64, "00000000    MOV        QWORD PTR [RAX], RAX",
+     "488900"),
+
+    (m32, "00000000    MOV        EAX, EBX",
+     "89d8"),
+    (m32, "00000000    MOV        EAX, EBX",
+     "8bc3"),
+
+
+    (m16, "00000000    MOV        WORD PTR [BX+SI], ES",
+     "8c00"),
+    (m32, "00000000    MOV        DWORD PTR [EAX], ES",
+     "8c00"),
+    (m32, "00000000    MOV        ES, DWORD PTR [EAX]",
+     "8e00"),
+    (m32, "00000000    MOV        DWORD PTR [EAX], CS",
+     "8c08"),
+    (m64, "00000000    MOV        DWORD PTR [RCX], ES",
+     "8c01"),
+
+    (m16, "00000000    MOV        BH, 0x12",
+     "b712"),
+    (m16, "00000000    MOV        DI, 0x1122",
+     "bf2211"),
+
+    (m32, "00000000    MOV        AL, 0x12",
+     "b012"),
+    (m32, "00000000    MOV        EAX, 0x11223344",
+     "b844332211"),
+    (m32, "00000000    MOV        BH, 0x12",
+     "b712"),
+    (m32, "00000000    MOV        EDI, 0x11223344",
+     "bf44332211"),
+
+    (m64, "00000000    MOV        BH, 0x12",
+     "b712"),
+    (m64, "00000000    MOV        EDI, 0x11223344",
+     "bf44332211"),
+
+    (m16, "00000000    MOV        WORD PTR [BX], 0x1122",
+     "c7072211"),
+    (m32, "00000000    MOV        DWORD PTR [EAX], 0x11223344",
+     "c70044332211"),
+    (m64, "00000000    MOV        DWORD PTR [RCX], 0x11223344",
+     "c70144332211"),
+
+    (m32, "00000000    MOV        CR0, EAX",
+     "0f22c0"),
+    (m32, "00000000    MOV        EAX, CR0",
+     "0f20c0"),
+
+    (m32, "00000000    MOV        EAX, DR0",
+     "0f21c0"),
+    (m32, "00000000    MOV        DR0, EAX",
+     "0f23c0"),
+
+    (m64, "00000000    MOV        DWORD PTR [RSP+0x20], 0x10",
+     "C744242010000000"),
+    (m64, "00000000    MOV        DWORD PTR [RBX+0x20], 0x30",
+     "c744a32030000000"),
+    (m64, "00000000    MOV        DWORD PTR [R12+0x20], 0x10",
+     "41C744242010000000"),
+
+    (m32, "00000000    MOV        BYTE PTR [EBX+0xFFFFFF98], 0xCC",
+     "C64398CC"),
+
+    (m64, "00000000    MOV        BYTE PTR [R11+0xFFFFFFFFFFFFFF98], 0xCC",
+     "41C64398CC"),
+
+    (m64, "00000000    MOV        RAX, 0x1122334455667788",
+     "48b88877665544332211"),
+
+    (m64, "00000000    MOV        RDX, 0x1122334455667788",
+     "48ba8877665544332211"),
+
+
+
+    (m64, "00000000    MOV        RAX, RBX",
+     "4889d8"),
+    (m64, "00000000    MOV        RAX, RBX",
+     "4A89d8"),
+    (m64, "00000000    MOV        RAX, R11",
+     "4C89d8"),
+    (m64, "00000000    MOV        R8D, EBX",
+     "4189d8"),
+    (m64, "00000000    MOV        R8D, EBX",
+     "4389d8"),
+    (m64, "00000000    MOV        EAX, R11D",
+     "4489d8"),
+    (m64, "00000000    MOV        R8D, R11D",
+     "4589d8"),
+    (m64, "00000000    MOV        EAX, R11D",
+     "4689d8"),
+    (m64, "00000000    MOV        R8D, R11D",
+     "4789d8"),
+
+    (m64, "00000000    MOV        BYTE PTR [RBX+0x3], R11B",
+     "44885B03"),
+
+    (m32, "00000000    MOV        AL, BYTE PTR [0x11223344]",
+     "A044332211"),
+    (m32, "00000000    MOV        BYTE PTR [0x11223344], AL",
+     "A244332211"),
+    (m32, "00000000    MOV        EAX, DWORD PTR [0x11223344]",
+     "A144332211"),
+    (m32, "00000000    MOV        DWORD PTR [0x11223344], EAX",
+     "A344332211"),
+
+    (m32, "00000000    MOV        WORD PTR [0x11223344], AX",
+     "66A344332211"),
+
+    (m32, "00000000    MOV        DWORD PTR [0x1122], EAX",
+     "67A32211"),
+
+
+
+    (m16, "00000000    MOV        AL, BYTE PTR [0x1122]",
+     "A02211"),
+    (m16, "00000000    MOV        BYTE PTR [0x1122], AL",
+     "A22211"),
+    (m16, "00000000    MOV        AX, WORD PTR [0x1122]",
+     "A12211"),
+    (m16, "00000000    MOV        WORD PTR [0x1122], AX",
+     "A32211"),
+
+    (m64, "00000000    MOV        AL, BYTE PTR [0x1122334455667788]",
+     "A08877665544332211"),
+    (m64, "00000000    MOV        BYTE PTR [0x1122334455667788], AL",
+     "A28877665544332211"),
+    (m64, "00000000    MOV        EAX, DWORD PTR [0x1122334455667788]",
+     "A18877665544332211"),
+    (m64, "00000000    MOV        DWORD PTR [0x1122334455667788], EAX",
+     "A38877665544332211"),
+
+
+
+    (m32, "00000000    MOV        EAX, DWORD PTR CS:[EAX]",
+     "2e8b00"),
+    (m32, "00000000    MOV        EAX, DWORD PTR SS:[EAX]",
+     "368b00"),
+    (m32, "00000000    MOV        EAX, DWORD PTR DS:[EAX]",
+     "3e8b00"),
+    (m32, "00000000    MOV        EAX, DWORD PTR ES:[EAX]",
+     "268b00"),
+    (m32, "00000000    MOV        EAX, DWORD PTR FS:[EAX]",
+     "648b00"),
+    (m32, "00000000    MOV        EAX, DWORD PTR GS:[EAX]",
+     "658b00"),
+
+
+
+    (m32, "00000000    MOVSX      EAX, BYTE PTR [EAX]",
+     "0fbe00"),
+    (m32, "00000000    MOVSX      EAX, WORD PTR [EAX]",
+     "0fbf00"),
+
+    (m64, "00000000    MOVSX      RAX, BYTE PTR [RAX]",
+     "480fbe00"),
+    (m64, "00000000    MOVSX      RAX, WORD PTR [RAX]",
+     "480fbf00"),
+
+    (m16, "00000000    MOVZX      AX, BYTE PTR [BX+SI]",
+     "0fb600"),
+    (m16, "00000000    MOVZX      AX, WORD PTR [BX+SI]",
+     "0fb700"),
+
+    (m32, "00000000    MOVZX      EAX, BYTE PTR [EAX]",
+     "0fb600"),
+    (m32, "00000000    MOVZX      EAX, WORD PTR [EAX]",
+     "0fb700"),
+
+    (m64, "00000000    MOVSXD     R8, EAX",
+     "4c63c0"),
+
+
+    (m32, "00000000    MUL        BYTE PTR [EAX]",
+     "f620"),
+    (m32, "00000000    MUL        EBX",
+     "f7e3"),
+
+    (m16, "00000000    CMPSW",
+     "a7"),
+    (m32, "00000000    CMPSW",
+     "66a7"),
+    (m32, "00000000    CMPSD",
+     "a7"),
+
+    (m64, "00000000    CMPSD",
+     "a7"),
+    (m64, "00000000    CMPSQ",
+     "48a7"),
+
+    (m16, "00000000    LODSB",
+     "aC"),
+    (m32, "00000000    LODSB",
+     "66ac"),
+    (m16, "00000000    LODSW",
+     "ad"),
+    (m32, "00000000    LODSW",
+     "66ad"),
+    (m32, "00000000    LODSD",
+     "ad"),
+
+    (m64, "00000000    LODSD",
+     "ad"),
+    (m64, "00000000    LODSQ",
+     "48ad"),
+
+
+
+    (m32, "00000000    NEG        BYTE PTR [EAX]",
+     "f618"),
+    (m32, "00000000    NEG        EBX",
+     "f7db"),
+
+    #(m32, "00000000    NOP",
+    # "90"),
+
+    (m32, "00000000    NOP        DWORD PTR [EAX]",
+     "0f1f00"),
+
+    (m32, "00000000    NOT        BYTE PTR [EAX]",
+     "f610"),
+    (m32, "00000000    NOT        EBX",
+     "f7d3"),
+
+    (m32, "00000000    OR         AL, 0x11",
+     "0c11"),
+    (m32, "00000000    OR         EAX, 0x11223344",
+     "0d44332211"),
+    (m32, "00000000    OR         BYTE PTR [EAX], 0x11",
+     "800811"),
+    (m32, "00000000    OR         DWORD PTR [EAX], 0x11223344",
+     "810844332211"),
+    (m32, "00000000    OR         DWORD PTR [EAX], 0x11",
+     "830811"),
+    (m32, "00000000    OR         BYTE PTR [EAX], AL",
+     "0800"),
+    (m32, "00000000    OR         DWORD PTR [EAX], EAX",
+     "0900"),
+    (m32, "00000000    OR         AL, BYTE PTR [EAX]",
+     "0A00"),
+    (m32, "00000000    OR         EAX, DWORD PTR [EAX]",
+     "0B00"),
+
+    (m32, "00000000    OUT        0x12, AL",
+     "e612"),
+    (m32, "00000000    OUT        0x12, EAX",
+     "e712"),
+    (m64, "00000000    OUT        0x12, RAX",
+     "48e712"),
+
+    (m32, "00000000    OUT        DL, AL",
+     "EE"),
+    (m32, "00000000    OUT        EDX, EAX",
+     "EF"),
+    (m32, "00000000    OUT        DX, AX",
+     "66EF"),
+
+    (m32, "00000000    OUTSB",
+     "6e"),
+    (m32, "00000000    OUTSD",
+     "6f"),
+    (m32, "00000000    OUTSW",
+     "666f"),
+    (m64, "00000000    OUTSD",
+     "6f"),
+    (m64, "00000000    OUTSW",
+     "666f"),
+
+    #(m32, "00000000    PAUSE",
+    # "f390"),
+
+
+    (m16, "00000000    POP        WORD PTR [BX+SI]",
+     "8f00"),
+    (m32, "00000000    POP        DWORD PTR [EAX]",
+     "8f00"),
+    (m64, "00000000    POP        QWORD PTR [RAX]",
+     "8f00"),
+
+
+    (m32, "00000000    POP        EAX",
+     "8fC0"),
+    (m64, "00000000    POP        RAX",
+     "8fC0"),
+
+    (m32, "00000000    POP        EAX",
+     "58"),
+    (m64, "00000000    POP        RAX",
+     "58"),
+    (m64, "00000000    POP        R10",
+     "415a"),
+
+    (m32, "00000000    POP        DS",
+     "1f"),
+    (m32, "00000000    POP        ES",
+     "07"),
+    (m32, "00000000    POP        SS",
+     "17"),
+    (m32, "00000000    POP        FS",
+     "0fa1"),
+    (m32, "00000000    POP        GS",
+     "0fa9"),
+
+    (m16, "00000000    POPA",
+     "61"),
+    (m32, "00000000    POPAD",
+     "61"),
+
+    (m16, "00000000    POPF",
+     "9d"),
+    (m32, "00000000    POPFD",
+     "9d"),
+    (m64, "00000000    POPFD",
+     "9d"),
+    (m64, "00000000    POPFQ",
+     "489d"),
+
+    (m32, "00000000    PREFETCH0  BYTE PTR [EAX]",
+     "0f1808"),
+    (m32, "00000000    PREFETCH1  BYTE PTR [EAX]",
+     "0f1810"),
+    (m32, "00000000    PREFETCH2  BYTE PTR [EAX]",
+     "0f1818"),
+    (m32, "00000000    PREFETCHNTA BYTE PTR [EAX]",
+     "0f1800"),
+
+
+    (m16, "00000000    PUSH       AX",
+     "50"),
+    (m32, "00000000    PUSH       EAX",
+     "50"),
+    (m64, "00000000    PUSH       RAX",
+     "50"),
+    (m64, "00000000    PUSH       R10",
+     "4152"),
+    (m16, "00000000    PUSH       WORD PTR [BX+SI]",
+     "FF30"),
+    (m16, "00000000    PUSH       WORD PTR [EAX]",
+     "67FF30"),
+    (m16, "00000000    PUSH       DWORD PTR [EAX]",
+     "6667FF30"),
+    (m32, "00000000    PUSH       DWORD PTR [EAX]",
+     "FF30"),
+    (m64, "00000000    PUSH       QWORD PTR [RAX]",
+     "FF30"),
+
+    (m16, "00000000    PUSH       0x11",
+     "6a11"),
+    (m32, "00000000    PUSH       0x11223344",
+     "6844332211"),
+    (m32, "00000000    PUSH       0x1122",
+     "66682211"),
+    (m32, "00000000    PUSH       0x80",
+     "6880000000"),
+
+    (m64, "00000000    PUSH       0x11223344",
+     "6844332211"),
+
+    (m32, "00000000    PUSH       CS",
+     "0e"),
+    (m32, "00000000    PUSH       SS",
+     "16"),
+    (m32, "00000000    PUSH       DS",
+     "1E"),
+    (m32, "00000000    PUSH       ES",
+     "06"),
+    (m32, "00000000    PUSH       FS",
+     "0fa0"),
+    (m32, "00000000    PUSH       GS",
+     "0fa8"),
+
+    (m16, "00000000    PUSHA",
+     "60"),
+    (m32, "00000000    PUSHAD",
+     "60"),
+
+    (m16, "00000000    PUSHF",
+     "9c"),
+    (m32, "00000000    PUSHFD",
+     "9c"),
+    (m64, "00000000    PUSHFD",
+     "9c"),
+    (m64, "00000000    PUSHFQ",
+     "489c"),
+
+    (m32, "00000000    RCL        BYTE PTR [EAX], 0x1",
+     "D010"),
+    (m32, "00000000    RCL        BYTE PTR [EAX], CL",
+     "d210"),
+
+    (m32, "00000000    RCL        DWORD PTR [EAX], 0x1",
+     "D110"),
+    (m32, "00000000    RCL        DWORD PTR [EAX], CL",
+     "d310"),
+
+    (m32, "00000000    RCL        BYTE PTR [EAX], 0x11",
+     "c01011"),
+    (m32, "00000000    RCL        DWORD PTR [EAX], 0x11",
+     "c11011"),
+
+    (m64, "00000000    RCL        QWORD PTR [RAX], 0x1",
+     "48D110"),
+    (m64, "00000000    RCL        QWORD PTR [RAX], CL",
+     "48d310"),
+
+    (m64, "00000000    RCL        BYTE PTR [RAX], 0x11",
+     "c01011"),
+    (m64, "00000000    RCL        QWORD PTR [RAX], 0x11",
+     "48c11011"),
+
+
+
+
+    (m32, "00000000    RCR        BYTE PTR [EAX], 0x1",
+     "D018"),
+    (m32, "00000000    RCR        BYTE PTR [EAX], CL",
+     "d218"),
+
+    (m32, "00000000    RCR        DWORD PTR [EAX], 0x1",
+     "D118"),
+    (m32, "00000000    RCR        DWORD PTR [EAX], CL",
+     "d318"),
+
+    (m32, "00000000    RCR        BYTE PTR [EAX], 0x11",
+     "c01811"),
+    (m32, "00000000    RCR        DWORD PTR [EAX], 0x11",
+     "c11811"),
+
+    (m64, "00000000    RCR        QWORD PTR [RAX], 0x1",
+     "48D118"),
+    (m64, "00000000    RCR        QWORD PTR [RAX], CL",
+     "48d318"),
+
+    (m64, "00000000    RCR        BYTE PTR [RAX], 0x11",
+     "c01811"),
+    (m64, "00000000    RCR        QWORD PTR [RAX], 0x11",
+     "48c11811"),
+
+
+
+
+    (m32, "00000000    ROL        BYTE PTR [EAX], 0x1",
+     "D000"),
+    (m32, "00000000    ROL        BYTE PTR [EAX], CL",
+     "d200"),
+
+    (m32, "00000000    ROL        DWORD PTR [EAX], 0x1",
+     "D100"),
+    (m32, "00000000    ROL        DWORD PTR [EAX], CL",
+     "d300"),
+
+    (m32, "00000000    ROL        BYTE PTR [EAX], 0x11",
+     "c00011"),
+    (m32, "00000000    ROL        DWORD PTR [EAX], 0x11",
+     "c10011"),
+
+    (m64, "00000000    ROL        QWORD PTR [RAX], 0x1",
+     "48D100"),
+    (m64, "00000000    ROL        QWORD PTR [RAX], CL",
+     "48d300"),
+
+    (m64, "00000000    ROL        BYTE PTR [RAX], 0x11",
+     "c00011"),
+    (m64, "00000000    ROL        QWORD PTR [RAX], 0x11",
+     "48c10011"),
+
+
+
+    (m32, "00000000    ROR        BYTE PTR [EAX], 0x1",
+     "D008"),
+    (m32, "00000000    ROR        BYTE PTR [EAX], CL",
+     "d208"),
+
+    (m32, "00000000    ROR        DWORD PTR [EAX], 0x1",
+     "D108"),
+    (m32, "00000000    ROR        DWORD PTR [EAX], CL",
+     "d308"),
+
+    (m32, "00000000    ROR        BYTE PTR [EAX], 0x11",
+     "c00811"),
+    (m32, "00000000    ROR        DWORD PTR [EAX], 0x11",
+     "c10811"),
+
+    (m64, "00000000    ROR        QWORD PTR [RAX], 0x1",
+     "48D108"),
+    (m64, "00000000    ROR        QWORD PTR [RAX], CL",
+     "48d308"),
+
+    (m64, "00000000    ROR        BYTE PTR [RAX], 0x11",
+     "c00811"),
+    (m64, "00000000    ROR        QWORD PTR [RAX], 0x11",
+     "48c10811"),
+
+
+
+    (m32, "00000000    RDMSR",
+     "0f32"),
+    (m32, "00000000    RDPMC",
+     "0f33"),
+    (m32, "00000000    RDTSC",
+     "0f31"),
+
+    (m32, "00000000    INSB",
+     "6C"),
+    (m16, "00000000    INSW",
+     "6D"),
+    (m32, "00000000    INSD",
+     "6D"),
+    (m64, "00000000    INSD",
+     "486D"),
+    (m64, "00000000    INSD",
+     "6D"),
+
+
+    (m32, "00000000    MOVSB",
+     "a4"),
+    (m16, "00000000    MOVSW",
+     "a5"),
+    (m32, "00000000    MOVSD",
+     "a5"),
+    (m64, "00000000    MOVSQ",
+     "48a5"),
+    (m64, "00000000    MOVSD",
+     "a5"),
+
+    (m32, "00000000    OUTSB",
+     "6e"),
+    (m16, "00000000    OUTSW",
+     "6f"),
+    (m32, "00000000    OUTSD",
+     "6f"),
+    (m64, "00000000    OUTSD",
+     "486f"),
+    (m64, "00000000    OUTSD",
+     "6f"),
+
+
+    (m32, "00000000    LODSB",
+     "ac"),
+    (m16, "00000000    LODSW",
+     "ad"),
+    (m32, "00000000    LODSD",
+     "ad"),
+    (m64, "00000000    LODSQ",
+     "48ad"),
+    (m64, "00000000    LODSD",
+     "ad"),
+
+    (m32, "00000000    STOSB",
+     "aa"),
+    (m16, "00000000    STOSW",
+     "ab"),
+    (m32, "00000000    STOSD",
+     "ab"),
+    (m64, "00000000    STOSQ",
+     "48ab"),
+    (m64, "00000000    STOSD",
+     "ab"),
+
+
+    (m32, "00000000    CMPSB",
+     "a6"),
+    (m16, "00000000    CMPSW",
+     "a7"),
+    (m32, "00000000    CMPSD",
+     "a7"),
+    (m64, "00000000    CMPSQ",
+     "48a7"),
+    (m64, "00000000    CMPSD",
+     "a7"),
+
+
+    (m32, "00000000    SCASB",
+     "ae"),
+    (m16, "00000000    SCASW",
+     "af"),
+    (m32, "00000000    SCASD",
+     "af"),
+    (m64, "00000000    SCASQ",
+     "48af"),
+    (m64, "00000000    SCASD",
+     "af"),
+
+    (m32, "00000000    REPNE SCASB",
+     "F2AE"),
+    (m32, "00000000    REPE SCASB",
+     "F3AE"),
+    (m32, "00000000    REPE LODSD",
+     "F3ad"),
+
+    (m32, "00000000    RET",
+     "c3"),
+
+    (m32, "00000000    RET        0x1122",
+     "C22211"),
+
+    (m32, "00000000    RETF       0x1122",
+     "CA2211"),
+
+    (m32, "00000000    RSM",
+     "0faa"),
+    (m32, "00000000    SAHF",
+     "9e"),
+
+    (m32, "00000000    SAL        BYTE PTR [EAX], 0x1",
+     "D030"),
+    (m32, "00000000    SAL        BYTE PTR [EAX], CL",
+     "d230"),
+
+    (m32, "00000000    SAR        BYTE PTR [EAX], 0x1",
+     "D038"),
+    (m32, "00000000    SAR        BYTE PTR [EAX], CL",
+     "d238"),
+
+    (m32, "00000000    SHL        BYTE PTR [EAX], 0x1",
+     "D020"),
+    (m32, "00000000    SHL        BYTE PTR [EAX], CL",
+     "d220"),
+
+    (m32, "00000000    SHR        BYTE PTR [EAX], 0x1",
+     "D028"),
+    (m32, "00000000    SHR        BYTE PTR [EAX], CL",
+     "d228"),
+
+
+    (m32, "00000000    SBB        AL, 0x11",
+     "1c11"),
+    (m32, "00000000    SBB        EAX, 0x11223344",
+     "1D44332211"),
+    (m32, "00000000    SBB        BYTE PTR [EAX], 0x11",
+     "801811"),
+    (m32, "00000000    SBB        DWORD PTR [EAX], 0x11223344",
+     "811844332211"),
+    (m32, "00000000    SBB        BYTE PTR [EAX], AL",
+     "1800"),
+    (m32, "00000000    SBB        DWORD PTR [EAX], EAX",
+     "1900"),
+    (m32, "00000000    SBB        AL, BYTE PTR [EAX]",
+     "1A00"),
+    (m32, "00000000    SBB        EAX, DWORD PTR [EAX]",
+     "1B00"),
+    (m64, "00000000    SBB        QWORD PTR [RAX], RAX",
+     "481900"),
+
+
+    (m32, "00000000    SETA       BYTE PTR [EAX]",
+     "0f9700"),
+    (m32, "00000000    SETO       BYTE PTR [EAX]",
+     "0f9000"),
+    (m32, "00000000    SETNZ      AL",
+     "0f95C0"),
+
+    (m32, "00000000    SGDT       DWORD PTR [EAX]",
+     "0f0100"),
+
+    (m32, "00000000    SHLD       DWORD PTR [EAX], EAX, 0x11",
+     "0fa40011"),
+    (m32, "00000000    SHLD       DWORD PTR [EAX], EAX, CL",
+     "0fa500"),
+
+    (m64, "00000000    SHLD       QWORD PTR [RAX], RAX, 0x11",
+     "480fa40011"),
+    (m64, "00000000    SHLD       QWORD PTR [RAX], RAX, CL",
+     "480fa500"),
+
+    (m32, "00000000    SHRD       DWORD PTR [EAX], EAX, 0x11",
+     "0fac0011"),
+    (m32, "00000000    SHRD       DWORD PTR [EAX], EAX, CL",
+     "0fad00"),
+
+    (m64, "00000000    SHRD       QWORD PTR [RAX], RAX, 0x11",
+     "480fac0011"),
+    (m64, "00000000    SHRD       QWORD PTR [RAX], RAX, CL",
+     "480fad00"),
+
+    (m32, "00000000    SIDT       DWORD PTR [EAX]",
+     "0f0108"),
+
+
+
+    (m32, "00000000    SUB        AL, 0x11",
+     "2c11"),
+    (m32, "00000000    SUB        EAX, 0x11223344",
+     "2D44332211"),
+    (m32, "00000000    SUB        BYTE PTR [EAX], 0x11",
+     "802811"),
+    (m32, "00000000    SUB        DWORD PTR [EAX], 0x11223344",
+     "812844332211"),
+    (m32, "00000000    SUB        BYTE PTR [EAX], AL",
+     "2800"),
+    (m32, "00000000    SUB        DWORD PTR [EAX], EAX",
+     "2900"),
+    (m32, "00000000    SUB        AL, BYTE PTR [EAX]",
+     "2A00"),
+    (m32, "00000000    SUB        EAX, DWORD PTR [EAX]",
+     "2B00"),
+    (m32, "00000000    SUB        EBX, DWORD PTR [EBP+0xFFFFF858]",
+     "2b9d58f8ffff"),
+
+
+    (m64, "00000000    SYSCALL",
+     "0f05"),
+    (m64, "00000000    SYSENTER",
+     "0f34"),
+    (m64, "00000000    SYSEXIT",
+     "0f35"),
+    (m64, "00000000    SYSRET",
+     "0f07"),
+
+
+
+    (m32, "00000000    TEST       AL, 0x11",
+     "a811"),
+    (m32, "00000000    TEST       EAX, 0x11223344",
+     "A944332211"),
+
+    (m32, "00000000    TEST       BYTE PTR [EAX], 0x11",
+     "f60011"),
+    (m32, "00000000    TEST       DWORD PTR [EAX], 0x11223344",
+     "f70044332211"),
+
+    (m32, "00000000    TEST       BYTE PTR [EAX], AL",
+     "8400"),
+    (m32, "00000000    TEST       DWORD PTR [EAX], EAX",
+     "8500"),
+
+    (m32, "00000000    UD2",
+     "0f0b"),
+
+    (m32, "00000000    VERR       DWORD PTR [EAX]",
+     "0f0020"),
+
+    (m32, "00000000    VERW       DWORD PTR [EAX]",
+     "0f0028"),
+
+    (m32, "00000000    WBIND",
+     "0f09"),
+
+    (m32, "00000000    WRMSR",
+     "0f30"),
+
+    (m32, "00000000    XADD       BYTE PTR [EAX], AL",
+     "0fc000"),
+    (m32, "00000000    XADD       DWORD PTR [EAX], EAX",
+     "0fc100"),
+
+    (m16, "00000000    XCHG       AX, CX",
+     "91"),
+
+    (m32, "00000000    XCHG       EAX, ECX",
+     "91"),
+
+    (m64, "00000000    XCHG       EAX, ECX",
+     "91"),
+    (m64, "00000000    XCHG       RAX, RCX",
+     "4891"),
+
+    (m32, "00000000    NOP",
+     "90"),
+
+
+    (m32, "00000000    XCHG       BYTE PTR [EAX], AL",
+     "8600"),
+    (m32, "00000000    XCHG       DWORD PTR [EAX], EAX",
+     "8700"),
+
+
+    (m32, "00000000    XOR        AL, 0x11",
+     "3411"),
+    (m32, "00000000    XOR        EAX, 0x11223344",
+     "3544332211"),
+    (m32, "00000000    XOR        BYTE PTR [EAX], 0x11",
+     "803011"),
+    (m32, "00000000    XOR        DWORD PTR [EAX], 0x11223344",
+     "813044332211"),
+    (m32, "00000000    XOR        DWORD PTR [EAX], 0xFFFFFFFF",
+     "8330FF"),
+    (m32, "00000000    XOR        BYTE PTR [EAX], AL",
+     "3000"),
+    (m32, "00000000    XOR        DWORD PTR [EAX], EAX",
+     "3100"),
+    (m32, "00000000    XOR        EAX, DWORD PTR [EAX]",
+     "3300"),
+
+    (m32, "00000000    XORPS      XMM1, XMM2",
+     "0f57ca"),
+    (m32, "00000000    XORPS      XMM1, DWORD PTR [EDI+0x42]",
+     "0f574f42"),
+    (m32, "00000000    XORPD      XMM1, XMM2",
+     "660f57ca"),
+
+    (m32, "00000000    MOVAPS     DWORD PTR [EBP+0xFFFFFFB8], XMM0",
+     "0f2945b8"),
+    (m32, "00000000    MOVAPS     XMM0, DWORD PTR [EBP+0xFFFFFFB8]",
+     "0f2845b8"),
+    (m32, "00000000    MOVAPD     WORD PTR [EBP+0xFFFFFFB8], XMM0",
+     "660f2945b8"),
+
+    (m32, "00000000    MOVUPS     XMM2, DWORD PTR [ECX]",
+     "0f1011"),
+    (m32, "00000000    MOVSD      XMM2, DWORD PTR [ECX]",
+     "f20f1011"),
+    (m32, "00000000    MOVSD      DWORD PTR [EBP+0xFFFFFFD8], XMM0",
+     "f20f1145d8"),
+    (m32, "00000000    MOVSS      XMM2, DWORD PTR [ECX]",
+     "f30f1011"),
+    (m32, "00000000    MOVUPD     XMM2, DWORD PTR [ECX]",
+     "660f1011"),
+
+    (m32, "00000000    ADDSS      XMM2, DWORD PTR [ECX]",
+     "f30f5811"),
+    (m32, "00000000    ADDSD      XMM2, DWORD PTR [ECX]",
+     "f20f5811"),
+
+    (m32, "00000000    MULSD      XMM2, DWORD PTR [ECX]",
+     "f20f5911"),
+
+
+    (m32, "00000000    PXOR       XMM0, XMM0",
+     "0fefc0"),
+    (m32, "00000000    UCOMISD    XMM0, DWORD PTR [EBP+0xFFFFFFD8]",
+     "660f2e45d8"),
+    (m32, "00000000    ANDPD      XMM0, DWORD PTR [EBX+0x2CBD27]",
+     "660f548327bd2c00"),
+
+    (m32, "00000000    SUBSD      XMM1, XMM0",
+     "f20f5cc8"),
+
+    (m32, "00000000    MAXSD      XMM0, DWORD PTR [EBX+0x2CBD37]",
+     "f20f5f8337bd2c00"),
+
+    (m32, "00000000    CVTSI2SD   XMM0, EBX",
+     "f20f2ac3"),
+
+    (m32, "00000000    PMINSW     MM0, MM1",
+     "0feac1"),
+    (m32, "00000000    PMINSW     XMM0, XMM1",
+     "660feac1"),
+
+    (m64, "00000000    MOV        BYTE PTR [RSI], DIL",
+     "40883E"),
+    (m32, "00000000    MOVZX      EAX, BH",
+     "0fb6c7"),
+    (m64, "00000000    MOVZX      EAX, BH",
+     "0fb6c7"),
+    (m64, "00000000    MOVZX      EAX, DIL",
+     "400fb6c7"),
+    (m64, "00000000    MOV        BYTE PTR [RCX], SIL",
+     "408831"),
+    (m64, "00000000    CMP        SIL, CL",
+     "4038ce"),
+
+    (m64, "00000000    SETZ       DIL",
+     "400f94c7"),
+    (m64, "00000000    SETNZ      BPL",
+     "400f95c5"),
+    (m64, "00000000    MOV        CL, BPL",
+     "4088e9"),
+    (m64, "00000000    AND        DIL, 0x0",
+     "4080e700"),
+    (m64, "00000000    MOV        DIL, AL",
+     "4088c7"),
+    (m64, "00000000    MOV        DIL, BYTE PTR [RSI]",
+     "408a3e"),
+    (m64, "00000000    DEC        DIL",
+     "40fecf"),
+
+    (m64, "00000000    TEST       DIL, DIL",
+     "4084ff"),
+    (m32, "00000000    JMP        EDX",
+     "FFE2"),
+    (m64, "00000000    JMP        RDX",
+     "FFE2"),
+]
+
+
+    # mode = 64
+    # l = mn_x86.dis('\x4D\x11\x7c\x18\x00', mode)
+    # print l
+    #"""
+    # mode = 64
+    # l = mn_x86.fromstring("ADC      DWORD PTR [RAX], 0x11223344", mode)
+    # print 'xx'
+    # t= time.time()
+    # import cProfile
+    # def f():
+    #    x = l.asm(mode)
+    #    print x
+    # cProfile.run('f()')
+    # l.asm(mode)
+    # print time.time()-t
+# reg_tests = reg_tests[-1:]
+
+fname64 = ('exe64.bin', 'r+')
+if not os.access(fname64[0], os.R_OK):
+    fname64 = ('regression_test64_ia32.bin', 'w')
+
+test_file = {16: open('regression_test16_ia32.bin', 'w'),
+             32: open('regression_test32_ia32.bin', 'w'),
+             # 64:open('regression_test64_ia32.bin', 'w+')}
+             # 64:open('testmnemo', 'r+')}
+             64: open(*fname64)}
+ts = time.time()
+# test_file[16].write("\x90"*0x10000)
+# test_file[32].write("\x90"*0x10000)
+file64off = 0x2524c
+test_file[64].seek(0x400)
+test_file[64].write('\x90' * 0x30000)
+test_file[64].seek(file64off)
+for mode, s, l, in reg_tests:
+    print "-" * 80
+    s = s[12:]
+    b = l.decode('hex')
+    print mode, repr(b)
+    mn = mn_x86.dis(b, mode)
+    print "dis args", [(str(x), x.size) for x in mn.args]
+    print s
+    print mn
+    assert(str(mn).strip() == s)
+    # print hex(b)
+    # print [str(x.get()) for x in mn.args]
+    print 'fromstring', repr(s)
+    l = mn_x86.fromstring(s, mode)
+    # print l
+    print 'str args', [(str(x), x.size) for x in l.args]
+    assert(str(l).strip(' ') == s)
+    a = mn_x86.asm(l)
+    print 'asm result', [x for x in a]
+    print repr(b)
+    # test_file[mode[0]].write(b)
+
+    for x in a:
+        print "BYTES", repr(x)
+        test_file[mode].write(x)
+    test_file[mode].write("\x90" * 2)
+
+    print 'test re dis'
+    for x in a:
+        print repr(x)
+        rl = mn_x86.dis(x, mode)
+        assert(str(rl).strip(' ') == s)
+    print repr(b), a
+    assert(b in a)
+    # print mn.args
+print 'TEST time', time.time() - ts
+
+
+# speed test thumb
+o = ""
+mode_x = m32
+for mode, s, l, in reg_tests:
+    if mode != mode_x:
+        continue
+    s = s[12:]
+    b = l.decode('hex')
+    o += b
+
+while len(o) < 1000:
+    o += o
+open('x86_speed_reg_test.bin', 'w').write(o)
+
+
+def profile_dis(o):
+    bs = bin_stream_str(o)
+    off = 0
+    instr_num = 0
+    ts = time.time()
+    while off < bs.getlen():
+        mn = mn_x86.dis(bs, mode_x, off)
+        # print instr_num, off, mn.l, str(mn)
+        instr_num += 1
+        off += mn.l
+    print 'instr per sec:', instr_num / (time.time() - ts)
+
+import cProfile
+# cProfile.run(r'mn_x86.dis("\x81\x54\x18\xfe\x44\x33\x22\x11", m32)')
+cProfile.run('profile_dis(o)')
+# profile_dis(o)
diff --git a/test/core/graph.py b/test/core/graph.py
new file mode 100644
index 00000000..a419a686
--- /dev/null
+++ b/test/core/graph.py
@@ -0,0 +1,18 @@
+from miasm2.core.graph import *
+
+g = DiGraph()
+g.add_node('a')
+g.add_node('b')
+
+g.add_edge('a', 'b')
+g.add_edge('a', 'c')
+g.add_edge('a', 'c')
+g.add_edge('c', 'c')
+
+print g
+
+print [x for x in g.successors('a')]
+print [x for x in g.predecessors('a')]
+print [x for x in g.predecessors('b')]
+print [x for x in g.predecessors('c')]
+print [x for x in g.successors('c')]
diff --git a/test/core/interval.py b/test/core/interval.py
new file mode 100644
index 00000000..34537d25
--- /dev/null
+++ b/test/core/interval.py
@@ -0,0 +1,156 @@
+#!/usr/bin/env python
+#-*- coding:utf-8 -*-
+
+from miasm2.core.interval import *
+from random import randint
+from pdb import pm
+
+i1 = interval([(1, 3)])
+i2 = interval([(2, 5)])
+i3 = interval([(3, 5)])
+i4 = interval([(5, 8)])
+
+i5 = interval([(1, 5)])
+i6 = interval([(1, 3), (5, 8)])
+i7 = interval([(2, 8)])
+i8 = interval([(1, 8)])
+i9 = interval([(4, 5)])
+
+i10 = interval([(1, 1)])
+i11 = interval([(1, 2)])
+i12 = interval([(2, 2)])
+i13 = interval([(2, 4)])
+i14 = interval([(0, 1), (3, 5), (7, 10)])
+i15 = interval([(0, 12)])
+i16 = interval([(2, 8)])
+
+i_empty = interval()
+
+assert(repr(i_empty) == '[]')
+
+assert(interval(i1) == i1)
+
+i1.cannon()
+i1.cannon()
+
+assert(cmp_interval(i1.intervals[0], i2.intervals[0]) == INT_JOIN)
+assert(cmp_interval(i1.intervals[0], i3.intervals[0]) == INT_JOIN)
+assert(cmp_interval(i1.intervals[0], i4.intervals[0]) == INT_DISJOIN)
+assert(cmp_interval(i2.intervals[0], i3.intervals[0]) == INT_B_IN_A)
+assert(cmp_interval(i3.intervals[0], i2.intervals[0]) == INT_A_IN_B)
+assert(cmp_interval(i1.intervals[0], i1.intervals[0]) == INT_EQ)
+assert(cmp_interval(i1.intervals[0], i9.intervals[0]) == INT_JOIN_AB)
+assert(cmp_interval(i9.intervals[0], i1.intervals[0]) == INT_JOIN_BA)
+
+assert((i1 in i2) is False)
+assert((i2 in i1) is False)
+assert((i1 in i3) is False)
+assert((i2 in i3) is False)
+
+assert((i3 in i2))
+assert((i2 in i3) is False)
+
+assert(interval.cannon_list(i1.intervals) == i1.intervals)
+
+assert(i1 + i2 == i5)
+assert(i1 + i3 == i5)
+assert(i1 + i4 == i6)
+
+assert(i2 + i3 == i2)
+assert(i2 + i4 == i7)
+assert(i1 + i2 + i4 == i8)
+
+assert(i1 - i2 == i10)
+assert(i1 - i3 == i11)
+assert(i1 - i4 == i1)
+assert(i2 - i3 == i12)
+assert(i2 - i4 == i13)
+assert(i8 - i1 == interval([(4, 8)]))
+assert(i8 - i2 == interval([(1, 1), (6, 8)]))
+
+assert(i10 + i12 == i11)
+assert(i1 - i1 == interval())
+assert(i6 - i6 == interval())
+assert(i6 - i6 - i1 == interval())
+assert(i1 - i10 == interval([(2, 3)]))
+
+assert(i1 & i1 == i1)
+assert(i1 & i2 == interval([(2, 3)]))
+assert(i1 & i3 == interval([(3, 3)]))
+assert(i3 & i1 == interval([(3, 3)]))
+assert(i1 & i4 == interval([]))
+assert(i4 & i1 == interval([]))
+assert(i1 & i5 == i1)
+assert(i5 & i1 == i1)
+assert(i1 & i6 == i1)
+assert(i5 & i13 == i13)
+assert(i6 & i6 == i6)
+assert(i14 & i15 == i14)
+assert(i15 & i14 == i14)
+assert(i14 & i16 == interval([(3, 5), (7, 8)]))
+
+x1 = [(7, 87), (76, 143), (94, 129), (79, 89), (46, 100)]
+assert(interval(x1) == interval([(7, 143)]))
+x2 = [(11, 16), (35, 74), (18, 114), (91, 188), (3, 75)]
+assert(interval(x2) == interval([(3, 188)]))
+
+i1.hull()
+i1.show(dry_run=True)
+
+assert(i_empty.hull() == (None, None))
+
+
+def gen_random_interval(l=100):
+    r = []
+    for j in xrange(5):
+        a = randint(0, l)
+        b = a + randint(0, l)
+        r.append((a, b))
+    return r
+
+
+def check_add(r1, r2):
+    i_sum = interval(r1) + interval(r2)
+    for a, b in r1 + r2:
+        for i in xrange(a, b + 1):
+            assert(i in i_sum)
+
+
+def check_sub(r1, r2):
+    i1 = interval(r1)
+    i2 = interval(r2)
+    i_sub = i1 - i2
+    for a, b in r1:
+        for i in xrange(a, b + 1):
+            if i in i2:
+                assert(i not in i_sub)
+            else:
+                assert(i in i_sub)
+
+
+def check_and(r1, r2):
+    i1 = interval(r1)
+    i2 = interval(r2)
+    i_and = i1 & i2
+    for a, b in r1:
+        for i in xrange(a, b + 1):
+            if i in i2:
+                assert(i in i_and)
+            else:
+                assert(i not in i_and)
+
+
+for i in xrange(1000):
+    r1 = gen_random_interval()
+    r2 = gen_random_interval()
+    r3 = gen_random_interval()
+
+    check_add(r1, r2)
+    check_sub(r1, r2)
+    check_and(r1, r2)
+
+    a = interval(r1)
+    b = interval(r2)
+    c = interval(r3)
+    assert((a & b) - c == a & (b - c) == (a - c) & (b - c))
+    assert(a - (b & c) == (a - b) + (a - c))
diff --git a/test/core/parse_asm.py b/test/core/parse_asm.py
new file mode 100644
index 00000000..c2a6dc72
--- /dev/null
+++ b/test/core/parse_asm.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+#-*- coding:utf-8 -*-
+
+import unittest
+
+
+class TestParseAsm(unittest.TestCase):
+
+    def test_ParseTxt(self):
+        from miasm2.arch.x86.arch import mn_x86
+        from miasm2.core.parse_asm import parse_txt
+
+        ASM0 = '''
+        ;
+        .LFB0:
+        .LA:
+        .text
+        .data
+        .bss
+        .string
+        .ustring
+        .byte 0 0x0
+        .byte a
+        .comm
+        .split
+        .dontsplit
+        .file
+        .cfi_0
+        label:
+            JMP EAX  ;comment
+        '''
+        ASM1 = '''
+        .XXX
+        '''
+        self.assertTrue(parse_txt(mn_x86, 32, ASM0))
+        self.assertRaises(ValueError, parse_txt, mn_x86, 32, ASM1)
+
+if __name__ == '__main__':
+    testsuite = unittest.TestLoader().loadTestsFromTestCase(TestParseAsm)
+    report = unittest.TextTestRunner(verbosity=2).run(testsuite)
+    exit(len(report.errors + report.failures))
diff --git a/test/expression/modint.py b/test/expression/modint.py
new file mode 100644
index 00000000..e7c19d0c
--- /dev/null
+++ b/test/expression/modint.py
@@ -0,0 +1,59 @@
+from miasm2.expression.modint import *
+
+a = uint8(0x42)
+b = uint8(0xFF)
+c = uint8(0x4)
+
+d = uint1(0)
+e = uint1(1)
+
+f = uint8(0x1)
+
+
+print a, b, c
+print a + b, a + c, b + c
+print a == a, a == b, a == 0x42, a == 0x78
+print a != b, a != a
+print d, e
+print d + e, d + d, e + e, e + e + e, e + 0x11
+
+assert(f == 1)
+assert(f + 1 == 2)
+assert(2 == f + 1)
+assert(f + 0xff == 0)
+assert(f & 0 == 0)
+assert(f & 0xff == f)
+assert(0xff & f == f)
+assert(f / 1 == f)
+assert(1 / f == f)
+assert(int(f) == 1)
+assert(long(f) == 1)
+assert(~f == 0xfe)
+assert(f << 1 == 2)
+assert(f << 8 == 0)
+assert(1 << f == 2)
+assert(0x80 << f == 0)
+assert(f % 2 == f)
+assert(f % 1 == 0)
+assert(2 % f == 0)
+assert(f * 2 == 2)
+assert(2 * f == 2)
+assert(f * f == 1)
+assert(f * uint8(0x80) == 0x80)
+assert(-f == 0xff)
+assert(f | f == f)
+assert(f | 0 == f)
+assert(2 | f == 3)
+assert(f >> 0 == f)
+assert(f >> 1 == 0)
+assert(0x10 >> f == 0x8)
+assert(0x100 >> f == 0x80)  # XXXX
+assert(0x1000 >> f == 0x0)  # XXXX
+assert(f ^ f == 0)
+assert(f ^ 0 == f)
+assert(0 ^ f == f)
+assert(1 ^ f == 0)
+
+print e + c, c + e, c - e, e - c
+print 1000 * a
+print hex(a)
diff --git a/test/expression/simplifications.py b/test/expression/simplifications.py
new file mode 100644
index 00000000..19f43d6e
--- /dev/null
+++ b/test/expression/simplifications.py
@@ -0,0 +1,258 @@
+#
+# Expression simplification regression tests  #
+#
+from pdb import pm
+from miasm2.expression.expression import *
+from miasm2.expression.simplifications import expr_simp
+
+# Define example objects
+a = ExprId('a')
+b = ExprId('b')
+c = ExprId('c')
+d = ExprId('d')
+e = ExprId('e')
+
+m = ExprMem(a)
+s = a[:8]
+
+i1 = ExprInt(uint32(0x1))
+i2 = ExprInt(uint32(0x2))
+cc = ExprCond(a, b, c)
+
+o = ExprCompose([(a[:8], 8, 16),
+                 (a[8:16], 0, 8)])
+
+o2 = ExprCompose([(a[8:16], 0, 8),
+                 (a[:8], 8, 16)])
+
+l = [a[:8], b[:8], c[:8], m[:8], s, i1[:8], i2[:8], o[:8]]
+l2 = l[::-1]
+
+
+x = ExprMem(a + b + ExprInt32(0x42))
+
+# Define tests: (expression to simplify, expected value)
+to_test = [(ExprInt32(1) - ExprInt32(1), ExprInt32(0)),
+           ((ExprInt32(5) + c + a + b - a + ExprInt32(1) - ExprInt32(5)),
+            b + c + ExprInt32(1)),
+           (a + b + c - a - b - c + a, a),
+           (a + a + b + c - (a + (b + c)), a),
+           (c ^ b ^ a ^ c ^ b, a),
+           (a ^ ExprInt32(0), a),
+           ((a + b) - b, a),
+           (-(ExprInt32(0) - ((a + b) - b)), a),
+
+           (ExprOp('<<<', a, ExprInt32(32)), a),
+           (ExprOp('>>>', a, ExprInt32(32)), a),
+           (ExprOp('>>>', a, ExprInt32(0)), a),
+           (ExprOp('<<', a, ExprInt32(0)), a),
+
+           (ExprOp('<<<', a, ExprOp('<<<', b, c)),
+            ExprOp('<<<', a, ExprOp('<<<', b, c))),
+           (ExprOp('<<<', ExprOp('<<<', a, b), c),
+            ExprOp('<<<', ExprOp('<<<', a, b), c)),
+           (ExprOp('<<<', ExprOp('>>>', a, b), c),
+            ExprOp('<<<', ExprOp('>>>', a, b), c)),
+           (ExprOp('>>>', ExprOp('<<<', a, b), c),
+            ExprOp('>>>', ExprOp('<<<', a, b), c)),
+           (ExprOp('>>>', ExprOp('<<<', a, b), b),
+            ExprOp('>>>', ExprOp('<<<', a, b), b)),
+
+
+           (ExprOp('>>>', ExprOp('<<<', a, ExprInt32(10)), ExprInt32(2)),
+            ExprOp('<<<', a, ExprInt32(8))),
+
+           (ExprOp('>>>', ExprOp('<<<', a, ExprInt32(10)), ExprInt32(2)) ^ ExprOp('>>>', ExprOp('<<<', a, ExprInt32(10)), ExprInt32(2)),
+            ExprInt32(0)),
+           (ExprOp(">>", (a & ExprInt32(0xF)), ExprInt32(0x15)),
+            ExprInt32(0)),
+           (ExprOp(">>", (ExprInt32(0x12345678)), ExprInt32(0x4)),
+            ExprInt32(0x1234567)),
+           (ExprOp("a>>", (ExprInt32(0x12345678)), ExprInt32(0x4)),
+            ExprInt32(0x1234567)),
+           (ExprOp("a>>", (ExprInt32(0xF1234567)), ExprInt32(0x4)),
+            ExprInt32(0xFF123456)),
+           (ExprOp("a>>", (ExprInt32(0xF1234567)), ExprInt32(28)),
+            ExprInt32(0xFFFFFFFF)),
+           (ExprOp("==", ExprInt32(12), ExprInt32(10)), ExprInt32(0)),
+           (ExprOp("==", ExprInt32(12), ExprInt32(12)), ExprInt32(1)),
+           (ExprOp("==", a | ExprInt32(12), ExprInt32(0)), ExprInt32(0)),
+           (ExprOp("==", a | ExprInt32(12), ExprInt32(14)),
+            ExprOp("==", a | ExprInt32(12), ExprInt32(14))),
+           (ExprOp("parity", ExprInt32(0xf)), ExprInt1(1)),
+           (ExprOp("parity", ExprInt32(0xe)), ExprInt1(0)),
+           (ExprInt32(0x4142)[:32], ExprInt32(0x4142)),
+           (ExprInt32(0x4142)[:8], ExprInt8(0x42)),
+           (ExprInt32(0x4142)[8:16], ExprInt8(0x41)),
+           (a[:32], a),
+           (a[:8][:8], a[:8]),
+           (a[:16][:8], a[:8]),
+           (a[8:16][:8], a[8:16]),
+           (a[8:32][:8], a[8:16]),
+           (a[:16][8:16], a[8:16]),
+           (ExprCompose([(a, 0, 32)]), a),
+           (ExprCompose([(a[:16], 0, 16)]), a[:16]),
+           (ExprCompose([(a[:16], 0, 16), (a[:16], 16, 32)]),
+            ExprCompose([(a[:16], 0, 16), (a[:16], 16, 32)]),),
+           (ExprCompose([(a[:16], 0, 16), (a[16:32], 16, 32)]), a),
+
+           (ExprMem(a)[:32], ExprMem(a)),
+           (ExprMem(a)[:16], ExprMem(a, size=16)),
+
+           (ExprCond(ExprInt32(1), a, b), a),
+           (ExprCond(ExprInt32(0), b, a), a),
+
+           (ExprInt32(0x80000000)[31:32], ExprInt1(1)),
+           (ExprCompose([
+               (ExprInt16(0x1337)[
+                   :8], 0, 8), (ExprInt16(0x1337)[8:16], 8, 16)]),
+            ExprInt16(0x1337)),
+
+           (ExprCompose([(ExprInt32(0x1337beef)[8:16], 8, 16),
+                        (ExprInt32(0x1337beef)[:8], 0, 8),
+                        (ExprInt32(0x1337beef)[16:32], 16, 32)]),
+            ExprInt32(0x1337BEEF)),
+           (ExprCond(a,
+                     ExprCond(a,
+                              b,
+                              c),
+                     d), ExprCond(a, b, d)),
+           ((a & b & ExprInt32(0x12))[31:32], ExprInt1(0)),
+
+           (ExprCompose([
+               (ExprCond(a, ExprInt16(0x10), ExprInt16(0x20)), 0, 16),
+    (ExprInt16(0x1337), 16, 32)]),
+               ExprCond(a, ExprInt32(0x13370010), ExprInt32(0x13370020))),
+    (ExprCond(ExprCond(a, ExprInt1(0), ExprInt1(1)), b, c),
+     ExprCond(a, c, b)),
+    (ExprCond(a, ExprInt32(0x10), ExprInt32(0x20)) + ExprInt32(0x13370000),
+     ExprCond(a, ExprInt32(0x13370010), ExprInt32(0x13370020))),
+
+    (ExprCond(a, ExprInt32(0x10), ExprInt32(0x20)) + ExprCond(a, ExprInt32(0x13370000), ExprInt32(0x13380000)),
+     ExprCond(a, ExprInt32(0x13370010), ExprInt32(0x13380020))),
+    (-ExprCond(a, ExprInt32(0x1), ExprInt32(0x2)),
+     ExprCond(a, ExprInt32(-0x1), ExprInt32(-0x2))),
+    (ExprOp('*', a, b, c, ExprInt32(0x12))[0:17],
+     ExprOp(
+     '*', a[0:17], b[0:17], c[0:17], ExprInt(mod_size2uint[17](0x12)))),
+    (ExprOp('*', a, ExprInt32(0xffffffff)),
+     -a),
+    (ExprOp('*', -a, -b, c, ExprInt32(0x12)),
+     ExprOp('*', a, b, c, ExprInt32(0x12))),
+    (ExprOp('*', -a, -b, -c, ExprInt32(0x12)),
+     ExprOp('*', -a, b, c, ExprInt32(0x12))),
+    (a | ExprInt32(0xffffffff),
+     ExprInt32(0xffffffff)),
+    (ExprCond(a, ExprInt32(1), ExprInt32(2)) * ExprInt32(4),
+     ExprCond(a, ExprInt32(4), ExprInt32(8))),
+    (ExprCond(a, b, c) + ExprCond(a, d, e),
+     ExprCond(a, b + d, c + e)),
+    (ExprCond(a, b, c) * ExprCond(a, d, e),
+     ExprCond(a, b * d, c * e)),
+
+    (ExprCond(a, ExprInt32(8), ExprInt32(4)) >> ExprInt32(1),
+     ExprCond(a, ExprInt32(4), ExprInt32(2))),
+
+    (ExprCond(a, b, c) >> ExprCond(a, d, e),
+     ExprCond(a, b >> d, c >> e)),
+
+    (a & b & ExprInt_fromsize(a.size, -1), a & b),
+    (a | b | ExprInt_fromsize(a.size, -1),
+     ExprInt_fromsize(a.size, -1)),
+]
+
+for e, e_check in to_test[:]:
+    #
+    print "#" * 80
+    e_check = expr_simp(e_check)
+    # print str(e), str(e_check)
+    e_new = expr_simp(e)
+    print "original: ", str(e), "new: ", str(e_new)
+    rez = e_new == e_check
+    if not rez:
+        raise ValueError(
+            'bug in expr_simp simp(%s) is %s and should be %s' % (e, e_new, e_check))
+
+
+x = ExprId('x')
+y = ExprId('y')
+z = ExprId('z')
+a = ExprId('a')
+b = ExprId('b')
+c = ExprId('c')
+
+
+jra = ExprId('jra')
+jrb = ExprId('jrb')
+jrint1 = ExprId('jrint1')
+
+
+e1 = ExprMem((a & ExprInt32(0xFFFFFFFC)) + ExprInt32(0x10), 32)
+e2 = ExprMem((a & ExprInt32(0xFFFFFFFC)) + b, 32)
+e3 = (a ^ b ^ ((a ^ b) & (b ^ (b - a))) ^ (b - a)).canonize()
+
+match_tests = [
+    (MatchExpr(ExprInt32(12), a, [a]), {a: ExprInt32(12)}),
+    (MatchExpr(x, a, [a]), {a: x}),
+    (MatchExpr(x + y, a, [a]), {a: x + y}),
+    (MatchExpr(x + y, a + y, [a]), {a: x}),
+    (MatchExpr(x + y, x + a, [a]), {a: y}),
+    (MatchExpr(x + y, a + b, [a, b]), {a: x, b: y}),
+    (MatchExpr(x + ExprInt32(12), a + b, [a, b]), {a: x, b: ExprInt32(12)}),
+    (MatchExpr(ExprMem(x), a, [a]), {a: ExprMem(x)}),
+    (MatchExpr(ExprMem(x), ExprMem(a), [a]), {a: x}),
+    (MatchExpr(x[0:8], a, [a]), {a: x[0:8]}),
+    (MatchExpr(x[0:8], a[0:8], [a]), {a: x}),
+    (MatchExpr(ExprCond(x, y, z), a, [a]), {a: ExprCond(x, y, z)}),
+    (MatchExpr(ExprCond(x, y, z),
+               ExprCond(a, b, c), [a, b, c]),
+     {a: x, b: y, c: z}),
+    (MatchExpr(ExprCompose([(x[:8], 0, 8), (y[:8], 8, 16)]), a, [a]),
+     {a: ExprCompose([(x[:8], 0, 8), (y[:8], 8, 16)])}),
+    (MatchExpr(ExprCompose([(x[:8], 0, 8), (y[:8], 8, 16)]),
+               ExprCompose([(a[:8], 0, 8), (b[:8], 8, 16)]), [a, b]),
+     {a: x, b: y}),
+    (MatchExpr(e1, e2, [b]), {b: ExprInt32(0x10)}),
+    (MatchExpr(e3,
+               (((jra ^ jrb) & (jrb ^ jrint1))
+                ^ jra ^ jrb ^ jrint1).canonize(),
+               [jra, jrb, jrint1]),
+     {jra: a, jrb: b, jrint1: b - a}),
+]
+
+for test, res in match_tests:
+    assert(test == res)
+
+
+get_tests = [
+    (ExprAff(ExprMem(a), ExprMem(b)).get_r(True), set([a, b, ExprMem(b)])),
+    (ExprAff(ExprMem(a), ExprMem(b)).get_w(), set([ExprMem(a)])),
+    (ExprAff(ExprMem(ExprMem(a)), ExprMem(b))
+     .get_r(True), set([a, b, ExprMem(b), ExprMem(a)])),
+]
+
+
+for test, res in get_tests:
+    assert(test == res)
+
+
+to_test = [(a + b, b + a),
+           (a + m, m + a),
+           ((a[:8] + s), (s + a[:8])),
+           ((m[:8] + s), (s + m[:8])),
+           ((i1 + i2), (i2 + i1)),
+           ((a + i2), (i2 + a)),
+           ((m + i2), (i2 + m)),
+           ((s + i2[:8]), (i2[:8] + s)),
+           (o, o2),
+           (ExprOp('+', *l), ExprOp('+', *l2)),
+           ]
+
+for x, y in to_test:
+    x, y = x.canonize(), y.canonize()
+
+    assert(x == y)
+    assert(str(x) == str(y))
+    print x
+
+print 'all tests ok'
diff --git a/test/expression/stp.py b/test/expression/stp.py
new file mode 100644
index 00000000..fe09e865
--- /dev/null
+++ b/test/expression/stp.py
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+#-*- coding:utf-8 -*-
+
+import unittest
+
+
+class TestIrIr2STP(unittest.TestCase):
+
+    def test_ExprOp_strcst(self):
+        from miasm2.expression.expression import ExprInt32, ExprOp
+        import miasm2.expression.stp   # /!\ REALLY DIRTY HACK
+        args = [ExprInt32(i) for i in xrange(9)]
+
+        self.assertEqual(
+            ExprOp('|',  *args[:2]).strcst(), r'(0bin00000000000000000000000000000000 | 0bin00000000000000000000000000000001)')
+        self.assertEqual(
+            ExprOp('-',  *args[:2]).strcst(), r'BVUMINUS(0bin00000000000000000000000000000000)')
+        self.assertEqual(
+            ExprOp('+',  *args[:3]).strcst(), r'BVPLUS(32,BVPLUS(32,0bin00000000000000000000000000000000, 0bin00000000000000000000000000000001), 0bin00000000000000000000000000000010)')
+        self.assertRaises(ValueError, ExprOp('X', *args[:1]).strcst)
+
+    def test_ExprSlice_strcst(self):
+        from miasm2.expression.expression import ExprInt32, ExprSlice
+        import miasm2.expression.stp   # /!\ REALLY DIRTY HACK
+        args = [ExprInt32(i) for i in xrange(9)]
+
+        self.assertEqual(
+            args[0][1:2].strcst(), r'(0bin00000000000000000000000000000000)[1:1]')
+        self.assertRaises(ValueError, args[0].__getitem__, slice(1,7,2))
+
+if __name__ == '__main__':
+    testsuite = unittest.TestLoader().loadTestsFromTestCase(TestIrIr2STP)
+    report = unittest.TextTestRunner(verbosity=2).run(testsuite)
+    exit(len(report.errors + report.failures))
+
diff --git a/test/ir/ir2C.py b/test/ir/ir2C.py
new file mode 100644
index 00000000..c5ae1b8f
--- /dev/null
+++ b/test/ir/ir2C.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+#-*- coding:utf-8 -*-
+
+import unittest
+
+
+class TestIrIr2C(unittest.TestCase):
+
+    def test_ExprOp_toC(self):
+        from miasm2.expression.expression import ExprInt32, ExprOp
+        import miasm2.ir.ir2C   # /!\ REALLY DIRTY HACK
+        args = [ExprInt32(i) for i in xrange(9)]
+
+        # Unary operators
+        self.assertEqual(
+            ExprOp('parity',  *args[:1]).toC(), r'parity(0x0&0xffffffff)')
+        self.assertEqual(
+            ExprOp('!',       *args[:1]).toC(), r'(~ 0x0)&0xffffffff')
+        self.assertEqual(
+            ExprOp('hex2bcd', *args[:1]).toC(), r'hex2bcd_32(0x0)')
+        self.assertEqual(ExprOp('fabs',    *args[:1]).toC(), r'fabs(0x0)')
+        self.assertRaises(ValueError, ExprOp('X', *args[:1]).toC)
+
+        # Binary operators
+        self.assertEqual(
+            ExprOp('==',      *args[:2]).toC(), r'(((0x0&0xffffffff) == (0x1&0xffffffff))?1:0)')
+        self.assertEqual(
+            ExprOp('%',       *args[:2]).toC(), r'(((0x0&0xffffffff)%(0x1&0xffffffff))&0xffffffff)')
+        self.assertEqual(
+            ExprOp('-',       *args[:2]).toC(), r'(((0x0&0xffffffff) - (0x1&0xffffffff))&0xffffffff)')
+        self.assertEqual(
+            ExprOp('bsr',     *args[:2]).toC(), r'my_bsr(0x0, 0x1)')
+        self.assertEqual(
+            ExprOp('cpuid0',  *args[:2]).toC(), r'cpuid0(0x0, 0x1)')
+        self.assertEqual(
+            ExprOp('fcom0',   *args[:2]).toC(), r'fcom0(0x0, 0x1)')
+        self.assertEqual(
+            ExprOp('fadd',    *args[:2]).toC(), r'fadd(0x0, 0x1)')
+        self.assertEqual(
+            ExprOp('segm',    *args[:2]).toC(), r'segm2addr(vmcpu, 0x0, 0x1)')
+        self.assertEqual(
+            ExprOp('imod',    *args[:2]).toC(), r'imod32(vmcpu, 0x0, 0x1)')
+        self.assertEqual(
+            ExprOp('bcdadd',  *args[:2]).toC(), r'bcdadd_32(0x0, 0x1)')
+        self.assertRaises(ValueError, ExprOp('X', *args[:2]).toC)
+
+        # Ternary operators
+        self.assertEqual(
+            ExprOp('div8',    *args[:3]).toC(), r'(div_op(32, 0x0, 0x1, 0x2) &0xffffffff)')
+
+        # Other cases
+        self.assertEqual(
+            ExprOp('+',       *args[:3]).toC(), r'(((0x0&0xffffffff)+(0x1&0xffffffff)+(0x2&0xffffffff))&0xffffffff)')
+        self.assertRaises(NotImplementedError, ExprOp('X', *args[:3]).toC)
+
+if __name__ == '__main__':
+    testsuite = unittest.TestLoader().loadTestsFromTestCase(TestIrIr2C)
+    report = unittest.TextTestRunner(verbosity=2).run(testsuite)
+    exit(len(report.errors + report.failures))
diff --git a/test/ir/symbexec.py b/test/ir/symbexec.py
new file mode 100644
index 00000000..0d3db7e8
--- /dev/null
+++ b/test/ir/symbexec.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+#-*- coding:utf-8 -*-
+
+import unittest
+
+
+class TestSymbExec(unittest.TestCase):
+
+    def test_ClassDef(self):
+        from miasm2.expression.expression import ExprInt32, ExprId, ExprMem, ExprCompose
+        from miasm2.arch.x86.arch import mn_x86
+        from miasm2.ir.symbexec import symbexec
+
+        addrX = ExprInt32(-1)
+        addr0 = ExprInt32(0)
+        addr1 = ExprInt32(1)
+        addr8 = ExprInt32(8)
+        addr9 = ExprInt32(9)
+        addr20 = ExprInt32(20)
+        addr40 = ExprInt32(40)
+        addr50 = ExprInt32(50)
+        mem0 = ExprMem(addr0)
+        mem1 = ExprMem(addr1)
+        mem8 = ExprMem(addr8)
+        mem9 = ExprMem(addr9)
+        mem20 = ExprMem(addr20)
+        mem40v = ExprMem(addr40,  8)
+        mem40w = ExprMem(addr40, 16)
+        mem50v = ExprMem(addr50,  8)
+        mem50w = ExprMem(addr50, 16)
+        id_x = ExprId('x')
+        id_y = ExprId('y', 8)
+        id_a = ExprId('a')
+        id_eax = ExprId('eax_init')
+
+        e = symbexec(
+            mn_x86, {mem0: id_x, mem1: id_y, mem9: id_x, mem40w: id_x, mem50v: id_y, id_a: addr0, id_eax: addr0})
+        self.assertEqual(e.find_mem_by_addr(addr0), mem0)
+        self.assertEqual(e.find_mem_by_addr(addrX), None)
+        self.assertEqual(e.eval_ExprMem(ExprMem(addr1 - addr1)), id_x)
+        self.assertEqual(e.eval_ExprMem(ExprMem(addr1,  8)),     id_y)
+        self.assertEqual(e.eval_ExprMem(ExprMem(addr1 + addr1)), ExprCompose(
+            [(id_x[16:32], 0, 16), (ExprMem(ExprInt32(4), 16), 16, 32)]))
+        self.assertEqual(e.eval_ExprMem(mem8),                   ExprCompose(
+            [(id_x[0:24], 0, 24), (ExprMem(ExprInt32(11), 8), 24, 32)]))
+        self.assertEqual(e.eval_ExprMem(mem40v),                 id_x[:8])
+        self.assertEqual(e.eval_ExprMem(mem50w),                 ExprCompose(
+            [(id_y, 0, 8), (ExprMem(ExprInt32(51), 8), 8, 16)]))
+        self.assertEqual(e.eval_ExprMem(mem20), mem20)
+        e.func_read = lambda x: x
+        self.assertEqual(e.eval_ExprMem(mem20), mem20)
+        self.assertEqual(set(e.modified()), set(e.symbols))
+        self.assertRaises(
+            KeyError, e.symbols.__getitem__, ExprMem(ExprInt32(100)))
+
+if __name__ == '__main__':
+    testsuite = unittest.TestLoader().loadTestsFromTestCase(TestSymbExec)
+    report = unittest.TextTestRunner(verbosity=2).run(testsuite)
+    exit(len(report.errors + report.failures))
diff --git a/test/test_all.py b/test/test_all.py
new file mode 100644
index 00000000..378755a4
--- /dev/null
+++ b/test/test_all.py
@@ -0,0 +1,443 @@
+import subprocess
+import sys
+import os
+import time
+import argparse
+import tempfile
+
+# Available tests
+
+all_tests = {
+    "test": {
+        "architecture": [
+            ["arch/x86/arch.py"],
+            ["arch/arm/arch.py"],
+            ["arch/arm/sem.py"],
+            ["arch/msp430/arch.py"],
+            ["arch/msp430/sem.py"],
+            ["arch/sh4/arch.py"],
+        ],
+        "core": [
+            ["core/interval.py"],
+            ["core/graph.py"],
+            ["core/parse_asm.py"],
+        ],
+        "expression": [
+            ["expression/modint.py"],
+            ["expression/stp.py"],
+            ["expression/simplifications.py"],
+        ],
+        "ir": [
+            ["ir/ir2C.py"],
+            ["ir/symbexec.py"],
+        ],
+        "order": [
+            "architecture",
+            "core",
+            "expression",
+            "ir",
+        ],
+    },
+    "example": {
+        "assembler": [
+            ["asm_x86.py"],
+            ["asm_arm.py"],
+            ["asm_box_x86_32.py"],
+            ["asm_box_x86_32_enc.py"],
+            ["asm_box_x86_32_mod.py"],
+            ["asm_box_x86_32_mod_self.py"],
+            ["asm_box_x86_32_repmod.py"],
+            ["disasm_01.py"],
+            ["disasm_02.py"],
+            ["disasm_03.py", "box_upx.exe", "0x410f90"],
+        ],
+        "expression": [
+            ["symbol_exec.py"],
+            ["expression/manip_expression1.py"],
+            ["expression/manip_expression2.py"],
+            ["expression/manip_expression3.py"],
+            ["expression/manip_expression4.py",
+                "expression/sc_connect_back.bin", "0x2e"],
+            ["expression/manip_expression5.py"],
+            ["expression/manip_expression6.py"],
+            ["expression/manip_expression7.py"],
+            ["test_dis.py", "-g", "-s", "-m", "arm", "demo_arm.bin", "0"],
+            ["test_dis.py", "-g", "-s", "-m",
+                "x86_32", "box_x86_32.bin", "0x401000"],
+            ["expression/solve_condition_stp.py",
+                "expression/simple_test.bin"],
+        ],
+        "jitter": [
+            ["unpack_upx.py", "--jitter", "tcc", "box_upx.exe"],
+            ["unpack_upx.py", "--jitter", "llvm", "box_upx.exe"],
+            ["test_jit_x86_32.py", "x86_32_sc.bin"],
+            ["test_jit_arm.py", "md5_arm", "A684"],
+            ["sandbox_pe_x86_32.py", "--jitter", "tcc", "box_x86_32.bin"],
+            ["sandbox_pe_x86_32.py", "--jitter", "llvm", "box_x86_32.bin"],
+            ["sandbox_pe_x86_32.py", "--jitter", "tcc", "box_x86_32_enc.bin"],
+            ["sandbox_pe_x86_32.py", "--jitter", "llvm", "box_x86_32_enc.bin"],
+            ["sandbox_pe_x86_32.py", "--jitter", "tcc", "box_x86_32_mod.bin"],
+            ["sandbox_pe_x86_32.py", "--jitter", "llvm", "box_x86_32_mod.bin"],
+            ["sandbox_pe_x86_32.py", "--jitter",
+                "tcc", "box_x86_32_mod_self.bin"],
+            ["sandbox_pe_x86_32.py", "--jitter",
+                "llvm", "box_x86_32_mod_self.bin"],
+            ["sandbox_pe_x86_32.py", "--jitter",
+                "tcc", "box_x86_32_repmod.bin"],
+            ["sandbox_pe_x86_32.py", "--jitter",
+                "llvm", "box_x86_32_repmod.bin"],
+        ],
+        "order": [
+            "assembler",
+            "expression",
+            "jitter",
+        ],
+    },
+    "order": [
+        "test",
+        "example",
+    ],
+}
+
+# Cosmetic
+
+
+def getTerminalSize():
+    "Return the size of the terminal : COLUMNS, LINES"
+
+    env = os.environ
+
+    def ioctl_GWINSZ(fd):
+        try:
+            import fcntl
+            import termios
+            import struct
+            import os
+            cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,
+                                                 '1234'))
+        except:
+            return
+        return cr
+    cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
+    if not cr:
+        try:
+            fd = os.open(os.ctermid(), os.O_RDONLY)
+            cr = ioctl_GWINSZ(fd)
+            os.close(fd)
+        except:
+            pass
+    if not cr:
+        cr = (env.get('LINES', 25), env.get('COLUMNS', 80))
+    return int(cr[1]), int(cr[0])
+
+
+WIDTH = getTerminalSize()[0]
+colors = {"red": "\033[91;1m",
+          "end": "\033[0m",
+          "green": "\033[92;1m",
+          "lightcyan": "\033[96m",
+          "blue": "\033[94;1m"}
+
+
+def write_colored(text, color, already_printed=0):
+    text_colored = colors[color] + text + colors["end"]
+    print " " * (WIDTH - already_printed - len(text)) + text_colored
+
+
+def write_underline(text):
+    print "\033[4m" + text + colors["end"]
+
+
+def print_conf(conf, value):
+    return colors["green"] + conf + ": " + colors["end"] + str(value)
+
+
+def clr_screen(global_state, pstate):
+    "Update the screen to display some information"
+
+    # Header
+    to_print = []
+    to_print.append(" " * (global_state["termSize"][0] / 2 - 10) + colors[
+                    "blue"] + "Miasm2 Regression tests" + colors["end"])
+    to_print.append("")
+    to_print.append("=" * global_state["termSize"][0])
+    to_print.append("")
+    to_print.append(print_conf("Current mode", "Multiprocessing"))
+    to_print.append(print_conf("Nb CPU detected", global_state["cpu_c"]))
+    to_print.append("")
+    to_print.append("=" * global_state["termSize"][0])
+    to_print.append("")
+    to_print.append(
+        print_conf("Current section", global_state["section"].upper()))
+    to_print.append(
+        print_conf("Current subsection", global_state["subsection"].upper()))
+    test_done = 0
+    test_failed = 0
+    message = global_state["message"] + "\n"
+    for k, v in pstate.items():
+        if v["status"] != "running":
+            test_done += 1
+            if v["status"] != 0:
+                test_failed += 1
+                message += colors["red"] + "FAIL: " + colors["end"] + k
+                message += v["message"] + "\n"
+
+    to_print.append(print_conf("Success rate", "%d/%d" %
+                    (test_done - test_failed, test_done)))
+    printed_time = time.strftime(
+        "%M:%S", time.gmtime(time.time() - global_state["init_time"]))
+    to_print.append(print_conf("Cumulated time", printed_time))
+    to_print.append("")
+    to_print.append("=" * global_state["termSize"][0])
+
+    cur = "\n".join(to_print)
+    cur += "\n"
+
+    # Message
+    cur += message
+    print cur
+    already_printed = cur.count("\n")
+
+    # Current state
+    current_job = []
+    for t in pstate.values():
+        if t["status"] == "running":
+            current_job.append(t)
+    print "\n" * (global_state["termSize"][1] - already_printed - 3 - len(current_job))
+
+    for j in current_job:
+        s = "[" + colors["lightcyan"] + j["command"] + colors["end"]
+        s_end = time.strftime(
+            "%M:%Ss", time.gmtime(time.time() - j["init_time"]))
+        l = len(j["command"]) + len(s_end) + 4 + len(str(j["pid"])) + 2
+        s_end += "    " + colors["blue"] + str(j["pid"]) + colors["end"] + "]"
+        print "%s%s%s" % (s, " " * (global_state["termSize"][0] - l), s_end)
+
+# Tests handling
+
+
+def are_tests_finished(test_names, done):
+    for t in test_names:
+        if t not in done:
+            return False
+    return True
+
+
+def are_tests_finished_multi(test_names, pstate):
+    for t in test_names:
+        t = " ".join(t)
+        if t not in pstate.keys():
+            return False
+        if pstate[t]["status"] == "running":
+            return False
+    return True
+
+
+def test_iter(done):
+    "Return an iterator on next tests, wait for previous sections"
+
+    for section_name in all_tests["order"]:
+        # Go to the right directory
+        os.chdir(os.path.join("..", section_name))
+
+        # Update global state
+        section_content = all_tests[section_name]
+        write_underline(section_name.upper())
+
+        for subsection_name in section_content["order"]:
+            subsection_content = section_content[subsection_name]
+            write_underline("%s > %s" % (section_name.upper(),
+                                         subsection_name.upper()))
+            for test_line in subsection_content:
+                yield test_line
+
+            while not(are_tests_finished(subsection_content, done)):
+                time.sleep(0.050)
+
+
+def test_iter_multi(global_state, pstate):
+    "Multiprocessor version of test_iter"
+
+    # Global message : subsections done
+    message = ""
+
+    for section_name in all_tests["order"]:
+        # Update global state
+        section_content = all_tests[section_name]
+        global_state["section"] = section_name
+
+        for subsection_name in section_content["order"]:
+            subsection_content = section_content[subsection_name]
+            beg_time = time.time()
+            global_state["subsection"] = subsection_name
+
+            for test_line in subsection_content:
+                yield test_line
+
+            while not(are_tests_finished_multi(subsection_content, pstate)):
+                # Wait for task to finish, update the screen
+                time.sleep(0.100)
+                clr_screen(global_state, pstate)
+
+            message += "%s > %s completed in %.08f seconds\n" % (section_name.upper(),
+                                                                 subsection_name.upper(
+                                                                 ),
+                                                                 time.time() - beg_time)
+            global_state["message"] = message
+
+    # Final update
+    clr_screen(global_state, pstate)
+
+
+def run_test(test, coveragerc=None):
+    s = "Running tests on %s ..." % " ".join(test)
+    sys.stdout.write(s)
+    sys.stdout.flush()
+
+    args = test
+    if coveragerc is not None:
+        args = ["-m", "coverage", "run", "--rcfile", coveragerc, "-a"] + test
+
+    # Launch test
+    testpy = subprocess.Popen(["python"] + args, stdout=subprocess.PIPE,
+                              stderr=subprocess.PIPE)
+    outputs = testpy.communicate()
+
+    # Check result
+    if testpy.returncode == 0:
+        write_colored("OK", "green", len(s))
+    else:
+        write_colored("ERROR", "red", len(s))
+        print outputs[1]
+
+
+def run_test_parallel(test, current, global_state):
+
+    pid = os.getpid()
+    test_key = " ".join(test)
+
+    # Keep current PID
+    current[test_key] = {"status": "running",
+                         "pid": pid,
+                         "command": test_key,
+                         "init_time": time.time()}
+
+    # Go to the right directory
+    os.chdir(os.path.join("..", global_state["section"]))
+
+    # Launch test
+    testpy = subprocess.Popen(["python"] + test, stdout=subprocess.PIPE,
+                              stderr=subprocess.PIPE)
+    outputs = testpy.communicate()
+
+    # Check result
+    message = ""
+    if testpy.returncode != 0:
+        message = outputs[1]
+
+    # Update result
+    current[test_key] = {"status": testpy.returncode,
+                         "message": message}
+
+# Multiprocessing handling
+
+try:
+    from multiprocessing import Manager, Pool, cpu_count
+    multiproc = True
+except ImportError:
+    multiproc = False
+
+# Argument parsing
+parser = argparse.ArgumentParser(description="Miasm2 testing tool")
+parser.add_argument("-m", "--mono", help="Force monothreading",
+                    action="store_true")
+parser.add_argument("-c", "--coverage", help="Include code coverage",
+                    action="store_true")
+args = parser.parse_args()
+
+if args.mono is True or args.coverage is True:
+    multiproc = False
+
+# Handle coverage
+coveragerc = None
+if args.coverage is True:
+    try:
+        import coverage
+    except ImportError:
+        print "%(red)s[Coverage]%(end)s Python 'coverage' module is required" % colors
+        exit(-1)
+
+    # Create directory
+    suffix = "_" + str(int(time.time()))
+    cov_dir = tempfile.mkdtemp(suffix, "m2_coverage_")
+
+    # Create configuration file
+    coveragerc = os.path.join(cov_dir, ".coveragerc")
+    coverage = os.path.join(cov_dir, ".coverage")
+
+    from ConfigParser import ConfigParser
+    from os.path import expanduser
+
+    config = ConfigParser()
+    config.read(['/etc/coveragerc', expanduser('~/.coveragerc')])
+    if not config.has_section('run'):
+        config.add_section('run')
+    config.set('run', 'data_file', coverage)
+    config.write(open(coveragerc, 'w'))
+
+    # Inform the user
+    d = {"blue": colors['blue'],
+         "end": colors['end'],
+         "cov_dir": cov_dir}
+    print "[%(blue)sCoverage%(end)s] Report will be written in %(cov_dir)s" % d
+
+# Handle llvm modularity
+
+llvm = True
+try:
+    import llvm
+except ImportError:
+    llvm = False
+
+# if llvm.version != (3,2):
+#    llvm = False
+
+if llvm is False:
+    print "%(red)s[LLVM]%(end)s Python 'py-llvm 3.2' module is required for llvm tests" % colors
+
+    # Remove llvm tests
+    for test in all_tests["example"]["jitter"]:
+        if "llvm" in test:
+            all_tests["example"]["jitter"].remove(test)
+            print "%(red)s[LLVM]%(end)s Remove" % colors, " ".join(test)
+
+    # Let the user see messages
+    time.sleep(0.5)
+
+# Run tests
+
+if multiproc is False:
+    done = list()
+    for test in test_iter(done):
+        run_test(test, coveragerc=coveragerc)
+        done.append(test)
+
+else:
+    # Parallel version
+    cpu_c = cpu_count()
+    global_state = {"cpu_c": cpu_c,
+                    "init_time": time.time(),
+                    "termSize": getTerminalSize(),
+                    "message": ""}
+
+    manager = Manager()
+    pool = Pool(processes=cpu_c)
+    current = manager.dict()
+
+    for test in test_iter_multi(global_state, current):
+        pool.apply_async(run_test_parallel, (test,
+                                             current,
+                                             global_state))
+
+    pool.close()
+    pool.join()