about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--miasm2/arch/x86/sem.py4
-rw-r--r--miasm2/ir/translators/C.py372
-rw-r--r--miasm2/jitter/JitCore.c152
-rw-r--r--miasm2/jitter/JitCore.h108
-rw-r--r--miasm2/jitter/Jitllvm.c1
-rw-r--r--miasm2/jitter/arch/JitCore_aarch64.c1
-rw-r--r--miasm2/jitter/arch/JitCore_arm.c7
-rw-r--r--miasm2/jitter/arch/JitCore_mep.c1
-rw-r--r--miasm2/jitter/arch/JitCore_mips32.c1
-rw-r--r--miasm2/jitter/arch/JitCore_msp430.c1
-rw-r--r--miasm2/jitter/arch/JitCore_ppc32.c1
-rw-r--r--miasm2/jitter/arch/JitCore_x86.c286
-rw-r--r--miasm2/jitter/arch/JitCore_x86.h91
-rw-r--r--miasm2/jitter/bn.c848
-rw-r--r--miasm2/jitter/bn.h145
-rw-r--r--miasm2/jitter/codegen.py75
-rw-r--r--miasm2/jitter/jitcore_cc_base.py1
-rw-r--r--miasm2/jitter/llvmconvert.py103
-rw-r--r--miasm2/jitter/op_semantics.c8
-rw-r--r--miasm2/jitter/op_semantics.h8
-rw-r--r--miasm2/jitter/vm_mngr.c48
-rw-r--r--miasm2/jitter/vm_mngr.h22
-rwxr-xr-xsetup.py23
23 files changed, 1918 insertions, 389 deletions
diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py
index ef939144..00bdd6d7 100644
--- a/miasm2/arch/x86/sem.py
+++ b/miasm2/arch/x86/sem.py
@@ -2820,8 +2820,8 @@ def das(_, instr):
 def aam(_, instr, src):
     e = []
     tempAL = mRAX[instr.mode][0:8]
-    newEAX = m2_expr.ExprCompose(tempAL % src,
-                                 tempAL / src,
+    newEAX = m2_expr.ExprCompose(m2_expr.ExprOp("umod", tempAL, src),
+                                 m2_expr.ExprOp("udiv", tempAL, src),
                                  mRAX[instr.mode][16:])
     e += [m2_expr.ExprAff(mRAX[instr.mode], newEAX)]
     e += update_flag_arith(newEAX)
diff --git a/miasm2/ir/translators/C.py b/miasm2/ir/translators/C.py
index f8fd4d3b..066c0f32 100644
--- a/miasm2/ir/translators/C.py
+++ b/miasm2/ir/translators/C.py
@@ -3,6 +3,22 @@ from miasm2.core import asmblock
 from miasm2.expression.modint import size2mask
 
 
+def int_size_to_bn(value, size):
+    if size < 32:
+        size = 32
+        int_str = "%.8x" % value
+        size_nibble = 8
+    else:
+        # size must be multiple of 4
+        size = ((size + 31) / 32) * 32
+        size_nibble = size / 4
+        fmt_str = "%%.%dx" % size_nibble
+        int_str = fmt_str % value
+    assert len(int_str) == size_nibble
+    return int_str, size_nibble
+
+
+
 class TranslatorC(Translator):
     "Translate a Miasm expression to an equivalent C code"
 
@@ -18,6 +34,8 @@ class TranslatorC(Translator):
                '>>>': 'rot_right',
                }
 
+    NATIVE_INT_MAX_SIZE = 64
+
     def __init__(self, loc_db=None, **kwargs):
         """Instance a C translator
         @loc_db: LocationDB instance
@@ -28,38 +46,34 @@ class TranslatorC(Translator):
 
     def _size2mask(self, size):
         """Return a C string corresponding to the size2mask operation, with support for
-        @size <= 128"""
+        @size <= 64"""
+        assert size <= 64
         mask = size2mask(size)
-        if size > 64:
-            # Avoid "integer constant is too large for its type" error
-            return "(0x%x | ((uint128_t) 0x%x << 64))" % (
-                mask & 0xFFFFFFFFFFFFFFFF,
-                (mask >> 64) & 0xFFFFFFFFFFFFFFFF,
-            )
         return "0x%x" % mask
 
     def from_ExprId(self, expr):
         return str(expr)
 
     def from_ExprInt(self, expr):
-        if expr.size == 128:
-            # Avoid "integer constant is too large for its type" error
-            return "(0x%x | ((uint128_t) 0x%x << 64))" % (
-                int(expr) & 0xFFFFFFFFFFFFFFFF,
-                (int(expr) >> 64) & 0xFFFFFFFFFFFFFFFF,
-            )
-        return "0x%x" % expr.arg.arg
+        if expr.size <= self.NATIVE_INT_MAX_SIZE:
+            assert expr.size <= 64
+            return "0x%x" % expr.arg.arg
+        value, int_size = int_size_to_bn(int(expr), expr.size)
+        return 'bignum_from_string("%s", %d)' % (value, int_size)
 
     def from_ExprLoc(self, expr):
         loc_key = expr.loc_key
         if self.loc_db is None:
             return str(loc_key)
-
         offset = self.loc_db.get_location_offset(loc_key)
         if offset is None:
             return str(loc_key)
 
-        return "0x%x" % offset
+        if expr.size <= self.NATIVE_INT_MAX_SIZE:
+            return "0x%x" % offset
+
+        value, int_size = int_size_to_bn(offset, 64)
+        return 'bignum_from_string("%s", %d)' % (value, int_size)
 
     def from_ExprAff(self, expr):
         new_dst = self.from_expr(expr.dst)
@@ -67,33 +81,66 @@ class TranslatorC(Translator):
         return "%s = %s" % (new_dst, new_src)
 
     def from_ExprCond(self, expr):
-        new_cond = self.from_expr(expr.cond)
-        new_src1 = self.from_expr(expr.src1)
-        new_src2 = self.from_expr(expr.src2)
-        return "(%s?%s:%s)" % (new_cond, new_src1, new_src2)
+        cond = self.from_expr(expr.cond)
+        src1 = self.from_expr(expr.src1)
+        src2 = self.from_expr(expr.src2)
+        if not expr.cond.size <= self.NATIVE_INT_MAX_SIZE:
+            cond = "(!bignum_is_zero(%s))" % cond
+        out = "(%s?%s:%s)" % (cond, src1, src2)
+        return out
 
     def from_ExprMem(self, expr):
-        new_ptr = self.from_expr(expr.arg)
-        return "MEM_LOOKUP_%.2d(jitcpu, %s)" % (expr.size, new_ptr)
+        ptr = expr.arg
+        if ptr.size <= self.NATIVE_INT_MAX_SIZE:
+            new_ptr = self.from_expr(ptr)
+            if expr.size <= self.NATIVE_INT_MAX_SIZE:
+                # Native ptr, Native Mem
+                return "MEM_LOOKUP_%.2d(jitcpu, %s)" % (expr.size, new_ptr)
+            else:
+                # Native ptr, BN mem
+                return "MEM_LOOKUP_INT_BN(jitcpu, %d, %s)" % (expr.size, new_ptr)
+        # BN ptr
+        new_ptr = self.from_expr(ptr)
+
+        if expr.size <= self.NATIVE_INT_MAX_SIZE:
+            # BN ptr, Native Mem
+            return "MEM_LOOKUP_BN_INT(jitcpu, %d, %s)" % (expr.size, new_ptr)
+        else:
+            # BN ptr, BN mem
+            return "MEM_LOOKUP_BN_BN(jitcpu, %d, %s)" % (expr.size, new_ptr)
 
     def from_ExprOp(self, expr):
         if len(expr.args) == 1:
             if expr.op == 'parity':
-                return "parity(%s&%s)" % (
-                    self.from_expr(expr.args[0]),
-                    self._size2mask(expr.args[0].size),
-                )
+                arg = expr.args[0]
+                out = self.from_expr(arg)
+                if arg.size <= self.NATIVE_INT_MAX_SIZE:
+                    out = "(%s&%s)" % (out, self._size2mask(arg.size))
+                else:
+                    out = 'bignum_mask(%s, 8)' % (out, 8)
+                    out = 'bignum_to_uint64(%s)' % out
+                out = 'parity(%s)' % out
+                return out
+
             elif expr.op in ['cntleadzeros', 'cnttrailzeros']:
-                return "%s(0x%x, %s)" % (
-                    expr.op,
-                    expr.args[0].size,
-                    self.from_expr(expr.args[0])
-                )
+                arg = expr.args[0]
+                out = self.from_expr(arg)
+                if arg.size <= self.NATIVE_INT_MAX_SIZE:
+                    out = "%s(0x%x, %s)" % (expr.op, expr.args[0].size, out)
+                else:
+                    out = "bignum_%s(%s, %d)" % (expr.op, out, arg.size)
+                return out
+
             elif expr.op == '!':
-                return "(~ %s)&%s" % (
-                    self.from_expr(expr.args[0]),
-                    self._size2mask(expr.args[0].size),
-                )
+                arg = expr.args[0]
+                out = self.from_expr(arg)
+                if expr.size <= self.NATIVE_INT_MAX_SIZE:
+                    out = "(~ %s)&%s" % (out, self._size2mask(arg.size))
+                else:
+                    out = "bignum_not(%s)" % out
+                    out = "bignum_mask(%s, expr.size)" % out
+                return out
+
             elif expr.op in [
                     "ftan", "frndint", "f2xm1", "fsin", "fsqrt", "fabs", "fcos",
                     "fchs",
@@ -105,12 +152,23 @@ class TranslatorC(Translator):
                 )
             elif (expr.op.startswith("access_")    or
                   expr.op.startswith("load_")      or
-                  expr.op.startswith("fxam_c")     or
-                  expr.op in ["-"]):
-                return "%s(%s)" % (
-                    expr.op,
-                    self.from_expr(expr.args[0])
-                )
+                  expr.op.startswith("fxam_c")):
+                arg = expr.args[0]
+                out = self.from_expr(arg)
+                out = "%s(%s)" % (expr.op, out)
+                return out
+
+            elif expr.op == "-":
+                arg = expr.args[0]
+                out = self.from_expr(arg)
+                if arg.size <= self.NATIVE_INT_MAX_SIZE:
+                    out = "(%s(%s))" % (expr.op, out)
+                    out = "(%s&%s)" % (out, self._size2mask(arg.size))
+                else:
+                    out = "bignum_sub(bignum_from_uint64(0), %s)" % out
+                    out = "bignum_mask(%s, %d)"% (out, expr.size)
+                return out
+
             elif expr.op.startswith("fpround_"):
                 return "%s_fp%d(%s)" % (
                     expr.op,
@@ -170,20 +228,52 @@ class TranslatorC(Translator):
                     self._size2mask(expr.args[1].size),
                 )
             elif expr.op in self.dct_shift:
-                return 'SHIFT_%s(%d, %s, %s)' % (
-                    self.dct_shift[expr.op].upper(),
-                    expr.args[0].size,
-                    self.from_expr(expr.args[0]),
-                    self.from_expr(expr.args[1])
-                )
-            elif expr.is_associative() or expr.op in ["%", "/"]:
-                oper = ['(%s&%s)' % (
-                    self.from_expr(arg),
-                    self._size2mask(arg.size)
-                )
+                arg0 = self.from_expr(expr.args[0])
+                arg1 = self.from_expr(expr.args[1])
+                if expr.size <= self.NATIVE_INT_MAX_SIZE:
+                    out = 'SHIFT_%s(%d, %s, %s)' % (
+                        self.dct_shift[expr.op].upper(),
+                        expr.args[0].size,
+                        self.from_expr(expr.args[0]),
+                        self.from_expr(expr.args[1])
+                    )
+                else:
+                    op = {
+                        "<<": "lshift",
+                        ">>": "rshift",
+                        "a>>": "a_rshift"
+                    }
+                    out = "bignum_%s(%s, bignum_to_uint64(%s))" % (
+                        op[expr.op], arg0, arg1
+                    )
+                    out = "bignum_mask(%s, %d)"% (out, expr.size)
+                return out
+
+            elif expr.is_associative():
+                args = [self.from_expr(arg)
                         for arg in expr.args]
-                oper = str(expr.op).join(oper)
-                return "((%s)&%s)" % (oper, self._size2mask(expr.args[0].size))
+                if expr.size <= self.NATIVE_INT_MAX_SIZE:
+                    out = (" %s " % expr.op).join(args)
+                    out = "((%s)&%s)" % (out, self._size2mask(expr.size))
+                else:
+                    op_to_bn_func = {
+                    "+": "add",
+                    "*": "mul",
+                    "|": "or",
+                    "^": "xor",
+                    "&": "and",
+                    }
+                    args = list(expr.args)
+                    out = self.from_expr(args.pop())
+                    while args:
+                        out = 'bignum_mask(bignum_%s(%s, %s), %d)' % (
+                            op_to_bn_func[expr.op],
+                            out,
+                            self.from_expr(args.pop()),
+                            expr.size
+                    )
+                return out
+
             elif expr.op in ['-']:
                 return '(((%s&%s) %s (%s&%s))&%s)' % (
                     self.from_expr(expr.args[0]),
@@ -194,13 +284,27 @@ class TranslatorC(Translator):
                     self._size2mask(expr.args[0].size)
                 )
             elif expr.op in self.dct_rot:
-                return '(%s(%s, %s, %s) &%s)' % (
-                    self.dct_rot[expr.op],
-                    expr.args[0].size,
-                    self.from_expr(expr.args[0]),
-                    self.from_expr(expr.args[1]),
-                    self._size2mask(expr.args[0].size),
-                )
+                arg0 = self.from_expr(expr.args[0])
+                arg1 = self.from_expr(expr.args[1])
+                if expr.size <= self.NATIVE_INT_MAX_SIZE:
+                    out = '(%s(%s, %s, %s) &%s)' % (
+                        self.dct_rot[expr.op],
+                        expr.args[0].size,
+                        self.from_expr(expr.args[0]),
+                        self.from_expr(expr.args[1]),
+                        self._size2mask(expr.args[0].size),
+                    )
+                else:
+                    op = {
+                        ">>>": "ror",
+                        "<<<": "rol"
+                    }
+                    out = "bignum_%d(%s, %d, bignum_to_uint64(%s))" % (
+                        op[expr.op], arg0, expr.size, arg1
+                    )
+                    out = "bignum_mask(%s, %d)"% (out, expr.size)
+                return out
+
             elif expr.op == 'x86_cpuid':
                 return "%s(%s, %s)" % (expr.op,
                                        self.from_expr(expr.args[0]),
@@ -208,24 +312,62 @@ class TranslatorC(Translator):
             elif (expr.op.startswith("fcom")  or
                   expr.op in ["fadd", "fsub", "fdiv", 'fmul', "fscale",
                               "fprem", "fprem_lsb", "fyl2x", "fpatan"]):
-                return "fpu_%s%d(%s, %s)" % (
-                    expr.op,
-                    expr.size,
-                    self.from_expr(expr.args[0]),
-                    self.from_expr(expr.args[1]),
-                )
+                arg0 = self.from_expr(expr.args[0])
+                arg1 = self.from_expr(expr.args[1])
+                if not expr.args[0].size <= self.NATIVE_INT_MAX_SIZE:
+                    raise ValueError("Bad semantic: fpu do operations do not support such size")
+                out = "fpu_%s%d(%s, %s)" % (expr.op, expr.size, arg0, arg1)
+                return out
+
             elif expr.op == "segm":
                 return "segm2addr(jitcpu, %s, %s)" % (
                     self.from_expr(expr.args[0]),
                     self.from_expr(expr.args[1])
                 )
-            elif expr.op in ['udiv', 'umod', 'idiv', 'imod']:
-                return '%s%d(%s, %s)' % (
-                    expr.op,
-                    expr.args[0].size,
-                    self.from_expr(expr.args[0]),
-                    self.from_expr(expr.args[1])
-                )
+
+            elif expr.op in ['udiv', 'umod']:
+                arg0 = self.from_expr(expr.args[0])
+                arg1 = self.from_expr(expr.args[1])
+
+                if expr.size <= self.NATIVE_INT_MAX_SIZE:
+                    out = '%s%d(%s, %s)' % (
+                        expr.op,
+                        expr.args[0].size,
+                        self.from_expr(expr.args[0]),
+                        self.from_expr(expr.args[1])
+                    )
+                else:
+                    out = "bignum_%s(%s, %s)" % (
+                        expr.op,
+                        self.from_expr(expr.args[0]),
+                        self.from_expr(expr.args[1])
+                    )
+                    out = "bignum_mask(%s, %d)"% (out, expr.size)
+                return out
+
+
+
+            elif expr.op in ['idiv', 'imod']:
+                arg0 = self.from_expr(expr.args[0])
+                arg1 = self.from_expr(expr.args[1])
+
+                if expr.size <= self.NATIVE_INT_MAX_SIZE:
+                    out = '%s%d(%s, %s)' % (
+                        expr.op,
+                        expr.args[0].size,
+                        self.from_expr(expr.args[0]),
+                        self.from_expr(expr.args[1])
+                    )
+                else:
+                    out = "bignum_%s(%s, %s, %d)" % (
+                        expr.op,
+                        self.from_expr(expr.args[0]),
+                        self.from_expr(expr.args[1]),
+                        expr.size
+                    )
+                    out = "bignum_mask(%s, %d)"% (out, expr.size)
+                return out
+
             elif expr.op in ["bcdadd", "bcdadd_cf"]:
                 return "%s_%d(%s, %s)" % (
                     expr.op, expr.args[0].size,
@@ -250,36 +392,64 @@ class TranslatorC(Translator):
             raise NotImplementedError('Unknown op: %s' % expr.op)
 
     def from_ExprSlice(self, expr):
-        # XXX check mask for 64 bit & 32 bit compat
-        return "((%s>>%d) &%s)" % (
-            self.from_expr(expr.arg),
-            expr.start,
-            self._size2mask(expr.stop - expr.start)
-        )
+        out = self.from_expr(expr.arg)
+        if expr.arg.size <= self.NATIVE_INT_MAX_SIZE:
+            # XXX check mask for 64 bit & 32 bit compat
+            out = "((%s>>%d) &%s)" % (
+                out, expr.start,
+                self._size2mask(expr.stop - expr.start)
+            )
+        else:
+            out = "bignum_rshift(%s, %d)" % (out, expr.start)
+            out = "bignum_mask(%s, %d)" % (out, expr.stop - expr.start)
+
+            if expr.size <= self.NATIVE_INT_MAX_SIZE:
+                # Convert bignum to int
+                out = "bignum_to_uint64(%s)" % out
+        return out
 
     def from_ExprCompose(self, expr):
-        out = []
-        # XXX check mask for 64 bit & 32 bit compat
-        if expr.size in [8, 16, 32, 64, 128]:
-            size = expr.size
+        if expr.size <= self.NATIVE_INT_MAX_SIZE:
+
+            out = []
+            # XXX check mask for 64 bit & 32 bit compat
+            if expr.size in [8, 16, 32, 64, 128]:
+                size = expr.size
+            else:
+                # Uncommon expression size, use at least uint8
+                size = max(expr.size, 8)
+                next_power = 1
+                while next_power <= size:
+                    next_power <<= 1
+                size = next_power
+
+            dst_cast = "uint%d_t" % size
+            for index, arg in expr.iter_args():
+                out.append("(((%s)(%s & %s)) << %d)" % (
+                    dst_cast,
+                    self.from_expr(arg),
+                    self._size2mask(arg.size),
+                    index)
+                )
+            out = ' | '.join(out)
+            return '(' + out + ')'
         else:
-            # Uncommon expression size, use at least uint8
-            size = max(expr.size, 8)
-            next_power = 1
-            while next_power <= size:
-                next_power <<= 1
-            size = next_power
-
-        dst_cast = "uint%d_t" % size
-        for index, arg in expr.iter_args():
-            out.append("(((%s)(%s & %s)) << %d)" % (
-                dst_cast,
-                self.from_expr(arg),
-                self._size2mask(arg.size),
-                index)
-            )
-        out = ' | '.join(out)
-        return '(' + out + ')'
+            # Convert all parts to bignum
+            args = []
+            for index, arg in expr.iter_args():
+                arg_str = self.from_expr(arg)
+                if arg.size <= self.NATIVE_INT_MAX_SIZE:
+                    arg_str = '((%s) & %s)' % (arg_str, self._size2mask(arg.size))
+                    arg_str = 'bignum_from_uint64(%s)' % arg_str
+                else:
+                    arg_str = 'bignum_mask(%s, %d)' % (arg_str, arg.size)
+                arg_str = 'bignum_lshift(%s, %d)' % (arg_str, index)
+                args.append(arg_str)
+            out = args.pop()
+            while args:
+                arg = args.pop()
+                out = "bignum_or(%s, %s)" % (out, arg)
+            return out
 
 
 # Register the class
diff --git a/miasm2/jitter/JitCore.c b/miasm2/jitter/JitCore.c
index 496ec8e1..1b9790d8 100644
--- a/miasm2/jitter/JitCore.c
+++ b/miasm2/jitter/JitCore.c
@@ -5,6 +5,7 @@
 #include "queue.h"
 #include "vm_mngr.h"
 #include "vm_mngr_py.h"
+#include "bn.h"
 #include "JitCore.h"
 
 
@@ -74,9 +75,85 @@ uint64_t __attribute__((weak)) MEM_LOOKUP_64(JitCpu* jitcpu, uint64_t addr)
 	return vm_MEM_LOOKUP_64(&(jitcpu->pyvm->vm_mngr), addr);
 }
 
-uint128_t __attribute__((weak)) MEM_LOOKUP_128(JitCpu* jitcpu, uint64_t addr)
+
+bn_t MEM_LOOKUP_BN_BN(JitCpu* jitcpu, int size, bn_t addr)
+{
+	uint64_t ptr;
+	int i;
+	uint8_t tmp;
+	bn_t val = bignum_from_int(0);
+
+	ptr = bignum_to_uint64(addr);
+
+
+	for (i=0; i < size; i += 8) {
+		tmp = vm_MEM_LOOKUP_08(&((VmMngr*)jitcpu->pyvm)->vm_mngr, ptr);
+		ptr += 1;
+		val = bignum_or(val, bignum_lshift(bignum_from_int(tmp), i));
+	}
+
+	return val;
+}
+
+
+uint64_t MEM_LOOKUP_BN_INT(JitCpu* jitcpu, int size, bn_t addr)
+{
+	uint64_t ptr;
+	uint64_t val = 0;
+
+	ptr = bignum_to_uint64(addr);
+
+	switch (size) {
+		case 8:
+			val = vm_MEM_LOOKUP_08(&(jitcpu->pyvm->vm_mngr), ptr);
+			break;
+		case 16:
+			val = vm_MEM_LOOKUP_16(&(jitcpu->pyvm->vm_mngr), ptr);
+			break;
+		case 32:
+			val = vm_MEM_LOOKUP_32(&(jitcpu->pyvm->vm_mngr), ptr);
+			break;
+		case 64:
+			val = vm_MEM_LOOKUP_64(&(jitcpu->pyvm->vm_mngr), ptr);
+			break;
+		default:
+			fprintf(stderr, "Error: bad READ size %d\n", size);
+			exit(-1);
+			break;
+	}
+
+	return val;
+}
+
+
+
+bn_t MEM_LOOKUP_INT_BN(JitCpu* jitcpu, int size, uint64_t addr)
+{
+	int i;
+	uint8_t tmp;
+	bn_t val = bignum_from_int(0);
+
+	for (i=0; i < size; i += 8) {
+		tmp = vm_MEM_LOOKUP_08(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr);
+		addr += 1;
+		val = bignum_or(val, bignum_lshift(bignum_from_int(tmp), i));
+	}
+
+	return val;
+}
+
+
+void MEM_LOOKUP_INT_BN_TO_PTR(JitCpu* jitcpu, int size, uint64_t addr, char* ptr)
 {
-	return vm_MEM_LOOKUP_128(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr);
+	bn_t ret;
+
+	if (size % 8) {
+		fprintf(stderr, "Bad size %d\n", size);
+		exit(-1);
+	}
+
+	ret = MEM_LOOKUP_INT_BN(jitcpu, size, addr);
+	memcpy(ptr, (char*)&ret, size / 8);
 }
 
 void __attribute__((weak)) MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src)
@@ -99,11 +176,78 @@ void __attribute__((weak)) MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t
 	vm_MEM_WRITE_64(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src);
 }
 
-void __attribute__((weak)) MEM_WRITE_128(JitCpu* jitcpu, uint64_t addr, uint128_t src)
+
+void MEM_WRITE_BN_BN(JitCpu* jitcpu, int size, bn_t addr, bn_t src)
+{
+	uint64_t ptr;
+	int val;
+	int i;
+
+	ptr = bignum_to_uint64(addr);
+	for (i=0; i < size; i += 8) {
+		val = bignum_to_uint64(src) & 0xFF;
+		vm_MEM_WRITE_08(&((VmMngr*)jitcpu->pyvm)->vm_mngr, ptr, val);
+		ptr += 1;
+		src = bignum_rshift(src, 8);
+	}
+}
+
+
+void MEM_WRITE_BN_INT(JitCpu* jitcpu, int size, bn_t addr, uint64_t src)
+{
+	uint64_t ptr;
+	ptr = bignum_to_uint64(addr);
+
+	switch (size) {
+		case 8:
+			vm_MEM_WRITE_08(&((VmMngr*)jitcpu->pyvm)->vm_mngr, ptr, src);
+			break;
+		case 16:
+			vm_MEM_WRITE_16(&((VmMngr*)jitcpu->pyvm)->vm_mngr, ptr, src);
+			break;
+		case 32:
+			vm_MEM_WRITE_32(&((VmMngr*)jitcpu->pyvm)->vm_mngr, ptr, src);
+			break;
+		case 64:
+			vm_MEM_WRITE_64(&((VmMngr*)jitcpu->pyvm)->vm_mngr, ptr, src);
+			break;
+		default:
+			fprintf(stderr, "Error: bad write size %d\n", size);
+			exit(-1);
+			break;
+	}
+}
+
+void MEM_WRITE_INT_BN(JitCpu* jitcpu, int size, uint64_t addr, bn_t src)
 {
-	vm_MEM_WRITE_128(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src);
+	int val;
+	int i;
+
+	for (i=0; i < size; i += 8) {
+		val = bignum_to_uint64(src) & 0xFF;
+		vm_MEM_WRITE_08(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, val);
+		addr += 1;
+		src = bignum_rshift(src, 8);
+	}
 }
 
+
+void MEM_WRITE_INT_BN_FROM_PTR(JitCpu* jitcpu, int size, uint64_t addr, char* ptr)
+{
+	bn_t val;
+
+	if (size % 8) {
+		fprintf(stderr, "Bad size %d\n", size);
+		exit(-1);
+	}
+
+	val = bignum_from_int(0);
+	memcpy(&val, ptr, size / 8);
+	MEM_WRITE_INT_BN(jitcpu, size, addr, val);
+}
+
+
+
 PyObject* __attribute__((weak)) vm_get_mem(JitCpu *self, PyObject* args)
 {
        PyObject *py_addr;
diff --git a/miasm2/jitter/JitCore.h b/miasm2/jitter/JitCore.h
index c703178d..dfa67b6b 100644
--- a/miasm2/jitter/JitCore.h
+++ b/miasm2/jitter/JitCore.h
@@ -1,10 +1,11 @@
 #ifndef JITCORE_H
 #define JITCORE_H
 
+
+
 #define RAISE(errtype, msg) {PyObject* p; p = PyErr_Format( errtype, msg ); return p;}
 #define RAISE_ret0(errtype, msg) {PyObject* p; p = PyErr_Format( errtype, msg ); return 0;}
 
-#define uint128_t __uint128_t
 
 #define PyGetInt(item, value)						\
 	if (PyInt_Check(item)){						\
@@ -31,24 +32,66 @@
 	}								\
 
 
-#define getset_reg_u128(regname)						\
+#define getset_reg_bn(regname)						\
 	static PyObject *JitCpu_get_ ## regname  (JitCpu *self, void *closure) \
-	{ \
-		return _PyLong_FromByteArray((const unsigned char*) &(((vm_cpu_t*)(self->cpu))->  regname  ), sizeof(uint128_t), /*little_endian*/ 1, /*is_signed*/ 0); \
+	{								\
+		bn_t bn;						\
+		PyObject* py_long;					\
+		PyObject* py_tmp;					\
+		PyObject* cst_32;					\
+		uint64_t tmp;						\
+		py_long = PyLong_FromLong(0);				\
+		cst_32 = PyLong_FromLong(32);				\
+		bn = ((vm_cpu_t*)(self->cpu))->  regname;		\
+		while (!bignum_is_zero(bn)) {				\
+			tmp = bignum_to_uint64(bignum_mask(bn, 32)) & 0xffffffff; \
+			bn = bignum_rshift(bn, 32);			\
+			py_tmp = PyLong_FromLong(tmp);			\
+			py_long = PyObject_CallMethod(py_long, "__lshift__", "O", cst_32); \
+			py_long = PyObject_CallMethod(py_long, "__add__", "O", py_tmp);	\
+		}							\
+		return py_long;						\
 	}								\
+									\
 	static int JitCpu_set_ ## regname  (JitCpu *self, PyObject *value, void *closure) \
 	{								\
-		uint128_t val = 0;					\
-		int i;                                                  \
-		unsigned char bytes[sizeof(uint128_t)];			\
-		_PyLong_AsByteArray((PyLongObject*)value, bytes, sizeof(uint128_t), /*little_endian*/ 1, /*is_signed*/ 0); \
-		for (i = 0; i < sizeof(uint128_t); i++) {               \
-			val |= (uint128_t) bytes[i] << (8 * i);         \
-		}                                                       \
-		((vm_cpu_t*)(self->cpu))->  regname   = val;		\
+		bn_t bn;						\
+		int j;							\
+		PyObject* py_long = value;				\
+		PyObject* py_tmp;					\
+		PyObject* cst_32;					\
+		PyObject* cst_ffffffff;					\
+		uint64_t tmp;						\
+									\
+		/* Ensure py_long is a PyLong */			\
+		if (PyInt_Check(py_long)){				\
+			tmp = (uint64_t)PyInt_AsLong(py_long);		\
+			py_long = PyLong_FromLong(tmp);			\
+		} else if (PyLong_Check(py_long)){			\
+			/* Already PyLong */				\
+		}							\
+		else{							\
+			PyErr_SetString(PyExc_TypeError, "Arg must be int"); \
+			return -1;					\
+		}							\
+									\
+		cst_ffffffff = PyLong_FromLong(0xffffffff);		\
+		cst_32 = PyLong_FromLong(32);				\
+		bn = bignum_from_int(0);				\
+									\
+		for (j = 0; j < BN_BYTE_SIZE; j += 4) {			\
+			py_tmp = PyObject_CallMethod(py_long, "__and__", "O", cst_ffffffff); \
+			tmp = PyLong_AsUnsignedLongMask(py_tmp);	\
+			bn = bignum_lshift(bn, 32);			\
+			bn = bignum_or(bn, bignum_from_uint64(tmp));	\
+			py_long = PyObject_CallMethod(py_long, "__rshift__", "O", cst_32); \
+		}							\
+									\
+		((vm_cpu_t*)(self->cpu))->  regname   = bn;		\
 		return 0;						\
 	}
 
+
 #define getset_reg_u64(regname)						\
 	static PyObject *JitCpu_get_ ## regname  (JitCpu *self, void *closure) \
 	{								\
@@ -97,6 +140,27 @@
 	} while(0);
 
 
+#define get_reg_bn(reg)  do {						\
+		bn_t bn;						\
+		PyObject* py_long;					\
+		PyObject* py_tmp;					\
+		PyObject* cst_32;					\
+		uint64_t tmp;						\
+		py_long = PyLong_FromLong(0);				\
+		cst_32 = PyLong_FromLong(32);				\
+		bn = ((vm_cpu_t*)(self->cpu))->  reg;			\
+		while (!bignum_is_zero(bn)) {				\
+			tmp = bignum_to_uint64(bignum_mask(bn, 32)) & 0xffffffff; \
+			bn = bignum_rshift(bn, 32);			\
+			py_tmp = PyLong_FromLong(tmp);			\
+			py_long = PyObject_CallMethod(py_long, "__lshift__", "O", cst_32); \
+			py_long = PyObject_CallMethod(py_long, "__add__", "O", py_tmp);	\
+		}							\
+		PyDict_SetItemString(dict, #reg, py_long);		\
+		Py_DECREF(py_long);					\
+	} while(0);
+
+
 #define get_reg_off(reg)  do {						\
 		o = PyLong_FromUnsignedLongLong((uint64_t)offsetof(vm_cpu_t, reg)); \
 		PyDict_SetItemString(dict, #reg, o);			\
@@ -104,6 +168,8 @@
 	} while(0);
 
 
+
+
 typedef struct {
 	uint8_t is_local;
 	uint64_t address;
@@ -120,6 +186,7 @@ typedef struct {
 typedef struct _reg_dict{
     char* name;
     size_t offset;
+    size_t size;
 } reg_dict;
 
 
@@ -140,14 +207,27 @@ uint8_t MEM_LOOKUP_08(JitCpu* jitcpu, uint64_t addr);
 uint16_t MEM_LOOKUP_16(JitCpu* jitcpu, uint64_t addr);
 uint32_t MEM_LOOKUP_32(JitCpu* jitcpu, uint64_t addr);
 uint64_t MEM_LOOKUP_64(JitCpu* jitcpu, uint64_t addr);
-uint128_t MEM_LOOKUP_128(JitCpu* jitcpu, uint64_t addr);
+
+bn_t MEM_LOOKUP_BN_BN(JitCpu* jitcpu, int size, bn_t addr);
+bn_t MEM_LOOKUP_INT_BN(JitCpu* jitcpu, int size, uint64_t addr);
+
+uint64_t MEM_LOOKUP_BN_INT(JitCpu* jitcpu, int size, bn_t addr);
+
 void MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src);
 void MEM_WRITE_16(JitCpu* jitcpu, uint64_t addr, uint16_t src);
 void MEM_WRITE_32(JitCpu* jitcpu, uint64_t addr, uint32_t src);
 void MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src);
-void MEM_WRITE_128(JitCpu* jitcpu, uint64_t addr, uint128_t src);
+
+void MEM_WRITE_BN_BN(JitCpu* jitcpu, int size, bn_t addr, bn_t src);
+void MEM_WRITE_BN_INT(JitCpu* jitcpu, int size, bn_t addr, uint64_t src);
+void MEM_WRITE_INT_BN(JitCpu* jitcpu, int size, uint64_t addr, bn_t src);
+
+
 PyObject* vm_get_mem(JitCpu *self, PyObject* args);
 
+void MEM_LOOKUP_INT_BN_TO_PTR(JitCpu* jitcpu, int size, uint64_t addr, char* ptr);
+void MEM_WRITE_INT_BN_FROM_PTR(JitCpu* jitcpu, int size, uint64_t addr, char* ptr);
+
 
 
 #define VM_exception_flag (jitcpu->pyvm->vm_mngr.exception_flags)
diff --git a/miasm2/jitter/Jitllvm.c b/miasm2/jitter/Jitllvm.c
index 6ecbd483..bb500d2e 100644
--- a/miasm2/jitter/Jitllvm.c
+++ b/miasm2/jitter/Jitllvm.c
@@ -6,6 +6,7 @@
 #include "queue.h"
 #include "vm_mngr.h"
 #include "vm_mngr_py.h"
+#include "bn.h"
 #include "JitCore.h"
 // Needed to get the JitCpu.cpu offset, arch independent
 #include "arch/JitCore_x86.h"
diff --git a/miasm2/jitter/arch/JitCore_aarch64.c b/miasm2/jitter/arch/JitCore_aarch64.c
index a8502ef9..f5977308 100644
--- a/miasm2/jitter/arch/JitCore_aarch64.c
+++ b/miasm2/jitter/arch/JitCore_aarch64.c
@@ -5,6 +5,7 @@
 #include "../queue.h"
 #include "../vm_mngr.h"
 #include "../vm_mngr_py.h"
+#include "../bn.h"
 #include "../JitCore.h"
 #include "../op_semantics.h"
 #include "JitCore_aarch64.h"
diff --git a/miasm2/jitter/arch/JitCore_arm.c b/miasm2/jitter/arch/JitCore_arm.c
index 8a09ba6c..c71db0c6 100644
--- a/miasm2/jitter/arch/JitCore_arm.c
+++ b/miasm2/jitter/arch/JitCore_arm.c
@@ -5,6 +5,7 @@
 #include "../queue.h"
 #include "../vm_mngr.h"
 #include "../vm_mngr_py.h"
+#include "../bn.h"
 #include "../JitCore.h"
 #include "../op_semantics.h"
 #include "JitCore_arm.h"
@@ -380,9 +381,9 @@ static PyGetSetDef JitCpu_getseters[] = {
     {"cf", (getter)JitCpu_get_cf, (setter)JitCpu_set_cf, "cf", NULL},
 
     {"ge0", (getter)JitCpu_get_ge0, (setter)JitCpu_set_ge0, "ge0", NULL},
-    {"ge1", (getter)JitCpu_get_ge1, (setter)JitCpu_set_ge0, "ge1", NULL},
-    {"ge2", (getter)JitCpu_get_ge2, (setter)JitCpu_set_ge0, "ge2", NULL},
-    {"ge3", (getter)JitCpu_get_ge3, (setter)JitCpu_set_ge0, "ge3", NULL},
+    {"ge1", (getter)JitCpu_get_ge1, (setter)JitCpu_set_ge1, "ge1", NULL},
+    {"ge2", (getter)JitCpu_get_ge2, (setter)JitCpu_set_ge2, "ge2", NULL},
+    {"ge3", (getter)JitCpu_get_ge3, (setter)JitCpu_set_ge3, "ge3", NULL},
 
     {NULL}  /* Sentinel */
 };
diff --git a/miasm2/jitter/arch/JitCore_mep.c b/miasm2/jitter/arch/JitCore_mep.c
index e63fa97b..dff65dd5 100644
--- a/miasm2/jitter/arch/JitCore_mep.c
+++ b/miasm2/jitter/arch/JitCore_mep.c
@@ -8,6 +8,7 @@
 #include "../queue.h"
 #include "../vm_mngr.h"
 #include "../vm_mngr_py.h"
+#include "../bn.h"
 #include "../JitCore.h"
 #include "JitCore_mep.h"
 
diff --git a/miasm2/jitter/arch/JitCore_mips32.c b/miasm2/jitter/arch/JitCore_mips32.c
index 4ebfbec8..a1bf44f5 100644
--- a/miasm2/jitter/arch/JitCore_mips32.c
+++ b/miasm2/jitter/arch/JitCore_mips32.c
@@ -5,6 +5,7 @@
 #include "../queue.h"
 #include "../vm_mngr.h"
 #include "../vm_mngr_py.h"
+#include "../bn.h"
 #include "../JitCore.h"
 #include "../op_semantics.h"
 #include "JitCore_mips32.h"
diff --git a/miasm2/jitter/arch/JitCore_msp430.c b/miasm2/jitter/arch/JitCore_msp430.c
index 7fe41413..7072a380 100644
--- a/miasm2/jitter/arch/JitCore_msp430.c
+++ b/miasm2/jitter/arch/JitCore_msp430.c
@@ -5,6 +5,7 @@
 #include "../queue.h"
 #include "../vm_mngr.h"
 #include "../vm_mngr_py.h"
+#include "../bn.h"
 #include "../JitCore.h"
 #include "JitCore_msp430.h"
 
diff --git a/miasm2/jitter/arch/JitCore_ppc32.c b/miasm2/jitter/arch/JitCore_ppc32.c
index 616e7cfd..3acf769a 100644
--- a/miasm2/jitter/arch/JitCore_ppc32.c
+++ b/miasm2/jitter/arch/JitCore_ppc32.c
@@ -5,6 +5,7 @@
 #include "../queue.h"
 #include "../vm_mngr.h"
 #include "../vm_mngr_py.h"
+#include "../bn.h"
 #include "../JitCore.h"
 #include "JitCore_ppc32.h"
 
diff --git a/miasm2/jitter/arch/JitCore_x86.c b/miasm2/jitter/arch/JitCore_x86.c
index eda6e6e5..cc3f8573 100644
--- a/miasm2/jitter/arch/JitCore_x86.c
+++ b/miasm2/jitter/arch/JitCore_x86.c
@@ -5,78 +5,79 @@
 #include "../queue.h"
 #include "../vm_mngr.h"
 #include "../vm_mngr_py.h"
+#include "../bn.h"
 #include "../JitCore.h"
 #include "../op_semantics.h"
 #include "JitCore_x86.h"
 
-
-
-reg_dict gpreg_dict[] = { {.name = "RAX", .offset = offsetof(vm_cpu_t, RAX)},
-			  {.name = "RBX", .offset = offsetof(vm_cpu_t, RBX)},
-			  {.name = "RCX", .offset = offsetof(vm_cpu_t, RCX)},
-			  {.name = "RDX", .offset = offsetof(vm_cpu_t, RDX)},
-			  {.name = "RSI", .offset = offsetof(vm_cpu_t, RSI)},
-			  {.name = "RDI", .offset = offsetof(vm_cpu_t, RDI)},
-			  {.name = "RSP", .offset = offsetof(vm_cpu_t, RSP)},
-			  {.name = "RBP", .offset = offsetof(vm_cpu_t, RBP)},
-
-			  {.name = "R8", .offset = offsetof(vm_cpu_t, R8)},
-			  {.name = "R9", .offset = offsetof(vm_cpu_t, R9)},
-			  {.name = "R10", .offset = offsetof(vm_cpu_t, R10)},
-			  {.name = "R11", .offset = offsetof(vm_cpu_t, R11)},
-			  {.name = "R12", .offset = offsetof(vm_cpu_t, R12)},
-			  {.name = "R13", .offset = offsetof(vm_cpu_t, R13)},
-			  {.name = "R14", .offset = offsetof(vm_cpu_t, R14)},
-			  {.name = "R15", .offset = offsetof(vm_cpu_t, R15)},
-
-			  {.name = "RIP", .offset = offsetof(vm_cpu_t, RIP)},
-
-			  {.name = "zf", .offset = offsetof(vm_cpu_t, zf)},
-			  {.name = "nf", .offset = offsetof(vm_cpu_t, nf)},
-			  {.name = "pf", .offset = offsetof(vm_cpu_t, pf)},
-			  {.name = "of", .offset = offsetof(vm_cpu_t, of)},
-			  {.name = "cf", .offset = offsetof(vm_cpu_t, cf)},
-			  {.name = "af", .offset = offsetof(vm_cpu_t, af)},
-			  {.name = "df", .offset = offsetof(vm_cpu_t, df)},
-
-			  {.name = "ES", .offset = offsetof(vm_cpu_t, ES)},
-			  {.name = "CS", .offset = offsetof(vm_cpu_t, CS)},
-			  {.name = "SS", .offset = offsetof(vm_cpu_t, SS)},
-			  {.name = "DS", .offset = offsetof(vm_cpu_t, DS)},
-			  {.name = "FS", .offset = offsetof(vm_cpu_t, FS)},
-			  {.name = "GS", .offset = offsetof(vm_cpu_t, GS)},
-
-			  {.name = "MM0", .offset = offsetof(vm_cpu_t, MM0)},
-			  {.name = "MM1", .offset = offsetof(vm_cpu_t, MM1)},
-			  {.name = "MM2", .offset = offsetof(vm_cpu_t, MM2)},
-			  {.name = "MM3", .offset = offsetof(vm_cpu_t, MM3)},
-			  {.name = "MM4", .offset = offsetof(vm_cpu_t, MM4)},
-			  {.name = "MM5", .offset = offsetof(vm_cpu_t, MM5)},
-			  {.name = "MM6", .offset = offsetof(vm_cpu_t, MM6)},
-			  {.name = "MM7", .offset = offsetof(vm_cpu_t, MM7)},
-
-			  {.name = "XMM0", .offset = offsetof(vm_cpu_t, XMM0)},
-			  {.name = "XMM1", .offset = offsetof(vm_cpu_t, XMM1)},
-			  {.name = "XMM2", .offset = offsetof(vm_cpu_t, XMM2)},
-			  {.name = "XMM3", .offset = offsetof(vm_cpu_t, XMM3)},
-			  {.name = "XMM4", .offset = offsetof(vm_cpu_t, XMM4)},
-			  {.name = "XMM5", .offset = offsetof(vm_cpu_t, XMM5)},
-			  {.name = "XMM6", .offset = offsetof(vm_cpu_t, XMM6)},
-			  {.name = "XMM7", .offset = offsetof(vm_cpu_t, XMM7)},
-			  {.name = "XMM8", .offset = offsetof(vm_cpu_t, XMM8)},
-			  {.name = "XMM9", .offset = offsetof(vm_cpu_t, XMM9)},
-			  {.name = "XMM10", .offset = offsetof(vm_cpu_t, XMM10)},
-			  {.name = "XMM11", .offset = offsetof(vm_cpu_t, XMM11)},
-			  {.name = "XMM12", .offset = offsetof(vm_cpu_t, XMM12)},
-			  {.name = "XMM13", .offset = offsetof(vm_cpu_t, XMM13)},
-			  {.name = "XMM14", .offset = offsetof(vm_cpu_t, XMM14)},
-			  {.name = "XMM15", .offset = offsetof(vm_cpu_t, XMM15)},
-
-			  {.name = "tsc1", .offset = offsetof(vm_cpu_t, tsc1)},
-			  {.name = "tsc2", .offset = offsetof(vm_cpu_t, tsc2)},
-
-			  {.name = "exception_flags", .offset = offsetof(vm_cpu_t, exception_flags)},
-			  {.name = "interrupt_num", .offset = offsetof(vm_cpu_t, interrupt_num)},
+vm_cpu_t ref_arch_regs;
+
+reg_dict gpreg_dict[] = { {.name = "RAX", .offset = offsetof(vm_cpu_t, RAX), .size = 8*sizeof(ref_arch_regs.RAX)},
+			  {.name = "RBX", .offset = offsetof(vm_cpu_t, RBX), .size = 8*sizeof(ref_arch_regs.RBX)},
+			  {.name = "RCX", .offset = offsetof(vm_cpu_t, RCX), .size = 8*sizeof(ref_arch_regs.RCX)},
+			  {.name = "RDX", .offset = offsetof(vm_cpu_t, RDX), .size = 8*sizeof(ref_arch_regs.RDX)},
+			  {.name = "RSI", .offset = offsetof(vm_cpu_t, RSI), .size = 8*sizeof(ref_arch_regs.RSI)},
+			  {.name = "RDI", .offset = offsetof(vm_cpu_t, RDI), .size = 8*sizeof(ref_arch_regs.RDI)},
+			  {.name = "RSP", .offset = offsetof(vm_cpu_t, RSP), .size = 8*sizeof(ref_arch_regs.RSP)},
+			  {.name = "RBP", .offset = offsetof(vm_cpu_t, RBP), .size = 8*sizeof(ref_arch_regs.RBP)},
+
+			  {.name = "R8", .offset = offsetof(vm_cpu_t, R8), .size = 8*sizeof(ref_arch_regs.R8)},
+			  {.name = "R9", .offset = offsetof(vm_cpu_t, R9), .size = 8*sizeof(ref_arch_regs.R9)},
+			  {.name = "R10", .offset = offsetof(vm_cpu_t, R10), .size = 8*sizeof(ref_arch_regs.R10)},
+			  {.name = "R11", .offset = offsetof(vm_cpu_t, R11), .size = 8*sizeof(ref_arch_regs.R11)},
+			  {.name = "R12", .offset = offsetof(vm_cpu_t, R12), .size = 8*sizeof(ref_arch_regs.R12)},
+			  {.name = "R13", .offset = offsetof(vm_cpu_t, R13), .size = 8*sizeof(ref_arch_regs.R13)},
+			  {.name = "R14", .offset = offsetof(vm_cpu_t, R14), .size = 8*sizeof(ref_arch_regs.R14)},
+			  {.name = "R15", .offset = offsetof(vm_cpu_t, R15), .size = 8*sizeof(ref_arch_regs.R15)},
+
+			  {.name = "RIP", .offset = offsetof(vm_cpu_t, RIP), .size = 8*sizeof(ref_arch_regs.RIP)},
+
+			  {.name = "zf", .offset = offsetof(vm_cpu_t, zf), .size = 8*sizeof(ref_arch_regs.zf)},
+			  {.name = "nf", .offset = offsetof(vm_cpu_t, nf), .size = 8*sizeof(ref_arch_regs.nf)},
+			  {.name = "pf", .offset = offsetof(vm_cpu_t, pf), .size = 8*sizeof(ref_arch_regs.pf)},
+			  {.name = "of", .offset = offsetof(vm_cpu_t, of), .size = 8*sizeof(ref_arch_regs.of)},
+			  {.name = "cf", .offset = offsetof(vm_cpu_t, cf), .size = 8*sizeof(ref_arch_regs.cf)},
+			  {.name = "af", .offset = offsetof(vm_cpu_t, af), .size = 8*sizeof(ref_arch_regs.af)},
+			  {.name = "df", .offset = offsetof(vm_cpu_t, df), .size = 8*sizeof(ref_arch_regs.df)},
+
+			  {.name = "ES", .offset = offsetof(vm_cpu_t, ES), .size = 8*sizeof(ref_arch_regs.ES)},
+			  {.name = "CS", .offset = offsetof(vm_cpu_t, CS), .size = 8*sizeof(ref_arch_regs.CS)},
+			  {.name = "SS", .offset = offsetof(vm_cpu_t, SS), .size = 8*sizeof(ref_arch_regs.SS)},
+			  {.name = "DS", .offset = offsetof(vm_cpu_t, DS), .size = 8*sizeof(ref_arch_regs.DS)},
+			  {.name = "FS", .offset = offsetof(vm_cpu_t, FS), .size = 8*sizeof(ref_arch_regs.FS)},
+			  {.name = "GS", .offset = offsetof(vm_cpu_t, GS), .size = 8*sizeof(ref_arch_regs.GS)},
+
+			  {.name = "MM0", .offset = offsetof(vm_cpu_t, MM0), .size = 8*sizeof(ref_arch_regs.MM0)},
+			  {.name = "MM1", .offset = offsetof(vm_cpu_t, MM1), .size = 8*sizeof(ref_arch_regs.MM1)},
+			  {.name = "MM2", .offset = offsetof(vm_cpu_t, MM2), .size = 8*sizeof(ref_arch_regs.MM2)},
+			  {.name = "MM3", .offset = offsetof(vm_cpu_t, MM3), .size = 8*sizeof(ref_arch_regs.MM3)},
+			  {.name = "MM4", .offset = offsetof(vm_cpu_t, MM4), .size = 8*sizeof(ref_arch_regs.MM4)},
+			  {.name = "MM5", .offset = offsetof(vm_cpu_t, MM5), .size = 8*sizeof(ref_arch_regs.MM5)},
+			  {.name = "MM6", .offset = offsetof(vm_cpu_t, MM6), .size = 8*sizeof(ref_arch_regs.MM6)},
+			  {.name = "MM7", .offset = offsetof(vm_cpu_t, MM7), .size = 8*sizeof(ref_arch_regs.MM7)},
+
+			  {.name = "XMM0", .offset = offsetof(vm_cpu_t, XMM0), .size = 128},
+			  {.name = "XMM1", .offset = offsetof(vm_cpu_t, XMM1), .size = 128},
+			  {.name = "XMM2", .offset = offsetof(vm_cpu_t, XMM2), .size = 128},
+			  {.name = "XMM3", .offset = offsetof(vm_cpu_t, XMM3), .size = 128},
+			  {.name = "XMM4", .offset = offsetof(vm_cpu_t, XMM4), .size = 128},
+			  {.name = "XMM5", .offset = offsetof(vm_cpu_t, XMM5), .size = 128},
+			  {.name = "XMM6", .offset = offsetof(vm_cpu_t, XMM6), .size = 128},
+			  {.name = "XMM7", .offset = offsetof(vm_cpu_t, XMM7), .size = 128},
+			  {.name = "XMM8", .offset = offsetof(vm_cpu_t, XMM8), .size = 128},
+			  {.name = "XMM9", .offset = offsetof(vm_cpu_t, XMM9), .size = 128},
+			  {.name = "XMM10", .offset = offsetof(vm_cpu_t, XMM10), .size = 128},
+			  {.name = "XMM11", .offset = offsetof(vm_cpu_t, XMM11), .size = 128},
+			  {.name = "XMM12", .offset = offsetof(vm_cpu_t, XMM12), .size = 128},
+			  {.name = "XMM13", .offset = offsetof(vm_cpu_t, XMM13), .size = 128},
+			  {.name = "XMM14", .offset = offsetof(vm_cpu_t, XMM14), .size = 128},
+			  {.name = "XMM15", .offset = offsetof(vm_cpu_t, XMM15), .size = 128},
+
+			  {.name = "tsc1", .offset = offsetof(vm_cpu_t, tsc1), .size = 8*sizeof(ref_arch_regs.tsc1)},
+			  {.name = "tsc2", .offset = offsetof(vm_cpu_t, tsc2), .size = 8*sizeof(ref_arch_regs.tsc2)},
+
+			  {.name = "exception_flags", .offset = offsetof(vm_cpu_t, exception_flags), .size = 8*sizeof(ref_arch_regs.exception_flags)},
+			  {.name = "interrupt_num", .offset = offsetof(vm_cpu_t, interrupt_num), .size = 8*sizeof(ref_arch_regs.interrupt_num)},
 };
 
 
@@ -137,22 +138,22 @@ PyObject* cpu_get_gpreg(JitCpu* self)
     get_reg(MM6);
     get_reg(MM7);
 
-    get_reg(XMM0);
-    get_reg(XMM1);
-    get_reg(XMM2);
-    get_reg(XMM3);
-    get_reg(XMM4);
-    get_reg(XMM5);
-    get_reg(XMM6);
-    get_reg(XMM7);
-    get_reg(XMM8);
-    get_reg(XMM9);
-    get_reg(XMM10);
-    get_reg(XMM11);
-    get_reg(XMM12);
-    get_reg(XMM13);
-    get_reg(XMM14);
-    get_reg(XMM15);
+    get_reg_bn(XMM0);
+    get_reg_bn(XMM1);
+    get_reg_bn(XMM2);
+    get_reg_bn(XMM3);
+    get_reg_bn(XMM4);
+    get_reg_bn(XMM5);
+    get_reg_bn(XMM6);
+    get_reg_bn(XMM7);
+    get_reg_bn(XMM8);
+    get_reg_bn(XMM9);
+    get_reg_bn(XMM10);
+    get_reg_bn(XMM11);
+    get_reg_bn(XMM12);
+    get_reg_bn(XMM13);
+    get_reg_bn(XMM14);
+    get_reg_bn(XMM15);
 
     get_reg(tsc1);
     get_reg(tsc2);
@@ -180,14 +181,68 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args)
 	    if(!PyString_Check(d_key))
 		    RAISE(PyExc_TypeError, "key must be str");
 
-	    PyGetInt(d_value, val);
-
 	    found = 0;
 	    for (i=0; i < sizeof(gpreg_dict)/sizeof(reg_dict); i++){
 		    if (strcmp(PyString_AsString(d_key), gpreg_dict[i].name))
 			    continue;
-		    *((uint64_t*)(((char*)(self->cpu)) + gpreg_dict[i].offset)) = val;
 		    found = 1;
+		    switch (gpreg_dict[i].size) {
+			    case 8:
+				    PyGetInt(d_value, val);
+				    *((uint8_t*)(((char*)(self->cpu)) + gpreg_dict[i].offset)) = val;
+				    break;
+			    case 16:
+				    PyGetInt(d_value, val);
+				    *((uint16_t*)(((char*)(self->cpu)) + gpreg_dict[i].offset)) = val;
+				    break;
+			    case 32:
+				    PyGetInt(d_value, val);
+				    *((uint32_t*)(((char*)(self->cpu)) + gpreg_dict[i].offset)) = val;
+				    break;
+			    case 64:
+				    PyGetInt(d_value, val);
+				    *((uint64_t*)(((char*)(self->cpu)) + gpreg_dict[i].offset)) = val;
+				    break;
+			    case 128:
+				    {
+					    bn_t bn;
+					    int j;
+					    PyObject* py_long = d_value;
+					    PyObject* py_tmp;
+					    PyObject* cst_32;
+					    PyObject* cst_ffffffff;
+					    uint64_t tmp;
+
+					    /* Ensure py_long is a PyLong */
+					    if (PyInt_Check(py_long)){
+						    tmp = (uint64_t)PyInt_AsLong(py_long);
+						    py_long = PyLong_FromLong(tmp);
+					    } else if (PyLong_Check(py_long)){
+						    /* Already PyLong */
+					    }
+					    else{
+						    RAISE(PyExc_TypeError,"arg must be int");
+					    }
+
+
+
+					    cst_ffffffff = PyLong_FromLong(0xffffffff);
+					    cst_32 = PyLong_FromLong(32);
+					    bn = bignum_from_int(0);
+
+					    for (j = 0; j < BN_BYTE_SIZE; j += 4) {
+						    py_tmp = PyObject_CallMethod(py_long, "__and__", "O", cst_ffffffff);
+						    tmp = PyLong_AsUnsignedLongMask(py_tmp);
+						    bn = bignum_lshift(bn, 32);
+						    bn = bignum_or(bn, bignum_from_uint64(tmp));
+						    py_long = PyObject_CallMethod(py_long, "__rshift__", "O", cst_32);
+					    }
+
+
+					    *(bn_t*)(((char*)(self->cpu)) + gpreg_dict[i].offset) = bn;
+				    }
+				    break;
+		    }
 		    break;
 	    }
 
@@ -203,11 +258,9 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args)
 PyObject * cpu_init_regs(JitCpu* self)
 {
 	memset(self->cpu, 0, sizeof(vm_cpu_t));
-
 	((vm_cpu_t*)self->cpu)->tsc1 = 0x22222222;
 	((vm_cpu_t*)self->cpu)->tsc2 = 0x11111111;
 	((vm_cpu_t*)self->cpu)->i_f = 1;
-
 	Py_INCREF(Py_None);
 	return Py_None;
 
@@ -215,7 +268,6 @@ PyObject * cpu_init_regs(JitCpu* self)
 
 void dump_gpregs_16(vm_cpu_t* vmcpu)
 {
-
 	printf("EAX %.8"PRIX32" EBX %.8"PRIX32" ECX %.8"PRIX32" EDX %.8"PRIX32" ",
 	       (uint32_t)(vmcpu->RAX & 0xFFFFFFFF),
 	       (uint32_t)(vmcpu->RBX & 0xFFFFFFFF),
@@ -228,12 +280,11 @@ void dump_gpregs_16(vm_cpu_t* vmcpu)
 	       (uint32_t)(vmcpu->RBP & 0xFFFFFFFF));
 	printf("EIP %.8"PRIX32" ",
 	       (uint32_t)(vmcpu->RIP & 0xFFFFFFFF));
-	printf("zf %.1"PRIX32" nf %.1"PRIX32" of %.1"PRIX32" cf %.1"PRIX32"\n",
+	printf("zf %.1d nf %.1d of %.1d cf %.1d\n",
 	       (uint32_t)(vmcpu->zf & 0x1),
 	       (uint32_t)(vmcpu->nf & 0x1),
 	       (uint32_t)(vmcpu->of & 0x1),
 	       (uint32_t)(vmcpu->cf & 0x1));
-
 }
 
 void dump_gpregs_32(vm_cpu_t* vmcpu)
@@ -251,7 +302,7 @@ void dump_gpregs_32(vm_cpu_t* vmcpu)
 	       (uint32_t)(vmcpu->RBP & 0xFFFFFFFF));
 	printf("EIP %.8"PRIX32" ",
 	       (uint32_t)(vmcpu->RIP & 0xFFFFFFFF));
-	printf("zf %.1"PRIX32" nf %.1"PRIX32" of %.1"PRIX32" cf %.1"PRIX32"\n",
+	printf("zf %.1d nf %.1d of %.1d cf %.1d\n",
 	       (uint32_t)(vmcpu->zf & 0x1),
 	       (uint32_t)(vmcpu->nf & 0x1),
 	       (uint32_t)(vmcpu->of & 0x1),
@@ -274,7 +325,7 @@ void dump_gpregs_64(vm_cpu_t* vmcpu)
 	       vmcpu->R12, vmcpu->R13, vmcpu->R14, vmcpu->R15);
 
 
-	printf("zf %.1"PRIX64" nf %.1"PRIX64" of %.1"PRIX64" cf %.1"PRIX64"\n",
+	printf("zf %.1d nf %.1d of %.1d cf %.1d\n",
 	       vmcpu->zf, vmcpu->nf, vmcpu->of, vmcpu->cf);
 
 }
@@ -459,7 +510,6 @@ JitCpu_init(JitCpu *self, PyObject *args, PyObject *kwds)
 	return 0;
 }
 
-
 #define getset_reg_E_u32(regname)						\
 	static PyObject *JitCpu_get_E ## regname  (JitCpu *self, void *closure) \
 	{								\
@@ -522,13 +572,12 @@ getset_reg_u64(af);
 getset_reg_u64(df);
 
 
-getset_reg_u64(ES);
-getset_reg_u64(CS);
-getset_reg_u64(SS);
-getset_reg_u64(DS);
-getset_reg_u64(FS);
-getset_reg_u64(GS);
-
+getset_reg_u16(ES);
+getset_reg_u16(CS);
+getset_reg_u16(SS);
+getset_reg_u16(DS);
+getset_reg_u16(FS);
+getset_reg_u16(GS);
 
 getset_reg_E_u32(AX);
 getset_reg_E_u32(BX);
@@ -560,22 +609,22 @@ getset_reg_u64(MM5);
 getset_reg_u64(MM6);
 getset_reg_u64(MM7);
 
-getset_reg_u128(XMM0);
-getset_reg_u128(XMM1);
-getset_reg_u128(XMM2);
-getset_reg_u128(XMM3);
-getset_reg_u128(XMM4);
-getset_reg_u128(XMM5);
-getset_reg_u128(XMM6);
-getset_reg_u128(XMM7);
-getset_reg_u128(XMM8);
-getset_reg_u128(XMM9);
-getset_reg_u128(XMM10);
-getset_reg_u128(XMM11);
-getset_reg_u128(XMM12);
-getset_reg_u128(XMM13);
-getset_reg_u128(XMM14);
-getset_reg_u128(XMM15);
+getset_reg_bn(XMM0);
+getset_reg_bn(XMM1);
+getset_reg_bn(XMM2);
+getset_reg_bn(XMM3);
+getset_reg_bn(XMM4);
+getset_reg_bn(XMM5);
+getset_reg_bn(XMM6);
+getset_reg_bn(XMM7);
+getset_reg_bn(XMM8);
+getset_reg_bn(XMM9);
+getset_reg_bn(XMM10);
+getset_reg_bn(XMM11);
+getset_reg_bn(XMM12);
+getset_reg_bn(XMM13);
+getset_reg_bn(XMM14);
+getset_reg_bn(XMM15);
 
 getset_reg_u32(tsc1);
 getset_reg_u32(tsc2);
@@ -588,7 +637,6 @@ PyObject* get_gpreg_offset_all(void)
 {
     PyObject *dict = PyDict_New();
     PyObject *o;
-
     get_reg_off(exception_flags);
 
     get_reg_off(RAX);
diff --git a/miasm2/jitter/arch/JitCore_x86.h b/miasm2/jitter/arch/JitCore_x86.h
index a5fc4bd4..cde113ab 100644
--- a/miasm2/jitter/arch/JitCore_x86.h
+++ b/miasm2/jitter/arch/JitCore_x86.h
@@ -1,4 +1,5 @@
-#define uint128_t __uint128_t
+#include "../bn.h"
+
 
 typedef struct {
 	uint32_t exception_flags;
@@ -26,28 +27,28 @@ typedef struct {
 	uint64_t RIP;
 
 	/* eflag */
-	uint64_t zf;
-	uint64_t nf;
-	uint64_t pf;
-	uint64_t of;
-	uint64_t cf;
-	uint64_t af;
-	uint64_t df;
-
-	uint64_t tf;
-	uint64_t i_f;
-	uint64_t iopl_f;
-	uint64_t nt;
-	uint64_t rf;
-	uint64_t vm;
-	uint64_t ac;
-	uint64_t vif;
-	uint64_t vip;
-	uint64_t i_d;
-
-	uint64_t my_tick;
-
-	uint64_t cond;
+	uint8_t zf;
+	uint8_t nf;
+	uint8_t pf;
+	uint8_t of;
+	uint8_t cf;
+	uint8_t af;
+	uint8_t df;
+
+	uint8_t tf;
+	uint8_t i_f;
+	uint8_t iopl_f;
+	uint8_t nt;
+	uint8_t rf;
+	uint8_t vm;
+	uint8_t ac;
+	uint8_t vif;
+	uint8_t vip;
+	uint8_t i_d;
+
+	bn_t my_tick;
+
+	bn_t cond;
 
 	uint64_t float_st0;
 	uint64_t float_st1;
@@ -78,12 +79,12 @@ typedef struct {
 	uint64_t tsc2;
 
 
-	uint64_t ES;
-	uint64_t CS;
-	uint64_t SS;
-	uint64_t DS;
-	uint64_t FS;
-	uint64_t GS;
+	uint16_t ES;
+	uint16_t CS;
+	uint16_t SS;
+	uint16_t DS;
+	uint16_t FS;
+	uint16_t GS;
 
 	unsigned int cr0;
 	unsigned int cr3;
@@ -98,22 +99,22 @@ typedef struct {
 	uint64_t MM7;
 
 	/* SSE */
-	uint128_t XMM0;
-	uint128_t XMM1;
-	uint128_t XMM2;
-	uint128_t XMM3;
-	uint128_t XMM4;
-	uint128_t XMM5;
-	uint128_t XMM6;
-	uint128_t XMM7;
-	uint128_t XMM8;
-	uint128_t XMM9;
-	uint128_t XMM10;
-	uint128_t XMM11;
-	uint128_t XMM12;
-	uint128_t XMM13;
-	uint128_t XMM14;
-	uint128_t XMM15;
+	bn_t XMM0;
+	bn_t XMM1;
+	bn_t XMM2;
+	bn_t XMM3;
+	bn_t XMM4;
+	bn_t XMM5;
+	bn_t XMM6;
+	bn_t XMM7;
+	bn_t XMM8;
+	bn_t XMM9;
+	bn_t XMM10;
+	bn_t XMM11;
+	bn_t XMM12;
+	bn_t XMM13;
+	bn_t XMM14;
+	bn_t XMM15;
 
 	uint32_t segm_base[0x10000];
 
diff --git a/miasm2/jitter/bn.c b/miasm2/jitter/bn.c
new file mode 100644
index 00000000..9462de2c
--- /dev/null
+++ b/miasm2/jitter/bn.c
@@ -0,0 +1,848 @@
+/*
+
+Big number library - arithmetic on multiple-precision unsigned integers.
+
+This library is an implementation of arithmetic on arbitrarily large integers.
+
+The difference between this and other implementations, is that the data structure
+has optimal memory utilization (i.e. a 1024 bit integer takes up 128 bytes RAM),
+and all memory is allocated statically: no dynamic allocation for better or worse.
+
+Primary goals are correctness, clarity of code and clean, portable implementation.
+Secondary goal is a memory footprint small enough to make it suitable for use in
+embedded applications.
+
+
+The current state is correct functionality and adequate performance.
+There may well be room for performance-optimizations and improvements.
+
+Source: https://github.com/kokke/tiny-bignum-c
+
+Code slightly modified to support ast generation calculus style from Expr.
+
+*/
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <inttypes.h>
+#include <assert.h>
+#include "bn.h"
+
+/* Functions for shifting number in-place. */
+static bn_t _lshift_one_bit(bn_t a);
+static bn_t _rshift_one_bit(bn_t a);
+static bn_t _lshift_word(bn_t a, int nwords);
+static bn_t _rshift_word(bn_t a, int nwords);
+
+
+
+
+/* Public / Exported functions. */
+bn_t bignum_init(void)
+{
+	int i;
+	bn_t n;
+
+	for (i = 0; i < BN_ARRAY_SIZE; ++i) {
+		n.array[i] = 0;
+	}
+
+	return n;
+}
+
+
+bn_t bignum_from_int(DTYPE_TMP i)
+{
+	bn_t n;
+
+	n = bignum_init();
+  /* Endianness issue if machine is not little-endian? */
+#ifdef WORD_SIZE
+ #if (WORD_SIZE == 1)
+	n.array[0] = (i & 0x000000ff);
+	n.array[1] = (i & 0x0000ff00) >> 8;
+	n.array[2] = (i & 0x00ff0000) >> 16;
+	n.array[3] = (i & 0xff000000) >> 24;
+ #elif (WORD_SIZE == 2)
+	n.array[0] = (i & 0x0000ffff);
+	n.array[1] = (i & 0xffff0000) >> 16;
+ #elif (WORD_SIZE == 4)
+	n.array[0] = i;
+	DTYPE_TMP num_32 = 32;
+	DTYPE_TMP tmp = i >> num_32; /* bit-shift with U64 operands to force 64-bit results */
+	n.array[1] = tmp;
+ #endif
+#endif
+
+	return n;
+}
+
+
+
+bn_t bignum_from_uint64(uint64_t i)
+{
+	bn_t n;
+	n = bignum_init();
+  /* Endianness issue if machine is not little-endian? */
+#ifdef WORD_SIZE
+ #if (WORD_SIZE == 1)
+	n.array[0] = (i & 0x000000ff);
+	n.array[1] = (i & 0x0000ff00) >> 8;
+	n.array[2] = (i & 0x00ff0000) >> 16;
+	n.array[3] = (i & 0xff000000) >> 24;
+ #elif (WORD_SIZE == 2)
+	n.array[0] = (i & 0x0000ffff);
+	n.array[1] = (i & 0xffff0000) >> 16;
+ #elif (WORD_SIZE == 4)
+	n.array[0] = i;
+	DTYPE_TMP num_32 = 32;
+	DTYPE_TMP tmp = i >> num_32; /* bit-shift with U64 operands to force 64-bit results */
+	n.array[1] = tmp;
+ #endif
+#endif
+
+	return n;
+}
+
+
+
+
+
+int bignum_to_int(bn_t n)
+{
+
+	int ret = 0;
+
+	/* Endianness issue if machine is not little-endian? */
+#if (WORD_SIZE == 1)
+	ret += n.array[0];
+	ret += n.array[1] << 8;
+	ret += n.array[2] << 16;
+	ret += n.array[3] << 24;
+#elif (WORD_SIZE == 2)
+	ret += n.array[0];
+	ret += n.array[1] << 16;
+#elif (WORD_SIZE == 4)
+	ret += n.array[0];
+#endif
+
+
+	return ret;
+}
+
+
+uint64_t bignum_to_uint64(bn_t n)
+{
+
+	uint64_t ret = 0;
+
+	/* Endianness issue if machine is not little-endian? */
+#if (WORD_SIZE == 1)
+	ret += (uint64_t)(n.array[0]);
+	ret += (uint64_t)(n.array[1]) << 8;
+	ret += (uint64_t)(n.array[2]) << 16;
+	ret += (uint64_t)(n.array[3]) << 24;
+
+	ret += (uint64_t)(n.array[4]) << 32;
+	ret += (uint64_t)(n.array[5]) << 40;
+	ret += (uint64_t)(n.array[6]) << 48;
+	ret += (uint64_t)(n.array[7]) << 56;
+
+
+#elif (WORD_SIZE == 2)
+	ret += (uint64_t)(n.array[0]);
+	ret += (uint64_t)(n.array[1]) << 16;
+	ret += (uint64_t)(n.array[2]) << 32;
+	ret += (uint64_t)(n.array[3]) << 48;
+#elif (WORD_SIZE == 4)
+	ret += n.array[0];
+	ret += (uint64_t)(n.array[1]) << 32;
+#endif
+
+	return ret;
+}
+
+
+
+
+bn_t bignum_from_string(char* str, int nbytes)
+{
+
+	require(str, "str is null");
+	require(nbytes > 0, "nbytes must be positive");
+	require((nbytes & 1) == 0, "string format must be in hex -> equal number of bytes");
+
+	bn_t n;
+
+	n = bignum_init();
+
+	DTYPE tmp;                        /* DTYPE is defined in bn.h - uint{8,16,32,64}_t */
+	int i = nbytes - (2 * WORD_SIZE); /* index into string */
+	int j = 0;                        /* index into array */
+
+	/* reading last hex-byte "MSB" from string first -> big endian */
+	/* MSB ~= most significant byte / block ? :) */
+	while (i >= 0) {
+		tmp = 0;
+		sscanf(&str[i], SSCANF_FORMAT_STR, &tmp);
+		n.array[j] = tmp;
+		i -= (2 * WORD_SIZE); /* step WORD_SIZE hex-byte(s) back in the string. */
+		j += 1;               /* step one element forward in the array. */
+	}
+
+	return n;
+}
+
+void bignum_to_string(bn_t n, char* str, int nbytes)
+{
+	require(str, "str is null");
+	require(nbytes > 0, "nbytes must be positive");
+	require((nbytes & 1) == 0, "string format must be in hex -> equal number of bytes");
+
+	int j = BN_ARRAY_SIZE - 1; /* index into array - reading "MSB" first -> big-endian */
+	int i = 0;                 /* index into string representation. */
+
+	/* reading last array-element "MSB" first -> big endian */
+	while ((j >= 0) && (nbytes > (i + 1))) {
+		sprintf(&str[i], SPRINTF_FORMAT_STR, n.array[j]);
+		i += (2 * WORD_SIZE); /* step WORD_SIZE hex-byte(s) forward in the string. */
+		j -= 1;               /* step one element back in the array. */
+	}
+
+	/* Zero-terminate string */
+	str[i] = 0;
+}
+
+
+
+bn_t bignum_dec(bn_t n)
+{
+	//require(n, "n is null");
+
+	DTYPE tmp; /* copy of n */
+	DTYPE res;
+
+	int i;
+	for (i = 0; i < BN_ARRAY_SIZE; ++i) {
+		tmp = n.array[i];
+		res = tmp - 1;
+		n.array[i] = res;
+
+		if (!(res > tmp)) {
+			break;
+		}
+	}
+
+	return n;
+}
+
+
+bn_t bignum_inc(bn_t n)
+{
+	//require(n, "n is null");
+
+	DTYPE res;
+	DTYPE_TMP tmp; /* copy of n */
+
+	int i;
+	for (i = 0; i < BN_ARRAY_SIZE; ++i) {
+		tmp = n.array[i];
+		res = tmp + 1;
+		n.array[i] = res;
+
+		if (res > tmp) {
+			break;
+		}
+	}
+
+	return n;
+}
+
+
+
+bn_t bignum_add(bn_t a, bn_t b)
+{
+	//require(a, "a is null");
+	//require(b, "b is null");
+	//require(c, "c is null");
+	bn_t c;
+
+	DTYPE_TMP tmp;
+	int carry = 0;
+	int i;
+	for (i = 0; i < BN_ARRAY_SIZE; ++i) {
+		tmp = (DTYPE_TMP)a.array[i] + b.array[i] + carry;
+		carry = (tmp > MAX_VAL);
+		c.array[i] = (tmp & MAX_VAL);
+	}
+
+	return c;
+}
+
+
+bn_t bignum_sub(bn_t a, bn_t b)
+{
+	//require(a, "a is null");
+	//require(b, "b is null");
+	//require(c, "c is null");
+	bn_t c;
+
+	DTYPE_TMP res;
+	DTYPE_TMP tmp1;
+	DTYPE_TMP tmp2;
+	int borrow = 0;
+	int i;
+	for (i = 0; i < BN_ARRAY_SIZE; ++i) {
+		tmp1 = (DTYPE_TMP)a.array[i] + (MAX_VAL + 1); /* + number_base */
+		tmp2 = (DTYPE_TMP)b.array[i] + borrow;;
+		res = (tmp1 - tmp2);
+		c.array[i] = (DTYPE)(res & MAX_VAL); /* "modulo number_base" == "% (number_base - 1)" if number_base is 2^N */
+		borrow = (res <= MAX_VAL);
+	}
+
+	return c;
+}
+
+
+
+
+bn_t bignum_mul(bn_t a, bn_t b)
+{
+	//require(a, "a is null");
+	//require(b, "b is null");
+	//require(c, "c is null");
+
+	bn_t c;
+	bn_t row;
+	bn_t tmp;
+	int i, j;
+
+	c = bignum_init();
+
+	for (i = 0; i < BN_ARRAY_SIZE; ++i) {
+		row = bignum_init();
+
+		for (j = 0; j < BN_ARRAY_SIZE; ++j) {
+			if (i + j < BN_ARRAY_SIZE) {
+				tmp = bignum_init();
+				DTYPE_TMP intermediate = ((DTYPE_TMP)a.array[i] * (DTYPE_TMP)b.array[j]);
+				tmp = bignum_from_int(intermediate);
+				tmp = _lshift_word(tmp, i + j);
+				row = bignum_add(tmp, row);
+			}
+		}
+		c = bignum_add(c, row);
+	}
+
+	return c;
+}
+
+
+bn_t bignum_udiv(bn_t a, bn_t b)
+{
+	//require(a, "a is null");
+	//require(b, "b is null");
+	//require(c, "c is null");
+
+	bn_t c;
+	bn_t current;
+	bn_t denom;
+	bn_t tmp;
+
+	current = bignum_from_int(1);               // int current = 1;
+	denom = bignum_assign(b);                   // denom = b
+	tmp = bignum_assign(a);                     // tmp   = a
+
+	const DTYPE_TMP half_max = 1 + (DTYPE_TMP)(MAX_VAL / 2);
+	bool overflow = false;
+
+	while (bignum_cmp(denom, a) != LARGER) {    // while (denom <= a) {
+		if (denom.array[BN_ARRAY_SIZE - 1] >= half_max) {
+			overflow = true;
+			break;
+		}
+		current = _lshift_one_bit(current);                //   current <<= 1;
+		denom = _lshift_one_bit(denom);                  //   denom <<= 1;
+	}
+	if (!overflow) {
+		denom = _rshift_one_bit(denom);                  // denom >>= 1;
+		current = _rshift_one_bit(current);                // current >>= 1;
+	}
+	c = bignum_init();                             // int answer = 0;
+
+	while (!bignum_is_zero(current)) {           // while (current != 0)
+		if (bignum_cmp(tmp, denom) != SMALLER) {  //   if (dividend >= denom)
+			tmp = bignum_sub(tmp, denom);         //     dividend -= denom;
+			c = bignum_or(c, current);              //     answer |= current;
+		}
+		current = _rshift_one_bit(current);                //   current >>= 1;
+		denom = _rshift_one_bit(denom);                  //   denom >>= 1;
+	}                                           // return answer;
+
+	return c;
+}
+
+
+
+bn_t bignum_lshift(bn_t a, int nbits)
+{
+	//require(a, "a is null");
+	//require(b, "b is null");
+	require(nbits >= 0, "no negative shifts");
+
+	bn_t b;
+
+	b = bignum_assign(a);
+	/* Handle shift in multiples of word-size */
+	const int nbits_pr_word = (WORD_SIZE * 8);
+	int nwords = nbits / nbits_pr_word;
+	if (nwords != 0) {
+		b = _lshift_word(b, nwords);
+		nbits -= (nwords * nbits_pr_word);
+	}
+
+	if (nbits != 0) {
+		int i;
+		for (i = (BN_ARRAY_SIZE - 1); i > 0; --i) {
+			b.array[i] = (b.array[i] << nbits) | (b.array[i - 1] >> ((8 * WORD_SIZE) - nbits));
+		}
+		b.array[i] <<= nbits;
+	}
+
+	return b;
+}
+
+
+bn_t bignum_rshift(bn_t a, int nbits)
+{
+	//require(a, "a is null");
+	//require(b, "b is null");
+	require(nbits >= 0, "no negative shifts");
+
+	bn_t b;
+
+	b = bignum_assign(a);
+	/* Handle shift in multiples of word-size */
+	const int nbits_pr_word = (WORD_SIZE * 8);
+	int nwords = nbits / nbits_pr_word;
+
+	if (nwords != 0) {
+		b = _rshift_word(b, nwords);
+		nbits -= (nwords * nbits_pr_word);
+	}
+	if (nbits != 0) {
+		int i;
+		for (i = 0; i < (BN_ARRAY_SIZE - 1); ++i) {
+			b.array[i] = (b.array[i] >> nbits) | (b.array[i + 1] << ((8 * WORD_SIZE) - nbits));
+		}
+		b.array[i] >>= nbits;
+	}
+
+	return b;
+}
+
+
+
+bn_t bignum_a_rshift(bn_t a, int size, int nbits)
+{
+	//require(a, "a is null");
+	//require(b, "b is null");
+	require(nbits >= 0, "no negative shifts");
+	require(size > 0, "no negative shifts");
+
+	bn_t b;
+	bn_t tmp, mask;
+
+	b = bignum_rshift(a, nbits);
+
+	/* get sign bit */
+	tmp = bignum_rshift(a, size - 1);
+	tmp = bignum_mask(tmp, 1);
+
+	if (!bignum_is_zero(tmp)) {
+		/* generate sign propag */
+		tmp = bignum_from_int(1);
+		tmp = bignum_lshift(tmp, size);
+		tmp = bignum_dec(tmp);
+
+		mask = bignum_from_int(1);
+		mask = bignum_lshift(mask, size - nbits);
+		mask = bignum_dec(mask);
+
+		tmp = bignum_xor(tmp, mask);
+		b = bignum_or(b, tmp);
+	}
+
+	return b;
+}
+
+bn_t bignum_not(bn_t a)
+{
+	int i;
+	bn_t b;
+
+	for (i = 0; i < BN_ARRAY_SIZE; ++i) {
+		b.array[i] = ~a.array[i];
+	}
+
+	return b;
+}
+
+
+
+bn_t bignum_umod(bn_t a, bn_t b)
+{
+	/*
+	  Take divmod and throw away div part
+	*/
+	//require(a, "a is null");
+	//require(b, "b is null");
+	//require(c, "c is null");
+
+	bn_t c, d;
+	bn_t tmp;
+
+	/* c = (a / b) */
+	c = bignum_udiv(a, b);
+	/* tmp = (c * b) */
+	tmp = bignum_mul(c, b);
+	/* c = a - tmp */
+	d = bignum_sub(a, tmp);
+	return d;
+}
+
+
+bn_t bignum_and(bn_t a, bn_t b)
+{
+	//require(a, "a is null");
+	//require(b, "b is null");
+	//require(c, "c is null");
+	bn_t c;
+
+	int i;
+	for (i = 0; i < BN_ARRAY_SIZE; ++i) {
+		c.array[i] = (a.array[i] & b.array[i]);
+	}
+
+	return c;
+}
+
+
+bn_t bignum_or(bn_t a, bn_t b)
+{
+	//require(a, "a is null");
+	//require(b, "b is null");
+	//require(c, "c is null");
+	bn_t c;
+	int i;
+	for (i = 0; i < BN_ARRAY_SIZE; ++i) {
+		c.array[i] = (a.array[i] | b.array[i]);
+	}
+
+	return c;
+}
+
+
+bn_t bignum_xor(bn_t a, bn_t b)
+{
+	//require(a, "a is null");
+	//require(b, "b is null");
+	//require(c, "c is null");
+
+	bn_t c;
+	int i;
+	for (i = 0; i < BN_ARRAY_SIZE; ++i) {
+		c.array[i] = (a.array[i] ^ b.array[i]);
+	}
+	return c;
+}
+
+
+int bignum_cmp(bn_t a, bn_t b)
+{
+	//require(a, "a is null");
+	//require(b, "b is null");
+
+	int i = BN_ARRAY_SIZE;
+	do {
+		i -= 1; /* Decrement first, to start with last array element */
+		if (a.array[i] > b.array[i]) {
+			return LARGER;
+		}
+		else if (a.array[i] < b.array[i]) {
+			return SMALLER;
+		}
+	}
+	while (i != 0);
+
+	return EQUAL;
+}
+
+
+int bignum_is_zero(bn_t n)
+{
+	//require(n, "n is null");
+
+	int i;
+	for (i = 0; i < BN_ARRAY_SIZE; ++i) {
+		if (n.array[i]) {
+			return 0;
+		}
+	}
+
+	return 1;
+}
+
+
+
+bn_t bignum_assign(bn_t src)
+{
+	//require(dst, "dst is null");
+	//require(src, "src is null");
+	bn_t dst;
+
+	int i;
+	for (i = 0; i < BN_ARRAY_SIZE; ++i) {
+		dst.array[i] = src.array[i];
+	}
+
+	return dst;
+}
+
+
+bn_t bignum_mask(bn_t src, int bits)
+{
+	bn_t dst;
+	bn_t mask;
+
+	mask = bignum_from_int(1);
+	mask = bignum_lshift(mask, bits);
+	mask = bignum_dec(mask);
+
+	dst = bignum_and(src, mask);
+	return dst;
+}
+
+/* Private / Static functions. */
+static bn_t _rshift_word(bn_t a, int nwords)
+{
+	/* Naive method: */
+	//require(a, "a is null");
+	int i;
+
+	require(nwords >= 0, "no negative shifts");
+
+	if (nwords >= BN_ARRAY_SIZE) {
+		for (i = 0; i < BN_ARRAY_SIZE; ++i) {
+			a.array[i] = 0;
+		}
+		return a;
+	}
+
+	for (i = 0; i < BN_ARRAY_SIZE - nwords; ++i) {
+		a.array[i] = a.array[i + nwords];
+	}
+
+	for (; i < BN_ARRAY_SIZE; ++i) {
+		a.array[i] = 0;
+	}
+
+	return a;
+}
+
+
+static bn_t _lshift_word(bn_t a, int nwords)
+{
+	//require(a, "a is null");
+	require(nwords >= 0, "no negative shifts");
+
+	int i;
+
+	if (nwords >= BN_ARRAY_SIZE) {
+		for (i = 0; i < BN_ARRAY_SIZE; ++i) {
+			a.array[i] = 0;
+		}
+		return a;
+	}
+
+	/* Shift whole words */
+	for (i = (BN_ARRAY_SIZE - 1); i >= nwords; --i) {
+		a.array[i] = a.array[i - nwords];
+	}
+	/* Zero pad shifted words. */
+	for (; i >= 0; --i) {
+		a.array[i] = 0;
+	}
+
+	return a;
+}
+
+
+static bn_t _lshift_one_bit(bn_t a)
+{
+	//require(a, "a is null");
+
+	int i;
+	for (i = (BN_ARRAY_SIZE - 1); i > 0; --i) {
+		a.array[i] = (a.array[i] << 1) | (a.array[i - 1] >> ((8 * WORD_SIZE) - 1));
+	}
+	a.array[0] <<= 1;
+
+	return a;
+}
+
+
+static bn_t _rshift_one_bit(bn_t a)
+{
+	//require(a, "a is null");
+
+	int i;
+	for (i = 0; i < (BN_ARRAY_SIZE - 1); ++i) {
+		a.array[i] = (a.array[i] >> 1) | (a.array[i + 1] << ((8 * WORD_SIZE) - 1));
+	}
+	a.array[BN_ARRAY_SIZE - 1] >>= 1;
+
+	return a;
+}
+
+
+bn_t bignum_rol(bn_t a, int size, int nbits)
+{
+	bn_t c;
+
+	c = bignum_or(
+		      bignum_lshift(a, nbits),
+		      bignum_rshift(a, size - nbits)
+		      );
+	c = bignum_mask(c, size);
+	return c;
+}
+
+
+bn_t bignum_ror(bn_t a, int size, int nbits)
+{
+	bn_t c;
+
+	c = bignum_or(
+		      bignum_rshift(a, nbits),
+		      bignum_lshift(a, size - nbits)
+		      );
+	c = bignum_mask(c, size);
+	return c;
+}
+
+
+int bignum_getbit(bn_t a, int pos)
+{
+	int d_pos, bit_pos;
+
+	require(pos < BN_BIT_SIZE, "size must be below bignum max size");
+
+	d_pos = pos / (sizeof(DTYPE) * 8);
+	bit_pos = pos % (sizeof(DTYPE) * 8);
+	return !!(a.array[d_pos] & (1 << bit_pos));
+
+}
+
+
+
+/*
+ * Count leading zeros - count the number of zero starting at the most
+ * significant bit
+ *
+ * Example:
+ * - cntleadzeros(size=32, src=2): 30
+ * - cntleadzeros(size=32, src=0): 32
+ */
+int bignum_cntleadzeros(bn_t n, int size)
+{
+	int i;
+
+	require(size, "size must be greater than 0");
+	require(size <= BN_BIT_SIZE, "size must be below bignum max size");
+
+	for (i = 0; i < size; i++) {
+		if (bignum_getbit(n, size - i - 1))
+			break;
+	}
+
+	return i;
+}
+
+
+
+/*
+ * Count trailing zeros - count the number of zero starting at the least
+ * significant bit
+ *
+ * Example:
+ * - cnttrailzeros(size=32, src=2): 1
+ * - cnttrailzeros(size=32, src=0): 32
+ */
+int bignum_cnttrailzeros(bn_t n, int size)
+{
+	int i;
+
+	require(size, "size must be greater than 0");
+	require(size <= BN_BIT_SIZE, "size must be below bignum max size");
+
+	for (i = 0; i < size; i++) {
+		if (bignum_getbit(n, i))
+			break;
+	}
+
+	return i;
+}
+
+
+
+
+bn_t bignum_idiv(bn_t a, bn_t b, int size)
+{
+	require(size, "size must be greater than 0");
+	require(size <= BN_BIT_SIZE, "size must be below bignum max size");
+
+	int a_sign, b_sign;
+	bn_t c;
+
+	a_sign = bignum_getbit(a, size - 1);
+	b_sign = bignum_getbit(b, size - 1);
+
+	if (a_sign) {
+		/* neg a */
+		printf("a neg\n");
+		a = bignum_sub(bignum_from_int(0), a);
+		a = bignum_mask(a, size - 1);
+	}
+
+	if (b_sign) {
+		/* neg b */
+		printf("b neg\n");
+		b = bignum_sub(bignum_from_int(0), b);
+		b = bignum_mask(b, size - 1);
+	}
+
+	c = bignum_udiv(a, b);
+	if (a_sign ^ b_sign) {
+		c = bignum_sub(bignum_from_int(0), c);
+	}
+
+	c = bignum_mask(c, size);
+	return c;
+}
+
+
+
+bn_t bignum_imod(bn_t a, bn_t b, int size)
+{
+	require(size, "size must be greater than 0");
+	require(size <= BN_BIT_SIZE, "size must be below bignum max size");
+
+	bn_t c;
+
+	c = bignum_idiv(a, b, size);
+	c = bignum_mul(c, b);
+	c = bignum_sub(a, c);
+	c = bignum_mask(c, size);
+	return c;
+}
diff --git a/miasm2/jitter/bn.h b/miasm2/jitter/bn.h
new file mode 100644
index 00000000..6f726eb3
--- /dev/null
+++ b/miasm2/jitter/bn.h
@@ -0,0 +1,145 @@
+#ifndef __BIGNUM_H__
+#define __BIGNUM_H__
+/*
+
+Big number library - arithmetic on multiple-precision unsigned integers.
+
+This library is an implementation of arithmetic on arbitrarily large integers.
+
+The difference between this and other implementations, is that the data structure
+has optimal memory utilization (i.e. a 1024 bit integer takes up 128 bytes RAM),
+and all memory is allocated statically: no dynamic allocation for better or worse.
+
+Primary goals are correctness, clarity of code and clean, portable implementation.
+Secondary goal is a memory footprint small enough to make it suitable for use in
+embedded applications.
+
+
+The current state is correct functionality and adequate performance.
+There may well be room for performance-optimizations and improvements.
+
+Source: https://github.com/kokke/tiny-bignum-c
+
+Code slightly modified to support ast generation calculus style from Expr.
+
+*/
+
+#include <stdint.h>
+#include <assert.h>
+
+
+/* This macro defines the word size in bytes of the array that constitues the big-number data structure. */
+#ifndef WORD_SIZE
+  #define WORD_SIZE 4
+#endif
+
+#define BN_BYTE_SIZE 32
+
+#define BN_BIT_SIZE ((BN_BYTE_SIZE) * 8)
+
+/* Size of big-numbers in bytes */
+//#define BN_ARRAY_SIZE    (128 / WORD_SIZE)
+#define BN_ARRAY_SIZE    (BN_BYTE_SIZE / WORD_SIZE)
+
+
+/* Here comes the compile-time specialization for how large the underlying array size should be. */
+/* The choices are 1, 2 and 4 bytes in size with uint32, uint64 for WORD_SIZE==4, as temporary. */
+#ifndef WORD_SIZE
+  #error Must define WORD_SIZE to be 1, 2, 4
+#elif (WORD_SIZE == 1)
+  /* Data type of array in structure */
+  #define DTYPE                    uint8_t
+  /* bitmask for getting MSB */
+  #define DTYPE_MSB                ((DTYPE_TMP)(0x80))
+  /* Data-type larger than DTYPE, for holding intermediate results of calculations */
+  #define DTYPE_TMP                uint32_t
+  /* sprintf format string */
+  #define SPRINTF_FORMAT_STR       "%.02x"
+  #define SSCANF_FORMAT_STR        "%2hhx"
+  /* Max value of integer type */
+  #define MAX_VAL                  ((DTYPE_TMP)0xFF)
+#elif (WORD_SIZE == 2)
+  #define DTYPE                    uint16_t
+  #define DTYPE_TMP                uint32_t
+  #define DTYPE_MSB                ((DTYPE_TMP)(0x8000))
+  #define SPRINTF_FORMAT_STR       "%.04x"
+  #define SSCANF_FORMAT_STR        "%4hx"
+  #define MAX_VAL                  ((DTYPE_TMP)0xFFFF)
+#elif (WORD_SIZE == 4)
+  #define DTYPE                    uint32_t
+  #define DTYPE_TMP                uint64_t
+  #define DTYPE_MSB                ((DTYPE_TMP)(0x80000000))
+  #define SPRINTF_FORMAT_STR       "%.08x"
+  #define SSCANF_FORMAT_STR        "%8x"
+  #define MAX_VAL                  ((DTYPE_TMP)0xFFFFFFFF)
+#endif
+#ifndef DTYPE
+  #error DTYPE must be defined to uint8_t, uint16_t uint32_t or whatever
+#endif
+
+
+/* Custom assert macro - easy to disable */
+#define require(p, msg) assert(p && #msg)
+
+
+/* Data-holding structure: array of DTYPEs */
+typedef struct bn
+{
+  DTYPE array[BN_ARRAY_SIZE];
+} bn_t;
+
+
+
+/* Tokens returned by bignum_cmp() for value comparison */
+enum { SMALLER = -1, EQUAL = 0, LARGER = 1 };
+
+/* Initialization functions: */
+bn_t bignum_init(void);
+bn_t bignum_from_int(DTYPE_TMP i);
+bn_t bignum_from_uint64(uint64_t i);
+int  bignum_to_int(bn_t n);
+uint64_t bignum_to_uint64(bn_t n);
+bn_t bignum_from_string(char* str, int nbytes);
+void bignum_to_string(bn_t n, char* str, int maxsize);
+
+
+/* Basic arithmetic operations: */
+bn_t bignum_add(bn_t a, bn_t b); /* c = a + b */
+bn_t bignum_sub(bn_t a, bn_t b); /* c = a - b */
+bn_t bignum_mul(bn_t a, bn_t b); /* c = a * b */
+bn_t bignum_udiv(bn_t a, bn_t b); /* c = a / b */
+bn_t bignum_umod(bn_t a, bn_t b); /* c = a % b */
+bn_t bignum_idiv(bn_t a, bn_t b, int size);
+bn_t bignum_imod(bn_t a, bn_t b, int size);
+//void bignum_udivmod(struct bn* a, struct bn* b, struct bn* c, struct bn* d); /* c = a/b, d = a%b */
+
+
+
+/* Bitwise operations: */
+bn_t bignum_and(bn_t a, bn_t b); /* c = a & b */
+bn_t bignum_or(bn_t a, bn_t b);  /* c = a | b */
+bn_t bignum_xor(bn_t a, bn_t b); /* c = a ^ b */
+bn_t bignum_lshift(bn_t a, int nbits); /* b = a << nbits */
+bn_t bignum_rshift(bn_t a, int nbits); /* b = a >> nbits */
+bn_t bignum_a_rshift(bn_t a, int size, int nbits); /* b = a a>> nbits */
+bn_t bignum_not(bn_t a); /* c = ~a */
+
+/* Special operators and comparison */
+int  bignum_cmp(bn_t a, bn_t b);               /* Compare: returns LARGER, EQUAL or SMALLER */
+int  bignum_is_zero(bn_t n);                         /* For comparison with zero */
+bn_t bignum_inc(bn_t n);                             /* Increment: add one to n */
+bn_t bignum_dec(bn_t n);                             /* Decrement: subtract one from n */
+//bn_t bignum_pow(bn_t a, bn_t b, bn_t c); /* Calculate a^b -- e.g. 2^10 => 1024 */
+//bn_t bignum_isqrt(bn_t a, bn_t b);             /* Integer square root -- e.g. isqrt(5) => 2*/
+int bignum_cntleadzeros(bn_t n, int size);
+int bignum_cnttrailzeros(bn_t n, int size);
+bn_t bignum_assign(bn_t src);        /* Copy src into dst -- dst := src */
+bn_t bignum_mask(bn_t src, int bits);  /*  c = src & ((1<<bits) -1) */
+
+bn_t bignum_rol(bn_t a, int size, int nbits);
+bn_t bignum_ror(bn_t a, int size, int nbits);
+int bignum_getbit(bn_t a, int pos);
+
+#endif /* #ifndef __BIGNUM_H__ */
+
+
diff --git a/miasm2/jitter/codegen.py b/miasm2/jitter/codegen.py
index a709d5ec..abba9843 100644
--- a/miasm2/jitter/codegen.py
+++ b/miasm2/jitter/codegen.py
@@ -6,13 +6,16 @@ from miasm2.expression.expression import Expr, ExprId, ExprLoc, ExprInt, \
     ExprMem, ExprCond, LocKey
 from miasm2.ir.ir import IRBlock, AssignBlock
 
-from miasm2.ir.translators.C import TranslatorC
+from miasm2.ir.translators.C import TranslatorC, int_size_to_bn
 from miasm2.core.asmblock import AsmBlockBad
 
 TRANSLATOR_NO_SYMBOL = TranslatorC(loc_db=None)
 
 SIZE_TO_MASK = {size: TRANSLATOR_NO_SYMBOL.from_expr(ExprInt(0, size).mask)
-                for size in (1, 2, 3, 7, 8, 16, 32, 64, 128)}
+                for size in (1, 2, 3, 7, 8, 16, 32, 64)}
+
+
+
 
 
 
@@ -88,7 +91,7 @@ class CGen(object):
 
     CODE_INIT = r"""
     int DST_case;
-    unsigned long long DST_value;
+    uint64_t DST_value;
     vm_cpu_t* mycpu = (vm_cpu_t*)jitcpu->cpu;
 
     goto %s;
@@ -232,7 +235,10 @@ class CGen(object):
             c_prefetch.append('%s = %s;' % (str_dst, str_src))
 
         for var in prefetchers.itervalues():
-            c_var.append("uint%d_t %s;" % (var.size, var))
+            if var.size <= self.translator.NATIVE_INT_MAX_SIZE:
+                c_var.append("uint%d_t %s;" % (var.size, var))
+            else:
+                c_var.append("bn_t %s; // %d" % (var, var.size))
 
         for dst, src in sorted(assignblk.iteritems()):
             src = src.replace_expr(prefetchers)
@@ -244,24 +250,50 @@ class CGen(object):
                     # Dont mask float affectation
                     c_main.append(
                         '%s = (%s);' % (self.id_to_c(new_dst), self.id_to_c(src)))
-                else:
+                elif new_dst.size <= self.translator.NATIVE_INT_MAX_SIZE:
                     c_main.append(
                         '%s = (%s)&%s;' % (self.id_to_c(new_dst),
                                            self.id_to_c(src),
                                            SIZE_TO_MASK[src.size]))
+                else:
+                    c_main.append(
+                        '%s = bignum_mask(%s, %d);' % (
+                            self.id_to_c(new_dst),
+                            self.id_to_c(src),
+                            src.size
+                        )
+                    )
             elif isinstance(dst, ExprMem):
                 ptr = dst.arg.replace_expr(prefetchers)
-                new_dst = ExprMem(ptr, dst.size)
-                str_dst = self.id_to_c(new_dst).replace('MEM_LOOKUP', 'MEM_WRITE')
-                c_mem.append('%s, %s);' % (str_dst[:-1], self.id_to_c(src)))
+                if ptr.size <= self.translator.NATIVE_INT_MAX_SIZE:
+                    new_dst = ExprMem(ptr, dst.size)
+                    str_dst = self.id_to_c(new_dst).replace('MEM_LOOKUP', 'MEM_WRITE')
+                    c_mem.append('%s, %s);' % (str_dst[:-1], self.id_to_c(src)))
+                else:
+                    ptr_str = self.id_to_c(ptr)
+                    if ptr.size <= self.translator.NATIVE_INT_MAX_SIZE:
+                        c_mem.append('%s, %s);' % (str_dst[:-1], self.id_to_c(src)))
+                    else:
+                        if src.size <= self.translator.NATIVE_INT_MAX_SIZE:
+                            c_mem.append('MEM_WRITE_BN_INT(jitcpu, %d, %s, %s);' % (
+                                src.size, ptr_str, self.id_to_c(src))
+                            )
+                        else:
+                            c_mem.append('MEM_WRITE_BN_BN(jitcpu, %d, %s, %s);' % (
+                                src.size, ptr_str, self.id_to_c(src))
+                            )
             else:
                 raise ValueError("Unknown dst")
 
         for dst, new_dst in dst_var.iteritems():
             if dst == self.ir_arch.IRDst:
                 continue
+
             c_updt.append('%s = %s;' % (self.id_to_c(dst), self.id_to_c(new_dst)))
-            c_var.append("uint%d_t %s;" % (new_dst.size, new_dst))
+            if dst.size <= self.translator.NATIVE_INT_MAX_SIZE:
+                c_var.append("uint%d_t %s;" % (new_dst.size, new_dst))
+            else:
+                c_var.append("bn_t %s; // %d" % (new_dst, new_dst.size))
 
         return c_prefetch, c_var, c_main, c_mem, c_updt
 
@@ -284,24 +316,39 @@ class CGen(object):
         """
 
         if isinstance(expr, ExprCond):
-            cond = self.id_to_c(expr.cond)
             src1, src1b = self.traverse_expr_dst(expr.src1, dst2index)
             src2, src2b = self.traverse_expr_dst(expr.src2, dst2index)
+            cond = self.id_to_c(expr.cond)
+            if not expr.cond.size <= self.translator.NATIVE_INT_MAX_SIZE:
+                cond = "(!bignum_is_zero(%s))" % cond
+
             return ("((%s)?(%s):(%s))" % (cond, src1, src2),
                     "((%s)?(%s):(%s))" % (cond, src1b, src2b))
         if isinstance(expr, ExprInt):
             offset = int(expr)
             loc_key = self.ir_arch.loc_db.get_or_create_offset_location(offset)
             self.add_label_index(dst2index, loc_key)
-            return ("%s" % dst2index[loc_key], hex(offset))
+
+            value, int_size = int_size_to_bn(offset, 64)
+            out = hex(offset)
+
+            return ("%s" % dst2index[loc_key], out)
         if expr.is_loc():
             loc_key = expr.loc_key
             offset = self.ir_arch.loc_db.get_location_offset(expr.loc_key)
             if offset is not None:
                 self.add_label_index(dst2index, loc_key)
-                return ("%s" % dst2index[loc_key], hex(offset))
+
+                value, int_size = int_size_to_bn(offset, 64)
+                out = hex(offset)
+
+                return ("%s" % dst2index[loc_key], out)
             self.add_label_index(dst2index, loc_key)
-            return ("%s" % dst2index[loc_key], "0")
+
+            value, int_size = int_size_to_bn(0, 64)
+            out = hex(0)
+
+            return ("%s" % dst2index[loc_key], out)
         dst2index[expr] = -1
         return ("-1", self.id_to_c(expr))
 
@@ -311,7 +358,7 @@ class CGen(object):
         dst2index = {}
         (ret, retb) = self.traverse_expr_dst(dst, dst2index)
         ret = "DST_case = %s;" % ret
-        retb = "DST_value = %s;" % retb
+        retb = 'DST_value = %s;' % retb
         return ['// %s' % dst2index,
                 '%s' % ret,
                 '%s' % retb], dst2index
diff --git a/miasm2/jitter/jitcore_cc_base.py b/miasm2/jitter/jitcore_cc_base.py
index bbf10a53..81a5d009 100644
--- a/miasm2/jitter/jitcore_cc_base.py
+++ b/miasm2/jitter/jitcore_cc_base.py
@@ -16,6 +16,7 @@ def gen_core(arch, attrib):
     txt += '#include "%s/op_semantics.h"\n' % lib_dir
     txt += '#include "%s/vm_mngr.h"\n' % lib_dir
     txt += '#include "%s/vm_mngr_py.h"\n' % lib_dir
+    txt += '#include "%s/bn.h"\n' % lib_dir
     txt += '#include "%s/JitCore.h"\n' % lib_dir
     txt += '#include "%s/arch/JitCore_%s.h"\n' % (lib_dir, arch.name)
 
diff --git a/miasm2/jitter/llvmconvert.py b/miasm2/jitter/llvmconvert.py
index c4e6709d..7c95688d 100644
--- a/miasm2/jitter/llvmconvert.py
+++ b/miasm2/jitter/llvmconvert.py
@@ -215,7 +215,7 @@ class LLVMContext_JIT(LLVMContext):
 
         fc = {}
         p8 = llvm_ir.PointerType(LLVMType.IntType(8))
-        for i in [8, 16, 32, 64, 128]:
+        for i in [8, 16, 32, 64]:
             fc["MEM_LOOKUP_%02d" % i] = {"ret": LLVMType.IntType(i),
                                          "args": [p8,
                                                   LLVMType.IntType(64)]}
@@ -224,6 +224,22 @@ class LLVMContext_JIT(LLVMContext):
                                         "args": [p8,
                                                  LLVMType.IntType(64),
                                                  LLVMType.IntType(i)]}
+
+        fc["MEM_LOOKUP_INT_BN_TO_PTR"] = {"ret": llvm_ir.VoidType(),
+                                          "args": [
+                                              p8,
+                                              LLVMType.IntType(32),
+                                              LLVMType.IntType(64),
+                                              p8
+                                          ]}
+        fc["MEM_WRITE_INT_BN_FROM_PTR"] = {"ret": llvm_ir.VoidType(),
+                                           "args": [
+                                               p8,
+                                               LLVMType.IntType(32),
+                                               LLVMType.IntType(64),
+                                               p8,
+                                           ]}
+
         fc["reset_memory_access"] = {"ret": llvm_ir.VoidType(),
                                      "args": [p8,
                                      ]}
@@ -307,25 +323,86 @@ class LLVMContext_JIT(LLVMContext):
     def memory_lookup(self, func, addr, size):
         """Perform a memory lookup at @addr of size @size (in bit)"""
         builder = func.builder
-        fc_name = "MEM_LOOKUP_%02d" % size
-        fc_ptr = self.mod.get_global(fc_name)
-        addr_casted = builder.zext(addr,
-                                   LLVMType.IntType(64))
+        if size <= 64:
+            fc_name = "MEM_LOOKUP_%02d" % size
+            fc_ptr = self.mod.get_global(fc_name)
+            addr_casted = builder.zext(addr, LLVMType.IntType(64))
+            ret = builder.call(
+                fc_ptr, [func.local_vars["jitcpu"],addr_casted]
+            )
+        else:
+            # Miasm uses a memory lookup function which returns a bn_t for its
+            # result. We cannot simply translate this into IntType. The trick
+            # here is to use the function MEM_LOOKUP_INT_BN_TO_PTR which has a
+            # different interface: the resulting bn_t is passed through a char*
+            # argument.
+            #
+            # WARNING: Here, we use the fact that the serialisation of LLVM
+            # IntType is the *same* as the bn_t structure.
+
+            fc_name = "MEM_LOOKUP_INT_BN_TO_PTR"
+            fc_ptr = self.mod.get_global(fc_name)
+            addr_casted = builder.zext(addr, LLVMType.IntType(64))
+            size_cst = llvm_ir.Constant(LLVMType.IntType(32), size)
+
+            value_ptr = builder.alloca(llvm_ir.IntType(size))
+            value_ptr_u8 = builder.bitcast(
+                value_ptr,
+                LLVMType.IntType(8).as_pointer()
+            )
+
+
+            builder.call(
+                fc_ptr,
+                [
+                    func.local_vars["jitcpu"],
+                    size_cst,
+                    addr_casted,
+                    value_ptr_u8
+                ]
+            )
+            ret = builder.load(value_ptr)
 
-        ret = builder.call(fc_ptr, [func.local_vars["jitcpu"],
-                                    addr_casted])
         return ret
 
     def memory_write(self, func, addr, size, value):
         """Perform a memory write at @addr of size @size (in bit) with LLVM IR @value"""
         # Function call
         builder = func.builder
-        fc_name = "MEM_WRITE_%02d" % size
-        fc_ptr = self.mod.get_global(fc_name)
-        dst_casted = builder.zext(addr, LLVMType.IntType(64))
-        builder.call(fc_ptr, [func.local_vars["jitcpu"],
-                              dst_casted,
-                              value])
+        if size <= 64:
+            fc_name = "MEM_WRITE_%02d" % size
+            fc_ptr = self.mod.get_global(fc_name)
+            dst_casted = builder.zext(addr, LLVMType.IntType(64))
+            builder.call(
+                fc_ptr,
+                [
+                    func.local_vars["jitcpu"],
+                    dst_casted,
+                    value
+                ]
+            )
+        else:
+            # The same trick as described in MEM_LOOKUP_INT_BN_TO_PTR is used
+            # here.
+
+            fc_name = "MEM_WRITE_INT_BN_FROM_PTR"
+            fc_ptr = self.mod.get_global(fc_name)
+            addr_casted = builder.zext(addr, LLVMType.IntType(64))
+            size_cst = llvm_ir.Constant(LLVMType.IntType(32), size)
+
+            ret = builder.alloca(value.type)
+            builder.store(value, ret)
+            value_ptr = builder.bitcast(ret, llvm_ir.IntType(8).as_pointer())
+
+            ret = builder.call(
+                fc_ptr,
+                [
+                    func.local_vars["jitcpu"],
+                    size_cst,
+                    addr_casted,
+                    value_ptr,
+                ]
+            )
 
 
     @staticmethod
diff --git a/miasm2/jitter/op_semantics.c b/miasm2/jitter/op_semantics.c
index 0bc3fcc5..061e7736 100644
--- a/miasm2/jitter/op_semantics.c
+++ b/miasm2/jitter/op_semantics.c
@@ -776,22 +776,22 @@ uint64_t fpround_towardszero_fp64(uint64_t a)
 }
 
 
+UDIV(8)
 UDIV(16)
 UDIV(32)
 UDIV(64)
-UDIV(128)
 
+UMOD(8)
 UMOD(16)
 UMOD(32)
 UMOD(64)
-UMOD(128)
 
+IDIV(8)
 IDIV(16)
 IDIV(32)
 IDIV(64)
-IDIV(128)
 
+IMOD(8)
 IMOD(16)
 IMOD(32)
 IMOD(64)
-IMOD(128)
diff --git a/miasm2/jitter/op_semantics.h b/miasm2/jitter/op_semantics.h
index f8042895..9ff2881e 100644
--- a/miasm2/jitter/op_semantics.h
+++ b/miasm2/jitter/op_semantics.h
@@ -1,9 +1,6 @@
 #ifndef OP_SEMANTICS_H
 #define OP_SEMANTICS_H
 
-#define uint128_t __uint128_t
-#define int128_t __int128_t
-
 #define CC_P 1
 extern const uint8_t parity_table[256];
 #define parity(a) parity_table[(a) & 0xFF]
@@ -95,6 +92,11 @@ uint16_t umod16(uint16_t a, uint16_t b);
 int16_t idiv16(int16_t a, int16_t b);
 int16_t imod16(int16_t a, int16_t b);
 
+uint8_t udiv8(uint8_t a, uint8_t b);
+uint8_t umod8(uint8_t a, uint8_t b);
+int8_t idiv8(int8_t a, int8_t b);
+int8_t imod8(int8_t a, int8_t b);
+
 unsigned int x86_cpuid(unsigned int a, unsigned int reg_num);
 
 uint32_t fpu_fadd32(uint32_t a, uint32_t b);
diff --git a/miasm2/jitter/vm_mngr.c b/miasm2/jitter/vm_mngr.c
index dd0f6cf2..9b7a4c98 100644
--- a/miasm2/jitter/vm_mngr.c
+++ b/miasm2/jitter/vm_mngr.c
@@ -101,14 +101,6 @@ uint64_t set_endian64(vm_mngr_t* vm_mngr, uint64_t val)
 		return Endian64_Swap(val);
 }
 
-uint128_t set_endian128(vm_mngr_t* vm_mngr, uint128_t val)
-{
-	if (vm_mngr->sex == __BYTE_ORDER)
-		return val;
-	else
-		return Endian128_Swap(val);
-}
-
 void print_val(uint64_t base, uint64_t addr)
 {
 	uint64_t *ptr = (uint64_t *) (intptr_t) addr;
@@ -163,14 +155,11 @@ struct memory_page_node * get_memory_page_from_address(vm_mngr_t* vm_mngr, uint6
 	return NULL;
 }
 
-
-
-
-static uint128_t memory_page_read(vm_mngr_t* vm_mngr, unsigned int my_size, uint64_t ad)
+static uint64_t memory_page_read(vm_mngr_t* vm_mngr, unsigned int my_size, uint64_t ad)
 {
 	struct memory_page_node * mpn;
 	unsigned char * addr;
-	uint128_t ret = 0;
+	uint64_t ret = 0;
 	struct memory_breakpoint_info * b;
 
 
@@ -213,11 +202,8 @@ static uint128_t memory_page_read(vm_mngr_t* vm_mngr, unsigned int my_size, uint
 			ret = *((uint64_t*)addr)&0xFFFFFFFFFFFFFFFFULL;
 			ret = set_endian64(vm_mngr, ret);
 			break;
-		case 128:
-			ret = *((uint128_t*)addr)&MASK_128;
-			ret = set_endian128(vm_mngr, ret);
-			break;
 		default:
+			fprintf(stderr, "Bad memory access size %d\n", my_size);
 			exit(EXIT_FAILURE);
 			break;
 		}
@@ -249,10 +235,8 @@ static uint128_t memory_page_read(vm_mngr_t* vm_mngr, unsigned int my_size, uint
 		case 64:
 			ret = set_endian64(vm_mngr, ret);
 			break;
-		case 128:
-			ret = set_endian128(vm_mngr, ret);
-			break;
 		default:
+			fprintf(stderr, "Bad memory access size %d\n", my_size);
 			exit(EXIT_FAILURE);
 			break;
 		}
@@ -261,7 +245,7 @@ static uint128_t memory_page_read(vm_mngr_t* vm_mngr, unsigned int my_size, uint
 }
 
 static void memory_page_write(vm_mngr_t* vm_mngr, unsigned int my_size,
-			      uint64_t ad, uint128_t src)
+			      uint64_t ad, uint64_t src)
 {
 	struct memory_page_node * mpn;
 	unsigned char * addr;
@@ -305,11 +289,8 @@ static void memory_page_write(vm_mngr_t* vm_mngr, unsigned int my_size,
 			src = set_endian64(vm_mngr, src);
 			*((uint64_t*)addr) = src&0xFFFFFFFFFFFFFFFFULL;
 			break;
-		case 128:
-			src = set_endian128(vm_mngr, src);
-			*((uint128_t*)addr) = src&MASK_128;
-			break;
 		default:
+			fprintf(stderr, "Bad memory access size %d\n", my_size);
 			exit(EXIT_FAILURE);
 			break;
 		}
@@ -330,10 +311,8 @@ static void memory_page_write(vm_mngr_t* vm_mngr, unsigned int my_size,
 		case 64:
 			src = set_endian64(vm_mngr, src);
 			break;
-		case 128:
-			src = set_endian128(vm_mngr, src);
-			break;
 		default:
+			fprintf(stderr, "Bad memory access size %d\n", my_size);
 			exit(EXIT_FAILURE);
 			break;
 		}
@@ -501,12 +480,6 @@ void vm_MEM_WRITE_64(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t src)
 	memory_page_write(vm_mngr, 64, addr, src);
 }
 
-void vm_MEM_WRITE_128(vm_mngr_t* vm_mngr, uint64_t addr, uint128_t src)
-{
-	add_mem_write(vm_mngr, addr, 16);
-	memory_page_write(vm_mngr, 128, addr, src);
-}
-
 unsigned char vm_MEM_LOOKUP_08(vm_mngr_t* vm_mngr, uint64_t addr)
 {
 	unsigned char ret;
@@ -535,13 +508,6 @@ uint64_t vm_MEM_LOOKUP_64(vm_mngr_t* vm_mngr, uint64_t addr)
 	ret = memory_page_read(vm_mngr, 64, addr);
 	return ret;
 }
-uint128_t vm_MEM_LOOKUP_128(vm_mngr_t* vm_mngr, uint128_t addr)
-{
-	uint128_t ret;
-	add_mem_read(vm_mngr, addr, 16);
-	ret = memory_page_read(vm_mngr, 128, addr);
-	return ret;
-}
 
 
 int vm_read_mem(vm_mngr_t* vm_mngr, uint64_t addr, char** buffer_ptr, uint64_t size)
diff --git a/miasm2/jitter/vm_mngr.h b/miasm2/jitter/vm_mngr.h
index a50b52d0..d65a45e8 100644
--- a/miasm2/jitter/vm_mngr.h
+++ b/miasm2/jitter/vm_mngr.h
@@ -26,7 +26,6 @@
 #define __LITTLE_ENDIAN _LITTLE_ENDIAN
 #endif
 
-#define uint128_t __uint128_t
 
 #define Endian16_Swap(value) \
       ((((uint16_t)((value) & 0x00FF)) << 8) | \
@@ -48,25 +47,6 @@
 	 ((((uint64_t)value)>>40) & 0x000000000000FF00ULL)  |	      \
 	 ((((uint64_t)value)>>56) & 0x00000000000000FFULL))
 
-#define Endian128_Swap(value)                                   \
-	(((((uint128_t)value)>>120) & 0xFF)             |	\
-	 ((((uint128_t)value)>>112) & 0xFF) << 8	|	\
-	 ((((uint128_t)value)>>104) & 0xFF) << 16       |	\
-	 ((((uint128_t)value)>>96) & 0xFF) << 24	|	\
-	 ((((uint128_t)value)>>88) & 0xFF) << 32	|	\
-	 ((((uint128_t)value)>>80) & 0xFF) << 40	|	\
-	 ((((uint128_t)value)>>72) & 0xFF) << 48	|	\
-	 ((((uint128_t)value)>>64) & 0xFF) << 56	|	\
-	 ((((uint128_t)value)>>56) & 0xFF) << 64	|	\
-	 ((((uint128_t)value)>>48) & 0xFF) << 72	|	\
-	 ((((uint128_t)value)>>40) & 0xFF) << 80	|	\
-	 ((((uint128_t)value)>>32) & 0xFF) << 88	|	\
-	 ((((uint128_t)value)>>24) & 0xFF) << 96	|	\
-	 ((((uint128_t)value)>>16) & 0xFF) << 104       |	\
-	 ((((uint128_t)value)>>8) & 0xFF) << 112	|	\
-	 ((((uint128_t)value)) & 0xFF) << 120)
-
-#define MASK_128 ((uint128_t) 0xFFFFFFFFFFFFFFFFULL | (uint128_t) 0xFFFFFFFFFFFFFFFFULL << 64)
 
 LIST_HEAD(code_bloc_list_head, code_bloc_node);
 LIST_HEAD(memory_breakpoint_info_head, memory_breakpoint_info);
@@ -193,13 +173,11 @@ void vm_MEM_WRITE_08(vm_mngr_t* vm_mngr, uint64_t addr, unsigned char src);
 void vm_MEM_WRITE_16(vm_mngr_t* vm_mngr, uint64_t addr, unsigned short src);
 void vm_MEM_WRITE_32(vm_mngr_t* vm_mngr, uint64_t addr, unsigned int src);
 void vm_MEM_WRITE_64(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t src);
-void vm_MEM_WRITE_128(vm_mngr_t* vm_mngr, uint64_t addr, uint128_t src);
 
 unsigned char vm_MEM_LOOKUP_08(vm_mngr_t* vm_mngr, uint64_t addr);
 unsigned short vm_MEM_LOOKUP_16(vm_mngr_t* vm_mngr, uint64_t addr);
 unsigned int vm_MEM_LOOKUP_32(vm_mngr_t* vm_mngr, uint64_t addr);
 uint64_t vm_MEM_LOOKUP_64(vm_mngr_t* vm_mngr, uint64_t addr);
-uint128_t vm_MEM_LOOKUP_128(vm_mngr_t* vm_mngr, uint128_t addr);
 
 void MEM_WRITE_08_PASSTHROUGH(uint64_t addr, unsigned char src);
 void MEM_WRITE_16_PASSTHROUGH(uint64_t addr, unsigned short src);
diff --git a/setup.py b/setup.py
index 1985a52e..209219b2 100755
--- a/setup.py
+++ b/setup.py
@@ -29,47 +29,62 @@ def buil_all():
     ext_modules_all = [
         Extension("miasm2.jitter.VmMngr",
                   ["miasm2/jitter/vm_mngr.c",
-                   "miasm2/jitter/vm_mngr_py.c"]),
+                   "miasm2/jitter/vm_mngr_py.c",
+                   "miasm2/jitter/bn.c",
+                  ]),
         Extension("miasm2.jitter.arch.JitCore_x86",
                   ["miasm2/jitter/JitCore.c",
                    "miasm2/jitter/vm_mngr.c",
                    "miasm2/jitter/op_semantics.c",
+                   "miasm2/jitter/bn.c",
                    "miasm2/jitter/arch/JitCore_x86.c"]),
         Extension("miasm2.jitter.arch.JitCore_arm",
                   ["miasm2/jitter/JitCore.c",
                    "miasm2/jitter/vm_mngr.c",
                    "miasm2/jitter/op_semantics.c",
+                   "miasm2/jitter/bn.c",
                    "miasm2/jitter/arch/JitCore_arm.c"]),
         Extension("miasm2.jitter.arch.JitCore_aarch64",
                   ["miasm2/jitter/JitCore.c",
                    "miasm2/jitter/vm_mngr.c",
                    "miasm2/jitter/op_semantics.c",
+                   "miasm2/jitter/bn.c",
                    "miasm2/jitter/arch/JitCore_aarch64.c"]),
         Extension("miasm2.jitter.arch.JitCore_msp430",
                   ["miasm2/jitter/JitCore.c",
                    "miasm2/jitter/vm_mngr.c",
                    "miasm2/jitter/op_semantics.c",
+                   "miasm2/jitter/bn.c",
                    "miasm2/jitter/arch/JitCore_msp430.c"]),
         Extension("miasm2.jitter.arch.JitCore_mep",
                   ["miasm2/jitter/JitCore.c",
                    "miasm2/jitter/vm_mngr.c",
+                   "miasm2/jitter/bn.c",
                    "miasm2/jitter/arch/JitCore_mep.c"]),
         Extension("miasm2.jitter.arch.JitCore_mips32",
                   ["miasm2/jitter/JitCore.c",
                    "miasm2/jitter/vm_mngr.c",
                    "miasm2/jitter/op_semantics.c",
+                   "miasm2/jitter/bn.c",
                    "miasm2/jitter/arch/JitCore_mips32.c"]),
         Extension("miasm2.jitter.arch.JitCore_ppc32",
                   ["miasm2/jitter/JitCore.c",
                    "miasm2/jitter/vm_mngr.c",
                    "miasm2/jitter/op_semantics.c",
+                   "miasm2/jitter/bn.c",
                    "miasm2/jitter/arch/JitCore_ppc32.c"],
                   depends=["miasm2/jitter/arch/JitCore_ppc32.h",
-                           "miasm2/jitter/arch/JitCore_ppc32_regs.h"]),
+                           "miasm2/jitter/arch/JitCore_ppc32_regs.h",
+                           "miasm2/jitter/bn.h",
+                  ]),
         Extension("miasm2.jitter.Jitllvm",
-                  ["miasm2/jitter/Jitllvm.c"]),
+                  ["miasm2/jitter/Jitllvm.c",
+                   "miasm2/jitter/bn.c",
+                  ]),
         Extension("miasm2.jitter.Jitgcc",
-                  ["miasm2/jitter/Jitgcc.c"]),
+                  ["miasm2/jitter/Jitgcc.c",
+                   "miasm2/jitter/bn.c",
+                  ]),
         ]
 
     print 'building'