about summary refs log tree commit diff stats
path: root/miasm2/jitter
diff options
context:
space:
mode:
Diffstat (limited to 'miasm2/jitter')
-rw-r--r--miasm2/jitter/JitCore.c11
-rw-r--r--miasm2/jitter/JitCore.h20
-rw-r--r--miasm2/jitter/Jitgcc.c14
-rw-r--r--miasm2/jitter/Jitllvm.c14
-rw-r--r--miasm2/jitter/arch/JitCore_aarch64.c19
-rw-r--r--miasm2/jitter/arch/JitCore_aarch64.h15
-rw-r--r--miasm2/jitter/arch/JitCore_arm.c26
-rw-r--r--miasm2/jitter/arch/JitCore_arm.h9
-rw-r--r--miasm2/jitter/arch/JitCore_mips32.c19
-rw-r--r--miasm2/jitter/arch/JitCore_mips32.h15
-rw-r--r--miasm2/jitter/arch/JitCore_msp430.h12
-rw-r--r--miasm2/jitter/arch/JitCore_ppc32.c32
-rw-r--r--miasm2/jitter/arch/JitCore_ppc32.h5
-rw-r--r--miasm2/jitter/arch/JitCore_x86.c103
-rw-r--r--miasm2/jitter/arch/JitCore_x86.h38
-rw-r--r--miasm2/jitter/codegen.py163
-rw-r--r--miasm2/jitter/jitcore.py189
-rw-r--r--miasm2/jitter/jitcore_cc_base.py17
-rw-r--r--miasm2/jitter/jitcore_gcc.py20
-rw-r--r--miasm2/jitter/jitcore_llvm.py18
-rw-r--r--miasm2/jitter/jitcore_python.py48
-rw-r--r--miasm2/jitter/jitload.py48
-rw-r--r--miasm2/jitter/llvmconvert.py152
-rw-r--r--miasm2/jitter/loader/elf.py2
-rw-r--r--miasm2/jitter/loader/pe.py3
-rw-r--r--miasm2/jitter/op_semantics.c20
-rw-r--r--miasm2/jitter/op_semantics.h26
-rw-r--r--miasm2/jitter/vm_mngr.c42
-rw-r--r--miasm2/jitter/vm_mngr.h27
29 files changed, 614 insertions, 513 deletions
diff --git a/miasm2/jitter/JitCore.c b/miasm2/jitter/JitCore.c
index 84f835f1..496ec8e1 100644
--- a/miasm2/jitter/JitCore.c
+++ b/miasm2/jitter/JitCore.c
@@ -74,6 +74,11 @@ 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)
+{
+	return vm_MEM_LOOKUP_128(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr);
+}
+
 void __attribute__((weak)) MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src)
 {
 	vm_MEM_WRITE_08(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src);
@@ -94,8 +99,10 @@ 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)
+{
+	vm_MEM_WRITE_128(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src);
+}
 
 PyObject* __attribute__((weak)) vm_get_mem(JitCpu *self, PyObject* args)
 {
diff --git a/miasm2/jitter/JitCore.h b/miasm2/jitter/JitCore.h
index f599d6ea..c703178d 100644
--- a/miasm2/jitter/JitCore.h
+++ b/miasm2/jitter/JitCore.h
@@ -4,6 +4,7 @@
 #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)){						\
@@ -30,6 +31,23 @@
 	}								\
 
 
+#define getset_reg_u128(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); \
+	}								\
+	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;		\
+		return 0;						\
+	}
 
 #define getset_reg_u64(regname)						\
 	static PyObject *JitCpu_get_ ## regname  (JitCpu *self, void *closure) \
@@ -122,10 +140,12 @@ 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);
 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);
 PyObject* vm_get_mem(JitCpu *self, PyObject* args);
 
 
diff --git a/miasm2/jitter/Jitgcc.c b/miasm2/jitter/Jitgcc.c
index 79274f24..329b7db4 100644
--- a/miasm2/jitter/Jitgcc.c
+++ b/miasm2/jitter/Jitgcc.c
@@ -10,13 +10,13 @@ typedef struct {
 typedef int (*jitted_func)(block_id*, PyObject*);
 
 
-PyObject* gcc_exec_bloc(PyObject* self, PyObject* args)
+PyObject* gcc_exec_block(PyObject* self, PyObject* args)
 {
 	jitted_func func;
 	PyObject* jitcpu;
 	PyObject* func_py;
 	PyObject* lbl2ptr;
-	PyObject* breakpoints;
+	PyObject* stop_offsets;
 	PyObject* retaddr = NULL;
 	int status;
 	block_id BlockDst;
@@ -26,7 +26,7 @@ PyObject* gcc_exec_bloc(PyObject* self, PyObject* args)
 
 
 	if (!PyArg_ParseTuple(args, "OOOO|K",
-			      &retaddr, &jitcpu, &lbl2ptr, &breakpoints,
+			      &retaddr, &jitcpu, &lbl2ptr, &stop_offsets,
 			      &max_exec_per_call))
 		return NULL;
 
@@ -73,8 +73,8 @@ PyObject* gcc_exec_bloc(PyObject* self, PyObject* args)
 		if (status)
 			return retaddr;
 
-		// Check breakpoint
-		if (PyDict_Contains(breakpoints, retaddr))
+		// Check stop offsets
+		if (PySet_Contains(stop_offsets, retaddr))
 			return retaddr;
 	}
 }
@@ -85,8 +85,8 @@ static PyObject *GccError;
 
 
 static PyMethodDef GccMethods[] = {
-    {"gcc_exec_bloc",  gcc_exec_bloc, METH_VARARGS,
-     "gcc exec bloc"},
+    {"gcc_exec_block",  gcc_exec_block, METH_VARARGS,
+     "gcc exec block"},
     {NULL, NULL, 0, NULL}        /* Sentinel */
 };
 
diff --git a/miasm2/jitter/Jitllvm.c b/miasm2/jitter/Jitllvm.c
index b46f88e3..6ecbd483 100644
--- a/miasm2/jitter/Jitllvm.c
+++ b/miasm2/jitter/Jitllvm.c
@@ -10,7 +10,7 @@
 // Needed to get the JitCpu.cpu offset, arch independent
 #include "arch/JitCore_x86.h"
 
-PyObject* llvm_exec_bloc(PyObject* self, PyObject* args)
+PyObject* llvm_exec_block(PyObject* self, PyObject* args)
 {
 	uint64_t (*func)(void*, void*, void*, uint8_t*);
 	vm_cpu_t* cpu;
@@ -20,14 +20,14 @@ PyObject* llvm_exec_bloc(PyObject* self, PyObject* args)
 	uint8_t status;
 	PyObject* func_py;
 	PyObject* lbl2ptr;
-	PyObject* breakpoints;
+	PyObject* stop_offsets;
 	PyObject* retaddr = NULL;
 	uint64_t max_exec_per_call = 0;
 	uint64_t cpt;
 	int do_cpt;
 
 	if (!PyArg_ParseTuple(args, "OOOO|K",
-			      &retaddr, &jitcpu, &lbl2ptr, &breakpoints,
+			      &retaddr, &jitcpu, &lbl2ptr, &stop_offsets,
 			      &max_exec_per_call))
 		return NULL;
 
@@ -68,16 +68,16 @@ PyObject* llvm_exec_bloc(PyObject* self, PyObject* args)
 		if (status)
 			return retaddr;
 
-		// Check breakpoint
-		if (PyDict_Contains(breakpoints, retaddr))
+		// Check stop offsets
+		if (PySet_Contains(stop_offsets, retaddr))
 			return retaddr;
 	}
 }
 
 
 static PyMethodDef LLVMMethods[] = {
-    {"llvm_exec_bloc",  llvm_exec_bloc, METH_VARARGS,
-     "llvm exec bloc"},
+    {"llvm_exec_block",  llvm_exec_block, METH_VARARGS,
+     "llvm exec block"},
     {NULL, NULL, 0, NULL}        /* Sentinel */
 };
 
diff --git a/miasm2/jitter/arch/JitCore_aarch64.c b/miasm2/jitter/arch/JitCore_aarch64.c
index 0224bfe2..a8502ef9 100644
--- a/miasm2/jitter/arch/JitCore_aarch64.c
+++ b/miasm2/jitter/arch/JitCore_aarch64.c
@@ -284,25 +284,6 @@ PyObject* vm_set_mem(JitCpu *self, PyObject* args)
        return Py_None;
 }
 
-
-UDIV(16)
-UDIV(32)
-UDIV(64)
-
-UMOD(16)
-UMOD(32)
-UMOD(64)
-
-
-IDIV(16)
-IDIV(32)
-IDIV(64)
-
-IMOD(16)
-IMOD(32)
-IMOD(64)
-
-
 static PyMemberDef JitCpu_members[] = {
     {NULL}  /* Sentinel */
 };
diff --git a/miasm2/jitter/arch/JitCore_aarch64.h b/miasm2/jitter/arch/JitCore_aarch64.h
index c7fc3cea..fa50513f 100644
--- a/miasm2/jitter/arch/JitCore_aarch64.h
+++ b/miasm2/jitter/arch/JitCore_aarch64.h
@@ -49,19 +49,4 @@ typedef struct {
 
 void dump_gpregs(vm_cpu_t* vmcpu);
 
-uint64_t udiv64(vm_cpu_t* vmcpu, uint64_t a, uint64_t b);
-uint64_t umod64(vm_cpu_t* vmcpu, uint64_t a, uint64_t b);
-int64_t idiv64(vm_cpu_t* vmcpu, int64_t a, int64_t b);
-int64_t imod64(vm_cpu_t* vmcpu, int64_t a, int64_t b);
-
-uint32_t udiv32(vm_cpu_t* vmcpu, uint32_t a, uint32_t b);
-uint32_t umod32(vm_cpu_t* vmcpu, uint32_t a, uint32_t b);
-int32_t idiv32(vm_cpu_t* vmcpu, int32_t a, int32_t b);
-int32_t imod32(vm_cpu_t* vmcpu, int32_t a, int32_t b);
-
-uint16_t udiv16(vm_cpu_t* vmcpu, uint16_t a, uint16_t b);
-uint16_t umod16(vm_cpu_t* vmcpu, uint16_t a, uint16_t b);
-int16_t idiv16(vm_cpu_t* vmcpu, int16_t a, int16_t b);
-int16_t imod16(vm_cpu_t* vmcpu, int16_t a, int16_t b);
-
 #define RETURN_PC return BlockDst;
diff --git a/miasm2/jitter/arch/JitCore_arm.c b/miasm2/jitter/arch/JitCore_arm.c
index 60b8f95b..8a09ba6c 100644
--- a/miasm2/jitter/arch/JitCore_arm.c
+++ b/miasm2/jitter/arch/JitCore_arm.c
@@ -187,16 +187,6 @@ void check_automod(JitCpu* jitcpu, uint64_t addr, uint64_t size)
 
 }
 
-
-UDIV(32)
-
-UMOD(32)
-
-IDIV(32)
-
-IMOD(32)
-
-
 void MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src)
 {
 	vm_MEM_WRITE_08(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src);
@@ -221,22 +211,6 @@ void MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src)
 	check_automod(jitcpu, addr, 64);
 }
 
-
-uint32_t clz(uint32_t arg)
-{
-
-	int i;
-
-	for (i=0; i<32; i++) {
-		if (arg & (1ull << (31-i)))
-			break;
-	}
-	return i;
-}
-
-
-
-
 PyObject* vm_set_mem(JitCpu *self, PyObject* args)
 {
        PyObject *py_addr;
diff --git a/miasm2/jitter/arch/JitCore_arm.h b/miasm2/jitter/arch/JitCore_arm.h
index 445ac44a..1f3ccaf2 100644
--- a/miasm2/jitter/arch/JitCore_arm.h
+++ b/miasm2/jitter/arch/JitCore_arm.h
@@ -38,13 +38,4 @@ typedef struct {
 
 void dump_gpregs(vm_cpu_t* vmcpu);
 
-
-uint32_t udiv32(vm_cpu_t* vmcpu, uint32_t a, uint32_t b);
-uint32_t umod32(vm_cpu_t* vmcpu, uint32_t a, uint32_t b);
-int32_t idiv32(vm_cpu_t* vmcpu, int32_t a, int32_t b);
-int32_t imod32(vm_cpu_t* vmcpu, int32_t a, int32_t b);
-
-
 #define RETURN_PC return BlockDst;
-
-uint32_t clz(uint32_t arg);
diff --git a/miasm2/jitter/arch/JitCore_mips32.c b/miasm2/jitter/arch/JitCore_mips32.c
index 2142e8cc..4ebfbec8 100644
--- a/miasm2/jitter/arch/JitCore_mips32.c
+++ b/miasm2/jitter/arch/JitCore_mips32.c
@@ -222,25 +222,6 @@ void check_automod(JitCpu* jitcpu, uint64_t addr, uint64_t size)
 }
 
 
-UDIV(16)
-UDIV(32)
-UDIV(64)
-
-UMOD(16)
-UMOD(32)
-UMOD(64)
-
-
-IDIV(16)
-IDIV(32)
-IDIV(64)
-
-IMOD(16)
-IMOD(32)
-IMOD(64)
-
-
-
 void MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src)
 {
 	vm_MEM_WRITE_08(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src);
diff --git a/miasm2/jitter/arch/JitCore_mips32.h b/miasm2/jitter/arch/JitCore_mips32.h
index b45cac2b..ff2045d7 100644
--- a/miasm2/jitter/arch/JitCore_mips32.h
+++ b/miasm2/jitter/arch/JitCore_mips32.h
@@ -335,19 +335,4 @@ typedef struct {
 
 void dump_gpregs(vm_cpu_t* vmcpu);
 
-uint64_t udiv64(vm_cpu_t* vmcpu, uint64_t a, uint64_t b);
-uint64_t umod64(vm_cpu_t* vmcpu, uint64_t a, uint64_t b);
-int64_t idiv64(vm_cpu_t* vmcpu, int64_t a, int64_t b);
-int64_t imod64(vm_cpu_t* vmcpu, int64_t a, int64_t b);
-
-uint32_t udiv32(vm_cpu_t* vmcpu, uint32_t a, uint32_t b);
-uint32_t umod32(vm_cpu_t* vmcpu, uint32_t a, uint32_t b);
-int32_t idiv32(vm_cpu_t* vmcpu, int32_t a, int32_t b);
-int32_t imod32(vm_cpu_t* vmcpu, int32_t a, int32_t b);
-
-uint16_t udiv16(vm_cpu_t* vmcpu, uint16_t a, uint16_t b);
-uint16_t umod16(vm_cpu_t* vmcpu, uint16_t a, uint16_t b);
-int16_t idiv16(vm_cpu_t* vmcpu, int16_t a, int16_t b);
-int16_t imod16(vm_cpu_t* vmcpu, int16_t a, int16_t b);
-
 #define RETURN_PC return BlockDst;
diff --git a/miasm2/jitter/arch/JitCore_msp430.h b/miasm2/jitter/arch/JitCore_msp430.h
index cad028a9..3934d37a 100644
--- a/miasm2/jitter/arch/JitCore_msp430.h
+++ b/miasm2/jitter/arch/JitCore_msp430.h
@@ -36,16 +36,4 @@ typedef struct {
 
 #define RETURN_PC return BlockDst;
 
-uint16_t bcdadd_16(uint16_t a, uint16_t b);
-
-uint16_t bcdadd_cf_16(uint16_t a, uint16_t b);
-
-uint16_t hex2bcd_16(uint16_t a);
-
-uint8_t hex2bcd_8(uint8_t a);
-
-uint8_t bcd2hex_8(uint8_t a);
-
-uint16_t bcd2hex_16(uint16_t a);
-
 void dump_gpregs(vm_cpu_t* vmcpu);
diff --git a/miasm2/jitter/arch/JitCore_ppc32.c b/miasm2/jitter/arch/JitCore_ppc32.c
index 7ea5e88f..616e7cfd 100644
--- a/miasm2/jitter/arch/JitCore_ppc32.c
+++ b/miasm2/jitter/arch/JitCore_ppc32.c
@@ -246,38 +246,6 @@ get_gpreg_offset_all(void) {
     return dict;
 }
 
-int32_t
-idiv32(struct vm_cpu *cpu, int32_t a, int32_t b) {
-    if (b == 0)
-	return 0;
-
-    return a / b;
-}
-
-uint32_t
-udiv32(struct vm_cpu *cpu, uint32_t a, uint32_t b) {
-    if (b == 0)
-	return 0;
-
-    return a / b;
-}
-
-int32_t
-imod32(struct vm_cpu *cpu, int32_t a, int32_t b) {
-    if (b == 0)
-	return 0;
-
-    return a % b;
-}
-
-uint32_t
-umod32(struct vm_cpu *cpu, uint32_t a, uint32_t b) {
-    if (b == 0)
-	return 0;
-
-    return a % b;
-}
-
 static PyGetSetDef JitCpu_getseters[] = {
     {"vmmngr",
      (getter)JitCpu_get_vmmngr, (setter)JitCpu_set_vmmngr,
diff --git a/miasm2/jitter/arch/JitCore_ppc32.h b/miasm2/jitter/arch/JitCore_ppc32.h
index 18cee358..5a048190 100644
--- a/miasm2/jitter/arch/JitCore_ppc32.h
+++ b/miasm2/jitter/arch/JitCore_ppc32.h
@@ -14,11 +14,6 @@ struct vm_cpu {
     uint32_t reserve_address;
 };
 
-int32_t idiv32(struct vm_cpu *, int32_t, int32_t);
-uint32_t udiv32(struct vm_cpu *, uint32_t, uint32_t);
-int32_t imod32(struct vm_cpu *, int32_t, int32_t);
-uint32_t umod32(struct vm_cpu *, uint32_t, uint32_t);
-
 void dump_gpregs(struct vm_cpu *);
 
 typedef struct vm_cpu vm_cpu_t;
diff --git a/miasm2/jitter/arch/JitCore_x86.c b/miasm2/jitter/arch/JitCore_x86.c
index e1e36989..eda6e6e5 100644
--- a/miasm2/jitter/arch/JitCore_x86.c
+++ b/miasm2/jitter/arch/JitCore_x86.c
@@ -55,6 +55,23 @@ reg_dict gpreg_dict[] = { {.name = "RAX", .offset = offsetof(vm_cpu_t, RAX)},
 			  {.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)},
 
@@ -120,6 +137,23 @@ 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(tsc1);
     get_reg(tsc2);
 
@@ -330,24 +364,6 @@ uint64_t segm2addr(JitCpu* jitcpu, uint64_t segm, uint64_t addr)
 	return addr + ((vm_cpu_t*)jitcpu->cpu)->segm_base[segm];
 }
 
-
-UDIV(16)
-UDIV(32)
-UDIV(64)
-
-UMOD(16)
-UMOD(32)
-UMOD(64)
-
-
-IDIV(16)
-IDIV(32)
-IDIV(64)
-
-IMOD(16)
-IMOD(32)
-IMOD(64)
-
 void MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src)
 {
 	vm_MEM_WRITE_08(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src);
@@ -544,6 +560,23 @@ 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_u32(tsc1);
 getset_reg_u32(tsc2);
 
@@ -620,6 +653,23 @@ PyObject* get_gpreg_offset_all(void)
     get_reg_off(MM6);
     get_reg_off(MM7);
 
+    get_reg_off(XMM0);
+    get_reg_off(XMM1);
+    get_reg_off(XMM2);
+    get_reg_off(XMM3);
+    get_reg_off(XMM4);
+    get_reg_off(XMM5);
+    get_reg_off(XMM6);
+    get_reg_off(XMM7);
+    get_reg_off(XMM8);
+    get_reg_off(XMM9);
+    get_reg_off(XMM10);
+    get_reg_off(XMM11);
+    get_reg_off(XMM12);
+    get_reg_off(XMM13);
+    get_reg_off(XMM14);
+    get_reg_off(XMM15);
+
     get_reg_off(tsc1);
     get_reg_off(tsc2);
 
@@ -708,6 +758,23 @@ static PyGetSetDef JitCpu_getseters[] = {
     {"MM6", (getter)JitCpu_get_MM6, (setter)JitCpu_set_MM6, "MM6", NULL},
     {"MM7", (getter)JitCpu_get_MM7, (setter)JitCpu_set_MM7, "MM7", NULL},
 
+    {"XMM0", (getter)JitCpu_get_XMM0, (setter)JitCpu_set_XMM0, "XMM0", NULL},
+    {"XMM1", (getter)JitCpu_get_XMM1, (setter)JitCpu_set_XMM1, "XMM1", NULL},
+    {"XMM2", (getter)JitCpu_get_XMM2, (setter)JitCpu_set_XMM2, "XMM2", NULL},
+    {"XMM3", (getter)JitCpu_get_XMM3, (setter)JitCpu_set_XMM3, "XMM3", NULL},
+    {"XMM4", (getter)JitCpu_get_XMM4, (setter)JitCpu_set_XMM4, "XMM4", NULL},
+    {"XMM5", (getter)JitCpu_get_XMM5, (setter)JitCpu_set_XMM5, "XMM5", NULL},
+    {"XMM6", (getter)JitCpu_get_XMM6, (setter)JitCpu_set_XMM6, "XMM6", NULL},
+    {"XMM7", (getter)JitCpu_get_XMM7, (setter)JitCpu_set_XMM7, "XMM7", NULL},
+    {"XMM8", (getter)JitCpu_get_XMM8, (setter)JitCpu_set_XMM8, "XMM8", NULL},
+    {"XMM9", (getter)JitCpu_get_XMM9, (setter)JitCpu_set_XMM9, "XMM9", NULL},
+    {"XMM10", (getter)JitCpu_get_XMM10, (setter)JitCpu_set_XMM10, "XMM10", NULL},
+    {"XMM11", (getter)JitCpu_get_XMM11, (setter)JitCpu_set_XMM11, "XMM11", NULL},
+    {"XMM12", (getter)JitCpu_get_XMM12, (setter)JitCpu_set_XMM12, "XMM12", NULL},
+    {"XMM13", (getter)JitCpu_get_XMM13, (setter)JitCpu_set_XMM13, "XMM13", NULL},
+    {"XMM14", (getter)JitCpu_get_XMM14, (setter)JitCpu_set_XMM14, "XMM14", NULL},
+    {"XMM15", (getter)JitCpu_get_XMM15, (setter)JitCpu_set_XMM15, "XMM15", NULL},
+
     {"tsc1", (getter)JitCpu_get_tsc1, (setter)JitCpu_set_tsc1, "tsc1", NULL},
     {"tsc2", (getter)JitCpu_get_tsc2, (setter)JitCpu_set_tsc2, "tsc2", NULL},
 
diff --git a/miasm2/jitter/arch/JitCore_x86.h b/miasm2/jitter/arch/JitCore_x86.h
index e55948e6..221ba5db 100644
--- a/miasm2/jitter/arch/JitCore_x86.h
+++ b/miasm2/jitter/arch/JitCore_x86.h
@@ -1,3 +1,4 @@
+#define uint128_t __uint128_t
 
 typedef struct {
 	uint32_t exception_flags;
@@ -96,31 +97,30 @@ typedef struct {
 	uint64_t MM6;
 	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;
+
 	uint32_t segm_base[0x10000];
 
 }vm_cpu_t;
 
-
-
-
 void dump_gpregs_32(vm_cpu_t* vmcpu);
 void dump_gpregs_64(vm_cpu_t* vmcpu);
 uint64_t segm2addr(JitCpu* jitcpu, uint64_t segm, uint64_t addr);
 
-
-uint64_t udiv64(vm_cpu_t* vmcpu, uint64_t a, uint64_t b);
-uint64_t umod64(vm_cpu_t* vmcpu, uint64_t a, uint64_t b);
-int64_t idiv64(vm_cpu_t* vmcpu, int64_t a, int64_t b);
-int64_t imod64(vm_cpu_t* vmcpu, int64_t a, int64_t b);
-
-uint32_t udiv32(vm_cpu_t* vmcpu, uint32_t a, uint32_t b);
-uint32_t umod32(vm_cpu_t* vmcpu, uint32_t a, uint32_t b);
-int32_t idiv32(vm_cpu_t* vmcpu, int32_t a, int32_t b);
-int32_t imod32(vm_cpu_t* vmcpu, int32_t a, int32_t b);
-
-uint16_t udiv16(vm_cpu_t* vmcpu, uint16_t a, uint16_t b);
-uint16_t umod16(vm_cpu_t* vmcpu, uint16_t a, uint16_t b);
-int16_t idiv16(vm_cpu_t* vmcpu, int16_t a, int16_t b);
-int16_t imod16(vm_cpu_t* vmcpu, int16_t a, int16_t b);
-
 #define RETURN_PC return BlockDst;
diff --git a/miasm2/jitter/codegen.py b/miasm2/jitter/codegen.py
index 2c546be8..10140fd2 100644
--- a/miasm2/jitter/codegen.py
+++ b/miasm2/jitter/codegen.py
@@ -2,17 +2,18 @@
 Module to generate C code for a given native @block
 """
 
-import miasm2.expression.expression as m2_expr
+from miasm2.expression.expression import Expr, ExprId, ExprLoc, ExprInt, \
+    ExprMem, ExprCond, LocKey
 from miasm2.ir.ir import IRBlock, AssignBlock
-from miasm2.ir.translators import Translator
-from miasm2.core.asmblock import expr_is_label, AsmBlockBad, AsmLabel
 
-# Miasm to C translator
-TRANSLATOR = Translator.to_language("C")
+from miasm2.ir.translators.C import TranslatorC
+from miasm2.core.asmblock import AsmBlockBad
 
-SIZE_TO_MASK = {x: 2**x - 1 for x in (1, 2, 3, 7, 8, 16, 32, 64)}
+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)}
 
-MASK_INT = 0xffffffffffffffff
 
 
 class Attributes(object):
@@ -101,26 +102,21 @@ class CGen(object):
     def __init__(self, ir_arch):
         self.ir_arch = ir_arch
         self.PC = self.ir_arch.pc
+        self.translator = TranslatorC(self.ir_arch.loc_db)
         self.init_arch_C()
 
     def init_arch_C(self):
         """Iinitialize jitter internals"""
         self.id_to_c_id = {}
         for reg in self.ir_arch.arch.regs.all_regs_ids:
-            self.id_to_c_id[reg] = m2_expr.ExprId('mycpu->%s' % reg, reg.size)
+            self.id_to_c_id[reg] = ExprId('mycpu->%s' % reg, reg.size)
 
         self.C_PC = self.id_to_c(self.PC)
 
-    @staticmethod
-    def label_to_jitlabel(lbl):
-        """Convert AsmLabel to a jitter label name"""
-        assert lbl.offset is not None
-        return "jitblock_%X" % lbl.offset
-
     def dst_to_c(self, src):
         """Translate Expr @src into C code"""
-        if not isinstance(src, m2_expr.Expr):
-            src = m2_expr.ExprInt(src, self.PC.size)
+        if not isinstance(src, Expr):
+            src = ExprInt(src, self.PC.size)
         return self.id_to_c(src)
 
     def patch_c_id(self, expr):
@@ -129,14 +125,14 @@ class CGen(object):
 
     def id_to_c(self, expr):
         """Translate Expr @expr into corresponding C code"""
-        return TRANSLATOR.from_expr(self.patch_c_id(expr))
+        return self.translator.from_expr(self.patch_c_id(expr))
 
-    def add_label_index(self, dst2index, lbl):
+    def add_label_index(self, dst2index, loc_key):
         """Insert @lbl to the dictionnary @dst2index with a uniq value
-        @dst2index: AsmLabel -> uniq value
-        @lbl: AsmLabel istance"""
+        @dst2index: LocKey -> uniq value
+        @loc_key: LocKey istance"""
 
-        dst2index[lbl] = len(dst2index)
+        dst2index[loc_key] = len(dst2index)
 
     def assignblk_to_irbloc(self, instr, assignblk):
         """
@@ -147,10 +143,11 @@ class CGen(object):
         new_assignblk = dict(assignblk)
         if self.ir_arch.IRDst not in assignblk:
             offset = instr.offset + instr.l
-            dst = m2_expr.ExprInt(offset, self.ir_arch.IRDst.size)
+            loc_key = self.ir_arch.loc_db.get_or_create_offset_location(offset)
+            dst = ExprLoc(loc_key, self.ir_arch.IRDst.size)
             new_assignblk[self.ir_arch.IRDst] = dst
         irs = [AssignBlock(new_assignblk, instr)]
-        return IRBlock(self.ir_arch.get_instr_label(instr), irs)
+        return IRBlock(self.ir_arch.get_loc_key_for_instr(instr), irs)
 
     def block2assignblks(self, block):
         """
@@ -168,6 +165,7 @@ class CGen(object):
             for irblock in irblocks:
                 assert irblock.dst is not None
             irblocks_list.append(irblocks)
+
         return irblocks_list
 
     def add_local_var(self, dst_var, dst_index, expr):
@@ -183,7 +181,7 @@ class CGen(object):
         if size not in dst_index:
             raise RuntimeError("Unsupported operand size %s", size)
         var_num = dst_index[size]
-        dst = m2_expr.ExprId("var_%.2d_%.2d" % (size, var_num), size)
+        dst = ExprId("var_%.2d_%.2d" % (size, var_num), size)
         dst_index[size] += 1
         dst_var[expr] = dst
         return dst
@@ -199,12 +197,13 @@ class CGen(object):
 
         # Prefetch memory read
         for expr in assignblk.get_r(mem_read=True):
-            if not isinstance(expr, m2_expr.ExprMem):
+            if not isinstance(expr, ExprMem):
                 continue
             var_num = mem_index[expr.size]
             mem_index[expr.size] += 1
-            var = m2_expr.ExprId(
-                "prefetch_%.2d_%.2d" % (expr.size, var_num), expr.size)
+            var = ExprId(
+                "prefetch_%.2d_%.2d" % (expr.size, var_num), expr.size
+            )
             mem_var[expr] = var
 
         # Generate memory prefetch
@@ -236,9 +235,9 @@ class CGen(object):
 
         for dst, src in sorted(assignblk.iteritems()):
             src = src.replace_expr(prefetchers)
-            if dst is self.ir_arch.IRDst:
+            if dst == self.ir_arch.IRDst:
                 pass
-            elif isinstance(dst, m2_expr.ExprId):
+            elif isinstance(dst, ExprId):
                 new_dst = self.add_local_var(dst_var, dst_index, dst)
                 if dst in self.ir_arch.arch.regs.regs_flt_expr:
                     # Dont mask float affectation
@@ -246,19 +245,19 @@ class CGen(object):
                         '%s = (%s);' % (self.id_to_c(new_dst), self.id_to_c(src)))
                 else:
                     c_main.append(
-                        '%s = (%s)&0x%X;' % (self.id_to_c(new_dst),
-                                             self.id_to_c(src),
-                                             SIZE_TO_MASK[src.size]))
-            elif isinstance(dst, m2_expr.ExprMem):
+                        '%s = (%s)&%s;' % (self.id_to_c(new_dst),
+                                           self.id_to_c(src),
+                                           SIZE_TO_MASK[src.size]))
+            elif isinstance(dst, ExprMem):
                 ptr = dst.arg.replace_expr(prefetchers)
-                new_dst = m2_expr.ExprMem(ptr, dst.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:
                 raise ValueError("Unknown dst")
 
         for dst, new_dst in dst_var.iteritems():
-            if dst is self.ir_arch.IRDst:
+            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))
@@ -283,25 +282,25 @@ class CGen(object):
         @dst2index: dictionnary to link label to its index
         """
 
-        if isinstance(expr, m2_expr.ExprCond):
+        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)
             return ("((%s)?(%s):(%s))" % (cond, src1, src2),
                     "((%s)?(%s):(%s))" % (cond, src1b, src2b))
-        if isinstance(expr, m2_expr.ExprInt):
+        if isinstance(expr, ExprInt):
             offset = int(expr)
-            self.add_label_index(dst2index, offset)
-            return ("%s" % dst2index[offset], hex(offset))
-        if expr_is_label(expr):
-            label = expr.name
-            if label.offset != None:
-                offset = label.offset
-                self.add_label_index(dst2index, offset)
-                return ("%s" % dst2index[offset], hex(offset))
-            self.add_label_index(dst2index, label)
-            return ("%s" % dst2index[label], "0")
-
+            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))
+        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))
+            self.add_label_index(dst2index, loc_key)
+            return ("%s" % dst2index[loc_key], "0")
         dst2index[expr] = -1
         return ("-1", self.id_to_c(expr))
 
@@ -337,8 +336,12 @@ class CGen(object):
         out = []
 
         if instr_attrib.log_mn:
-            out.append('printf("%.8X %s\\n");' % (instr_attrib.instr.offset,
-                                                  instr_attrib.instr))
+            out.append(
+                'printf("%.8X %s\\n");' % (
+                    instr_attrib.instr.offset,
+                    instr_attrib.instr.to_string(self.ir_arch.loc_db)
+                )
+            )
         return out
 
     def gen_post_code(self, attrib):
@@ -354,24 +357,27 @@ class CGen(object):
         @attrib: instruction Attributes
         @instr_offsets: instructions offsets list
         @dst: potential instruction destination"""
-        if isinstance(dst, AsmLabel) and dst.offset is None:
-            # Generate goto for local labels
-            return ['goto %s;' % dst.name]
-        offset = None
-        if isinstance(dst, AsmLabel) and dst.offset is not None:
-            offset = dst.offset
-        elif isinstance(dst, (int, long)):
-            offset = dst
+
         out = []
-        if (offset is not None and
-            offset > attrib.instr.offset and
+        if isinstance(dst, Expr):
+            out += self.gen_post_code(attrib)
+            out.append('BlockDst->address = DST_value;')
+            out += self.gen_post_instr_checks(attrib)
+            out.append('\t\treturn JIT_RET_NO_EXCEPTION;')
+            return out
+
+        assert isinstance(dst, LocKey)
+        offset = self.ir_arch.loc_db.get_location_offset(dst)
+        if offset is None:
+            # Generate goto for local labels
+            return ['goto %s;' % dst]
+        if (offset > attrib.instr.offset and
             offset in instr_offsets):
             # Only generate goto for next instructions.
             # (consecutive instructions)
-            lbl = self.ir_arch.symbol_pool.getby_offset_create(dst)
             out += self.gen_post_code(attrib)
             out += self.gen_post_instr_checks(attrib)
-            out.append('goto %s;' % self.label_to_jitlabel(lbl))
+            out.append('goto %s;' % dst)
         else:
             out += self.gen_post_code(attrib)
             out.append('BlockDst->address = DST_value;')
@@ -467,10 +473,10 @@ class CGen(object):
 
         element_read = assignblk.get_r(mem_read=True)
         # Check mem read
-        attrib.mem_read = any(isinstance(expr, m2_expr.ExprMem)
+        attrib.mem_read = any(isinstance(expr, ExprMem)
                               for expr in element_read)
         # Check mem write
-        attrib.mem_write = any(isinstance(dst, m2_expr.ExprMem)
+        attrib.mem_write = any(isinstance(dst, ExprMem)
                                for dst in assignblk)
 
     def get_attributes(self, instr, irblocks, log_mn=False, log_regs=False):
@@ -512,7 +518,7 @@ class CGen(object):
 
         last_instr = block.lines[-1]
         offset = last_instr.offset + last_instr.l
-        return self.ir_arch.symbol_pool.getby_offset_create(offset)
+        return self.ir_arch.loc_db.get_or_create_offset_location(offset)
 
     def gen_init(self, block):
         """
@@ -521,9 +527,11 @@ class CGen(object):
         """
 
         instr_offsets = [line.offset for line in block.lines]
-        instr_offsets.append(self.get_block_post_label(block).offset)
-        lbl_start = self.ir_arch.symbol_pool.getby_offset_create(instr_offsets[0])
-        return (self.CODE_INIT % self.label_to_jitlabel(lbl_start)).split("\n"), instr_offsets
+        post_label = self.get_block_post_label(block)
+        post_offset = self.ir_arch.loc_db.get_location_offset(post_label)
+        instr_offsets.append(post_offset)
+        lbl_start = block.loc_key
+        return (self.CODE_INIT % lbl_start).split("\n"), instr_offsets
 
     def gen_irblock(self, instr_attrib, attributes, instr_offsets, irblock):
         """
@@ -555,9 +563,10 @@ class CGen(object):
         Generate the C code for the final block instruction
         """
 
-        lbl = self.get_block_post_label(block)
-        dst = self.dst_to_c(lbl.offset)
-        code = self.CODE_RETURN_NO_EXCEPTION % (self.label_to_jitlabel(lbl), self.C_PC, dst, dst)
+        loc_key = self.get_block_post_label(block)
+        offset = self.ir_arch.loc_db.get_location_offset(loc_key)
+        dst = self.dst_to_c(offset)
+        code = self.CODE_RETURN_NO_EXCEPTION % (loc_key, self.C_PC, dst, dst)
         return code.split('\n')
 
     def gen_c(self, block, log_mn=False, log_regs=False):
@@ -570,23 +579,19 @@ class CGen(object):
         if isinstance(block, AsmBlockBad):
             return self.gen_bad_block()
         irblocks_list = self.block2assignblks(block)
-
         out, instr_offsets = self.gen_init(block)
         assert len(block.lines) == len(irblocks_list)
         for instr, irblocks in zip(block.lines, irblocks_list):
             instr_attrib, irblocks_attributes = self.get_attributes(instr, irblocks, log_mn, log_regs)
-
             for index, irblock in enumerate(irblocks):
                 new_irblock = self.ir_arch.irbloc_fix_regs_for_mode(irblock, self.ir_arch.attrib)
-                if new_irblock.label.offset is None:
-                    out.append("%-40s // %.16X %s" %
-                               (str(new_irblock.label.name) + ":", instr.offset, instr))
-                else:
-                    out.append("%-40s // %.16X %s" %
-                               (self.label_to_jitlabel(new_irblock.label) + ":", instr.offset, instr))
+                label = str(new_irblock.loc_key)
+                out.append("%-40s // %.16X %s" %
+                           (label + ":", instr.offset, instr))
                 if index == 0:
                     out += self.gen_pre_code(instr_attrib)
                 out += self.gen_irblock(instr_attrib, irblocks_attributes[index], instr_offsets, new_irblock)
 
         out += self.gen_finalize(block)
+
         return ['\t' + line for line in out]
diff --git a/miasm2/jitter/jitcore.py b/miasm2/jitter/jitcore.py
index f2b1375d..fc5cf35e 100644
--- a/miasm2/jitter/jitcore.py
+++ b/miasm2/jitter/jitcore.py
@@ -16,66 +16,69 @@
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 #
 from hashlib import md5
+import warnings
 
-from miasm2.core import asmblock
+from miasm2.core.asmblock import disasmEngine, AsmBlockBad
 from miasm2.core.interval import interval
 from miasm2.core.utils import BoundedDict
+from miasm2.expression.expression import LocKey
 from miasm2.jitter.csts import *
 
-
 class JitCore(object):
 
     "JiT management. This is an abstract class"
 
+    # Jitted function's name
+    FUNCNAME = "block_entry"
+
     jitted_block_delete_cb = None
     jitted_block_max_size = 10000
 
-    def __init__(self, ir_arch, bs=None):
+    def __init__(self, ir_arch, bin_stream):
         """Initialise a JitCore instance.
         @ir_arch: ir instance for current architecture
-        @bs: bitstream
+        @bin_stream: bin_stream instance
         """
-
+        # Arch related
         self.ir_arch = ir_arch
+        self.ircfg = self.ir_arch.new_ircfg()
         self.arch_name = "%s%s" % (self.ir_arch.arch.name, self.ir_arch.attrib)
-        self.bs = bs
-        self.known_blocs = {}
-        self.lbl2jitbloc = BoundedDict(self.jitted_block_max_size,
+
+        # Structures for block tracking
+        self.offset_to_jitted_func = BoundedDict(self.jitted_block_max_size,
                                        delete_cb=self.jitted_block_delete_cb)
-        self.lbl2bloc = {}
+        self.loc_key_to_block = {}
+        self.blocks_mem_interval = interval()
+
+        # Logging & options
         self.log_mn = False
         self.log_regs = False
         self.log_newbloc = False
-        self.segm_to_do = set()
-        self.jitcount = 0
-        self.addr2obj = {}
-        self.addr2objref = {}
-        self.blocs_mem_interval = interval()
-        self.disasm_cb = None
-        self.split_dis = set()
         self.options = {"jit_maxline": 50,  # Maximum number of line jitted
                         "max_exec_per_call": 0 # 0 means no limit
                         }
 
-        self.mdis = asmblock.disasmEngine(ir_arch.arch, ir_arch.attrib, bs,
-                                          lines_wd=self.options["jit_maxline"],
-                                          symbol_pool=ir_arch.symbol_pool,
-                                          follow_call=False,
-                                          dontdis_retcall=False,
-                                          split_dis=self.split_dis,
-                                          dis_block_callback=self.disasm_cb)
+        # Disassembly Engine
+        self.split_dis = set()
+        self.mdis = disasmEngine(
+            ir_arch.arch, ir_arch.attrib, bin_stream,
+            lines_wd=self.options["jit_maxline"],
+            loc_db=ir_arch.loc_db,
+            follow_call=False,
+            dontdis_retcall=False,
+            split_dis=self.split_dis,
+        )
 
 
     def set_options(self, **kwargs):
         "Set options relative to the backend"
-
         self.options.update(kwargs)
 
     def clear_jitted_blocks(self):
         "Reset all jitted blocks"
-        self.lbl2jitbloc.clear()
-        self.lbl2bloc.clear()
-        self.blocs_mem_interval = interval()
+        self.offset_to_jitted_func.clear()
+        self.loc_key_to_block.clear()
+        self.blocks_mem_interval = interval()
 
     def add_disassembly_splits(self, *args):
         """The disassembly engine will stop on address in args if they
@@ -90,7 +93,7 @@ class JitCore(object):
         "Initialise the Jitter"
         raise NotImplementedError("Abstract class")
 
-    def get_bloc_min_max(self, cur_block):
+    def set_block_min_max(self, cur_block):
         "Update cur_block to set min/max address"
 
         if cur_block.lines:
@@ -98,94 +101,107 @@ class JitCore(object):
             cur_block.ad_max = cur_block.lines[-1].offset + cur_block.lines[-1].l
         else:
             # 1 byte block for unknown mnemonic
-            cur_block.ad_min = cur_block.label.offset
-            cur_block.ad_max = cur_block.label.offset+1
+            offset = ir_arch.loc_db.get_location_offset(cur_block.loc_key)
+            cur_block.ad_min = offset
+            cur_block.ad_max = offset+1
 
 
-    def add_bloc_to_mem_interval(self, vm, block):
+    def add_block_to_mem_interval(self, vm, block):
         "Update vm to include block addresses in its memory range"
-
-        self.blocs_mem_interval += interval([(block.ad_min, block.ad_max - 1)])
+        self.blocks_mem_interval += interval([(block.ad_min, block.ad_max - 1)])
 
         vm.reset_code_bloc_pool()
-        for a, b in self.blocs_mem_interval:
+        for a, b in self.blocks_mem_interval:
             vm.add_code_bloc(a, b + 1)
 
-    def jitirblocs(self, label, irblocks):
+    def jit_irblocks(self, label, irblocks):
         """JiT a group of irblocks.
         @label: the label of the irblocks
-        @irblocks: a gorup of irblocks
+        @irblocks: a group of irblocks
         """
 
         raise NotImplementedError("Abstract class")
 
-    def add_bloc(self, block):
+    def add_block(self, block):
         """Add a block to JiT and JiT it.
         @block: asm_bloc to add
         """
-
-        irblocks = self.ir_arch.add_block(block, gen_pc_updt = True)
+        irblocks = self.ir_arch.add_asmblock_to_ircfg(block, self.ircfg, gen_pc_updt = True)
         block.blocks = irblocks
-        self.jitirblocs(block.label, irblocks)
+        self.jit_irblocks(block.loc_key, irblocks)
 
-    def disbloc(self, addr, vm):
+    def disasm_and_jit_block(self, addr, vm):
         """Disassemble a new block and JiT it
-        @addr: address of the block to disassemble (AsmLabel or int)
+        @addr: address of the block to disassemble (LocKey or int)
         @vm: VmMngr instance
         """
 
         # Get the block
-        if isinstance(addr, asmblock.AsmLabel):
-            addr = addr.offset
+        if isinstance(addr, LocKey):
+            addr = self.ir_arch.loc_db.get_location_offset(addr)
+            if addr is None:
+                raise RuntimeError("Unknown offset for LocKey")
 
         # Prepare disassembler
         self.mdis.lines_wd = self.options["jit_maxline"]
-        self.mdis.dis_block_callback = self.disasm_cb
 
         # Disassemble it
-        try:
-            cur_block = self.mdis.dis_block(addr)
-        except IOError:
-            # vm_exception_flag is set
-            label = self.ir_arch.symbol_pool.getby_offset_create(addr)
-            cur_block = asmblock.AsmBlockBad(label)
-
+        cur_block = self.mdis.dis_block(addr)
+        if isinstance(cur_block, AsmBlockBad):
+            return cur_block
         # Logging
         if self.log_newbloc:
-            print cur_block
+            print cur_block.to_string(self.mdis.loc_db)
 
         # Update label -> block
-        self.lbl2bloc[cur_block.label] = cur_block
+        self.loc_key_to_block[cur_block.loc_key] = cur_block
 
         # Store min/max block address needed in jit automod code
-        self.get_bloc_min_max(cur_block)
+        self.set_block_min_max(cur_block)
 
         # JiT it
-        self.add_bloc(cur_block)
+        self.add_block(cur_block)
 
         # Update jitcode mem range
-        self.add_bloc_to_mem_interval(vm, cur_block)
-
-    def runbloc(self, cpu, lbl, breakpoints):
-        """Run the block starting at lbl.
+        self.add_block_to_mem_interval(vm, cur_block)
+        return cur_block
+
+    def run_at(self, cpu, offset, stop_offsets):
+        """Run from the starting address @offset.
+        Execution will stop if:
+        - max_exec_per_call option is reached
+        - a new, yet unknown, block is reached after the execution of block at
+          address @offset
+        - an address in @stop_offsets is reached
         @cpu: JitCpu instance
-        @lbl: target label
+        @offset: starting address (int)
+        @stop_offsets: set of address on which the jitter must stop
         """
 
-        if lbl is None:
-            lbl = getattr(cpu, self.ir_arch.pc.name)
+        if offset is None:
+            offset = getattr(cpu, self.ir_arch.pc.name)
 
-        if not lbl in self.lbl2jitbloc:
+        if offset not in self.offset_to_jitted_func:
             # Need to JiT the block
-            self.disbloc(lbl, cpu.vmmngr)
+            cur_block = self.disasm_and_jit_block(offset, cpu.vmmngr)
+            if isinstance(cur_block, AsmBlockBad):
+                errno = cur_block.errno
+                if errno == AsmBlockBad.ERROR_IO:
+                    cpu.vmmngr.set_exception(EXCEPT_ACCESS_VIOL)
+                elif errno == AsmBlockBad.ERROR_CANNOT_DISASM:
+                    cpu.set_exception(EXCEPT_UNK_MNEMO)
+                else:
+                    raise RuntimeError("Unhandled disasm result %r" % errno)
+                return offset
 
         # Run the block and update cpu/vmmngr state
-        return self.exec_wrapper(lbl, cpu, self.lbl2jitbloc.data, breakpoints,
+        return self.exec_wrapper(offset, cpu, self.offset_to_jitted_func.data,
+                                 stop_offsets,
                                  self.options["max_exec_per_call"])
 
-    def blocs2memrange(self, blocks):
+    def blocks_to_memrange(self, blocks):
         """Return an interval instance standing for blocks addresses
-        @blocks: list of asm_bloc instances
+        @blocks: list of AsmBlock instances
         """
 
         mem_range = interval()
@@ -204,10 +220,10 @@ class JitCore(object):
         vm.reset_code_bloc_pool()
 
         # Add blocks in the pool
-        for start, stop in self.blocs_mem_interval:
+        for start, stop in self.blocks_mem_interval:
             vm.add_code_bloc(start, stop + 1)
 
-    def del_bloc_in_range(self, ad1, ad2):
+    def del_block_in_range(self, ad1, ad2):
         """Find and remove jitted block in range [ad1, ad2].
         Return the list of block removed.
         @ad1: First address
@@ -216,7 +232,7 @@ class JitCore(object):
 
         # Find concerned blocks
         modified_blocks = set()
-        for block in self.lbl2bloc.values():
+        for block in self.loc_key_to_block.values():
             if not block.lines:
                 continue
             if block.ad_max <= ad1 or block.ad_min >= ad2:
@@ -227,26 +243,28 @@ class JitCore(object):
                 modified_blocks.add(block)
 
         # Generate interval to delete
-        del_interval = self.blocs2memrange(modified_blocks)
+        del_interval = self.blocks_to_memrange(modified_blocks)
 
         # Remove interval from monitored interval list
-        self.blocs_mem_interval -= del_interval
+        self.blocks_mem_interval -= del_interval
 
         # Remove modified blocks
         for block in modified_blocks:
             try:
                 for irblock in block.blocks:
                     # Remove offset -> jitted block link
-                    if irblock.label.offset in self.lbl2jitbloc:
-                        del(self.lbl2jitbloc[irblock.label.offset])
+                    offset = self.ir_arch.loc_db.get_location_offset(irblock.loc_key)
+                    if offset in self.offset_to_jitted_func:
+                        del(self.offset_to_jitted_func[offset])
 
             except AttributeError:
                 # The block has never been translated in IR
-                if block.label.offset in self.lbl2jitbloc:
-                    del(self.lbl2jitbloc[block.label.offset])
+                offset = self.ir_arch.loc_db.get_location_offset(block.loc_key)
+                if offset in self.offset_to_jitted_func:
+                    del(self.offset_to_jitted_func[offset])
 
             # Remove label -> block link
-            del(self.lbl2bloc[block.label])
+            del(self.loc_key_to_block[block.loc_key])
 
         return modified_blocks
 
@@ -256,7 +274,7 @@ class JitCore(object):
         @mem_range: list of start/stop addresses
         """
         for addr_start, addr_stop in mem_range:
-            self.del_bloc_in_range(addr_start, addr_stop)
+            self.del_block_in_range(addr_start, addr_stop)
         self.__updt_jitcode_mem_range(vm)
         vm.reset_memory_access()
 
@@ -275,9 +293,20 @@ class JitCore(object):
         @block: asmblock
         """
         block_raw = "".join(line.b for line in block.lines)
-        block_hash = md5("%X_%s_%s_%s_%s" % (block.label.offset,
+        offset = self.ir_arch.loc_db.get_location_offset(block.loc_key)
+        block_hash = md5("%X_%s_%s_%s_%s" % (offset,
                                              self.arch_name,
                                              self.log_mn,
                                              self.log_regs,
                                              block_raw)).hexdigest()
         return block_hash
+
+    @property
+    def disasm_cb(self):
+        warnings.warn("Deprecated API: use .mdis.dis_block_callback")
+        return self.mdis.dis_block_callback
+
+    @disasm_cb.setter
+    def disasm_cb(self, value):
+        warnings.warn("Deprecated API: use .mdis.dis_block_callback")
+        self.mdis.dis_block_callback = value
diff --git a/miasm2/jitter/jitcore_cc_base.py b/miasm2/jitter/jitcore_cc_base.py
index 4dd8825a..bbf10a53 100644
--- a/miasm2/jitter/jitcore_cc_base.py
+++ b/miasm2/jitter/jitcore_cc_base.py
@@ -46,9 +46,9 @@ class resolver:
 class JitCore_Cc_Base(JitCore):
     "JiT management, abstract class using a C compiler as backend"
 
-    def __init__(self, ir_arch, bs=None):
+    def __init__(self, ir_arch, bin_stream):
         self.jitted_block_delete_cb = self.deleteCB
-        super(JitCore_Cc_Base, self).__init__(ir_arch, bs)
+        super(JitCore_Cc_Base, self).__init__(ir_arch, bin_stream)
         self.resolver = resolver()
         self.ir_arch = ir_arch
         self.states = {}
@@ -85,21 +85,12 @@ class JitCore_Cc_Base(JitCore):
         """
         self.codegen = codegen
 
-    def label2fname(self, label):
-        """
-        Generate function name from @label
-        @label: AsmLabel instance
-        """
-        return "block_%s" % self.codegen.label_to_jitlabel(label)
-
-    def gen_c_code(self, label, block):
+    def gen_c_code(self, block):
         """
         Return the C code corresponding to the @irblocks
-        @label: AsmLabel of the block to jit
         @irblocks: list of irblocks
         """
-        f_name = self.label2fname(label)
-        f_declaration = 'int %s(block_id * BlockDst, JitCpu* jitcpu)' % f_name
+        f_declaration = 'int %s(block_id * BlockDst, JitCpu* jitcpu)' % self.FUNCNAME
         out = self.codegen.gen_c(block, log_mn=self.log_mn, log_regs=self.log_regs)
         out = [f_declaration + '{'] + out + ['}\n']
         c_code = out
diff --git a/miasm2/jitter/jitcore_gcc.py b/miasm2/jitter/jitcore_gcc.py
index ccccc37a..dbaa2a08 100644
--- a/miasm2/jitter/jitcore_gcc.py
+++ b/miasm2/jitter/jitcore_gcc.py
@@ -13,9 +13,9 @@ from miasm2.jitter.jitcore_cc_base import JitCore_Cc_Base, gen_core
 class JitCore_Gcc(JitCore_Cc_Base):
     "JiT management, using a C compiler as backend"
 
-    def __init__(self, ir_arch, bs=None):
-        super(JitCore_Gcc, self).__init__(ir_arch, bs)
-        self.exec_wrapper = Jitgcc.gcc_exec_bloc
+    def __init__(self, ir_arch, bin_stream):
+        super(JitCore_Gcc, self).__init__(ir_arch, bin_stream)
+        self.exec_wrapper = Jitgcc.gcc_exec_block
 
     def deleteCB(self, offset):
         """Free the state associated to @offset and delete it
@@ -25,14 +25,14 @@ class JitCore_Gcc(JitCore_Cc_Base):
         del self.states[offset]
 
     def load_code(self, label, fname_so):
-        f_name = self.label2fname(label)
         lib = ctypes.cdll.LoadLibrary(fname_so)
-        func = getattr(lib, f_name)
+        func = getattr(lib, self.FUNCNAME)
         addr = ctypes.cast(func, ctypes.c_void_p).value
-        self.lbl2jitbloc[label.offset] = addr
-        self.states[label.offset] = lib
+        offset = self.ir_arch.loc_db.get_location_offset(label)
+        self.offset_to_jitted_func[offset] = addr
+        self.states[offset] = lib
 
-    def add_bloc(self, block):
+    def add_block(self, block):
         """Add a bloc to JiT and JiT it.
         @block: block to jit
         """
@@ -40,7 +40,7 @@ class JitCore_Gcc(JitCore_Cc_Base):
         fname_out = os.path.join(self.tempdir, "%s.so" % block_hash)
 
         if not os.access(fname_out, os.R_OK | os.X_OK):
-            func_code = self.gen_c_code(block.label, block)
+            func_code = self.gen_c_code(block)
 
             # Create unique C file
             fdesc, fname_in = tempfile.mkstemp(suffix=".c")
@@ -60,7 +60,7 @@ class JitCore_Gcc(JitCore_Cc_Base):
             os.rename(fname_tmp, fname_out)
             os.remove(fname_in)
 
-        self.load_code(block.label, fname_out)
+        self.load_code(block.loc_key, fname_out)
 
     @staticmethod
     def gen_C_source(ir_arch, func_code):
diff --git a/miasm2/jitter/jitcore_llvm.py b/miasm2/jitter/jitcore_llvm.py
index 452b6d84..ea4f20ec 100644
--- a/miasm2/jitter/jitcore_llvm.py
+++ b/miasm2/jitter/jitcore_llvm.py
@@ -8,7 +8,6 @@ import Jitllvm
 
 
 class JitCore_LLVM(jitcore.JitCore):
-
     "JiT management, using LLVM as backend"
 
     # Architecture dependant libraries
@@ -20,8 +19,8 @@ class JitCore_LLVM(jitcore.JitCore):
                            "ppc32": "JitCore_ppc32.so",
     }
 
-    def __init__(self, ir_arch, bs=None):
-        super(JitCore_LLVM, self).__init__(ir_arch, bs)
+    def __init__(self, ir_arch, bin_stream):
+        super(JitCore_LLVM, self).__init__(ir_arch, bin_stream)
 
         self.options.update({"safe_mode": True,   # Verify each function
                              "optimise": True,     # Optimise functions
@@ -29,7 +28,7 @@ class JitCore_LLVM(jitcore.JitCore):
                              "log_assembly": False,  # Print assembly executed
                              })
 
-        self.exec_wrapper = Jitllvm.llvm_exec_bloc
+        self.exec_wrapper = Jitllvm.llvm_exec_block
         self.ir_arch = ir_arch
 
         # Cache temporary dir
@@ -74,16 +73,17 @@ class JitCore_LLVM(jitcore.JitCore):
         # Enable caching
         self.context.enable_cache()
 
-    def add_bloc(self, block):
+    def add_block(self, block):
         """Add a block to JiT and JiT it.
         @block: the block to add
         """
+
         block_hash = self.hash_block(block)
         fname_out = os.path.join(self.tempdir, "%s.bc" % block_hash)
 
         if not os.access(fname_out, os.R_OK):
             # Build a function in the context
-            func = LLVMFunction(self.context, LLVMFunction.canonize_label_name(block.label))
+            func = LLVMFunction(self.context, self.FUNCNAME)
 
             # Set log level
             func.log_regs = self.log_regs
@@ -114,7 +114,9 @@ class JitCore_LLVM(jitcore.JitCore):
 
         else:
             # The cache file exists: function can be loaded from cache
-            ptr = self.context.get_ptr_from_cache(fname_out, LLVMFunction.canonize_label_name(block.label))
+            ptr = self.context.get_ptr_from_cache(fname_out, self.FUNCNAME)
 
         # Store a pointer on the function jitted code
-        self.lbl2jitbloc[block.label.offset] = ptr
+        loc_key = block.loc_key
+        offset = self.ir_arch.loc_db.get_location_offset(loc_key)
+        self.offset_to_jitted_func[offset] = ptr
diff --git a/miasm2/jitter/jitcore_python.py b/miasm2/jitter/jitcore_python.py
index 799848ab..61bd98d0 100644
--- a/miasm2/jitter/jitcore_python.py
+++ b/miasm2/jitter/jitcore_python.py
@@ -4,7 +4,6 @@ import miasm2.jitter.csts as csts
 from miasm2.expression.simplifications import ExpressionSimplifier
 from miasm2.jitter.emulatedsymbexec import EmulatedSymbExec
 
-
 ################################################################################
 #                              Python jitter Core                              #
 ################################################################################
@@ -15,15 +14,19 @@ class JitCore_Python(jitcore.JitCore):
 
     SymbExecClass = EmulatedSymbExec
 
-    def __init__(self, ir_arch, bs=None):
-        super(JitCore_Python, self).__init__(ir_arch, bs)
+    def __init__(self, ir_arch, bin_stream):
+        super(JitCore_Python, self).__init__(ir_arch, bin_stream)
         self.ir_arch = ir_arch
+        self.ircfg = self.ir_arch.new_ircfg()
 
         # CPU & VM (None for now) will be set later
         expr_simp = ExpressionSimplifier()
         expr_simp.enable_passes(ExpressionSimplifier.PASS_COMMONS)
-        self.symbexec = self.SymbExecClass(None, None, self.ir_arch, {},
-                                           sb_expr_simp=expr_simp)
+        self.symbexec = self.SymbExecClass(
+            None, None,
+            self.ir_arch, {},
+            sb_expr_simp=expr_simp
+        )
         self.symbexec.enable_emulated_simplifications()
 
     def set_cpu_vm(self, cpu, vm):
@@ -34,10 +37,10 @@ class JitCore_Python(jitcore.JitCore):
         "Preload symbols according to current architecture"
         self.symbexec.reset_regs()
 
-    def jitirblocs(self, label, irblocks):
+    def jit_irblocks(self, loc_key, irblocks):
         """Create a python function corresponding to an irblocks' group.
-        @label: the label of the irblocks
-        @irblocks: a gorup of irblocks
+        @loc_key: the loc_key of the irblocks
+        @irblocks: a group of irblocks
         """
 
         def myfunc(cpu):
@@ -48,7 +51,7 @@ class JitCore_Python(jitcore.JitCore):
             vmmngr = cpu.vmmngr
 
             # Keep current location in irblocks
-            cur_label = label
+            cur_loc_key = loc_key
 
             # Required to detect new instructions
             offsets_jitted = set()
@@ -57,13 +60,14 @@ class JitCore_Python(jitcore.JitCore):
             exec_engine = self.symbexec
             expr_simp = exec_engine.expr_simp
 
+            known_loc_keys = set(irb.loc_key for irb in irblocks)
             # For each irbloc inside irblocks
             while True:
-
                 # Get the current bloc
                 for irb in irblocks:
-                    if irb.label == cur_label:
+                    if irb.loc_key == cur_loc_key:
                         break
+
                 else:
                     raise RuntimeError("Irblocks must end with returning an "
                                        "ExprInt instance")
@@ -75,7 +79,7 @@ class JitCore_Python(jitcore.JitCore):
                 for assignblk in irb:
                     instr = assignblk.instr
                     # For each new instruction (in assembly)
-                    if instr.offset not in offsets_jitted:
+                    if instr is not None and instr.offset not in offsets_jitted:
                         # Test exceptions
                         vmmngr.check_invalid_code_blocs()
                         vmmngr.check_memory_breakpoint()
@@ -120,23 +124,25 @@ class JitCore_Python(jitcore.JitCore):
                 # Manage resulting address
                 if isinstance(ad, m2_expr.ExprInt):
                     return ad.arg.arg
-                elif isinstance(ad, m2_expr.ExprId):
-                    cur_label = ad.name
+                elif isinstance(ad, m2_expr.ExprLoc):
+                    cur_loc_key = ad.loc_key
                 else:
                     raise NotImplementedError("Type not handled: %s" % ad)
 
-        # Associate myfunc with current label
-        self.lbl2jitbloc[label.offset] = myfunc
+        # Associate myfunc with current loc_key
+        offset = self.ir_arch.loc_db.get_location_offset(loc_key)
+        assert offset is not None
+        self.offset_to_jitted_func[offset] = myfunc
 
-    def exec_wrapper(self, label, cpu, _lbl2jitbloc, _breakpoints,
+    def exec_wrapper(self, loc_key, cpu, _offset_to_jitted_func, _stop_offsets,
                      _max_exec_per_call):
-        """Call the function @label with @cpu
-        @label: function's label
+        """Call the function @loc_key with @cpu
+        @loc_key: function's loc_key
         @cpu: JitCpu instance
         """
 
-        # Get Python function corresponding to @label
-        fc_ptr = self.lbl2jitbloc[label]
+        # Get Python function corresponding to @loc_key
+        fc_ptr = self.offset_to_jitted_func[loc_key]
 
         # Execute the function
         return fc_ptr(cpu)
diff --git a/miasm2/jitter/jitload.py b/miasm2/jitter/jitload.py
index db486b4f..288e737a 100644
--- a/miasm2/jitter/jitload.py
+++ b/miasm2/jitter/jitload.py
@@ -1,5 +1,6 @@
 
 import logging
+import warnings
 from functools import wraps
 from collections import Sequence, namedtuple, Iterator
 
@@ -160,7 +161,7 @@ class ExceptionHandle():
         return not self.__eq__(to_cmp)
 
 
-class jitter(object):
+class Jitter(object):
 
     "Main class for JIT handling"
 
@@ -204,8 +205,11 @@ class jitter(object):
         self.cpu = jcore.JitCpu()
         self.ir_arch = ir_arch
         self.bs = bin_stream_vm(self.vm)
+        self.ircfg = self.ir_arch.new_ircfg()
 
-        self.symbexec = EmulatedSymbExec(self.cpu, self.vm, self.ir_arch, {})
+        self.symbexec = EmulatedSymbExec(
+            self.cpu, self.vm, self.ir_arch, {}
+        )
         self.symbexec.reset_regs()
 
         try:
@@ -302,18 +306,20 @@ class jitter(object):
         """
         self.exceptions_handler.add_callback(flag, callback)
 
-    def runbloc(self, pc):
+    def run_at(self, pc):
         """Wrapper on JiT backend. Run the code at PC and return the next PC.
         @pc: address of code to run"""
 
-        return self.jit.runbloc(self.cpu, pc, self.breakpoints_handler.callbacks)
+        return self.jit.run_at(
+            self.cpu, pc,
+            set(self.breakpoints_handler.callbacks.keys())
+        )
 
     def runiter_once(self, pc):
         """Iterator on callbacks results on code running from PC.
         Check exceptions before breakpoints."""
 
         self.pc = pc
-
         # Callback called before exec
         if self.exec_cb is not None:
             res = self.exec_cb(self)
@@ -349,7 +355,7 @@ class jitter(object):
         assert(self.get_exception() == 0)
 
         # Run the bloc at PC
-        self.pc = self.runbloc(self.pc)
+        self.pc = self.run_at(self.pc)
 
         # Check exceptions (raised by the execution of the block)
         exception_flag = self.get_exception()
@@ -485,3 +491,33 @@ class jitter(object):
         self.symbexec.update_cpu_from_engine()
 
         return ret
+
+    def set_trace_log(self,
+                      trace_instr=True, trace_regs=True,
+                      trace_new_blocks=False):
+        """
+        Activate/Deactivate trace log options
+
+        @trace_instr: activate instructions tracing log
+        @trace_regs: activate registers tracing log
+        @trace_new_blocks: dump new code blocks log
+        """
+
+        # As trace state changes, clear already jitted blocks
+        self.jit.clear_jitted_blocks()
+
+        self.jit.log_mn = trace_instr
+        self.jit.log_regs = trace_regs
+        self.jit.log_newbloc = trace_new_blocks
+
+
+class jitter(Jitter):
+    """
+    DEPRECATED object
+    Use Jitter instead of jitter
+    """
+
+
+    def __init__(self, *args, **kwargs):
+        warnings.warn("Deprecated API: use Jitter")
+        super(jitter, self).__init__(*args, **kwargs)
diff --git a/miasm2/jitter/llvmconvert.py b/miasm2/jitter/llvmconvert.py
index 97cd9f17..d63351cc 100644
--- a/miasm2/jitter/llvmconvert.py
+++ b/miasm2/jitter/llvmconvert.py
@@ -14,7 +14,8 @@
 import os
 from llvmlite import binding as llvm
 from llvmlite import ir as llvm_ir
-import miasm2.expression.expression as m2_expr
+from miasm2.expression.expression import ExprId, ExprInt, ExprMem, ExprSlice, \
+    ExprCond, ExprLoc, ExprOp, ExprCompose, LocKey
 import miasm2.jitter.csts as m2_csts
 import miasm2.core.asmblock as m2_asmblock
 from miasm2.jitter.codegen import CGen
@@ -43,7 +44,7 @@ class LLVMType(llvm_ir.Type):
     @classmethod
     def generic(cls, e):
         "Generic value for execution"
-        if isinstance(e, m2_expr.ExprInt):
+        if isinstance(e, ExprInt):
             return llvm_e.GenericValue.int(LLVMType.IntType(e.size), int(e.arg))
         elif isinstance(e, llvm_e.GenericValue):
             return e
@@ -69,6 +70,16 @@ class LLVMContext():
         self.target_machine = target.create_target_machine()
         self.init_exec_engine()
 
+    def canonize_label_name(self, label):
+        """Canonize @label names to a common form.
+        @label: str or asmlabel instance"""
+        if isinstance(label, str):
+            return label
+        elif isinstance(label, LocKey):
+            return str(label)
+        else:
+            raise ValueError("label must either be str or LocKey")
+
     def optimise_level(self, level=2):
         """Set the optimisation level to @level from 0 to 2
         0: non-optimized
@@ -193,7 +204,7 @@ class LLVMContext_JIT(LLVMContext):
 
         fc = {}
         p8 = llvm_ir.PointerType(LLVMType.IntType(8))
-        for i in [8, 16, 32, 64]:
+        for i in [8, 16, 32, 64, 128]:
             fc["MEM_LOOKUP_%02d" % i] = {"ret": LLVMType.IntType(i),
                                          "args": [p8,
                                                   LLVMType.IntType(64)]}
@@ -405,7 +416,7 @@ class LLVMFunction():
         @label: str or asmlabel
         @overwrite: if False, do nothing if a bbl with the same name already exists
         Return the corresponding LLVM Basic Block"""
-        name = self.canonize_label_name(label)
+        name = self.llvm_context.canonize_label_name(label)
         bbl = self.name2bbl.get(name, None)
         if not overwrite and bbl is not None:
             return bbl
@@ -483,25 +494,9 @@ class LLVMFunction():
             var_casted = var
         self.builder.ret(var_casted)
 
-    @staticmethod
-    def canonize_label_name(label):
-        """Canonize @label names to a common form.
-        @label: str or asmlabel instance"""
-        if isinstance(label, str):
-            return label
-        if m2_asmblock.expr_is_label(label):
-            label = label.name
-        if isinstance(label, m2_asmblock.AsmLabel):
-            if label.offset is None:
-                return "label_%s" % label.name
-            else:
-                return "label_%X" % label.offset
-        else:
-            raise ValueError("label must either be str or asmlabel")
-
-    def get_basic_bloc_by_label(self, label):
+    def get_basic_block_by_loc_key(self, loc_key):
         "Return the bbl corresponding to label, None otherwise"
-        return self.name2bbl.get(self.canonize_label_name(label), None)
+        return self.name2bbl.get(self.llvm_context.canonize_label_name(loc_key), None)
 
     def global_constant(self, name, value):
         """
@@ -567,11 +562,11 @@ class LLVMFunction():
         # Destination
         builder = self.builder
 
-        if isinstance(dst, m2_expr.ExprId):
+        if isinstance(dst, ExprId):
             ptr_casted = self.get_ptr_by_expr(dst)
             builder.store(src, ptr_casted)
 
-        elif isinstance(dst, m2_expr.ExprMem):
+        elif isinstance(dst, ExprMem):
             addr = self.add_ir(dst.arg)
             self.llvm_context.memory_write(self, addr, dst.size, src)
         else:
@@ -624,20 +619,19 @@ class LLVMFunction():
 
         builder = self.builder
 
-        if isinstance(expr, m2_expr.ExprInt):
+        if isinstance(expr, ExprInt):
             ret = llvm_ir.Constant(LLVMType.IntType(expr.size), int(expr.arg))
             self.update_cache(expr, ret)
             return ret
 
-        if isinstance(expr, m2_expr.ExprId):
-            name = expr.name
-            if not isinstance(name, str):
-                # Resolve label
-                offset = name.offset
-                ret = llvm_ir.Constant(LLVMType.IntType(expr.size), offset)
-                self.update_cache(expr, ret)
-                return ret
+        if expr.is_loc():
+            offset = self.llvm_context.ir_arch.loc_db.get_location_offset(expr.loc_key)
+            ret = llvm_ir.Constant(LLVMType.IntType(expr.size), offset)
+            self.update_cache(expr, ret)
+            return ret
 
+        if isinstance(expr, ExprId):
+            name = expr.name
             try:
                 # If expr.name is already known (args)
                 return self.local_vars[name]
@@ -650,7 +644,7 @@ class LLVMFunction():
             self.update_cache(expr, var)
             return var
 
-        if isinstance(expr, m2_expr.ExprOp):
+        if isinstance(expr, ExprOp):
             op = expr.op
 
             if (op in self.op_translate or
@@ -857,12 +851,12 @@ class LLVMFunction():
 
             raise NotImplementedError()
 
-        if isinstance(expr, m2_expr.ExprMem):
+        if isinstance(expr, ExprMem):
 
             addr = self.add_ir(expr.arg)
             return self.llvm_context.memory_lookup(self, addr, expr.size)
 
-        if isinstance(expr, m2_expr.ExprCond):
+        if isinstance(expr, ExprCond):
             # Compute cond
             cond = self.add_ir(expr.cond)
             zero_casted = LLVMType.IntType(expr.cond.size)(0)
@@ -875,7 +869,7 @@ class LLVMFunction():
             self.update_cache(expr, ret)
             return ret
 
-        if isinstance(expr, m2_expr.ExprSlice):
+        if isinstance(expr, ExprSlice):
 
             src = self.add_ir(expr.arg)
 
@@ -901,7 +895,7 @@ class LLVMFunction():
             self.update_cache(expr, ret)
             return ret
 
-        if isinstance(expr, m2_expr.ExprCompose):
+        if isinstance(expr, ExprCompose):
 
             args = []
 
@@ -982,9 +976,9 @@ class LLVMFunction():
         builder.position_at_end(then_block)
         PC = self.llvm_context.PC
         if isinstance(offset, (int, long)):
-            offset = self.add_ir(m2_expr.ExprInt(offset, PC.size))
+            offset = self.add_ir(ExprInt(offset, PC.size))
         self.affect(offset, PC)
-        self.affect(self.add_ir(m2_expr.ExprInt(1, 8)), m2_expr.ExprId("status", 32))
+        self.affect(self.add_ir(ExprInt(1, 8)), ExprId("status", 32))
         self.set_ret(offset)
 
         builder.position_at_end(merge_block)
@@ -1029,9 +1023,9 @@ class LLVMFunction():
         builder.position_at_end(then_block)
         PC = self.llvm_context.PC
         if isinstance(offset, (int, long)):
-            offset = self.add_ir(m2_expr.ExprInt(offset, PC.size))
+            offset = self.add_ir(ExprInt(offset, PC.size))
         self.affect(offset, PC)
-        self.affect(self.add_ir(m2_expr.ExprInt(1, 8)), m2_expr.ExprId("status", 32))
+        self.affect(self.add_ir(ExprInt(1, 8)), ExprId("status", 32))
         self.set_ret(offset)
 
         builder.position_at_end(merge_block)
@@ -1056,6 +1050,9 @@ class LLVMFunction():
             self.builder.call(fc_ptr, [self.local_vars["vmmngr"]])
             self.check_memory_exception(next_instr, restricted_exception=False)
 
+        if attrib.set_exception:
+            self.check_cpu_exception(next_instr, restricted_exception=False)
+
         if attrib.mem_read | attrib.mem_write:
             fc_ptr = self.mod.get_global("reset_memory_access")
             self.builder.call(fc_ptr, [self.local_vars["vmmngr"]])
@@ -1073,9 +1070,9 @@ class LLVMFunction():
         for i, solution in enumerate(possible_values(expr)):
             value = solution.value
             index = dst2case.get(value, i)
-            to_eval = to_eval.replace_expr({value: m2_expr.ExprInt(index, value.size)})
+            to_eval = to_eval.replace_expr({value: ExprInt(index, value.size)})
             dst2case[value] = index
-            if m2_asmblock.expr_is_int_or_label(value):
+            if value.is_int() or value.is_loc():
                 case2dst[i] = value
             else:
                 case2dst[i] = self.add_ir(value)
@@ -1101,13 +1098,14 @@ class LLVMFunction():
         # We are no longer in the main stream, deactivate cache
         self.main_stream = False
 
-        if isinstance(dst, m2_expr.ExprInt):
-            dst = m2_expr.ExprId(self.llvm_context.ir_arch.symbol_pool.getby_offset_create(int(dst)),
-                                 dst.size)
+        if isinstance(dst, ExprInt):
+            loc_key = self.llvm_context.ir_arch.loc_db.get_or_create_offset_location(int(dst))
+            dst = ExprLoc(loc_key, dst.size)
 
-        if m2_asmblock.expr_is_label(dst):
-            bbl = self.get_basic_bloc_by_label(dst)
-            offset = dst.name.offset
+        if isinstance(dst, ExprLoc):
+            loc_key = dst.loc_key
+            bbl = self.get_basic_block_by_loc_key(loc_key)
+            offset = self.llvm_context.ir_arch.loc_db.get_location_offset(loc_key)
             if bbl is not None:
                 # "local" jump, inside this function
                 if offset is None:
@@ -1127,7 +1125,7 @@ class LLVMFunction():
                 # extern
 
             # "extern" jump on a defined offset, return to the caller
-            dst = self.add_ir(m2_expr.ExprInt(offset, PC.size))
+            dst = self.add_ir(ExprInt(offset, PC.size))
 
         # "extern" jump with a computed value, return to the caller
         assert isinstance(dst, (llvm_ir.Instruction, llvm_ir.Value))
@@ -1139,7 +1137,7 @@ class LLVMFunction():
         self.gen_post_code(attrib)
         self.affect(dst, PC)
         self.gen_post_instr_checks(attrib, dst)
-        self.affect(self.add_ir(m2_expr.ExprInt(0, 8)), m2_expr.ExprId("status", 32))
+        self.affect(self.add_ir(ExprInt(0, 8)), ExprId("status", 32))
         self.set_ret(dst)
 
 
@@ -1163,7 +1161,7 @@ class LLVMFunction():
 
             # Prefetch memory
             for element in assignblk.get_r(mem_read=True):
-                if isinstance(element, m2_expr.ExprMem):
+                if isinstance(element, ExprMem):
                     self.add_ir(element)
 
             # Evaluate expressions
@@ -1181,7 +1179,7 @@ class LLVMFunction():
 
             # Update the memory
             for dst, src in values.iteritems():
-                if isinstance(dst, m2_expr.ExprMem):
+                if isinstance(dst, ExprMem):
                     self.affect(src, dst)
 
             # Check memory write exception
@@ -1191,7 +1189,7 @@ class LLVMFunction():
 
             # Update registers values
             for dst, src in values.iteritems():
-                if not isinstance(dst, m2_expr.ExprMem):
+                if not isinstance(dst, ExprMem):
                     self.affect(src, dst)
 
             # Check post assignblk exception flags
@@ -1232,11 +1230,12 @@ class LLVMFunction():
         builder = self.builder
         m2_exception_flag = self.llvm_context.ir_arch.arch.regs.exception_flags
         t_size = LLVMType.IntType(m2_exception_flag.size)
-        self.affect(self.add_ir(m2_expr.ExprInt(1, 8)),
-                    m2_expr.ExprId("status", 32))
+        self.affect(self.add_ir(ExprInt(1, 8)),
+                    ExprId("status", 32))
         self.affect(t_size(m2_csts.EXCEPT_UNK_MNEMO),
                     m2_exception_flag)
-        self.set_ret(LLVMType.IntType(64)(asmblock.label.offset))
+        offset = self.llvm_context.ir_arch.loc_db.get_location_offset(asmblock.loc_key)
+        self.set_ret(LLVMType.IntType(64)(offset))
 
     def gen_finalize(self, asmblock, codegen):
         """
@@ -1247,11 +1246,11 @@ class LLVMFunction():
             next_label = codegen.get_block_post_label(asmblock)
             builder = self.builder
 
-            builder.position_at_end(self.get_basic_bloc_by_label(next_label))
+            builder.position_at_end(self.get_basic_block_by_loc_key(next_label))
 
             # Common code
-            self.affect(self.add_ir(m2_expr.ExprInt(0, 8)),
-                        m2_expr.ExprId("status", 32))
+            self.affect(self.add_ir(ExprInt(0, 8)),
+                        ExprId("status", 32))
 
             # Check if IRDst has been set
             zero_casted = LLVMType.IntType(codegen.delay_slot_set.size)(0)
@@ -1274,14 +1273,15 @@ class LLVMFunction():
             PC = self.llvm_context.PC
             to_ret = self.add_ir(codegen.delay_slot_dst)
             self.affect(to_ret, PC)
-            self.affect(self.add_ir(m2_expr.ExprInt(0, 8)),
-                        m2_expr.ExprId("status", 32))
+            self.affect(self.add_ir(ExprInt(0, 8)),
+                        ExprId("status", 32))
             self.set_ret(to_ret)
 
             # Else Block
             builder.position_at_end(else_block)
             PC = self.llvm_context.PC
-            to_ret = LLVMType.IntType(PC.size)(next_label.offset)
+            next_label_offset = self.llvm_context.ir_arch.loc_db.get_location_offset(next_label)
+            to_ret = LLVMType.IntType(PC.size)(next_label_offset)
             self.affect(to_ret, PC)
             self.set_ret(to_ret)
 
@@ -1290,16 +1290,16 @@ class LLVMFunction():
         Prototype : f(i8* jitcpu, i8* vmcpu, i8* vmmngr, i8* status)"""
 
         # Build function signature
-        self.my_args.append((m2_expr.ExprId("jitcpu", 32),
+        self.my_args.append((ExprId("jitcpu", 32),
                              llvm_ir.PointerType(LLVMType.IntType(8)),
                              "jitcpu"))
-        self.my_args.append((m2_expr.ExprId("vmcpu", 32),
+        self.my_args.append((ExprId("vmcpu", 32),
                              llvm_ir.PointerType(LLVMType.IntType(8)),
                              "vmcpu"))
-        self.my_args.append((m2_expr.ExprId("vmmngr", 32),
+        self.my_args.append((ExprId("vmmngr", 32),
                              llvm_ir.PointerType(LLVMType.IntType(8)),
                              "vmmngr"))
-        self.my_args.append((m2_expr.ExprId("status", 32),
+        self.my_args.append((ExprId("status", 32),
                              llvm_ir.PointerType(LLVMType.IntType(8)),
                              "status"))
         ret_size = 64
@@ -1317,7 +1317,7 @@ class LLVMFunction():
         # Create basic blocks (for label branchs)
         entry_bbl, builder = self.entry_bbl, self.builder
         for instr in asmblock.lines:
-            lbl = self.llvm_context.ir_arch.symbol_pool.getby_offset_create(instr.offset)
+            lbl = self.llvm_context.ir_arch.loc_db.get_or_create_offset_location(instr.offset)
             self.append_basic_block(lbl)
 
         # TODO: merge duplicate code with CGen
@@ -1332,9 +1332,10 @@ class LLVMFunction():
                 ptr = self.CreateEntryBlockAlloca(eltype,
                                                   default_value=eltype(0))
                 self.local_vars_pointers[element.name] = ptr
-            lbl = codegen.get_block_post_label(asmblock)
-            instr_offsets.append(lbl.offset)
-            self.append_basic_block(lbl)
+            loc_key = codegen.get_block_post_label(asmblock)
+            offset = self.llvm_context.ir_arch.loc_db.get_location_offset(loc_key)
+            instr_offsets.append(offset)
+            self.append_basic_block(loc_key)
 
         # Add content
         builder.position_at_end(entry_bbl)
@@ -1347,7 +1348,7 @@ class LLVMFunction():
 
             # Pre-create basic blocks
             for irblock in irblocks:
-                self.append_basic_block(irblock.label, overwrite=False)
+                self.append_basic_block(irblock.loc_key, overwrite=False)
 
             # Generate the corresponding code
             for index, irblock in enumerate(irblocks):
@@ -1355,8 +1356,7 @@ class LLVMFunction():
                     irblock, self.llvm_context.ir_arch.attrib)
 
                 # Set the builder at the begining of the correct bbl
-                name = self.canonize_label_name(new_irblock.label)
-                self.builder.position_at_end(self.get_basic_bloc_by_label(name))
+                self.builder.position_at_end(self.get_basic_block_by_loc_key(new_irblock.loc_key))
 
                 if index == 0:
                     self.gen_pre_code(instr_attrib)
@@ -1367,7 +1367,7 @@ class LLVMFunction():
 
         # Branch entry_bbl on first label
         builder.position_at_end(entry_bbl)
-        first_label_bbl = self.get_basic_bloc_by_label(asmblock.label)
+        first_label_bbl = self.get_basic_block_by_loc_key(asmblock.loc_key)
         builder.branch(first_label_bbl)
 
 
diff --git a/miasm2/jitter/loader/elf.py b/miasm2/jitter/loader/elf.py
index deaebd09..01dea647 100644
--- a/miasm2/jitter/loader/elf.py
+++ b/miasm2/jitter/loader/elf.py
@@ -32,7 +32,6 @@ def preload_elf(vm, e, runtime_lib, patch_vm_imp=True):
     # XXX quick hack
     fa = get_import_address_elf(e)
     dyn_funcs = {}
-    # log.debug('imported funcs: %s' % fa)
     for (libname, libfunc), ads in fa.items():
         for ad in ads:
             ad_base_lib = runtime_lib.lib_get_add_base(libname)
@@ -77,7 +76,6 @@ def vm_load_elf(vm, fdata, name="", **kargs):
         # -2: Trick to avoid merging 2 consecutive pages
         i += [(a_addr, b_addr - 2)]
     for a, b in i.intervals:
-        # print hex(a), hex(b)
         vm.add_memory_page(a, PAGE_READ | PAGE_WRITE, "\x00" * (b + 2 - a),
                            repr(name))
 
diff --git a/miasm2/jitter/loader/pe.py b/miasm2/jitter/loader/pe.py
index 2fe4cd3f..9bc0ef8b 100644
--- a/miasm2/jitter/loader/pe.py
+++ b/miasm2/jitter/loader/pe.py
@@ -163,7 +163,8 @@ def vm_load_pe(vm, fdata, align_s=True, load_hdr=True, name="", **kargs):
                 section.size = new_size
                 section.rawsize = new_size
                 section.data = strpatchwork.StrPatchwork(
-                    section.data[:new_size])
+                    section.data[:new_size]
+                )
                 section.offset = section.addr
 
             # Last section alignement
diff --git a/miasm2/jitter/op_semantics.c b/miasm2/jitter/op_semantics.c
index 82f56422..0420532a 100644
--- a/miasm2/jitter/op_semantics.c
+++ b/miasm2/jitter/op_semantics.c
@@ -774,3 +774,23 @@ uint64_t double_to_mem_64(double d)
 #endif
 	return m;
 }
+
+UDIV(16)
+UDIV(32)
+UDIV(64)
+UDIV(128)
+
+UMOD(16)
+UMOD(32)
+UMOD(64)
+UMOD(128)
+
+IDIV(16)
+IDIV(32)
+IDIV(64)
+IDIV(128)
+
+IMOD(16)
+IMOD(32)
+IMOD(64)
+IMOD(128)
diff --git a/miasm2/jitter/op_semantics.h b/miasm2/jitter/op_semantics.h
index a52afd42..3eb81cff 100644
--- a/miasm2/jitter/op_semantics.h
+++ b/miasm2/jitter/op_semantics.h
@@ -1,6 +1,9 @@
 #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]
@@ -27,7 +30,7 @@ unsigned int cntleadzeros(uint64_t size, uint64_t src);
 unsigned int cnttrailzeros(uint64_t size, uint64_t src);
 
 #define UDIV(sizeA)						\
-	uint ## sizeA ## _t udiv ## sizeA (vm_cpu_t* vmcpu, uint ## sizeA ## _t a, uint ## sizeA ## _t b) \
+	uint ## sizeA ## _t udiv ## sizeA (uint ## sizeA ## _t a, uint ## sizeA ## _t b) \
 	{								\
 		uint ## sizeA ## _t r;					\
 		if (b == 0) {						\
@@ -40,7 +43,7 @@ unsigned int cnttrailzeros(uint64_t size, uint64_t src);
 
 
 #define UMOD(sizeA)						\
-	uint ## sizeA ## _t umod ## sizeA (vm_cpu_t* vmcpu, uint ## sizeA ## _t a, uint ## sizeA ## _t b) \
+	uint ## sizeA ## _t umod ## sizeA (uint ## sizeA ## _t a, uint ## sizeA ## _t b) \
 	{								\
 		uint ## sizeA ## _t r;					\
 		if (b == 0) {						\
@@ -53,7 +56,7 @@ unsigned int cnttrailzeros(uint64_t size, uint64_t src);
 
 
 #define IDIV(sizeA)						\
-	int ## sizeA ## _t idiv ## sizeA (vm_cpu_t* vmcpu, int ## sizeA ## _t a, int ## sizeA ## _t b) \
+	int ## sizeA ## _t idiv ## sizeA (int ## sizeA ## _t a, int ## sizeA ## _t b) \
 	{								\
 		int ## sizeA ## _t r;					\
 		if (b == 0) {						\
@@ -66,7 +69,7 @@ unsigned int cnttrailzeros(uint64_t size, uint64_t src);
 
 
 #define IMOD(sizeA)						\
-	int ## sizeA ## _t imod ## sizeA (vm_cpu_t* vmcpu, int ## sizeA ## _t a, int ## sizeA ## _t b) \
+	int ## sizeA ## _t imod ## sizeA (int ## sizeA ## _t a, int ## sizeA ## _t b) \
 	{								\
 		int ## sizeA ## _t r;					\
 		if (b == 0) {						\
@@ -77,6 +80,21 @@ unsigned int cnttrailzeros(uint64_t size, uint64_t src);
 		return r;						\
 	}
 
+uint64_t udiv64(uint64_t a, uint64_t b);
+uint64_t umod64(uint64_t a, uint64_t b);
+int64_t idiv64(int64_t a, int64_t b);
+int64_t imod64(int64_t a, int64_t b);
+
+uint32_t udiv32(uint32_t a, uint32_t b);
+uint32_t umod32(uint32_t a, uint32_t b);
+int32_t idiv32(int32_t a, int32_t b);
+int32_t imod32(int32_t a, int32_t b);
+
+uint16_t udiv16(uint16_t a, uint16_t b);
+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);
+
 unsigned int x86_cpuid(unsigned int a, unsigned int reg_num);
 double int2double(unsigned int m);
 
diff --git a/miasm2/jitter/vm_mngr.c b/miasm2/jitter/vm_mngr.c
index 6da7bfed..dd0f6cf2 100644
--- a/miasm2/jitter/vm_mngr.c
+++ b/miasm2/jitter/vm_mngr.c
@@ -101,6 +101,13 @@ 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)
 {
@@ -108,7 +115,7 @@ void print_val(uint64_t base, uint64_t addr)
 	fprintf(stderr, "addr 0x%"PRIX64" val 0x%"PRIX64"\n", addr-base, *ptr);
 }
 
-inline int midpoint(int imin, int imax)
+int midpoint(int imin, int imax)
 {
 	return (imin + imax) / 2;
 }
@@ -159,11 +166,11 @@ struct memory_page_node * get_memory_page_from_address(vm_mngr_t* vm_mngr, uint6
 
 
 
-static uint64_t memory_page_read(vm_mngr_t* vm_mngr, unsigned int my_size, uint64_t ad)
+static uint128_t memory_page_read(vm_mngr_t* vm_mngr, unsigned int my_size, uint64_t ad)
 {
 	struct memory_page_node * mpn;
 	unsigned char * addr;
-	uint64_t ret = 0;
+	uint128_t ret = 0;
 	struct memory_breakpoint_info * b;
 
 
@@ -206,6 +213,10 @@ static uint64_t memory_page_read(vm_mngr_t* vm_mngr, unsigned int my_size, uint6
 			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:
 			exit(EXIT_FAILURE);
 			break;
@@ -238,6 +249,9 @@ static uint64_t memory_page_read(vm_mngr_t* vm_mngr, unsigned int my_size, uint6
 		case 64:
 			ret = set_endian64(vm_mngr, ret);
 			break;
+		case 128:
+			ret = set_endian128(vm_mngr, ret);
+			break;
 		default:
 			exit(EXIT_FAILURE);
 			break;
@@ -247,7 +261,7 @@ static uint64_t memory_page_read(vm_mngr_t* vm_mngr, unsigned int my_size, uint6
 }
 
 static void memory_page_write(vm_mngr_t* vm_mngr, unsigned int my_size,
-			      uint64_t ad, uint64_t src)
+			      uint64_t ad, uint128_t src)
 {
 	struct memory_page_node * mpn;
 	unsigned char * addr;
@@ -291,6 +305,10 @@ 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:
 			exit(EXIT_FAILURE);
 			break;
@@ -312,6 +330,9 @@ 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:
 			exit(EXIT_FAILURE);
 			break;
@@ -480,6 +501,12 @@ 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;
@@ -508,6 +535,13 @@ 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 eff5e0da..a50b52d0 100644
--- a/miasm2/jitter/vm_mngr.h
+++ b/miasm2/jitter/vm_mngr.h
@@ -26,6 +26,8 @@
 #define __LITTLE_ENDIAN _LITTLE_ENDIAN
 #endif
 
+#define uint128_t __uint128_t
+
 #define Endian16_Swap(value) \
       ((((uint16_t)((value) & 0x00FF)) << 8) | \
        (((uint16_t)((value) & 0xFF00)) >> 8))
@@ -46,8 +48,25 @@
 	 ((((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);
@@ -174,13 +193,13 @@ 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);