about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--.appveyor.yml2
-rw-r--r--.travis.yml6
-rw-r--r--README.md28
-rwxr-xr-xexample/asm/shellcode.py59
-rw-r--r--example/asm/simple.py3
-rw-r--r--example/disasm/callback.py20
-rw-r--r--example/disasm/dis_binary.py3
-rw-r--r--example/disasm/dis_binary_ir.py6
-rw-r--r--example/disasm/dis_binary_ira.py6
-rw-r--r--example/disasm/dis_x86_string.py5
-rw-r--r--example/disasm/full.py33
-rw-r--r--example/disasm/single_instr.py11
-rw-r--r--example/expression/access_c.py27
-rw-r--r--example/expression/asm_to_ir.py21
-rw-r--r--example/expression/basic_op.py15
-rw-r--r--example/expression/basic_simplification.py11
-rw-r--r--example/expression/constant_propagation.py2
-rw-r--r--example/expression/export_llvm.py16
-rw-r--r--example/expression/expr_c.py7
-rw-r--r--example/expression/expr_grapher.py14
-rw-r--r--example/expression/expr_random.py26
-rw-r--r--example/expression/expr_translate.py27
-rw-r--r--example/expression/get_read_write.py22
-rw-r--r--example/expression/graph_dataflow.py45
-rw-r--r--example/expression/simplification_add.py13
-rw-r--r--example/expression/simplification_tools.py35
-rw-r--r--example/expression/solve_condition_stp.py39
-rw-r--r--example/ida/ctype_propagation.py20
-rw-r--r--example/ida/depgraph.py41
-rw-r--r--example/ida/graph_ir.py39
-rw-r--r--example/ida/rpyc_ida.py3
-rw-r--r--example/ida/symbol_exec.py23
-rw-r--r--example/ida/utils.py6
-rwxr-xr-xexample/jitter/arm.py3
-rwxr-xr-xexample/jitter/arm_sc.py7
-rwxr-xr-xexample/jitter/example_types.py54
-rwxr-xr-xexample/jitter/mips32.py9
-rwxr-xr-xexample/jitter/msp430.py9
-rw-r--r--example/jitter/run_with_linuxenv.py43
-rw-r--r--example/jitter/sandbox_elf_ppc32.py6
-rw-r--r--example/jitter/trace.py8
-rw-r--r--example/jitter/unpack_upx.py12
-rw-r--r--example/jitter/x86_32.py2
-rw-r--r--example/symbol_exec/depgraph.py29
-rw-r--r--example/symbol_exec/dse_crackme.py41
-rw-r--r--example/symbol_exec/dse_strategies.py29
-rw-r--r--example/symbol_exec/single_instr.py5
-rw-r--r--miasm2/analysis/binary.py34
-rw-r--r--miasm2/analysis/cst_propag.py6
-rw-r--r--miasm2/analysis/data_analysis.py39
-rw-r--r--miasm2/analysis/data_flow.py100
-rw-r--r--miasm2/analysis/debugging.py175
-rw-r--r--miasm2/analysis/depgraph.py43
-rw-r--r--miasm2/analysis/disasm_cb.py24
-rw-r--r--miasm2/analysis/dse.py59
-rw-r--r--miasm2/analysis/expression_range.py11
-rw-r--r--miasm2/analysis/gdbserver.py336
-rw-r--r--miasm2/analysis/modularintervals.py11
-rw-r--r--miasm2/analysis/outofssa.py28
-rw-r--r--miasm2/analysis/sandbox.py148
-rw-r--r--miasm2/analysis/simplifier.py4
-rw-r--r--miasm2/analysis/ssa.py41
-rw-r--r--miasm2/arch/aarch64/arch.py67
-rw-r--r--miasm2/arch/aarch64/jit.py9
-rw-r--r--miasm2/arch/aarch64/regs.py21
-rw-r--r--miasm2/arch/aarch64/sem.py25
-rw-r--r--miasm2/arch/arm/arch.py61
-rw-r--r--miasm2/arch/arm/disasm.py4
-rw-r--r--miasm2/arch/arm/jit.py7
-rw-r--r--miasm2/arch/arm/regs.py3
-rw-r--r--miasm2/arch/arm/sem.py27
-rw-r--r--miasm2/arch/mep/arch.py7
-rw-r--r--miasm2/arch/mep/regs.py5
-rw-r--r--miasm2/arch/mep/sem.py8
-rw-r--r--miasm2/arch/mips32/arch.py6
-rw-r--r--miasm2/arch/mips32/jit.py7
-rw-r--r--miasm2/arch/mips32/regs.py15
-rw-r--r--miasm2/arch/msp430/arch.py16
-rw-r--r--miasm2/arch/msp430/regs.py3
-rw-r--r--miasm2/arch/msp430/sem.py4
-rw-r--r--miasm2/arch/ppc/arch.py9
-rw-r--r--miasm2/arch/ppc/jit.py7
-rw-r--r--miasm2/arch/ppc/regs.py11
-rw-r--r--miasm2/arch/ppc/sem.py19
-rw-r--r--miasm2/arch/sh4/arch.py37
-rw-r--r--miasm2/arch/sh4/regs.py9
-rw-r--r--miasm2/arch/x86/arch.py259
-rw-r--r--miasm2/arch/x86/jit.py35
-rw-r--r--miasm2/arch/x86/regs.py23
-rw-r--r--miasm2/arch/x86/sem.py223
-rw-r--r--miasm2/core/asm_ast.py4
-rw-r--r--miasm2/core/asmblock.py73
-rw-r--r--miasm2/core/bin_stream.py38
-rw-r--r--miasm2/core/bin_stream_ida.py10
-rw-r--r--miasm2/core/cpu.py112
-rw-r--r--miasm2/core/ctypesmngr.py6
-rw-r--r--miasm2/core/graph.py39
-rw-r--r--miasm2/core/interval.py8
-rw-r--r--miasm2/core/locationdb.py46
-rw-r--r--miasm2/core/objc.py158
-rw-r--r--miasm2/core/parse_asm.py24
-rw-r--r--miasm2/core/sembuilder.py22
-rw-r--r--miasm2/core/types.py70
-rw-r--r--miasm2/core/utils.py84
-rw-r--r--miasm2/expression/expression.py106
-rw-r--r--miasm2/expression/expression_helper.py74
-rw-r--r--miasm2/expression/modint.py51
-rw-r--r--miasm2/expression/simplifications.py4
-rw-r--r--miasm2/expression/simplifications_common.py18
-rw-r--r--miasm2/ir/ir.py80
-rw-r--r--miasm2/ir/symbexec.py93
-rw-r--r--miasm2/ir/symbexec_top.py8
-rw-r--r--miasm2/ir/symbexec_types.py20
-rw-r--r--miasm2/ir/translators/C.py4
-rw-r--r--miasm2/ir/translators/miasm.py7
-rw-r--r--miasm2/ir/translators/python.py46
-rw-r--r--miasm2/ir/translators/smt2.py16
-rw-r--r--miasm2/ir/translators/translator.py25
-rw-r--r--miasm2/ir/translators/z3_ir.py16
-rw-r--r--miasm2/jitter/JitCore.c5
-rw-r--r--miasm2/jitter/JitCore.h109
-rw-r--r--miasm2/jitter/Jitgcc.c20
-rw-r--r--miasm2/jitter/Jitllvm.c17
-rw-r--r--miasm2/jitter/arch/JitCore_aarch64.c49
-rw-r--r--miasm2/jitter/arch/JitCore_arm.c47
-rw-r--r--miasm2/jitter/arch/JitCore_mep.c123
-rw-r--r--miasm2/jitter/arch/JitCore_mips32.c50
-rw-r--r--miasm2/jitter/arch/JitCore_msp430.c50
-rw-r--r--miasm2/jitter/arch/JitCore_ppc32.c51
-rw-r--r--miasm2/jitter/arch/JitCore_x86.c88
-rw-r--r--miasm2/jitter/codegen.py14
-rw-r--r--miasm2/jitter/compat_py23.h87
-rw-r--r--miasm2/jitter/emulatedsymbexec.py13
-rw-r--r--miasm2/jitter/jitcore.py23
-rw-r--r--miasm2/jitter/jitcore_cc_base.py36
-rw-r--r--miasm2/jitter/jitcore_gcc.py55
-rw-r--r--miasm2/jitter/jitcore_llvm.py45
-rw-r--r--miasm2/jitter/jitcore_python.py6
-rw-r--r--miasm2/jitter/jitload.py46
-rw-r--r--miasm2/jitter/llvmconvert.py323
-rw-r--r--miasm2/jitter/loader/elf.py20
-rw-r--r--miasm2/jitter/loader/pe.py83
-rw-r--r--miasm2/jitter/loader/utils.py31
-rw-r--r--miasm2/jitter/vm_mngr_py.c78
-rw-r--r--miasm2/os_dep/common.py82
-rw-r--r--miasm2/os_dep/linux/environment.py96
-rw-r--r--miasm2/os_dep/linux/syscall.py25
-rw-r--r--miasm2/os_dep/linux_stdlib.py31
-rw-r--r--miasm2/os_dep/win_api_x86_32.py143
-rw-r--r--miasm2/os_dep/win_api_x86_32_seh.py141
-rw-r--r--requirements.txt3
-rwxr-xr-xsetup.py216
-rw-r--r--test/analysis/data_flow.py8
-rw-r--r--test/analysis/depgraph.py539
-rw-r--r--test/analysis/dg_check.py9
-rw-r--r--test/analysis/dse.py6
-rw-r--r--test/analysis/modularintervals.py9
-rw-r--r--test/analysis/range.py3
-rw-r--r--test/analysis/unssa.py6
-rw-r--r--test/arch/aarch64/arch.py18
-rw-r--r--test/arch/aarch64/unit/asm_test.py6
-rw-r--r--test/arch/arm/arch.py45
-rwxr-xr-xtest/arch/arm/sem.py571
-rw-r--r--test/arch/mep/asm/test_asm.py18
-rw-r--r--test/arch/mep/asm/test_major_opcode_0.py2
-rw-r--r--test/arch/mep/asm/test_major_opcode_1.py2
-rw-r--r--test/arch/mep/asm/test_major_opcode_10.py2
-rw-r--r--test/arch/mep/asm/test_major_opcode_11.py2
-rw-r--r--test/arch/mep/asm/test_major_opcode_12.py2
-rw-r--r--test/arch/mep/asm/test_major_opcode_13.py2
-rw-r--r--test/arch/mep/asm/test_major_opcode_14.py2
-rw-r--r--test/arch/mep/asm/test_major_opcode_15.py2
-rw-r--r--test/arch/mep/asm/test_major_opcode_2.py2
-rw-r--r--test/arch/mep/asm/test_major_opcode_3.py2
-rw-r--r--test/arch/mep/asm/test_major_opcode_4.py2
-rw-r--r--test/arch/mep/asm/test_major_opcode_5.py2
-rw-r--r--test/arch/mep/asm/test_major_opcode_6.py2
-rw-r--r--test/arch/mep/asm/test_major_opcode_7.py2
-rw-r--r--test/arch/mep/asm/test_major_opcode_8.py2
-rw-r--r--test/arch/mep/asm/test_major_opcode_9.py2
-rw-r--r--test/arch/mep/asm/ut_helpers_asm.py33
-rw-r--r--test/arch/mep/ir/test_arithmetic.py2
-rw-r--r--test/arch/mep/ir/test_bitmanipulation.py2
-rw-r--r--test/arch/mep/ir/test_branchjump.py2
-rw-r--r--test/arch/mep/ir/test_control.py2
-rw-r--r--test/arch/mep/ir/test_coprocessor.py2
-rw-r--r--test/arch/mep/ir/test_datacache.py2
-rw-r--r--test/arch/mep/ir/test_debug.py2
-rw-r--r--test/arch/mep/ir/test_divide.py2
-rw-r--r--test/arch/mep/ir/test_extension.py2
-rw-r--r--test/arch/mep/ir/test_ir.py23
-rw-r--r--test/arch/mep/ir/test_ldz.py2
-rw-r--r--test/arch/mep/ir/test_loadstore.py2
-rw-r--r--test/arch/mep/ir/test_logical.py2
-rw-r--r--test/arch/mep/ir/test_move.py2
-rw-r--r--test/arch/mep/ir/test_multiply.py2
-rw-r--r--test/arch/mep/ir/test_repeat.py2
-rw-r--r--test/arch/mep/ir/test_shift.py2
-rw-r--r--test/arch/mep/ir/ut_helpers_ir.py15
-rw-r--r--test/arch/mep/jit/test_jit_branchjump.py2
-rw-r--r--test/arch/mep/jit/test_jit_repeat.py2
-rw-r--r--test/arch/mep/jit/ut_helpers_jit.py10
-rw-r--r--test/arch/mips32/arch.py16
-rw-r--r--test/arch/mips32/unit/asm_test.py6
-rw-r--r--test/arch/msp430/arch.py19
-rwxr-xr-xtest/arch/msp430/sem.py15
-rw-r--r--test/arch/sh4/arch.py26
-rw-r--r--test/arch/x86/arch.py55
-rw-r--r--test/arch/x86/qemu/testqemu.py66
-rw-r--r--test/arch/x86/qemu/testqemu64.py60
-rwxr-xr-xtest/arch/x86/sem.py21
-rw-r--r--test/arch/x86/unit/access_xmm.py4
-rw-r--r--test/arch/x86/unit/asm_test.py8
-rw-r--r--test/arch/x86/unit/mn_getset128.py8
-rwxr-xr-xtest/arch/x86/unit/mn_pcmpeq.py2
-rwxr-xr-xtest/arch/x86/unit/mn_pshufb.py4
-rwxr-xr-xtest/arch/x86/unit/mn_psrl_psll.py16
-rwxr-xr-xtest/arch/x86/unit/mn_pushpop.py16
-rwxr-xr-xtest/arch/x86/unit/mn_seh.py3
-rw-r--r--test/core/asmblock.py43
-rw-r--r--test/core/graph.py15
-rwxr-xr-xtest/core/interval.py11
-rw-r--r--test/core/locationdb.py7
-rwxr-xr-xtest/core/parse_asm.py5
-rw-r--r--test/core/sembuilder.py19
-rwxr-xr-xtest/core/test_types.py67
-rwxr-xr-xtest/core/utils.py8
-rw-r--r--test/expr_type/test_chandler.py38
-rw-r--r--test/expression/expr_pickle.py15
-rw-r--r--test/expression/expression.py15
-rwxr-xr-xtest/expression/expression_helper.py15
-rw-r--r--test/expression/modint.py31
-rw-r--r--test/expression/parser.py3
-rw-r--r--test/expression/simplifications.py57
-rwxr-xr-xtest/expression/stp.py5
-rw-r--r--test/ir/ir.py7
-rwxr-xr-xtest/ir/ir2C.py3
-rw-r--r--test/ir/reduce_graph.py10
-rwxr-xr-xtest/ir/symbexec.py28
-rw-r--r--test/ir/translators/smt2.py29
-rw-r--r--test/ir/translators/z3_ir.py3
-rw-r--r--test/jitter/bad_block.py3
-rw-r--r--test/jitter/jit_options.py11
-rw-r--r--test/jitter/jitload.py5
-rw-r--r--test/jitter/jmp_out_mem.py3
-rw-r--r--test/jitter/test_post_instr.py16
-rw-r--r--test/jitter/vm_mngr.py2
-rwxr-xr-xtest/os_dep/common.py3
-rwxr-xr-xtest/os_dep/linux/stdlib.py8
-rw-r--r--test/os_dep/linux/test_env.py3
-rwxr-xr-xtest/os_dep/win_api_x86_32.py19
-rwxr-xr-xtest/test_all.py77
-rw-r--r--test/utils/cosmetics.py29
-rw-r--r--test/utils/multithread.py21
-rw-r--r--test/utils/testset.py10
255 files changed, 5027 insertions, 3694 deletions
diff --git a/.appveyor.yml b/.appveyor.yml
index fb565570..3023dc8f 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -11,11 +11,13 @@ environment:
       APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
       PLATFORM_TOOLSET: v141
       PYTHON: c:\Python27
+      PYTHON_VERSION: "2.7.x"
 
     - platform: x64
       APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
       PLATFORM_TOOLSET: v141
       PYTHON: c:\Python27-x64
+      PYTHON_VERSION: "2.7.x"
 
       # on_finish:
       #  - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
diff --git a/.travis.yml b/.travis.yml
index ee4f0ed5..e395e804 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,8 @@
 sudo: false
 language: python
-python: 2.7
+python:
+  - 2.7
+  - 3.6
 addons:
   apt:
     sources: ['llvm-toolchain-trusty-6.0', 'ubuntu-toolchain-r-test']
@@ -29,4 +31,4 @@ before_script:
 # install
 - python setup.py build build_ext
 - python setup.py install
-script: cd test && python -W error test_all.py $MIASM_TEST_EXTRA_ARG && git ls-files -o --exclude-standard
+script: cd test && flags=""; python --version |& grep -q "Python 3" || flags="-W error"; python $flags test_all.py $MIASM_TEST_EXTRA_ARG && git ls-files -o --exclude-standard
diff --git a/README.md b/README.md
index e8e257c8..bee55db3 100644
--- a/README.md
+++ b/README.md
@@ -58,7 +58,7 @@ Get a location db:
 Assemble a line:
 ```pycon
 >>> l = mn_x86.fromstring('XOR ECX, ECX', loc_db, 32)
->>> print l
+>>> print(l)
 XOR        ECX, ECX
 >>> mn_x86.asm(l)
 ['1\xc9', '3\xc9', 'g1\xc9', 'g3\xc9']
@@ -66,15 +66,15 @@ XOR        ECX, ECX
 Modify an operand:
 ```pycon
 >>> l.args[0] = mn_x86.regs.EAX
->>> print l
+>>> print(l)
 XOR        EAX, ECX
 >>> a = mn_x86.asm(l)
->>> print a
+>>> print(a)
 ['1\xc8', '3\xc1', 'g1\xc8', 'g3\xc1']
 ```
 Disassemble the result:
 ```pycon
->>> print mn_x86.dis(a[0], 32)
+>>> print(mn_x86.dis(a[0], 32))
 XOR        EAX, ECX
 ```
 Using `Machine` abstraction:
@@ -82,14 +82,14 @@ Using `Machine` abstraction:
 ```pycon
 >>> from miasm2.analysis.machine import Machine
 >>> mn = Machine('x86_32').mn
->>> print mn.dis('\x33\x30', 32)
+>>> print(mn.dis('\x33\x30', 32))
 XOR        ESI, DWORD PTR [EAX]
 ```
 
 For Mips:
 ```pycon
 >>> mn = Machine('mips32b').mn
->>> print  mn.dis('97A30020'.decode('hex'), "b")
+>>> print(mn.dis(b'\x97\xa3\x00 ', "b"))
 LHU        V1, 0x20(SP)
 ```
 Intermediate representation
@@ -99,8 +99,8 @@ Create an instruction:
 
 ```pycon
 >>> machine = Machine('arml')
->>> instr = machine.mn.dis('002088e0'.decode('hex'), 'l')
->>> print instr
+>>> instr = machine.mn.dis('\x00 \x88\xe0', 'l')
+>>> print(instr)
 ADD        R2, R8, R0
 ```
 
@@ -120,7 +120,7 @@ Add instruction to the pool:
 Print current pool:
 ```pycon
 >>> for lbl, irblock in ircfg.blocks.items():
-...     print irblock.to_string(loc_db)
+...     print(irblock.to_string(loc_db))
 loc_0:
 R2 = R8 + R0
 
@@ -133,9 +133,9 @@ Working with IR, for instance by getting side effects:
 ...     for assignblk in irblock:
 ...         rw = assignblk.get_rw()
 ...         for dst, reads in rw.iteritems():
-...             print 'read:   ', [str(x) for x in reads]
-...             print 'written:', dst
-...             print
+...             print('read:   ', [str(x) for x in reads])
+...             print('written:', dst)
+...             print()
 ...
 read:    ['R8', 'R0']
 written: R2
@@ -178,7 +178,7 @@ Disassembling the shellcode at address `0`:
 >>> mdis = machine.dis_engine(c.bin_stream)
 >>> asmcfg = mdis.dis_multiblock(0)
 >>> for block in asmcfg.blocks:
-...  print block.to_string(asmcfg.loc_db)
+...  print(block.to_string(asmcfg.loc_db))
 ...
 loc_0
 LEA        ECX, DWORD PTR [ECX + 0x4]
@@ -292,7 +292,7 @@ Launching the execution:
 
 ```pycon
 >>> symbolic_pc = sb.run_at(ircfg, 0)
->>> print symbolic_pc
+>>> print(symbolic_pc)
 ((ECX + 0x4)[0:8] + 0xFF)?(0xB,0x10)
 ```
 
diff --git a/example/asm/shellcode.py b/example/asm/shellcode.py
index 9be5b517..b14b7441 100755
--- a/example/asm/shellcode.py
+++ b/example/asm/shellcode.py
@@ -1,7 +1,9 @@
 #! /usr/bin/env python2
+from __future__ import print_function
 from argparse import ArgumentParser
 from pdb import pm
 
+from future.utils import viewitems
 from elfesteem import pe_init
 from elfesteem.strpatchwork import StrPatchwork
 
@@ -9,6 +11,7 @@ from miasm2.core import parse_asm, asmblock
 from miasm2.analysis.machine import Machine
 from miasm2.core.interval import interval
 from miasm2.core.locationdb import LocationDB
+from miasm2.core.utils import iterbytes, int_to_byte
 
 parser = ArgumentParser("Multi-arch (32 bits) assembler")
 parser.add_argument('architecture', help="architecture: " +
@@ -41,8 +44,17 @@ if args.PE:
     pe = pe_init.PE(wsize=size)
     s_text = pe.SHList.add_section(name="text", addr=0x1000, rawsize=0x1000)
     s_iat = pe.SHList.add_section(name="iat", rawsize=0x100)
-    new_dll = [({"name": "USER32.dll",
-                 "firstthunk": s_iat.addr}, ["MessageBoxA"])]
+    new_dll = [
+        (
+            {
+                "name": "USER32.dll",
+                "firstthunk": s_iat.addr
+            },
+            [
+                "MessageBoxA"
+            ]
+        )
+    ]
     pe.DirImport.add_dlldesc(new_dll)
     s_myimp = pe.SHList.add_section(name="myimp", rawsize=len(pe.DirImport))
     pe.DirImport.set_rva(s_myimp.addr)
@@ -51,8 +63,11 @@ if args.PE:
     addr_main = pe.rva2virt(s_text.addr)
     virt = pe.virt
     output = pe
-    dst_interval = interval([(pe.rva2virt(s_text.addr),
-                              pe.rva2virt(s_text.addr + s_text.size))])
+    dst_interval = interval(
+        [
+            (pe.rva2virt(s_text.addr), pe.rva2virt(s_text.addr + s_text.size))
+        ]
+    )
 else:
     st = StrPatchwork()
 
@@ -74,20 +89,26 @@ asmcfg, loc_db = parse_asm.parse_txt(machine.mn, attrib, source, loc_db)
 loc_db.set_location_offset(loc_db.get_name_location("main"), addr_main)
 
 if args.PE:
-    loc_db.set_location_offset(loc_db.get_or_create_name_location("MessageBoxA"),
-                               pe.DirImport.get_funcvirt('USER32.dll',
-                                                         'MessageBoxA'))
+    loc_db.set_location_offset(
+        loc_db.get_or_create_name_location("MessageBoxA"),
+        pe.DirImport.get_funcvirt(
+            'USER32.dll',
+            'MessageBoxA'
+        )
+    )
 
 # Print and graph firsts blocks before patching it
 for block in asmcfg.blocks:
-    print block
+    print(block)
 open("graph.dot", "w").write(asmcfg.dot())
 
 # Apply patches
-patches = asmblock.asm_resolve_final(machine.mn,
-                                    asmcfg,
-                                    loc_db,
-                                    dst_interval)
+patches = asmblock.asm_resolve_final(
+    machine.mn,
+    asmcfg,
+    loc_db,
+    dst_interval
+)
 if args.encrypt:
     # Encrypt code
     loc_start = loc_db.get_or_create_name_location(args.encrypt[0])
@@ -95,20 +116,18 @@ if args.encrypt:
     ad_start = loc_db.get_location_offset(loc_start)
     ad_stop = loc_db.get_location_offset(loc_stop)
 
-    new_patches = dict(patches)
-    for ad, val in patches.items():
+    for ad, val in list(viewitems(patches)):
         if ad_start <= ad < ad_stop:
-            new_patches[ad] = "".join([chr(ord(x) ^ 0x42) for x in val])
-    patches = new_patches
+            patches[ad] = b"".join(int_to_byte(ord(x) ^ 0x42) for x in iterbytes(val))
 
-print patches
+print(patches)
 if isinstance(virt, StrPatchwork):
-    for offset, raw in patches.items():
+    for offset, raw in viewitems(patches):
         virt[offset] = raw
 else:
-    for offset, raw in patches.items():
+    for offset, raw in viewitems(patches):
         virt.set(offset, raw)
 
 
 # Produce output
-open(args.output, 'wb').write(str(output))
+open(args.output, 'wb').write(bytes(output))
diff --git a/example/asm/simple.py b/example/asm/simple.py
index 5480e2f5..e46faa48 100644
--- a/example/asm/simple.py
+++ b/example/asm/simple.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 from pdb import pm
 from pprint import pprint
 
@@ -29,7 +30,7 @@ patches = asmblock.asm_resolve_final(mn_x86, asmcfg, loc_db)
 
 # Show resolved asmcfg
 for block in asmcfg.blocks:
-    print block
+    print(block)
 
 # Print offset -> bytes
 pprint(patches)
diff --git a/example/disasm/callback.py b/example/disasm/callback.py
index 02416b38..95c165d4 100644
--- a/example/disasm/callback.py
+++ b/example/disasm/callback.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 from miasm2.analysis.binary import Container
 from miasm2.analysis.machine import Machine
 from miasm2.core.asmblock import AsmConstraint
@@ -41,27 +42,28 @@ def cb_x86_callpop(cur_bloc, loc_db, *args, **kwargs):
 
 
 # Prepare a tiny shellcode
-shellcode = ''.join(["\xe8\x00\x00\x00\x00", # CALL $
-                     "X",                    # POP EAX
-                     "\xc3",                 # RET
-                     ])
+shellcode = (
+    b"\xe8\x00\x00\x00\x00" # CALL $
+    b"X"                    # POP EAX
+    b"\xc3"                 # RET
+)
 
 # Instantiate a x86 32 bit architecture
 machine = Machine("x86_32")
 cont = Container.from_string(shellcode)
 mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db)
 
-print "Without callback:\n"
+print("Without callback:\n")
 asmcfg = mdis.dis_multiblock(0)
-print "\n".join(str(block) for block in asmcfg.blocks)
+print("\n".join(str(block) for block in asmcfg.blocks))
 
 # Enable callback
 mdis.dis_block_callback = cb_x86_callpop
 
-print "=" * 40
-print "With callback:\n"
+print("=" * 40)
+print("With callback:\n")
 asmcfg_after = mdis.dis_multiblock(0)
-print "\n".join(str(block) for block in asmcfg_after.blocks)
+print("\n".join(str(block) for block in asmcfg_after.blocks))
 
 # Ensure the callback has been called
 assert asmcfg.loc_key_to_block(asmcfg.heads()[0]).lines[0].name == "CALL"
diff --git a/example/disasm/dis_binary.py b/example/disasm/dis_binary.py
index 3e12ca91..4ac5ef26 100644
--- a/example/disasm/dis_binary.py
+++ b/example/disasm/dis_binary.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 import sys
 from miasm2.analysis.binary import Container
 from miasm2.analysis.machine import Machine
@@ -23,7 +24,7 @@ asmcfg = mdis.dis_multiblock(addr)
 
 # Display each basic blocks
 for block in asmcfg.blocks:
-    print block
+    print(block)
 
 # Output control flow graph in a dot file
 open('bin_cfg.dot', 'w').write(asmcfg.dot())
diff --git a/example/disasm/dis_binary_ir.py b/example/disasm/dis_binary_ir.py
index 197fccfd..ac642a36 100644
--- a/example/disasm/dis_binary_ir.py
+++ b/example/disasm/dis_binary_ir.py
@@ -1,4 +1,6 @@
+from __future__ import print_function
 import sys
+from future.utils import viewvalues
 from miasm2.analysis.binary import Container
 from miasm2.analysis.machine import Machine
 
@@ -28,8 +30,8 @@ ir_arch = machine.ir(mdis.loc_db)
 ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg)
 
 # Display each IR basic blocks
-for irblock in ircfg.blocks.values():
-    print irblock
+for irblock in viewvalues(ircfg.blocks):
+    print(irblock)
 
 # Output ir control flow graph in a dot file
 open('bin_ir_cfg.dot', 'w').write(ircfg.dot())
diff --git a/example/disasm/dis_binary_ira.py b/example/disasm/dis_binary_ira.py
index 726f353e..04bddbbb 100644
--- a/example/disasm/dis_binary_ira.py
+++ b/example/disasm/dis_binary_ira.py
@@ -1,4 +1,6 @@
+from __future__ import print_function
 import sys
+from future.utils import viewvalues
 from miasm2.analysis.binary import Container
 from miasm2.analysis.machine import Machine
 
@@ -30,8 +32,8 @@ ir_arch_analysis = machine.ira(mdis.loc_db)
 ircfg_analysis = ir_arch_analysis.new_ircfg_from_asmcfg(asmcfg)
 
 # Display each IR basic blocks
-for irblock in ircfg_analysis.blocks.values():
-    print irblock
+for irblock in viewvalues(ircfg_analysis.blocks):
+    print(irblock)
 
 # Output ir control flow graph in a dot file
 open('bin_ira_cfg.dot', 'w').write(ircfg_analysis.dot())
diff --git a/example/disasm/dis_x86_string.py b/example/disasm/dis_x86_string.py
index 8f919e4e..175e9264 100644
--- a/example/disasm/dis_x86_string.py
+++ b/example/disasm/dis_x86_string.py
@@ -1,8 +1,9 @@
+from __future__ import print_function
 from miasm2.analysis.binary import Container
 from miasm2.analysis.machine import Machine
 
 # The Container will provide a *bin_stream*, bytes source for the disasm engine
-cont = Container.from_string("\x83\xf8\x10\x74\x07\x89\xc6\x0f\x47\xc3\xeb\x08\x89\xc8\xe8\x31\x33\x22\x11\x40\xc3")
+cont = Container.from_string(b"\x83\xf8\x10\x74\x07\x89\xc6\x0f\x47\xc3\xeb\x08\x89\xc8\xe8\x31\x33\x22\x11\x40\xc3")
 
 # Instantiate a x86 32 bit architecture
 machine = Machine("x86_32")
@@ -16,7 +17,7 @@ asmcfg = mdis.dis_multiblock(0)
 
 # Display each basic blocks
 for block in asmcfg.blocks:
-    print block
+    print(block)
 
 # Output control flow graph in a dot file
 open('str_cfg.dot', 'w').write(asmcfg.dot())
diff --git a/example/disasm/full.py b/example/disasm/full.py
index 5161a299..de3f82ac 100644
--- a/example/disasm/full.py
+++ b/example/disasm/full.py
@@ -1,7 +1,10 @@
+from __future__ import print_function
 import logging
 from argparse import ArgumentParser
 from pdb import pm
 
+from future.utils import viewitems, viewvalues
+
 from miasm2.analysis.binary import Container
 from miasm2.core.asmblock import log_asmblock, AsmCFG
 from miasm2.core.interval import interval
@@ -35,7 +38,8 @@ parser.add_argument('-n', "--funcswatchdog", default=None, type=int,
                     help="Maximum number of function to disassemble")
 parser.add_argument('-r', "--recurfunctions", action="store_true",
                     help="Disassemble founded functions")
-parser.add_argument('-v', "--verbose", action="count", help="Verbose mode")
+parser.add_argument('-v', "--verbose", action="count", help="Verbose mode",
+                    default=0)
 parser.add_argument('-g', "--gen_ir", action="store_true",
                     help="Compute the intermediate representation")
 parser.add_argument('-z', "--dis-nulstart-block", action="store_true",
@@ -43,7 +47,8 @@ parser.add_argument('-z', "--dis-nulstart-block", action="store_true",
 parser.add_argument('-l', "--dontdis-retcall", action="store_true",
                     help="If set, disassemble only call destinations")
 parser.add_argument('-s', "--simplify", action="count",
-                    help="Apply simplifications rules (liveness, graph simplification, ...)")
+                    help="Apply simplifications rules (liveness, graph simplification, ...)",
+                    default=0)
 parser.add_argument("--base-address", default=0,
                     type=lambda x: int(x, 0),
                     help="Base address of the input binary")
@@ -92,7 +97,7 @@ log.info("import machine...")
 # Use the guessed architecture or the specified one
 arch = args.architecture if args.architecture else cont.arch
 if not arch:
-    print "Architecture recognition fail. Please specify it in arguments"
+    print("Architecture recognition fail. Please specify it in arguments")
     exit(-1)
 
 # Instance the arch-dependent machine
@@ -177,7 +182,7 @@ while not finish and todo:
 
 # Generate dotty graph
 all_asmcfg = AsmCFG(mdis.loc_db)
-for blocks in all_funcs_blocks.values():
+for blocks in viewvalues(all_funcs_blocks):
     all_asmcfg += blocks
 
 
@@ -189,7 +194,7 @@ log.info('generate intervals')
 all_lines = []
 total_l = 0
 
-print done_interval
+print(done_interval)
 if args.image:
     log.info('build img')
     done_interval.show()
@@ -199,7 +204,7 @@ for i, j in done_interval.intervals:
 
 
 all_lines.sort(key=lambda x: x.offset)
-open('lines.dot', 'w').write('\n'.join([str(l) for l in all_lines]))
+open('lines.dot', 'w').write('\n'.join(str(l) for l in all_lines))
 log.info('total lines %s' % total_l)
 
 
@@ -217,7 +222,7 @@ class IRADelModCallStack(ira):
             for assignblk in assignblks:
                 dct = dict(assignblk)
                 dct = {
-                    dst:src for (dst, src) in dct.iteritems() if dst != self.sp
+                    dst:src for (dst, src) in viewitems(dct) if dst != self.sp
                 }
                 out.append(AssignBlock(dct, assignblk.instr))
             return out, extra
@@ -238,21 +243,21 @@ if args.gen_ir:
 
     head = list(entry_points)[0]
 
-    for ad, asmcfg in all_funcs_blocks.items():
+    for ad, asmcfg in viewitems(all_funcs_blocks):
         log.info("generating IR... %x" % ad)
         for block in asmcfg.blocks:
             ir_arch.add_asmblock_to_ircfg(block, ircfg)
             ir_arch_a.add_asmblock_to_ircfg(block, ircfg_a)
 
     log.info("Print blocks (without analyse)")
-    for label, block in ir_arch.blocks.iteritems():
-        print block
+    for label, block in viewitems(ir_arch.blocks):
+        print(block)
 
     log.info("Gen Graph... %x" % ad)
 
     log.info("Print blocks (with analyse)")
-    for label, block in ir_arch_a.blocks.iteritems():
-        print block
+    for label, block in viewitems(ir_arch_a.blocks):
+        print(block)
 
     if args.simplify > 0:
         log.info("Simplify...")
@@ -289,7 +294,7 @@ if args.propagexpr:
                         continue
                     if reg in regs_todo:
                         out[reg] = dst
-            return set(out.values())
+            return set(viewvalues(out))
 
     # Add dummy dependency to uncover out regs assignment
     for loc in ircfg_a.leaves():
@@ -317,7 +322,7 @@ if args.propagexpr:
 
         """
         try:
-            _ = bs.getbytes(addr, size/8)
+            _ = bs.getbytes(addr, size // 8)
         except IOError:
             return False
         return True
diff --git a/example/disasm/single_instr.py b/example/disasm/single_instr.py
index d17e303f..70b37220 100644
--- a/example/disasm/single_instr.py
+++ b/example/disasm/single_instr.py
@@ -1,14 +1,15 @@
+from __future__ import print_function
 from miasm2.arch.x86.arch import mn_x86
 from miasm2.arch.x86.regs import EDX
 from miasm2.core.locationdb import LocationDB
 
 loc_db = LocationDB()
 l = mn_x86.fromstring('MOV EAX, EBX', loc_db, 32)
-print "instruction:", l
-print "arg:", l.args[0]
+print("instruction:", l)
+print("arg:", l.args[0])
 x = mn_x86.asm(l)
-print x
+print(x)
 l.args[0] = EDX
 y = mn_x86.asm(l)
-print y
-print mn_x86.dis(y[0], 32)
+print(y)
+print(mn_x86.dis(y[0], 32))
diff --git a/example/expression/access_c.py b/example/expression/access_c.py
index b23ba81b..c6f26a10 100644
--- a/example/expression/access_c.py
+++ b/example/expression/access_c.py
@@ -39,10 +39,12 @@ Then, in the C generator:
 ExprCompose(var1, 0) => var1
 
 """
-
+from __future__ import print_function
 
 import sys
 
+from future.utils import viewitems, viewvalues
+
 from miasm2.analysis.machine import Machine
 from miasm2.analysis.binary import Container
 from miasm2.expression.expression import ExprOp, ExprCompose, ExprId, ExprInt
@@ -57,21 +59,21 @@ from miasm2.core.ctypesmngr import CAstTypes, CTypePtr, CTypeStruct
 def find_call(ircfg):
     """Returns (irb, index) which call"""
 
-    for irb in ircfg.blocks.values():
+    for irb in viewvalues(ircfg.blocks):
         out = set()
         if len(irb) < 2:
             continue
         assignblk = irb[-2]
-        for src in assignblk.itervalues():
+        for src in viewvalues(assignblk):
             if not isinstance(src, ExprOp):
                 continue
             if not src.op.startswith('call_func'):
                 continue
-            out.add((irb, len(irb) - 2))
+            out.add((irb.loc_key, len(irb) - 2))
         if len(out) != 1:
             continue
-        irb, index = out.pop()
-        yield irb, index
+        loc_key, index = out.pop()
+        yield loc_key, index
 
 
 class MyExprToAccessC(ExprToAccessC):
@@ -96,9 +98,10 @@ def get_funcs_arg0(ctx, ira, ircfg, lbl_head):
     g_dep = DependencyGraph(ircfg, follow_call=False)
     element = ira.arch.regs.RSI
 
-    for irb, index in find_call(ircfg):
+    for loc_key, index in find_call(ircfg):
+        irb = ircfg.get_block(loc_key)
         instr = irb[index].instr
-        print 'Analysing references from:', hex(instr.offset), instr
+        print('Analysing references from:', hex(instr.offset), instr)
         g_list = g_dep.get(irb.loc_key, set([element]), index, set([lbl_head]))
         for dep in g_list:
             emul_result = dep.emul(ira, ctx)
@@ -113,7 +116,7 @@ class MyCHandler(CHandler):
 
 
 
-data = open(sys.argv[1]).read()
+data = open(sys.argv[1], 'rb').read()
 # Digest C information
 text = """
 struct human {
@@ -160,7 +163,7 @@ expr_types = {arg0: (ptr_llhuman,),
 mychandler = MyCHandler(types_mngr, expr_types)
 
 for expr in get_funcs_arg0(ctx, ir_arch_a, ircfg, lbl_head):
-    print "Access:", expr
+    print("Access:", expr)
     for c_str, ctype in mychandler.expr_to_c_and_types(expr):
-        print '\taccess:', c_str
-        print '\tc type:', ctype
+        print('\taccess:', c_str)
+        print('\tc type:', ctype)
diff --git a/example/expression/asm_to_ir.py b/example/expression/asm_to_ir.py
index 7036d960..16f766e1 100644
--- a/example/expression/asm_to_ir.py
+++ b/example/expression/asm_to_ir.py
@@ -1,5 +1,8 @@
+from __future__ import print_function
 from pdb import pm
 
+from future.utils import viewitems
+
 from miasm2.arch.x86.arch import mn_x86
 from miasm2.core import parse_asm
 from miasm2.expression.expression import *
@@ -27,11 +30,11 @@ loop:
 
 loc_db.set_location_offset(loc_db.get_name_location("main"), 0x0)
 for block in asmcfg.blocks:
-    print block
+    print(block)
 
 
-print "symbols:"
-print loc_db
+print("symbols:")
+print(loc_db)
 patches = asmblock.asm_resolve_final(mn_x86, asmcfg, loc_db)
 
 # Translate to IR
@@ -39,16 +42,16 @@ ir_arch = ir_a_x86_32(loc_db)
 ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg)
 
 # Display IR
-for lbl, irblock in ircfg.blocks.items():
-    print irblock
+for lbl, irblock in viewitems(ircfg.blocks):
+    print(irblock)
 
 # Dead propagation
 open('graph.dot', 'w').write(ircfg.dot())
-print '*' * 80
+print('*' * 80)
 dead_simp(ir_arch, ircfg)
 open('graph2.dot', 'w').write(ircfg.dot())
 
 # Display new IR
-print 'new ir blocks'
-for lbl, irblock in ircfg.blocks.items():
-    print irblock
+print('new ir blocks')
+for lbl, irblock in viewitems(ircfg.blocks):
+    print(irblock)
diff --git a/example/expression/basic_op.py b/example/expression/basic_op.py
index 6032f483..8b5d7e2b 100644
--- a/example/expression/basic_op.py
+++ b/example/expression/basic_op.py
@@ -1,31 +1,32 @@
+from __future__ import print_function
 from miasm2.expression.expression import *
 
-print """
+print("""
 Simple expression manipulation demo
-"""
+""")
 
 # define 2 ID
 a = ExprId('eax', 32)
 b = ExprId('ebx', 32)
-print a, b
+print(a, b)
 # eax ebx
 
 # add those ID
 c = ExprOp('+', a, b)
-print c
+print(c)
 # (eax + ebx)
 
 # + automatically generates ExprOp('+', a, b)
 c = a + b
-print c
+print(c)
 # (eax + ebx)
 
 # ax is a slice of eax
 ax = a[:16]
-print ax
+print(ax)
 # eax[0:16]
 
 # memory deref
 d = ExprMem(c, 32)
-print d
+print(d)
 # @32[(eax + ebx)]
diff --git a/example/expression/basic_simplification.py b/example/expression/basic_simplification.py
index eefdc765..5ecf21db 100644
--- a/example/expression/basic_simplification.py
+++ b/example/expression/basic_simplification.py
@@ -1,9 +1,10 @@
+from __future__ import print_function
 from miasm2.expression.expression import *
 from miasm2.expression.simplifications import expr_simp
 
-print """
+print("""
 Simple expression simplification demo
-"""
+""")
 
 
 a = ExprId('eax', 32)
@@ -14,6 +15,6 @@ exprs = [a + b - a,
          ExprCompose(a[:8], a[8:16])]
 
 for e in exprs:
-    print '*' * 40
-    print 'original expression:', e
-    print "simplified:", expr_simp(e)
+    print('*' * 40)
+    print('original expression:', e)
+    print("simplified:", expr_simp(e))
diff --git a/example/expression/constant_propagation.py b/example/expression/constant_propagation.py
index e70f8163..1259758b 100644
--- a/example/expression/constant_propagation.py
+++ b/example/expression/constant_propagation.py
@@ -25,7 +25,7 @@ args = parser.parse_args()
 
 machine = Machine("x86_32")
 
-cont = Container.from_stream(open(args.filename))
+cont = Container.from_stream(open(args.filename, 'rb'))
 mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db)
 ir_arch = machine.ira(mdis.loc_db)
 addr = int(args.address, 0)
diff --git a/example/expression/export_llvm.py b/example/expression/export_llvm.py
index a0af66b7..c8ee14a5 100644
--- a/example/expression/export_llvm.py
+++ b/example/expression/export_llvm.py
@@ -1,3 +1,5 @@
+from future.utils import viewitems, viewvalues
+
 from argparse import ArgumentParser
 from miasm2.analysis.binary import Container
 from miasm2.analysis.machine import Machine
@@ -12,7 +14,7 @@ parser.add_argument("--architecture", "-a", help="Force architecture")
 args = parser.parse_args()
 
 # This part focus on obtaining an IRCFG to transform #
-cont = Container.from_stream(open(args.target))
+cont = Container.from_stream(open(args.target, 'rb'))
 machine = Machine(args.architecture if args.architecture else cont.arch)
 ir = machine.ir(cont.loc_db)
 dis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db)
@@ -47,12 +49,14 @@ func.init_fc()
 #     ...
 
 all_regs = set()
-for block in ircfg.blocks.itervalues():
+for block in viewvalues(ircfg.blocks):
     for irs in block.assignblks:
-        for dst, src in irs.get_rw(mem_read=True).iteritems():
+        for dst, src in viewitems(irs.get_rw(mem_read=True)):
             elem = src.union(set([dst]))
-            all_regs.update(x for x in elem
-                            if x.is_id())
+            all_regs.update(
+                x for x in elem
+                if x.is_id()
+            )
 
 reg2glob = {}
 for var in all_regs:
@@ -70,7 +74,7 @@ for var in all_regs:
 func.from_ircfg(ircfg, append_ret=False)
 
 # Finish the saving of registers (temporary version to global)
-for reg, glob in reg2glob.iteritems():
+for reg, glob in viewitems(reg2glob):
     value = func.builder.load(func.local_vars_pointers[reg.name])
     func.builder.store(value, glob)
 
diff --git a/example/expression/expr_c.py b/example/expression/expr_c.py
index 37c9f510..83cc727b 100644
--- a/example/expression/expr_c.py
+++ b/example/expression/expr_c.py
@@ -3,6 +3,7 @@ Parse C expression to access variables and retrieve information:
 * Miasm expression to access this variable
 * variable type
 """
+from __future__ import print_function
 
 from miasm2.core.ctypesmngr import CTypeStruct, CAstTypes, CTypePtr
 from miasm2.arch.x86.ctype import CTypeAMD64_unk
@@ -56,6 +57,6 @@ c_acceses = ["ptr->width",
 for c_str in c_acceses:
     expr = mychandler.c_to_expr(c_str)
     c_type = mychandler.c_to_type(c_str)
-    print 'C access:', c_str
-    print '\tExpr:', expr
-    print '\tType:', c_type
+    print('C access:', c_str)
+    print('\tExpr:', expr)
+    print('\tType:', c_type)
diff --git a/example/expression/expr_grapher.py b/example/expression/expr_grapher.py
index e0562852..e1643b03 100644
--- a/example/expression/expr_grapher.py
+++ b/example/expression/expr_grapher.py
@@ -1,6 +1,8 @@
+from __future__ import print_function
+
 from miasm2.expression.expression import *
 
-print "Simple Expression grapher demo"
+print("Simple Expression grapher demo")
 
 a = ExprId("A", 32)
 b = ExprId("B", 32)
@@ -8,13 +10,13 @@ c = ExprId("C", 32)
 d = ExprId("D", 32)
 m = ExprMem(a + b + c + a, 32)
 
-e1 = ExprCompose(a + b - (c * a) / m | b, a + m)
+e1 = ExprCompose(a + b - ((c * a) // m) | b, a + m)
 e2 = ExprInt(15, 64)
 e = ExprCond(d, e1, e2)[0:32]
 
-print "[+] Expression:"
-print e
+print("[+] Expression:")
+print(e)
 
 g = e.graph()
-print "[+] Graph:"
-print g.dot()
+print("[+] Graph:")
+print(g.dot())
diff --git a/example/expression/expr_random.py b/example/expression/expr_random.py
index 66c09f2e..5ac3be06 100644
--- a/example/expression/expr_random.py
+++ b/example/expression/expr_random.py
@@ -1,22 +1,24 @@
+from __future__ import print_function
+from builtins import range
 import string
 import random
 
 from miasm2.expression.expression_helper import ExprRandom
 
-print "Simple expression generator\n"
+print("Simple expression generator\n")
 
 depth = 8
 seed = 0
 random.seed(seed)
 
-print "- An ID:"
-print ExprRandom.identifier()
-print "- A number:"
-print ExprRandom.number()
+print("- An ID:")
+print(ExprRandom.identifier())
+print("- A number:")
+print(ExprRandom.number())
 
-print "- 3 expressions (without cleaning expression cache):"
-for i in xrange(3):
-    print "\t%s\n" % ExprRandom.get(depth=depth, clean=False)
+print("- 3 expressions (without cleaning expression cache):")
+for i in range(3):
+    print("\t%s\n" % ExprRandom.get(depth=depth, clean=False))
 
 class ExprRandom_NoPerfect_NoReuse_UppercaseIdent(ExprRandom):
     """ExprRandom extension with:
@@ -27,8 +29,8 @@ class ExprRandom_NoPerfect_NoReuse_UppercaseIdent(ExprRandom):
 
     perfect_tree = False
     reuse_element = False
-    identifier_charset = string.uppercase
+    identifier_charset = string.ascii_uppercase
 
-print "- 3 expressions with a custom generator:"
-for i in xrange(3):
-    print "\t%s\n" % ExprRandom_NoPerfect_NoReuse_UppercaseIdent.get(depth=depth)
+print("- 3 expressions with a custom generator:")
+for i in range(3):
+    print("\t%s\n" % ExprRandom_NoPerfect_NoReuse_UppercaseIdent.get(depth=depth))
diff --git a/example/expression/expr_translate.py b/example/expression/expr_translate.py
index e1505dae..1a36a64c 100644
--- a/example/expression/expr_translate.py
+++ b/example/expression/expr_translate.py
@@ -1,5 +1,8 @@
+from __future__ import print_function
 import random
 
+from future.utils import viewitems
+
 from miasm2.expression.expression import *
 from miasm2.expression.expression_helper import ExprRandom
 from miasm2.ir.translators import Translator
@@ -13,32 +16,32 @@ class ExprRandom_OpSubRange(ExprRandom):
                                  }
 
 
-print "[+] Compute a random expression:"
+print("[+] Compute a random expression:")
 expr = ExprRandom_OpSubRange.get(depth=8)
-print "-> %s" % expr
-print
+print("-> %s" % expr)
+print()
 
 target_exprs = {lang:Translator.to_language(lang).from_expr(expr)
                 for lang in Translator.available_languages()}
-for target_lang, target_expr in target_exprs.iteritems():
-    print "[+] Translate in %s:" % target_lang
-    print target_expr
-    print
+for target_lang, target_expr in viewitems(target_exprs):
+    print("[+] Translate in %s:" % target_lang)
+    print(target_expr)
+    print()
 
-print "[+] Eval in Python:"
+print("[+] Eval in Python:")
 def memory(addr, size):
     ret = random.randint(0, (1 << size) - 1)
-    print "Memory access: @0x%x -> 0x%x" % (addr, ret)
+    print("Memory access: @0x%x -> 0x%x" % (addr, ret))
     return ret
 
 for expr_id in expr.get_r(mem_read=True):
     if isinstance(expr_id, ExprId):
         value = random.randint(0, (1 << expr_id.size) - 1)
-        print "Declare var: %s = 0x%x" % (expr_id.name, value)
+        print("Declare var: %s = 0x%x" % (expr_id.name, value))
         globals()[expr_id.name] = value
 
-print "-> 0x%x" % eval(target_exprs["Python"])
+print("-> 0x%x" % eval(target_exprs["Python"]))
 
-print "[+] Validate the Miasm syntax rebuilding"
+print("[+] Validate the Miasm syntax rebuilding")
 exprRebuild = eval(target_exprs["Miasm"])
 assert(expr == exprRebuild)
diff --git a/example/expression/get_read_write.py b/example/expression/get_read_write.py
index 34d0f94a..0c8bb3dd 100644
--- a/example/expression/get_read_write.py
+++ b/example/expression/get_read_write.py
@@ -1,3 +1,7 @@
+from __future__ import print_function
+
+from future.utils import viewitems
+
 from miasm2.arch.x86.arch import mn_x86
 from miasm2.expression.expression import get_rw
 from miasm2.arch.x86.ira import ir_a_x86_32
@@ -6,10 +10,10 @@ from miasm2.core.locationdb import LocationDB
 loc_db = LocationDB()
 
 
-print """
+print("""
 Simple expression manipulation demo.
 Get read/written registers for a given instruction
-"""
+""")
 
 arch = mn_x86
 ir_arch = ir_a_x86_32(loc_db)
@@ -18,14 +22,14 @@ instr = arch.fromstring('LODSB', loc_db, 32)
 instr.offset, instr.l = 0, 15
 ir_arch.add_instr_to_ircfg(instr, ircfg)
 
-print '*' * 80
-for lbl, irblock in ircfg.blocks.iteritems():
-    print irblock
+print('*' * 80)
+for lbl, irblock in viewitems(ircfg.blocks):
+    print(irblock)
     for assignblk in irblock:
         rw = assignblk.get_rw()
-        for dst, reads in rw.iteritems():
-            print 'read:   ', [str(x) for x in reads]
-            print 'written:', dst
-            print
+        for dst, reads in viewitems(rw):
+            print('read:   ', [str(x) for x in reads])
+            print('written:', dst)
+            print()
 
 open('graph_instr.dot', 'w').write(ircfg.dot())
diff --git a/example/expression/graph_dataflow.py b/example/expression/graph_dataflow.py
index 92bcf249..55159598 100644
--- a/example/expression/graph_dataflow.py
+++ b/example/expression/graph_dataflow.py
@@ -1,5 +1,8 @@
+from __future__ import print_function
 from argparse import ArgumentParser
 
+from future.utils import viewitems, viewvalues
+
 from miasm2.analysis.binary import Container
 from miasm2.analysis.machine import Machine
 from miasm2.expression.expression import get_expr_mem
@@ -17,10 +20,6 @@ parser.add_argument("-s", "--symb", help="Symbolic execution mode",
 args = parser.parse_args()
 
 
-def node_x_2_id(n, x):
-    return hash(str(n) + str(x)) & 0xffffffffffffffff
-
-
 def get_node_name(label, i, n):
     n_name = (label, i, n)
     return n_name
@@ -30,8 +29,8 @@ def intra_block_flow_symb(ir_arch, _, flow_graph, irblock, in_nodes, out_nodes):
     symbols_init = ir_arch.arch.regs.regs_init.copy()
     sb = SymbolicExecutionEngine(ir_arch, symbols_init)
     sb.eval_updt_irblock(irblock)
-    print '*' * 40
-    print irblock
+    print('*' * 40)
+    print(irblock)
 
 
     out = sb.modified(mems=False)
@@ -86,14 +85,14 @@ def node2str(node):
 
 
 def gen_block_data_flow_graph(ir_arch, ircfg, ad, block_flow_cb):
-    for irblock in ircfg.blocks.values():
-        print irblock
+    for irblock in viewvalues(ircfg.blocks):
+        print(irblock)
 
     dead_simp(ir_arch, ircfg)
 
 
     irblock_0 = None
-    for irblock in ircfg.blocks.values():
+    for irblock in viewvalues(ircfg.blocks):
         loc_key = irblock.loc_key
         offset = ircfg.loc_db.get_location_offset(loc_key)
         if offset == ad:
@@ -110,15 +109,15 @@ def gen_block_data_flow_graph(ir_arch, ircfg, ad, block_flow_cb):
         irb_in_nodes[label] = {}
         irb_out_nodes[label] = {}
 
-    for label, irblock in ircfg.blocks.iteritems():
+    for label, irblock in viewitems(ircfg.blocks):
         block_flow_cb(ir_arch, ircfg, flow_graph, irblock, irb_in_nodes[label], irb_out_nodes[label])
 
     for label in ircfg.blocks:
-        print label
-        print 'IN', [str(x) for x in irb_in_nodes[label]]
-        print 'OUT', [str(x) for x in irb_out_nodes[label]]
+        print(label)
+        print('IN', [str(x) for x in irb_in_nodes[label]])
+        print('OUT', [str(x) for x in irb_out_nodes[label]])
 
-    print '*' * 20, 'interblock', '*' * 20
+    print('*' * 20, 'interblock', '*' * 20)
     inter_block_flow(ir_arch, ircfg, flow_graph, irblock_0.loc_key, irb_in_nodes, irb_out_nodes)
 
     # from graph_qt import graph_qt
@@ -128,22 +127,22 @@ def gen_block_data_flow_graph(ir_arch, ircfg, ad, block_flow_cb):
 
 ad = int(args.addr, 16)
 
-print 'disasm...'
-cont = Container.from_stream(open(args.filename))
+print('disasm...')
+cont = Container.from_stream(open(args.filename, 'rb'))
 machine = Machine("x86_32")
 
 mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db)
 mdis.follow_call = True
 asmcfg = mdis.dis_multiblock(ad)
-print 'ok'
+print('ok')
 
 
-print 'generating dataflow graph for:'
+print('generating dataflow graph for:')
 ir_arch_analysis = machine.ira(mdis.loc_db)
 ircfg = ir_arch_analysis.new_ircfg_from_asmcfg(asmcfg)
 
-for irblock in ircfg.blocks.values():
-    print irblock
+for irblock in viewvalues(ircfg.blocks):
+    print(irblock)
 
 
 if args.symb:
@@ -153,11 +152,11 @@ else:
 
 gen_block_data_flow_graph(ir_arch_analysis, ircfg, ad, block_flow_cb)
 
-print '*' * 40
-print """
+print('*' * 40)
+print("""
  View with:
 dotty dataflow.dot
  or
  Generate ps with pdf:
 dot -Tps dataflow_xx.dot -o graph.ps
-"""
+""")
diff --git a/example/expression/simplification_add.py b/example/expression/simplification_add.py
index 621d1139..6ac36a17 100644
--- a/example/expression/simplification_add.py
+++ b/example/expression/simplification_add.py
@@ -1,13 +1,14 @@
+from __future__ import print_function
 import miasm2.expression.expression as m2_expr
 from miasm2.expression.simplifications import expr_simp
 from pdb import pm
 
-print """
+print("""
 Expression simplification demo: Adding a simplification:
 a + a + a == a * 3
 
 More detailed examples can be found in miasm2/expression/simplification*.
-"""
+""")
 
 # Define the simplification method
 ## @expr_simp is the current expression simplifier instance
@@ -32,14 +33,14 @@ def simp_add_mul(expr_simp, expr):
 
 a = m2_expr.ExprId('a', 32)
 base_expr = a + a + a
-print "Without adding the simplification:"
-print "\t%s = %s" % (base_expr, expr_simp(base_expr))
+print("Without adding the simplification:")
+print("\t%s = %s" % (base_expr, expr_simp(base_expr)))
 
 # Enable pass
 expr_simp.enable_passes({m2_expr.ExprOp: [simp_add_mul]})
 
-print "After adding the simplification:"
-print "\t%s = %s" % (base_expr, expr_simp(base_expr))
+print("After adding the simplification:")
+print("\t%s = %s" % (base_expr, expr_simp(base_expr)))
 
 # Automatic fail
 assert(expr_simp(base_expr) == m2_expr.ExprOp("*", a,
diff --git a/example/expression/simplification_tools.py b/example/expression/simplification_tools.py
index cb062fb3..a9bcc429 100644
--- a/example/expression/simplification_tools.py
+++ b/example/expression/simplification_tools.py
@@ -1,10 +1,11 @@
+from __future__ import print_function
 from miasm2.expression.expression import *
 from pdb import pm
 
-print """
+print("""
 Expression simplification demo.
 (and regression test)
-"""
+""")
 
 
 a = ExprId('a', 32)
@@ -39,26 +40,26 @@ def replace_expr(e):
     return e
 
 
-print x
+print(x)
 y = x.visit(replace_expr)
-print y
-print x.copy()
-print y.copy()
-print y == y.copy()
-print repr(y), repr(y.copy())
+print(y)
+print(x.copy())
+print(y.copy())
+print(y == y.copy())
+print(repr(y), repr(y.copy()))
 
 
 z = ExprCompose(a[5:5 + 8], b[:16], x[:8])
-print z
-print z.copy()
-print z[:31].copy().visit(replace_expr)
+print(z)
+print(z.copy())
+print(z[:31].copy().visit(replace_expr))
 
-print 'replace'
-print x.replace_expr({c + ExprInt(0x42, 32): d,
-                      a + b: c, })
-print z.replace_expr({c + ExprInt(0x42, 32): d,
-                      a + b: c, })
+print('replace')
+print(x.replace_expr({c + ExprInt(0x42, 32): d,
+                      a + b: c, }))
+print(z.replace_expr({c + ExprInt(0x42, 32): d,
+                      a + b: c, }))
 
 
 u = z.copy()
-print u
+print(u)
diff --git a/example/expression/solve_condition_stp.py b/example/expression/solve_condition_stp.py
index c79dd0b8..e0ab09da 100644
--- a/example/expression/solve_condition_stp.py
+++ b/example/expression/solve_condition_stp.py
@@ -1,8 +1,11 @@
+from __future__ import print_function
 import sys
 import subprocess
 from optparse import OptionParser
 from pdb import pm
 
+from future.utils import viewitems
+
 from miasm2.analysis.machine import Machine
 from miasm2.analysis.binary import Container
 from miasm2.expression.expression import ExprInt, ExprCond, ExprId, \
@@ -29,9 +32,9 @@ if not args:
 def emul_symb(ir_arch, ircfg, mdis, states_todo, states_done):
     while states_todo:
         addr, symbols, conds = states_todo.pop()
-        print '*' * 40, "addr", addr, '*' * 40
+        print('*' * 40, "addr", addr, '*' * 40)
         if (addr, symbols, conds) in states_done:
-            print 'Known state, skipping', addr
+            print('Known state, skipping', addr)
             continue
         states_done.add((addr, symbols, conds))
         symbexec = SymbolicExecutionEngine(ir_arch)
@@ -40,10 +43,10 @@ def emul_symb(ir_arch, ircfg, mdis, states_todo, states_done):
             del symbexec.symbols[ir_arch.pc]
         irblock = get_block(ir_arch, ircfg, mdis, addr)
 
-        print 'Run block:'
-        print irblock
+        print('Run block:')
+        print(irblock)
         addr = symbexec.eval_updt_irblock(irblock)
-        print 'Final state:'
+        print('Final state:')
         symbexec.dump(mems=False)
 
         assert addr is not None
@@ -55,16 +58,16 @@ def emul_symb(ir_arch, ircfg, mdis, states_todo, states_done):
             addr_b = expr_simp(symbexec.eval_expr(addr.replace_expr(cond_group_b), {}))
             if not (addr_a.is_int() or addr_a.is_loc() and
                     addr_b.is_int() or addr_b.is_loc()):
-                print str(addr_a), str(addr_b)
+                print(str(addr_a), str(addr_b))
                 raise ValueError("Unsupported condition")
             if isinstance(addr_a, ExprInt):
                 addr_a = int(addr_a.arg)
             if isinstance(addr_b, ExprInt):
                 addr_b = int(addr_b.arg)
-            states_todo.add((addr_a, symbexec.symbols.copy(), tuple(list(conds) + cond_group_a.items())))
-            states_todo.add((addr_b, symbexec.symbols.copy(), tuple(list(conds) + cond_group_b.items())))
+            states_todo.add((addr_a, symbexec.symbols.copy(), tuple(list(conds) + list(viewitems(cond_group_a)))))
+            states_todo.add((addr_b, symbexec.symbols.copy(), tuple(list(conds) + list(viewitems(cond_group_b)))))
         elif addr == ret_addr:
-            print 'Return address reached'
+            print('Return address reached')
             continue
         elif addr.is_int():
             addr = int(addr.arg)
@@ -81,7 +84,7 @@ if __name__ == '__main__':
 
     addr = int(options.address, 16)
 
-    cont = Container.from_stream(open(args[0]))
+    cont = Container.from_stream(open(args[0], 'rb'))
     mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db)
     ir_arch = machine.ir(mdis.loc_db)
     ircfg = ir_arch.new_ircfg()
@@ -120,7 +123,7 @@ if __name__ == '__main__':
     for instr in block.lines:
         for i, arg in enumerate(instr.args):
             instr.args[i]= arg.replace_expr(fix_args)
-    print block
+    print(block)
 
     # add fake address and len to parsed instructions
     ir_arch.add_asmblock_to_ircfg(block, ircfg)
@@ -139,12 +142,12 @@ if __name__ == '__main__':
 
     all_info = []
 
-    print '*' * 40, 'conditions to match', '*' * 40
-    for addr, symbols, conds in sorted(states_done):
-        print '*' * 40, addr, '*' * 40
+    print('*' * 40, 'conditions to match', '*' * 40)
+    for addr, symbols, conds in sorted(states_done, key=str):
+        print('*' * 40, addr, '*' * 40)
         reqs = []
         for k, v in conds:
-            print k, v
+            print(k, v)
             reqs.append((k, v))
         all_info.append((addr, reqs))
 
@@ -179,14 +182,14 @@ if __name__ == '__main__':
                                              "-p", '--SMTLIB2',
                                              "out.dot"])
         except OSError:
-            print "Cannot find stp binary!"
+            print("Cannot find stp binary!")
             break
         for c in cases.split('\n'):
             if c.startswith('ASSERT'):
                 all_cases.add((addr, c))
 
-    print '*' * 40, 'ALL COND', '*' * 40
+    print('*' * 40, 'ALL COND', '*' * 40)
     all_cases = list(all_cases)
     all_cases.sort(key=lambda x: (x[0], x[1]))
     for addr, val in all_cases:
-        print 'Address:', addr, 'is reachable using argc', val
+        print('Address:', addr, 'is reachable using argc', val)
diff --git a/example/ida/ctype_propagation.py b/example/ida/ctype_propagation.py
index 61bc747f..a043b9c9 100644
--- a/example/ida/ctype_propagation.py
+++ b/example/ida/ctype_propagation.py
@@ -1,7 +1,10 @@
+from __future__ import print_function
 import ida_kernwin
 import idc
 import ida_funcs
 
+from future.utils import viewitems
+
 from miasm2.core.bin_stream_ida import bin_stream_ida
 from miasm2.expression import expression as m2_expr
 from miasm2.expression.simplifications import expr_simp
@@ -198,11 +201,12 @@ class SymbExecCTypeFix(SymbExecCType):
                 for c_str, c_type in self.chandler.expr_to_c_and_types(expr, self.symbols):
                     expr = self.cst_propag_link.get((irb.loc_key, index), {}).get(expr, expr)
                     offset2cmt.setdefault(instr.offset, set()).add(
-                        "\n%s: %s\n%s" % (expr, c_str, c_type))
+                        "\n%s: %s\n%s" % (expr, c_str, c_type)
+                    )
             self.eval_updt_assignblk(assignblk)
-        for offset, value in offset2cmt.iteritems():
+        for offset, value in viewitems(offset2cmt):
             idc.MakeComm(offset, '\n'.join(value))
-            print "%x\n" % offset, '\n'.join(value)
+            print("%x\n" % offset, '\n'.join(value))
 
         return self.eval_expr(self.ir_arch.IRDst)
 
@@ -222,11 +226,11 @@ def get_ira_call_fixer(ira):
     class iraCallStackFixer(ira):
 
         def call_effects(self, ad, instr):
-            print hex(instr.offset), instr
+            print(hex(instr.offset), instr)
             stk_before = idc.GetSpd(instr.offset)
             stk_after = idc.GetSpd(instr.offset + instr.l)
             stk_diff = stk_after - stk_before
-            print hex(stk_diff)
+            print(hex(stk_diff))
             call_assignblk = AssignBlock(
                 [
                     ExprAssign(self.ret_reg, ExprOp('call_func_ret', ad)),
@@ -299,8 +303,8 @@ def analyse_function():
         )
         ctype = mychandler.types_mngr.types_ast.ast_parse_declaration(ast.ext[0])
         objc = types_mngr.get_objc(ctype)
-        print '=' * 20
-        print expr, objc
+        print('=' * 20)
+        print(expr, objc)
         infos_types[expr] = set([objc])
 
     # Add fake head
@@ -344,7 +348,7 @@ def analyse_function():
                 symbexec_engine.get_state()
             )
 
-    for lbl, state in states.iteritems():
+    for lbl, state in viewitems(states):
         if lbl not in ircfg.blocks:
             continue
         symbexec_engine = CTypeEngineFixer(ir_arch, types_mngr, state, cst_propag_link)
diff --git a/example/ida/depgraph.py b/example/ida/depgraph.py
index 2c79c05d..3de19cbc 100644
--- a/example/ida/depgraph.py
+++ b/example/ida/depgraph.py
@@ -1,11 +1,17 @@
+from __future__ import print_function
+from builtins import map
+from builtins import range
 import os
 import tempfile
 
+from future.utils import viewitems, viewvalues
+
 import idautils
 import idc
 import ida_funcs
 import ida_kernwin
 
+
 from miasm2.core.bin_stream_ida import bin_stream_ida
 from miasm2.core.asmblock import *
 from miasm2.expression import expression as m2_expr
@@ -23,12 +29,13 @@ class depGraphSettingsForm(ida_kernwin.Form):
 
         self.ira = ira
         self.ircfg = ircfg
-        self.stk_args = {'ARG%d' % i:i for i in xrange(10)}
+        self.stk_args = {'ARG%d' % i:i for i in range(10)}
         self.stk_unalias_force = False
 
         self.address = idc.ScreenEA()
         cur_block = None
-        for block in ircfg.getby_offset(self.address):
+        for loc_key in ircfg.getby_offset(self.address):
+            block = ircfg.get_block(loc_key)
             offset = self.ircfg.loc_db.get_location_offset(block.loc_key)
             if offset is not None:
                 # Only one block non-generated
@@ -41,11 +48,11 @@ class depGraphSettingsForm(ida_kernwin.Form):
                 break
         assert line_nb is not None
         cur_loc_key = str(cur_block.loc_key)
-        loc_keys = sorted(map(str, ircfg.blocks.keys()))
-        regs = sorted(ira.arch.regs.all_regs_ids_byname.keys())
-        regs += self.stk_args.keys()
+        loc_keys = sorted(map(str, ircfg.blocks))
+        regs = sorted(ira.arch.regs.all_regs_ids_byname)
+        regs += list(self.stk_args)
         reg_default = regs[0]
-        for i in xrange(10):
+        for i in range(10):
             opnd = idc.GetOpnd(self.address, i).upper()
             if opnd in regs:
                 reg_default = opnd
@@ -121,7 +128,7 @@ Method to use:
             line = self.ircfg.blocks[self.loc_key][self.line_nb].instr
             arg_num = self.stk_args[value]
             stk_high = m2_expr.ExprInt(idc.GetSpd(line.offset), ir_arch.sp.size)
-            stk_off = m2_expr.ExprInt(self.ira.sp.size/8 * arg_num, ir_arch.sp.size)
+            stk_off = m2_expr.ExprInt(self.ira.sp.size // 8 * arg_num, ir_arch.sp.size)
             element =  m2_expr.ExprMem(mn.regs.regs_init[ir_arch.sp] + stk_high + stk_off, self.ira.sp.size)
             element = expr_simp(element)
             # Force stack unaliasing
@@ -162,33 +169,33 @@ def treat_element():
     global graphs, comments, sol_nb, settings, addr, ir_arch, ircfg
 
     try:
-        graph = graphs.next()
+        graph = next(graphs)
     except StopIteration:
         comments = {}
-        print "Done: %d solutions" % (sol_nb)
+        print("Done: %d solutions" % (sol_nb))
         return
 
     sol_nb += 1
-    print "Get graph number %02d" % sol_nb
+    print("Get graph number %02d" % sol_nb)
     filename = os.path.join(tempfile.gettempdir(), "solution_0x%08x_%02d.dot" % (addr, sol_nb))
-    print "Dump the graph to %s" % filename
+    print("Dump the graph to %s" % filename)
     open(filename, "w").write(graph.graph.dot())
 
     for node in graph.relevant_nodes:
         try:
             offset = ircfg.blocks[node.loc_key][node.line_nb].instr.offset
         except IndexError:
-            print "Unable to highlight %s" % node
+            print("Unable to highlight %s" % node)
             continue
         comments[offset] = comments.get(offset, []) + [node.element]
         idc.SetColor(offset, idc.CIC_ITEM, settings.color)
 
     if graph.has_loop:
-        print 'Graph has dependency loop: symbolic execution is inexact'
+        print('Graph has dependency loop: symbolic execution is inexact')
     else:
-        print "Possible value: %s" % graph.emul(ir_arch).values()[0]
+        print("Possible value: %s" % next(iter(viewvalues(graph.emul(ir_arch)))))
 
-    for offset, elements in comments.iteritems():
+    for offset, elements in viewitems(comments):
         idc.MakeComm(offset, ", ".join(map(str, elements)))
 
 def next_element():
@@ -228,7 +235,7 @@ def launch_depgraph():
 
     loc_key, elements, line_nb = settings.loc_key, settings.elements, settings.line_nb
     # Simplify assignments
-    for irb in ircfg.blocks.values():
+    for irb in list(viewvalues(ircfg.blocks)):
         irs = []
         offset = ir_arch.loc_db.get_location_offset(irb.loc_key)
         fix_stack = offset is not None and settings.unalias_stack
@@ -238,7 +245,7 @@ def launch_depgraph():
                 fix_dct = {ir_arch.sp: mn.regs.regs_init[ir_arch.sp] + stk_high}
 
             new_assignblk = {}
-            for dst, src in assignblk.iteritems():
+            for dst, src in viewitems(assignblk):
                 if fix_stack:
                     src = src.replace_expr(fix_dct)
                     if dst != ir_arch.sp:
diff --git a/example/ida/graph_ir.py b/example/ida/graph_ir.py
index 8026174d..de46c22d 100644
--- a/example/ida/graph_ir.py
+++ b/example/ida/graph_ir.py
@@ -1,11 +1,16 @@
+from __future__ import print_function
 import os
 import tempfile
+from builtins import int as int_types
+
+from future.utils import viewitems, viewvalues
 
 import idaapi
 import ida_kernwin
 import idc
 import ida_funcs
 import idautils
+
 from miasm2.core.asmblock import is_int
 from miasm2.core.bin_stream_ida import bin_stream_ida
 from miasm2.expression.simplifications import expr_simp
@@ -89,9 +94,9 @@ def label_init(self, name="", offset=None):
 
 
 def label_str(self):
-    if isinstance(self.offset, (int, long)):
+    if isinstance(self.offset, int_types):
         return "%s:0x%x" % (self.name, self.offset)
-    return "%s:%s" % (self.name, str(self.offset))
+    return "%s:%s" % (self.name, self.offset)
 
 
 def color_irblock(irblock, ir_arch):
@@ -99,7 +104,7 @@ def color_irblock(irblock, ir_arch):
     lbl = idaapi.COLSTR("%s:" % ir_arch.loc_db.pretty_str(irblock.loc_key), idaapi.SCOLOR_INSN)
     out.append(lbl)
     for assignblk in irblock:
-        for dst, src in sorted(assignblk.iteritems()):
+        for dst, src in sorted(viewitems(assignblk)):
             dst_f = expr2colorstr(dst, loc_db=ir_arch.loc_db)
             src_f = expr2colorstr(src, loc_db=ir_arch.loc_db)
             line = idaapi.COLSTR("%s = %s" % (dst_f, src_f), idaapi.SCOLOR_INSN)
@@ -120,11 +125,11 @@ class GraphMiasmIR(idaapi.GraphViewer):
     def OnRefresh(self):
         self.Clear()
         addr_id = {}
-        for irblock in self.ircfg.blocks.values():
+        for irblock in viewvalues(self.ircfg.blocks):
             id_irblock = self.AddNode(color_irblock(irblock, self.ircfg))
             addr_id[irblock] = id_irblock
 
-        for irblock in self.ircfg.blocks.values():
+        for irblock in viewvalues(self.ircfg.blocks):
             if not irblock:
                 continue
             all_dst = self.ircfg.dst_trackback(irblock)
@@ -164,7 +169,7 @@ def is_addr_ro_variable(bs, addr, size):
 
     """
     try:
-        _ = bs.getbytes(addr, size/8)
+        _ = bs.getbytes(addr, size // 8)
     except IOError:
         return False
     return True
@@ -183,18 +188,18 @@ def build_graph(start_addr, type_graph, simplify=False, dontmodstack=True, loadi
             for assignblk in assignblks:
                 dct = dict(assignblk)
                 dct = {
-                    dst:src for (dst, src) in dct.iteritems() if dst != self.sp
+                    dst:src for (dst, src) in viewitems(dct) if dst != self.sp
                 }
                 out.append(AssignBlock(dct, assignblk.instr))
             return out, extra
 
 
     if verbose:
-        print "Arch", dis_engine
+        print("Arch", dis_engine)
 
     fname = idc.GetInputFile()
     if verbose:
-        print fname
+        print(fname)
 
     bs = bin_stream_ida()
     mdis = dis_engine(bs)
@@ -212,28 +217,28 @@ def build_graph(start_addr, type_graph, simplify=False, dontmodstack=True, loadi
         mdis.loc_db.add_location(name, addr)
 
     if verbose:
-        print "start disasm"
+        print("start disasm")
     if verbose:
-        print hex(start_addr)
+        print(hex(start_addr))
 
     asmcfg = mdis.dis_multiblock(start_addr)
     entry_points = set([mdis.loc_db.get_offset_location(start_addr)])
     if verbose:
-        print "generating graph"
+        print("generating graph")
         open('asm_flow.dot', 'w').write(asmcfg.dot())
-        print "generating IR... %x" % start_addr
+        print("generating IR... %x" % start_addr)
 
     ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg)
 
     if verbose:
-        print "IR ok... %x" % start_addr
+        print("IR ok... %x" % start_addr)
 
-    for irb in ircfg.blocks.itervalues():
+    for irb in list(viewvalues(ircfg.blocks)):
         irs = []
         for assignblk in irb:
             new_assignblk = {
                 expr_simp(dst): expr_simp(src)
-                for dst, src in assignblk.iteritems()
+                for dst, src in viewitems(assignblk)
             }
             irs.append(AssignBlock(new_assignblk, instr=assignblk.instr))
         ircfg.blocks[irb.loc_key] = IRBlock(irb.loc_key, irs)
@@ -268,7 +273,7 @@ def build_graph(start_addr, type_graph, simplify=False, dontmodstack=True, loadi
                         continue
                     if reg in regs_todo:
                         out[reg] = dst
-            return set(out.values())
+            return set(viewvalues(out))
 
 
 
diff --git a/example/ida/rpyc_ida.py b/example/ida/rpyc_ida.py
index 21faf43a..6c18fb7a 100644
--- a/example/ida/rpyc_ida.py
+++ b/example/ida/rpyc_ida.py
@@ -1,4 +1,5 @@
 """rpyc IDA server"""
+from __future__ import print_function
 
 from rpyc.utils.server import OneShotServer
 from rpyc.core import SlaveService
@@ -11,7 +12,7 @@ def serve_threaded(hostname="localhost", port=4455):
     WARNING: IDA will be locked until the client script terminates.
     """
 
-    print 'Running server'
+    print('Running server')
     server = OneShotServer(SlaveService, hostname=hostname,
                            port=port, reuse_addr=True, ipv6=False,
                            authenticator=None,
diff --git a/example/ida/symbol_exec.py b/example/ida/symbol_exec.py
index e004b1b6..aa1d57fe 100644
--- a/example/ida/symbol_exec.py
+++ b/example/ida/symbol_exec.py
@@ -1,7 +1,12 @@
+from __future__ import print_function
 import operator
 
+from future.utils import viewitems
+
 import idaapi
 import idc
+
+
 from miasm2.expression.expression_helper import Variables_Identifier
 from miasm2.expression.expression import ExprAssign
 
@@ -49,10 +54,12 @@ class symbolicexec_t(idaapi.simplecustviewer_t):
         element = self.line2eq[linenum]
         expanded = Variables_Identifier(element[1],
                                         var_prefix="%s_v" % element[0])
-        self.line2eq = self.line2eq[0:linenum] + \
-            expanded.vars.items() + \
-            [(element[0], expanded.equation)] + \
+        self.line2eq = (
+            self.line2eq[0:linenum] +
+            list(viewitems(expanded.vars)) +
+            [(element[0], expanded.equation)] +
             self.line2eq[linenum + 1:]
+        )
 
     def print_lines(self):
         self.ClearLines()
@@ -75,7 +82,7 @@ class symbolicexec_t(idaapi.simplecustviewer_t):
 
         self.machine = machine
         self.loc_db = loc_db
-        self.line2eq = sorted(equations.items(), key=operator.itemgetter(0))
+        self.line2eq = sorted(viewitems(equations), key=operator.itemgetter(0))
         self.lines_expanded = set()
 
         self.print_lines()
@@ -144,7 +151,7 @@ def symbolic_exec():
     ira = machine.ira(loc_db=mdis.loc_db)
     ircfg = ira.new_ircfg_from_asmcfg(asmcfg)
 
-    print "Run symbolic execution..."
+    print("Run symbolic execution...")
     sb = SymbolicExecutionEngine(ira, machine.mn.regs.regs_init)
     sb.run_at(ircfg, start)
     modified = {}
@@ -192,7 +199,7 @@ if __name__ == '__main__':
     idaapi.CompileLine('static key_F3() { RunPythonStatement("symbolic_exec()"); }')
     idc.AddHotkey("F3", "key_F3")
 
-    print "=" * 50
-    print """Available commands:
+    print("=" * 50)
+    print("""Available commands:
     symbolic_exec() - F3: Symbolic execution of current selection
-    """
+    """)
diff --git a/example/ida/utils.py b/example/ida/utils.py
index a64973f1..b6d5dac4 100644
--- a/example/ida/utils.py
+++ b/example/ida/utils.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+from builtins import map
 import idaapi
 from idc import *
 
@@ -67,7 +69,7 @@ def guess_machine(addr=None):
     elif processor_name == "PPC":
         machine = Machine("ppc32b")
     else:
-        print repr(processor_name)
+        print(repr(processor_name))
         raise NotImplementedError('not fully functional')
 
     return machine
@@ -204,7 +206,7 @@ Python Expression
             dest_lang = self.languages[self.GetControlValue(self.cbLanguage)]
             try:
                 text = Translator.to_language(dest_lang).from_expr(self.expr)
-            except Exception, error:
+            except Exception as error:
                 self.ShowField(self.result, False)
                 return -1
 
diff --git a/example/jitter/arm.py b/example/jitter/arm.py
index e475abeb..86772874 100755
--- a/example/jitter/arm.py
+++ b/example/jitter/arm.py
@@ -1,5 +1,6 @@
 #! /usr/bin/env python2
 #-*- coding:utf-8 -*-
+from __future__ import print_function
 import logging
 from pdb import pm
 
@@ -22,7 +23,7 @@ else:
     logging.basicConfig(level=logging.WARNING)
 
 if options.verbose is True:
-    print sb.jitter.vm
+    print(sb.jitter.vm)
 
 # Run the code
 sb.run()
diff --git a/example/jitter/arm_sc.py b/example/jitter/arm_sc.py
index 7720ad68..b81d3784 100755
--- a/example/jitter/arm_sc.py
+++ b/example/jitter/arm_sc.py
@@ -1,5 +1,6 @@
 #! /usr/bin/env python2
 #-*- coding:utf-8 -*-
+from miasm2.core.utils import int_to_byte
 from miasm2.analysis.sandbox import Sandbox_Linux_armb_str
 from miasm2.analysis.sandbox import Sandbox_Linux_arml_str
 from elfesteem.strpatchwork import StrPatchwork
@@ -35,8 +36,8 @@ stop = sb.jitter.cpu.R1
 s = sb.jitter.vm.get_mem(start, stop-start)
 s = StrPatchwork(s)
 for i, c in enumerate(s):
-    s[i] = chr(ord(c)^0x11)
-s = str(s)
-assert(s == "test string\x00")
+    s[i] = int_to_byte(ord(c)^0x11)
+s = bytes(s)
+assert(s == b"test string\x00")
 
 
diff --git a/example/jitter/example_types.py b/example/jitter/example_types.py
index bcf9bf70..d0751bbd 100755
--- a/example/jitter/example_types.py
+++ b/example/jitter/example_types.py
@@ -4,7 +4,9 @@ For a more complete view of what is possible, tests/core/types.py covers
 most of the module possibilities, and the module doc gives useful information
 as well.
 """
+from __future__ import print_function
 
+from miasm2.core.utils import iterbytes
 from miasm2.analysis.machine import Machine
 from miasm2.core.types import MemStruct, Self, Void, Str, Array, Ptr, \
                               Num, Array, set_allocator
@@ -145,9 +147,9 @@ class DataStr(MemStruct):
     ]
 
 
-print "This script demonstrates a LinkedList implementation using the types "
-print "module in the first part, and how to play with some casts in the second."
-print
+print("This script demonstrates a LinkedList implementation using the types ")
+print("module in the first part, and how to play with some casts in the second.")
+print()
 
 # A random jitter
 # You can also use miasm2.jitter.VmMngr.Vm(), but it does not happen in real
@@ -172,17 +174,17 @@ assert link.size == 3
 # If you get it directly from the VM, it is updated as well
 raw_size = vm.get_mem(link.get_addr("size"), link.get_type()
                                                  .get_field_type("size").size)
-assert raw_size == '\x03\x00\x00\x00'
+assert raw_size == b'\x03\x00\x00\x00'
 
-print "The linked list just built:"
-print repr(link), '\n'
+print("The linked list just built:")
+print(repr(link), '\n')
 
-print "Its uninitialized data elements:"
+print("Its uninitialized data elements:")
 for data in link:
     # __iter__ returns MemVoids here, just cast them to the real data type
     real_data = data.cast(DataArray)
-    print repr(real_data)
-print
+    print(repr(real_data))
+print()
 
 # Now let's play with one data
 data = link.pop(DataArray)
@@ -196,9 +198,9 @@ assert data.arrayptr.deref == data.array
 # Let's say that it is a DataStr:
 datastr = data.cast(DataStr)
 
-print "First element casted to DataStr:"
-print repr(datastr)
-print
+print("First element casted to DataStr:")
+print(repr(datastr))
+print()
 
 # data and datastr really share the same memory:
 data.val1 = 0x34
@@ -212,29 +214,29 @@ memstr = datastr.data.deref
 # Note that memstr is Str("utf16")
 memstr.val = 'Miams'
 
-print "Cast data.array to MemStr and set the string value:"
-print repr(memstr)
-print
+print("Cast data.array to MemStr and set the string value:")
+print(repr(memstr))
+print()
 
 # If you followed, memstr and data.array point to the same object, so:
-raw_miams = '\x00'.join('Miams') + '\x00'*3
-raw_miams_array = [ord(c) for c in raw_miams]
+raw_miams = 'Miams'.encode('utf-16le') + b'\x00'*2
+raw_miams_array = [ord(c) for c in iterbytes(raw_miams)]
 assert list(data.array)[:len(raw_miams_array)] == raw_miams_array
 assert data.array.cast(Str("utf16")) == memstr
 # Default is "ansi"
 assert data.array.cast(Str()) != memstr
 assert data.array.cast(Str("utf16")).val == memstr.val
 
-print "See that the original array has been modified:"
-print repr(data)
-print
+print("See that the original array has been modified:")
+print(repr(data))
+print()
 
 # Some type manipulation examples, for example let's construct an argv for
 # a program:
 # Let's say that we have two arguments, +1 for the program name and +1 for the
 # final null ptr in argv, the array has 4 elements:
 argv_t = Array(Ptr("<I", Str()), 4)
-print "3 arguments argv type:", argv_t
+print("3 arguments argv type:", argv_t)
 
 # alloc argv somewhere
 argv = argv_t.lval(vm)
@@ -249,10 +251,10 @@ argv[3].val = 0
 # If you changed your mind on the second arg, you could do:
 argv[2].deref.val = "42"
 
-print "An argv instance:", repr(argv)
-print "argv values:", repr([val.deref.val for val in argv[:-1]])
-print
+print("An argv instance:", repr(argv))
+print("argv values:", repr([val.deref.val for val in argv[:-1]]))
+print()
 
-print "See test/core/types.py and the miasm2.core.types module doc for "
-print "more information."
+print("See test/core/types.py and the miasm2.core.types module doc for ")
+print("more information.")
 
diff --git a/example/jitter/mips32.py b/example/jitter/mips32.py
index 70181a2a..2eb06c87 100755
--- a/example/jitter/mips32.py
+++ b/example/jitter/mips32.py
@@ -1,5 +1,6 @@
 #! /usr/bin/env python2
 #-*- coding:utf-8 -*-
+from __future__ import print_function
 from argparse import ArgumentParser
 from miasm2.analysis import debugging
 from miasm2.jitter.csts import *
@@ -44,12 +45,16 @@ def jit_mips32_binary(args):
         trace_new_blocks=args.log_newbloc
     )
 
-    myjit.vm.add_memory_page(0, PAGE_READ | PAGE_WRITE, open(filepath).read())
+    myjit.vm.add_memory_page(
+        0,
+        PAGE_READ | PAGE_WRITE,
+        open(filepath, 'rb').read()
+    )
     myjit.add_breakpoint(0x1337BEEF, code_sentinelle)
 
 
     # for stack
-    myjit.vm.add_memory_page(0xF000, PAGE_READ | PAGE_WRITE, "\x00"*0x1000)
+    myjit.vm.add_memory_page(0xF000, PAGE_READ | PAGE_WRITE, b"\x00"*0x1000)
 
     myjit.cpu.SP = 0xF800
 
diff --git a/example/jitter/msp430.py b/example/jitter/msp430.py
index 36e45421..1ecb4cef 100755
--- a/example/jitter/msp430.py
+++ b/example/jitter/msp430.py
@@ -1,5 +1,6 @@
 #! /usr/bin/env python2
 #-*- coding:utf-8 -*-
+from __future__ import print_function
 from argparse import ArgumentParser
 from miasm2.analysis import debugging
 from miasm2.jitter.csts import *
@@ -39,12 +40,16 @@ def jit_msp430_binary(args):
         trace_new_blocks=args.log_newbloc
     )
 
-    myjit.vm.add_memory_page(0, PAGE_READ | PAGE_WRITE, open(filepath, "rb").read())
+    myjit.vm.add_memory_page(
+        0,
+        PAGE_READ | PAGE_WRITE,
+        open(filepath, "rb").read()
+    )
     myjit.add_breakpoint(0x1337, lambda _: exit(0))
 
 
     # for stack
-    myjit.vm.add_memory_page(0xF000, PAGE_READ | PAGE_WRITE, "\x00"*0x1000)
+    myjit.vm.add_memory_page(0xF000, PAGE_READ | PAGE_WRITE, b"\x00"*0x1000)
 
     myjit.cpu.SP = 0xF800
 
diff --git a/example/jitter/run_with_linuxenv.py b/example/jitter/run_with_linuxenv.py
index f4900a96..fda76f9a 100644
--- a/example/jitter/run_with_linuxenv.py
+++ b/example/jitter/run_with_linuxenv.py
@@ -24,8 +24,8 @@ if args.verbose:
     syscall.log.setLevel(logging.DEBUG)
 
 # Get corresponding interpreter and reloc address
-cont_target_tmp = Container.from_stream(open(args.target))
-ld_path = str(cont_target_tmp.executable.getsectionbyname(".interp").content).strip("\x00")
+cont_target_tmp = Container.from_stream(open(args.target, 'rb'))
+ld_path = bytes(cont_target_tmp.executable.getsectionbyname(".interp").content).strip(b"\x00")
 if cont_target_tmp.executable.Ehdr.type in [elf_csts.ET_REL, elf_csts.ET_DYN]:
     elf_base_addr = 0x40000000
 elif cont_target_tmp.executable.Ehdr.type == elf_csts.ET_EXEC:
@@ -52,29 +52,38 @@ else:
 
 # Load the interpreter in memory, applying relocation
 linux_env = LinuxEnvironment()
-linux_env.filesystem.passthrough.append(re.compile(args.passthrough))
+linux_env.filesystem.passthrough.append(re.compile(args.passthrough.encode()))
 ld_path = linux_env.filesystem.resolve_path(ld_path)
-cont_ld = Container.from_stream(open(ld_path),
-                                vm=jitter.vm,
-                                addr=0x80000000,
-                                apply_reloc=True)
+cont_ld = Container.from_stream(
+    open(ld_path, "rb"),
+    vm=jitter.vm,
+    addr=0x80000000,
+    apply_reloc=True
+)
 # Load the target ELF in memory, without applying reloc
 loc_db = cont_ld.loc_db
-cont_target = Container.from_stream(open(args.target), vm=jitter.vm,
-                                    loc_db=loc_db,
-                                    addr=elf_base_addr,
-                                    apply_reloc=False)
+cont_target = Container.from_stream(
+    open(args.target, "rb"),
+    vm=jitter.vm,
+    loc_db=loc_db,
+    addr=elf_base_addr,
+    apply_reloc=False
+)
 # PHDR containing the PH header
-elf_phdr_header = [ph32.ph for ph32 in cont_target.executable.ph
-                   if ph32.ph.type == elf_csts.PT_PHDR][0]
+elf_phdr_header = next(
+    ph32.ph for ph32 in cont_target.executable.ph
+    if ph32.ph.type == elf_csts.PT_PHDR
+)
 
 # Prepare the desired environment
-argv = [args.target] + args.extra_args
+argv = [args.target.encode()] + [arg.encode() for arg in args.extra_args]
 if args.flags:
     argv += ["-%s" % args.flags]
-envp = {"PATH": "/usr/local/bin", "USER": linux_env.user_name}
-auxv = environment.AuxVec(elf_base_addr + elf_phdr_header.vaddr,
-                          cont_target.entry_point, linux_env)
+envp = {b"PATH": b"/usr/local/bin", b"USER": linux_env.user_name}
+auxv = environment.AuxVec(
+    elf_base_addr + elf_phdr_header.vaddr,
+    cont_target.entry_point, linux_env
+)
 prepare_loader(jitter, argv, envp, auxv, linux_env)
 syscall.enable_syscall_handling(jitter, linux_env, syscall_callbacks)
 
diff --git a/example/jitter/sandbox_elf_ppc32.py b/example/jitter/sandbox_elf_ppc32.py
index c5960e8e..04ecfd9e 100644
--- a/example/jitter/sandbox_elf_ppc32.py
+++ b/example/jitter/sandbox_elf_ppc32.py
@@ -5,12 +5,6 @@ from miasm2.jitter.csts import *
 from miasm2.jitter.jitload import log_func
 import logging
 
-
-# Python auto completion
-filename = os.environ.get('PYTHONSTARTUP')
-if filename and os.path.isfile(filename):
-    execfile(filename)
-
 # Insert here user defined methods
 
 # Parse arguments
diff --git a/example/jitter/trace.py b/example/jitter/trace.py
index e1683450..9f025bfd 100644
--- a/example/jitter/trace.py
+++ b/example/jitter/trace.py
@@ -6,6 +6,8 @@ This example demonstrates two instrumentation possibility:
 Note: for better performance, one can also extend Codegen to produce
 instrumentation at the C / LLVM level
 """
+from __future__ import print_function
+
 import os
 import time
 from pdb import pm
@@ -26,11 +28,11 @@ class ESETrackMemory(EmulatedSymbExec):
 
     def mem_read(self, expr_mem):
         value = super(ESETrackMemory, self).mem_read(expr_mem)
-        print "Read %s: %s" % (expr_mem, value)
+        print("Read %s: %s" % (expr_mem, value))
         return value
 
     def mem_write(self, dest, data):
-        print "Write %s: %s" % (dest, data)
+        print("Write %s: %s" % (dest, data))
         return super(ESETrackMemory, self).mem_write(dest, data)
 
 # Parse arguments
@@ -55,4 +57,4 @@ sb.run()
 stop_time = time.time()
 
 assert sb.jitter.run is False
-print "Instr speed: %02.f / sec" % (instr_count / (stop_time - start_time))
+print("Instr speed: %02.f / sec" % (instr_count / (stop_time - start_time)))
diff --git a/example/jitter/unpack_upx.py b/example/jitter/unpack_upx.py
index 6bcef1ab..5d862dd1 100644
--- a/example/jitter/unpack_upx.py
+++ b/example/jitter/unpack_upx.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 import os
 import logging
 from pdb import pm
@@ -12,12 +13,12 @@ def kernel32_GetProcAddress(jitter):
 
     # When the function is called, EBX is a pointer to the destination buffer
     dst_ad = jitter.cpu.EBX
-    logging.info('EBX ' + hex(dst_ad))
+    logging.error('EBX ' + hex(dst_ad))
 
     # Handle ordinal imports
     fname = (args.fname if args.fname < 0x10000
              else jitter.get_str_ansi(args.fname))
-    logging.info(fname)
+    logging.error(fname)
 
     # Get the generated address of the library, and store it in memory to
     # dst_ad
@@ -38,6 +39,7 @@ parser.add_argument("--graph",
                     action="store_true")
 options = parser.parse_args()
 options.load_hdr = True
+
 sb = Sandbox_Win_x86_32(options.filename, options, globals(),
                         parse_reloc=False)
 
@@ -48,7 +50,7 @@ else:
     logging.basicConfig(level=logging.WARNING)
 
 if options.verbose is True:
-    print sb.jitter.vm
+    print(sb.jitter.vm)
 
 # Ensure there is one and only one leave (for OEP discovering)
 mdis = sb.machine.dis_engine(sb.jitter.bs)
@@ -70,7 +72,7 @@ if options.graph is True:
 
 
 if options.verbose is True:
-    print sb.jitter.vm
+    print(sb.jitter.vm)
 
 
 def update_binary(jitter):
@@ -114,4 +116,4 @@ sb.pe.NThdr.optentries[pe.DIRECTORY_ENTRY_DELAY_IMPORT].rva = 0
 
 bname, fname = os.path.split(options.filename)
 fname = os.path.join(bname, fname.replace('.', '_'))
-open(fname + '_unupx.bin', 'w').write(str(sb.pe))
+open(fname + '_unupx.bin', 'wb').write(bytes(sb.pe))
diff --git a/example/jitter/x86_32.py b/example/jitter/x86_32.py
index 5272f732..2a73a2ad 100644
--- a/example/jitter/x86_32.py
+++ b/example/jitter/x86_32.py
@@ -20,7 +20,7 @@ def code_sentinelle(jitter):
 myjit = Machine("x86_32").jitter(args.jitter)
 myjit.init_stack()
 
-data = open(args.filename).read()
+data = open(args.filename, 'rb').read()
 run_addr = 0x40000000
 myjit.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, data)
 
diff --git a/example/symbol_exec/depgraph.py b/example/symbol_exec/depgraph.py
index 260d62ab..c1dbd422 100644
--- a/example/symbol_exec/depgraph.py
+++ b/example/symbol_exec/depgraph.py
@@ -1,7 +1,11 @@
+from __future__ import print_function
+from builtins import range
 from argparse import ArgumentParser
 from pdb import pm
 import json
 
+from future.utils import viewitems
+
 from miasm2.analysis.machine import Machine
 from miasm2.analysis.binary import Container
 from miasm2.analysis.depgraph import DependencyGraph
@@ -54,7 +58,7 @@ init_ctx = {}
 if args.rename_args:
     if arch == "x86_32":
         # StdCall example
-        for i in xrange(4):
+        for i in range(4):
             e_mem = ExprMem(ExprId("ESP_init", 32) + ExprInt(4 * (i + 1), 32), 32)
             init_ctx[e_mem] = ExprId("arg%d" % i, 32)
 
@@ -74,8 +78,9 @@ dg = DependencyGraph(
 
 # Build information
 target_addr = int(args.target_addr, 0)
-current_block = list(ircfg.getby_offset(target_addr))[0]
+current_loc_key = next(iter(ircfg.getby_offset(target_addr)))
 assignblk_index = 0
+current_block = ircfg.get_block(current_loc_key)
 for assignblk_index, assignblk in enumerate(current_block):
     if assignblk.instr.offset == target_addr:
         break
@@ -88,14 +93,14 @@ for sol_nb, sol in enumerate(dg.get(current_block.loc_key, elements, assignblk_i
             fdesc.write(sol.graph.dot())
 
     results = sol.emul(ir_arch, ctx=init_ctx)
-    tokens = {str(k): str(v) for k, v in results.iteritems()}
+    tokens = {str(k): str(v) for k, v in viewitems(results)}
     if not args.json:
-        result = ", ".join("=".join(x) for x in tokens.iteritems())
-        print "Solution %d: %s -> %s" % (sol_nb,
+        result = ", ".join("=".join(x) for x in viewitems(tokens))
+        print("Solution %d: %s -> %s" % (sol_nb,
                                          result,
-                                         fname)
+                                         fname))
         if sol.has_loop:
-            print '\tLoop involved'
+            print('\tLoop involved')
 
     if args.implicit:
         sat = sol.is_satisfiable
@@ -109,10 +114,12 @@ for sol_nb, sol in enumerate(dg.get(current_block.loc_key, elements, assignblk_i
                 constraints[element] = result
         if args.json:
             tokens["satisfiability"] = sat
-            tokens["constraints"] = {str(k): str(v)
-                                     for k, v in constraints.iteritems()}
+            tokens["constraints"] = {
+                str(k): str(v)
+                for k, v in viewitems(constraints)
+            }
         else:
-            print "\tSatisfiability: %s %s" % (sat, constraints)
+            print("\tSatisfiability: %s %s" % (sat, constraints))
 
     if args.json:
         tokens["has_loop"] = sol.has_loop
@@ -120,4 +127,4 @@ for sol_nb, sol in enumerate(dg.get(current_block.loc_key, elements, assignblk_i
 
 
 if args.json:
-    print json.dumps(json_solutions)
+    print(json.dumps(json_solutions))
diff --git a/example/symbol_exec/dse_crackme.py b/example/symbol_exec/dse_crackme.py
index 37700d75..33ec3b72 100644
--- a/example/symbol_exec/dse_crackme.py
+++ b/example/symbol_exec/dse_crackme.py
@@ -4,15 +4,19 @@ This example should run on the compiled ELF x86 64bits version of
 "dse_crackme.c"
 
 """
+from __future__ import print_function
 
 #### This part is only related to the run of the sample, without DSE ####
+from builtins import range
 import os
 import subprocess
 import platform
 from collections import namedtuple
 from pdb import pm
 from tempfile import NamedTemporaryFile
+from future.utils import viewitems
 
+from miasm2.core.utils import int_to_byte
 from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE
 from miasm2.analysis.sandbox import Sandbox_Linux_x86_64
 from miasm2.expression.expression import *
@@ -81,8 +85,11 @@ FS_0_ADDR = 0x7ff70000
 sb.jitter.cpu.FS = 0x4
 sb.jitter.cpu.set_segm_base(sb.jitter.cpu.FS, FS_0_ADDR)
 sb.jitter.vm.add_memory_page(
-    FS_0_ADDR + 0x28, PAGE_READ, "\x42\x42\x42\x42\x42\x42\x42\x42",
-    "Stack canary FS[0x28]")
+    FS_0_ADDR + 0x28,
+    PAGE_READ,
+    b"\x42\x42\x42\x42\x42\x42\x42\x42",
+    "Stack canary FS[0x28]"
+)
 
 # Prepare the execution
 sb.jitter.init_run(sb.entry_point)
@@ -108,7 +115,7 @@ class SymbolicFile(object):
     def read(self, length):
         assert self.state == "OPEN"
         out = []
-        for i in xrange(self.position, min(self.position + length,
+        for i in range(self.position, min(self.position + length,
                                            self.max_size)):
             if i not in self.gen_bytes:
                 ret = ExprId("SF_%08x_%d" % (id(self), i), 8)
@@ -220,7 +227,7 @@ def xxx_puts_symb(dse):
     raise FinishOn(string)
 
 
-todo = set([""]) # Set of file content to test
+todo = set([b""]) # Set of file content to test
 
 # Instantiate the DSE engine
 machine = Machine("x86_64")
@@ -262,7 +269,7 @@ found = False
 while todo:
     # Prepare a solution to try, based on the clean state
     file_content = todo.pop()
-    print "CUR: %r" % file_content
+    print("CUR: %r" % file_content)
     open(TEMP_FILE.name, "wb").write(file_content)
     dse.restore_snapshot(snapshot, keep_known_solutions=True)
     FILE_to_info.clear()
@@ -272,38 +279,38 @@ while todo:
     try:
         sb.run()
     except FinishOn as finish_info:
-        print finish_info.string
-        if finish_info.string == "OK":
+        print(finish_info.string)
+        if finish_info.string == b"OK":
             # Stop if the expected result is found
             found = True
             break
 
     finfo = FILE_to_info_symb[FILE_stream]
-    for sol_ident, model in dse.new_solutions.iteritems():
+    for sol_ident, model in viewitems(dse.new_solutions):
         # Build the file corresponding to solution in 'model'
 
-        out = ""
+        out = []
         fsize = max(model.eval(dse.z3_trans.from_expr(FILE_size)).as_long(),
                     len(finfo.gen_bytes))
-        for index in xrange(fsize):
+        for index in range(fsize):
             try:
                 byteid = finfo.gen_bytes[index]
-                out += chr(model.eval(dse.z3_trans.from_expr(byteid)).as_long())
+                out.append(int_to_byte(model.eval(dse.z3_trans.from_expr(byteid)).as_long()))
             except (KeyError, AttributeError) as _:
                 # Default value if there is no constraint on current byte
-                out += "\x00"
+                out.append(b"\x00")
 
-        todo.add(out)
+        todo.add(b"".join(out))
 
 # Assert that the result has been found
 assert found == True
-print "FOUND !"
+print("FOUND !")
 
 TEMP_FILE.close()
 
 # Replay for real
 if not is_win:
-    print "Trying to launch the binary without Miasm"
+    print("Trying to launch the binary without Miasm")
     crackme = subprocess.Popen([options.filename, TEMP_FILE.name],
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
@@ -311,8 +318,8 @@ if not is_win:
     assert not stderr
     os.unlink(TEMP_FILE.name)
     stdout = stdout.strip()
-    print stdout
-    assert stdout == "OK"
+    print(stdout)
+    assert stdout == b"OK"
 else:
     os.unlink(TEMP_FILE.name)
 
diff --git a/example/symbol_exec/dse_strategies.py b/example/symbol_exec/dse_strategies.py
index b38c797a..8e479d61 100644
--- a/example/symbol_exec/dse_strategies.py
+++ b/example/symbol_exec/dse_strategies.py
@@ -17,8 +17,11 @@ Global overview:
    - Ask the DSE for new candidates, according to its strategy, ie. finding new
 block / branch / path
 """
+from __future__ import print_function
 from argparse import ArgumentParser
 
+from future.utils import viewitems
+
 from miasm2.analysis.machine import Machine
 from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE
 from miasm2.analysis.dse import DSEPathConstraint
@@ -42,9 +45,13 @@ strategy = {
 run_addr = 0x40000
 machine = Machine("x86_32")
 jitter = machine.jitter("python")
-with open(args.filename) as fdesc:
-    jitter.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, fdesc.read(),
-                              "Binary")
+with open(args.filename, "rb") as fdesc:
+    jitter.vm.add_memory_page(
+        run_addr,
+        PAGE_READ | PAGE_WRITE,
+        fdesc.read(),
+        "Binary"
+    )
 
 # Expect a binary with one argument on the stack
 jitter.init_stack()
@@ -94,7 +101,7 @@ while todo:
         continue
     done.add(arg_value)
 
-    print "Run with ARG = %s" % arg_value
+    print("Run with ARG = %s" % arg_value)
     # Restore state, while keeping already found solutions
     dse.restore_snapshot(snapshot, keep_known_solutions=True)
 
@@ -113,17 +120,21 @@ while todo:
     # - last edge for branch coverage
     # - execution path for path coverage
 
-    for sol_ident, model in dse.new_solutions.iteritems():
-        print "Found a solution to reach: %s" % str(sol_ident)
+    for sol_ident, model in viewitems(dse.new_solutions):
+        print("Found a solution to reach: %s" % str(sol_ident))
         # Get the argument to use as a Miasm Expr
         sol_value = model.eval(dse.z3_trans.from_expr(arg)).as_long()
         sol_expr = ExprInt(sol_value, arg.size)
 
         # Display info and update storages
-        print "\tARG = %s" % sol_expr
+        print("\tARG = %s" % sol_expr)
         todo.add(sol_expr)
         reaches.add(sol_ident)
 
-print "Found %d input, to reach %d element of coverage" % (len(done),
-                                                           len(reaches))
+print(
+    "Found %d input, to reach %d element of coverage" % (
+        len(done),
+        len(reaches)
+    )
+)
 
diff --git a/example/symbol_exec/single_instr.py b/example/symbol_exec/single_instr.py
index 3b27a814..bdc65360 100644
--- a/example/symbol_exec/single_instr.py
+++ b/example/symbol_exec/single_instr.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 # Minimalist Symbol Exec example
 from miasm2.analysis.binary import Container
 from miasm2.analysis.machine import Machine
@@ -32,9 +33,9 @@ symb = SymbolicExecutionEngine(ira)
 cur_addr = symb.run_at(ircfg, START_ADDR)
 
 # Modified elements
-print 'Modified registers:'
+print('Modified registers:')
 symb.dump(mems=False)
-print 'Modified memory (should be empty):'
+print('Modified memory (should be empty):')
 symb.dump(ids=False)
 
 # Check final status
diff --git a/miasm2/analysis/binary.py b/miasm2/analysis/binary.py
index 93bd74b2..ee733d79 100644
--- a/miasm2/analysis/binary.py
+++ b/miasm2/analysis/binary.py
@@ -46,7 +46,7 @@ class Container(object):
                 return container_type(data, *args, **kwargs)
             except ContainerSignatureException:
                 continue
-            except ContainerParsingException, error:
+            except ContainerParsingException as error:
                 log.error(error)
 
         # Fallback mode
@@ -134,7 +134,7 @@ class ContainerPE(Container):
         from elfesteem import pe_init
 
         # Parse signature
-        if not data.startswith('MZ'):
+        if not data.startswith(b'MZ'):
             raise ContainerSignatureException()
 
         # Build executable instance
@@ -143,7 +143,7 @@ class ContainerPE(Container):
                 self._executable = vm_load_pe(vm, data)
             else:
                 self._executable = pe_init.PE(data)
-        except Exception, error:
+        except Exception as error:
             raise ContainerParsingException('Cannot read PE: %s' % error)
 
         # Check instance validity
@@ -159,7 +159,7 @@ class ContainerPE(Container):
             self._bin_stream = bin_stream_pe(self._executable)
             ep_detected = self._executable.Opthdr.AddressOfEntryPoint
             self._entry_point = self._executable.rva2virt(ep_detected)
-        except Exception, error:
+        except Exception as error:
             raise ContainerParsingException('Cannot read PE: %s' % error)
 
 
@@ -168,7 +168,7 @@ class ContainerELF(Container):
 
     def parse(self, data, vm=None, addr=0, apply_reloc=False, **kwargs):
         """Load an ELF from @data
-        @data: str containing the ELF bytes
+        @data: bytes containing the ELF bytes
         @vm (optional): VmMngr instance. If set, load the ELF in virtual memory
         @addr (optional): base address the ELF in virtual memory
         @apply_reloc (optional): if set, apply relocation during ELF loading
@@ -181,18 +181,22 @@ class ContainerELF(Container):
         from elfesteem import elf_init
 
         # Parse signature
-        if not data.startswith('\x7fELF'):
+        if not data.startswith(b'\x7fELF'):
             raise ContainerSignatureException()
 
         # Build executable instance
         try:
             if vm is not None:
-                self._executable = vm_load_elf(vm, data, loc_db=self.loc_db,
-                                               base_addr=addr,
-                                               apply_reloc=apply_reloc)
+                self._executable = vm_load_elf(
+                    vm,
+                    data,
+                    loc_db=self.loc_db,
+                    base_addr=addr,
+                    apply_reloc=apply_reloc
+                )
             else:
                 self._executable = elf_init.ELF(data)
-        except Exception, error:
+        except Exception as error:
             raise ContainerParsingException('Cannot read ELF: %s' % error)
 
         # Guess the architecture
@@ -202,7 +206,7 @@ class ContainerELF(Container):
         try:
             self._bin_stream = bin_stream_elf(self._executable)
             self._entry_point = self._executable.Ehdr.entry + addr
-        except Exception, error:
+        except Exception as error:
             raise ContainerParsingException('Cannot read ELF: %s' % error)
 
         if vm is None:
@@ -217,9 +221,11 @@ class ContainerUnknown(Container):
     def parse(self, data, vm=None, addr=0, **kwargs):
         self._bin_stream = bin_stream_str(data, base_address=addr)
         if vm is not None:
-            vm.add_memory_page(addr,
-                               PAGE_READ,
-                               data)
+            vm.add_memory_page(
+                addr,
+                PAGE_READ,
+                data
+            )
         self._executable = None
         self._entry_point = 0
 
diff --git a/miasm2/analysis/cst_propag.py b/miasm2/analysis/cst_propag.py
index 9a5e3d54..25d66318 100644
--- a/miasm2/analysis/cst_propag.py
+++ b/miasm2/analysis/cst_propag.py
@@ -1,5 +1,7 @@
 import logging
 
+from future.utils import viewitems
+
 from miasm2.ir.symbexec import SymbolicExecutionEngine
 from miasm2.expression.expression import ExprMem
 from miasm2.expression.expression_helper import possible_values
@@ -95,7 +97,7 @@ class SymbExecStateFix(SymbolicExecutionEngine):
         for index, assignblk in enumerate(irb):
             new_assignblk = {}
             links = {}
-            for dst, src in assignblk.iteritems():
+            for dst, src in viewitems(assignblk):
                 src = self.propag_expr_cst(src)
                 if dst.is_mem():
                     ptr = dst.ptr
@@ -175,7 +177,7 @@ def propagate_cst_expr(ir_arch, ircfg, addr, init_infos):
     """
     states = compute_cst_propagation_states(ir_arch, ircfg, addr, init_infos)
     cst_propag_link = {}
-    for lbl, state in states.iteritems():
+    for lbl, state in viewitems(states):
         if lbl not in ircfg.blocks:
             continue
         symbexec = SymbExecStateFix(ir_arch, ircfg, state, cst_propag_link)
diff --git a/miasm2/analysis/data_analysis.py b/miasm2/analysis/data_analysis.py
index 30346e63..bd073fcb 100644
--- a/miasm2/analysis/data_analysis.py
+++ b/miasm2/analysis/data_analysis.py
@@ -1,5 +1,12 @@
+from __future__ import print_function
+
+from future.utils import viewitems
+
+from builtins import object
+from functools import cmp_to_key
 from miasm2.expression.expression \
-    import get_expr_mem, get_list_rw, ExprId, ExprInt
+    import get_expr_mem, get_list_rw, ExprId, ExprInt, \
+    compare_exprs
 from miasm2.ir.symbexec import SymbolicExecutionEngine
 
 
@@ -19,7 +26,7 @@ def intra_block_flow_raw(ir_arch, ircfg, flow_graph, irb, in_nodes, out_nodes):
 
         # gen mem arg to mem node links
         all_mems = set()
-        for node_w, nodes_r in dict_rw.iteritems():
+        for node_w, nodes_r in viewitems(dict_rw):
             for n in nodes_r.union([node_w]):
                 all_mems.update(get_expr_mem(n))
             if not all_mems:
@@ -40,7 +47,7 @@ def intra_block_flow_raw(ir_arch, ircfg, flow_graph, irb, in_nodes, out_nodes):
                     flow_graph.add_uniq_edge(node_n_r, node_n_w)
 
         # gen data flow links
-        for node_w, nodes_r in dict_rw.iteritems():
+        for node_w, nodes_r in viewitems(dict_rw):
             for n_r in nodes_r:
                 if n_r in current_nodes:
                     node_n_r = current_nodes[n_r]
@@ -65,11 +72,11 @@ def inter_block_flow_link(ir_arch, ircfg, flow_graph, irb_in_nodes, irb_out_node
 
     # link current nodes to bloc in_nodes
     if not lbl in ircfg.blocks:
-        print "cannot find bloc!!", lbl
+        print("cannot find bloc!!", lbl)
         return set()
     irb = ircfg.blocks[lbl]
     to_del = set()
-    for n_r, node_n_r in irb_in_nodes[irb.loc_key].items():
+    for n_r, node_n_r in viewitems(irb_in_nodes[irb.loc_key]):
         if not n_r in current_nodes:
             continue
         flow_graph.add_uniq_edge(current_nodes[n_r], node_n_r)
@@ -78,7 +85,7 @@ def inter_block_flow_link(ir_arch, ircfg, flow_graph, irb_in_nodes, irb_out_node
     # if link exec to data, all nodes depends on exec nodes
     if link_exec_to_data:
         for n_x_r in exec_nodes:
-            for n_r, node_n_r in irb_in_nodes[irb.loc_key].items():
+            for n_r, node_n_r in viewitems(irb_in_nodes[irb.loc_key]):
                 if not n_x_r in current_nodes:
                     continue
                 if isinstance(n_r, ExprInt):
@@ -86,15 +93,15 @@ def inter_block_flow_link(ir_arch, ircfg, flow_graph, irb_in_nodes, irb_out_node
                 flow_graph.add_uniq_edge(current_nodes[n_x_r], node_n_r)
 
     # update current nodes using bloc out_nodes
-    for n_w, node_n_w in irb_out_nodes[irb.loc_key].items():
+    for n_w, node_n_w in viewitems(irb_out_nodes[irb.loc_key]):
         current_nodes[n_w] = node_n_w
 
     # get nodes involved in exec flow
-    x_nodes = tuple(sorted(list(irb.dst.get_r())))
+    x_nodes = tuple(sorted(irb.dst.get_r(), key=cmp_to_key(compare_exprs)))
 
     todo = set()
     for lbl_dst in ircfg.successors(irb.loc_key):
-        todo.add((lbl_dst, tuple(current_nodes.items()), x_nodes))
+        todo.add((lbl_dst, tuple(viewitems(current_nodes)), x_nodes))
 
     return todo
 
@@ -109,7 +116,7 @@ def create_implicit_flow(ir_arch, flow_graph, irb_in_nodes, irb_out_ndes):
         irb = ir_arch.blocks[lbl]
         for lbl_son in ir_arch.graph.successors(irb.loc_key):
             if not lbl_son in ir_arch.blocks:
-                print "cannot find bloc!!", lbl
+                print("cannot find bloc!!", lbl)
                 continue
             irb_son = ir_arch.blocks[lbl_son]
             for n_r in irb_in_nodes[irb_son.loc_key]:
@@ -144,7 +151,7 @@ def inter_block_flow(ir_arch, ircfg, flow_graph, irb_0, irb_in_nodes, irb_out_no
         todo.update(out)
 
 
-class symb_exec_func:
+class symb_exec_func(object):
 
     """
     This algorithm will do symbolic execution on a function, trying to propagate
@@ -164,15 +171,13 @@ class symb_exec_func:
         self.ir_arch = ir_arch
 
     def add_state(self, parent, ad, state):
-        variables = dict(state.symbols.items())
+        variables = dict(state.symbols)
 
         # get bloc dead, and remove from state
         b = self.ir_arch.get_block(ad)
         if b is None:
             raise ValueError("unknown bloc! %s" % ad)
-        variables = variables.items()
-
-        s = parent, ad, tuple(sorted(variables))
+        s = parent, ad, tuple(sorted(viewitems(variables)))
         self.todo.add(s)
 
     def get_next_state(self):
@@ -183,10 +188,10 @@ class symb_exec_func:
         if len(self.todo) == 0:
             return None
         if self.total_done > 600:
-            print "symbexec watchdog!"
+            print("symbexec watchdog!")
             return None
         self.total_done += 1
-        print 'CPT', self.total_done
+        print('CPT', self.total_done)
         while self.todo:
             state = self.get_next_state()
             parent, ad, s = state
diff --git a/miasm2/analysis/data_flow.py b/miasm2/analysis/data_flow.py
index 2201a088..3874b21b 100644
--- a/miasm2/analysis/data_flow.py
+++ b/miasm2/analysis/data_flow.py
@@ -1,6 +1,8 @@
 """Data flow analysis based on miasm intermediate representation"""
-
+from builtins import range
 from collections import namedtuple
+from future.utils import viewitems, viewvalues
+from miasm2.core.utils import encode_hex
 from miasm2.core.graph import DiGraph
 from miasm2.ir.ir import AssignBlock, IRBlock
 from miasm2.expression.expression import ExprLoc, ExprMem, ExprId, ExprInt,\
@@ -56,7 +58,7 @@ class ReachingDefinitions(dict):
         modified = True
         while modified:
             modified = False
-            for block in self.ircfg.blocks.itervalues():
+            for block in viewvalues(self.ircfg.blocks):
                 modified |= self.process_block(block)
 
     def process_block(self, block):
@@ -67,7 +69,7 @@ class ReachingDefinitions(dict):
         predecessor_state = {}
         for pred_lbl in self.ircfg.predecessors(block.loc_key):
             pred = self.ircfg.blocks[pred_lbl]
-            for lval, definitions in self.get_definitions(pred_lbl, len(pred)).iteritems():
+            for lval, definitions in viewitems(self.get_definitions(pred_lbl, len(pred))):
                 predecessor_state.setdefault(lval, set()).update(definitions)
 
         modified = self.get((block.loc_key, 0)) != predecessor_state
@@ -75,7 +77,7 @@ class ReachingDefinitions(dict):
             return False
         self[(block.loc_key, 0)] = predecessor_state
 
-        for index in xrange(len(block)):
+        for index in range(len(block)):
             modified |= self.process_assignblock(block, index)
         return modified
 
@@ -151,7 +153,7 @@ class DiGraphDefUse(DiGraph):
 
     def _compute_def_use(self, reaching_defs,
                          deref_mem=False):
-        for block in self._blocks.itervalues():
+        for block in viewvalues(self._blocks):
             self._compute_def_use_block(block,
                                         reaching_defs,
                                         deref_mem=deref_mem)
@@ -159,7 +161,7 @@ class DiGraphDefUse(DiGraph):
     def _compute_def_use_block(self, block, reaching_defs, deref_mem=False):
         for index, assignblk in enumerate(block):
             assignblk_reaching_defs = reaching_defs.get_definitions(block.loc_key, index)
-            for lval, expr in assignblk.iteritems():
+            for lval, expr in viewitems(assignblk):
                 self.add_node(AssignblkNode(block.loc_key, index, lval))
 
                 read_vars = expr.get_r(mem_read=deref_mem)
@@ -212,7 +214,7 @@ def dead_simp_useful_assignblks(irarch, defuse, reaching_defs):
     ircfg = reaching_defs.ircfg
     useful = set()
 
-    for block_lbl, block in ircfg.blocks.iteritems():
+    for block_lbl, block in viewitems(ircfg.blocks):
         successors = ircfg.successors(block_lbl)
         for successor in successors:
             if successor not in ircfg.blocks:
@@ -225,14 +227,14 @@ def dead_simp_useful_assignblks(irarch, defuse, reaching_defs):
         if keep_all_definitions or (len(successors) == 0):
             valid_definitions = reaching_defs.get_definitions(block_lbl,
                                                               len(block))
-            for lval, definitions in valid_definitions.iteritems():
+            for lval, definitions in viewitems(valid_definitions):
                 if lval in irarch.get_out_regs(block) or keep_all_definitions:
                     for definition in definitions:
                         useful.add(AssignblkNode(definition[0], definition[1], lval))
 
         # Force keeping of specific cases
         for index, assignblk in enumerate(block):
-            for lval, rval in assignblk.iteritems():
+            for lval, rval in viewitems(assignblk):
                 if (lval.is_mem() or
                     irarch.IRDst == lval or
                     lval.is_id("exception_flags") or
@@ -262,7 +264,7 @@ def dead_simp(irarch, ircfg):
     reaching_defs = ReachingDefinitions(ircfg)
     defuse = DiGraphDefUse(reaching_defs, deref_mem=True)
     useful = set(dead_simp_useful_assignblks(irarch, defuse, reaching_defs))
-    for block in ircfg.blocks.itervalues():
+    for block in list(viewvalues(ircfg.blocks)):
         irs = []
         for idx, assignblk in enumerate(block):
             new_assignblk = dict(assignblk)
@@ -311,7 +313,7 @@ def _do_merge_blocks(ircfg, loc_key, son_loc_key):
             assignblks.append(assignblk)
             continue
         affs = {}
-        for dst, src in assignblk.iteritems():
+        for dst, src in viewitems(assignblk):
             if dst != ircfg.IRDst:
                 affs[dst] = src
         if affs:
@@ -348,7 +350,7 @@ def _test_jmp_only(ircfg, loc_key, heads):
     irblock = ircfg.blocks[loc_key]
     if len(irblock.assignblks) != 1:
         return None
-    items = dict(irblock.assignblks[0]).items()
+    items = list(viewitems(dict(irblock.assignblks[0])))
     if len(items) != 1:
         return None
     if len(ircfg.successors(loc_key)) != 1:
@@ -528,7 +530,7 @@ def remove_empty_assignblks(ircfg):
     @ircfg: IRCFG instance
     """
     modified = False
-    for loc_key, block in ircfg.blocks.iteritems():
+    for loc_key, block in list(viewitems(ircfg.blocks)):
         irs = []
         block_modified = False
         for assignblk in block:
@@ -591,13 +593,13 @@ class SSADefUse(DiGraph):
             if block is None:
                 continue
             for index, assignblk in enumerate(block):
-                for dst, src in assignblk.iteritems():
+                for dst, src in viewitems(assignblk):
                     node = AssignblkNode(lbl, index, dst)
                     graph.add_var_def(node, src)
                     graph.add_def_node(def_nodes, node, src)
                     graph.add_use_node(use_nodes, node, src)
 
-        for dst, node in def_nodes.iteritems():
+        for dst, node in viewitems(def_nodes):
             graph.add_node(node)
             if dst not in use_nodes:
                 continue
@@ -650,7 +652,7 @@ class PropagateThroughExprId(object):
         @assignblks: list of AssignBlock to check
         """
         for assignblk in assignblks:
-            for dst, src in assignblk.iteritems():
+            for dst, src in viewitems(assignblk):
                 if src.is_function_call():
                     return True
                 if dst.is_mem():
@@ -723,7 +725,7 @@ class PropagateThroughExprId(object):
         def_dct = {}
         for node in ircfg.nodes():
             for index, assignblk in enumerate(ircfg.blocks[node]):
-                for dst, src in assignblk.iteritems():
+                for dst, src in viewitems(assignblk):
                     if not dst.is_id():
                         continue
                     if dst in ssa.immutable_ids:
@@ -786,7 +788,7 @@ class PropagateThroughExprId(object):
         """
         node_to_reg, to_replace, defuse = self.get_candidates(ssa, head, max_expr_depth)
         modified = False
-        for node, reg in node_to_reg.iteritems():
+        for node, reg in viewitems(node_to_reg):
             for successor in defuse.successors(node):
                 if not self.propagation_allowed(ssa, to_replace, node, successor):
                     continue
@@ -800,7 +802,7 @@ class PropagateThroughExprId(object):
                 assignblks = list(block)
                 assignblk = block[node_b.index]
                 out = {}
-                for dst, src in assignblk.iteritems():
+                for dst, src in viewitems(assignblk):
                     if src.is_op('Phi'):
                         out[dst] = src
                         continue
@@ -874,16 +876,16 @@ class PropagateThroughExprMem(object):
         ircfg = ssa.graph
         todo = set()
         modified = False
-        for block in ircfg.blocks.itervalues():
+        for block in viewvalues(ircfg.blocks):
             for i, assignblk in enumerate(block):
-                for dst, src in assignblk.iteritems():
+                for dst, src in viewitems(assignblk):
                     if not dst.is_mem():
                         continue
                     if expr_has_mem(src):
                         continue
                     todo.add((block.loc_key, i + 1, dst, src))
                     ptr = dst.ptr
-                    for size in xrange(8, dst.size, 8):
+                    for size in range(8, dst.size, 8):
                         todo.add((block.loc_key, i + 1, ExprMem(ptr, size), src[:size]))
 
         while todo:
@@ -891,13 +893,13 @@ class PropagateThroughExprMem(object):
             block = ircfg.blocks[loc_key]
             assignblks = list(block)
             block_modified = False
-            for i in xrange(index, len(block)):
+            for i in range(index, len(block)):
                 assignblk = block[i]
                 write_mem = False
                 assignblk_modified = False
                 out = dict(assignblk)
                 out_new = {}
-                for dst, src in out.iteritems():
+                for dst, src in viewitems(out):
                     if dst.is_mem():
                         write_mem = True
                         ptr = dst.ptr.replace_expr({mem_dst:mem_src})
@@ -941,7 +943,7 @@ def stack_to_reg(expr):
             diff = int(ptr.args[1])
             assert diff % 4 == 0
             diff = (0 - diff) & 0xFFFFFFFF
-            return ExprId("STACK.%d" % (diff / 4), expr.size)
+            return ExprId("STACK.%d" % (diff // 4), expr.size)
     return False
 
 
@@ -997,12 +999,12 @@ def retrieve_stack_accesses(ir_arch_a, ircfg):
     @ircfg: IRCFG instance
     """
     stack_vars = set()
-    for block in ircfg.blocks.itervalues():
+    for block in viewvalues(ircfg.blocks):
         for assignblk in block:
-            for dst, src in assignblk.iteritems():
+            for dst, src in viewitems(assignblk):
                 stack_vars.update(get_stack_accesses(ir_arch_a, dst))
                 stack_vars.update(get_stack_accesses(ir_arch_a, src))
-    stack_vars = filter(lambda expr: check_expr_below_stack(ir_arch_a, expr), stack_vars)
+    stack_vars = [expr for expr in stack_vars if check_expr_below_stack(ir_arch_a, expr)]
 
     base_to_var = {}
     for var in stack_vars:
@@ -1010,7 +1012,7 @@ def retrieve_stack_accesses(ir_arch_a, ircfg):
 
 
     base_to_interval = {}
-    for addr, vars in base_to_var.iteritems():
+    for addr, vars in viewitems(base_to_var):
         var_interval = interval()
         for var in vars:
             offset = expr_simp(addr - ir_arch_a.sp)
@@ -1019,7 +1021,7 @@ def retrieve_stack_accesses(ir_arch_a, ircfg):
                 continue
 
             start = int(offset)
-            stop = int(expr_simp(offset + ExprInt(var.size / 8, offset.size)))
+            stop = int(expr_simp(offset + ExprInt(var.size // 8, offset.size)))
             mem = interval([(start, stop-1)])
             var_interval += mem
         base_to_interval[addr] = var_interval
@@ -1033,7 +1035,7 @@ def retrieve_stack_accesses(ir_arch_a, ircfg):
         tmp += mem
 
     base_to_info = {}
-    for addr, vars in base_to_var.iteritems():
+    for addr, vars in viewitems(base_to_var):
         name = "var_%d" % (len(base_to_info))
         size = max([var.size for var in vars])
         base_to_info[addr] = size, name
@@ -1079,11 +1081,11 @@ def replace_stack_vars(ir_arch_a, ircfg):
 
     base_to_info = retrieve_stack_accesses(ir_arch_a, ircfg)
     modified = False
-    for block in ircfg.blocks.itervalues():
+    for block in list(viewvalues(ircfg.blocks)):
         assignblks = []
         for assignblk in block:
             out = {}
-            for dst, src in assignblk.iteritems():
+            for dst, src in viewitems(assignblk):
                 new_dst = dst.visit(lambda expr:replace_mem_stack_vars(expr, base_to_info))
                 new_src = src.visit(lambda expr:replace_mem_stack_vars(expr, base_to_info))
                 if new_dst != dst or new_src != src:
@@ -1120,9 +1122,9 @@ def get_memlookup(expr, bs, is_addr_ro_variable):
 
 def read_mem(bs, expr):
     ptr = int(expr.ptr)
-    var_bytes = bs.getbytes(ptr, expr.size / 8)[::-1]
+    var_bytes = bs.getbytes(ptr, expr.size // 8)[::-1]
     try:
-        value = int(var_bytes.encode('hex'), 16)
+        value = int(encode_hex(var_bytes), 16)
     except ValueError:
         return expr
     return ExprInt(value, expr.size)
@@ -1137,11 +1139,11 @@ def load_from_int(ir_arch, bs, is_addr_ro_variable):
     """
 
     modified = False
-    for block in ir_arch.blocks.itervalues():
+    for block in list(viewvalues(ir_arch.blocks)):
         assignblks = list()
         for assignblk in block:
             out = {}
-            for dst, src in assignblk.iteritems():
+            for dst, src in viewitems(assignblk):
                 # Test src
                 mems = get_memlookup(src, bs, is_addr_ro_variable)
                 src_new = src
@@ -1197,7 +1199,7 @@ class AssignBlockLivenessInfos(object):
         out.append(
             '\n'.join(
                 "\t%s = %s" % (dst, src)
-                for (dst, src) in self.assignblk.iteritems()
+                for (dst, src) in viewitems(self.assignblk)
             )
         )
         out.append("\tVarOut:" + ", ".join(str(x) for x in self.var_out))
@@ -1217,7 +1219,7 @@ class IRBlockLivenessInfos(object):
         self.assignblks = []
         for assignblk in irblock:
             gens, kills = set(), set()
-            for dst, src in assignblk.iteritems():
+            for dst, src in viewitems(assignblk):
                 expr = ExprAssign(dst, src)
                 read = expr.get_r(mem_read=True)
                 write = expr.get_w()
@@ -1290,13 +1292,13 @@ class DiGraphLiveness(DiGraph):
         )
         if node not in self._blocks:
             yield [self.DotCellDescription(text="NOT PRESENT", attr={})]
-            raise StopIteration
+            return
 
         for i, info in enumerate(self._blocks[node].infos):
             var_in = "VarIn:" + ", ".join(str(x) for x in info.var_in)
             var_out = "VarOut:" + ", ".join(str(x) for x in info.var_out)
 
-            assignmnts = ["%s = %s" % (dst, src) for (dst, src) in info.assignblk.iteritems()]
+            assignmnts = ["%s = %s" % (dst, src) for (dst, src) in viewitems(info.assignblk)]
 
             if i == 0:
                 yield self.DotCellDescription(
@@ -1323,7 +1325,7 @@ class DiGraphLiveness(DiGraph):
         """
         infos = block.infos
         modified = False
-        for i in reversed(xrange(len(infos))):
+        for i in reversed(range(len(infos))):
             new_vars = set(infos[i].gen.union(infos[i].var_out.difference(infos[i].kill)))
             if infos[i].var_in != new_vars:
                 modified = True
@@ -1385,13 +1387,13 @@ def discard_phi_sources(ircfg, deleted_vars):
     @ircfg: IRCFG instance in ssa form
     @deleted_vars: unused phi sources
     """
-    for block in ircfg.blocks.values():
+    for block in list(viewvalues(ircfg.blocks)):
         if not block.assignblks:
             continue
         assignblk = block[0]
         todo = {}
         modified = False
-        for dst, src in assignblk.iteritems():
+        for dst, src in viewitems(assignblk):
             if not src.is_op('Phi'):
                 todo[dst] = src
                 continue
@@ -1459,7 +1461,7 @@ def update_phi_with_deleted_edges(ircfg, edges_to_del):
         assignblks = list(block)
         assignblk = assignblks[0]
         out = {}
-        for dst, phi_sources in assignblk.iteritems():
+        for dst, phi_sources in viewitems(assignblk):
             if not phi_sources.is_op('Phi'):
                 out = assignblk
                 break
@@ -1484,7 +1486,7 @@ def update_phi_with_deleted_edges(ircfg, edges_to_del):
         new_irblock = IRBlock(loc_dst, assignblks)
         blocks[block.loc_key] = new_irblock
 
-    for loc_key, block in blocks.iteritems():
+    for loc_key, block in viewitems(blocks):
         ircfg.blocks[loc_key] = block
     return modified
 
@@ -1543,13 +1545,13 @@ class DiGraphLivenessSSA(DiGraphLivenessIRA):
         super(DiGraphLivenessSSA, self).__init__(ircfg)
 
         self.loc_key_to_phi_parents = {}
-        for irblock in self.blocks.values():
+        for irblock in viewvalues(self.blocks):
             if not irblock_has_phi(irblock):
                 continue
             out = {}
-            for sources in irblock[0].itervalues():
+            for sources in viewvalues(irblock[0]):
                 var_to_parents = get_phi_sources_parent_block(self, irblock.loc_key, sources.args)
-                for var, var_parents in var_to_parents.iteritems():
+                for var, var_parents in viewitems(var_to_parents):
                     out.setdefault(var, set()).update(var_parents)
             self.loc_key_to_phi_parents[irblock.loc_key] = out
 
diff --git a/miasm2/analysis/debugging.py b/miasm2/analysis/debugging.py
index 6b88f00a..824b62ce 100644
--- a/miasm2/analysis/debugging.py
+++ b/miasm2/analysis/debugging.py
@@ -1,11 +1,16 @@
+from __future__ import print_function
+from builtins import map
+from builtins import range
 import cmd
+from future.utils import viewitems
+
 from miasm2.core.utils import hexdump
 from miasm2.core.interval import interval
 import miasm2.jitter.csts as csts
 from miasm2.jitter.jitload import ExceptionHandle
 
 
-class DebugBreakpoint:
+class DebugBreakpoint(object):
 
     "Debug Breakpoint parent class"
     pass
@@ -46,17 +51,19 @@ class DebugBreakpointMemory(DebugBreakpoint):
 
     def __str__(self):
         bp_type = ""
-        for k, v in self.type2str.items():
+        for k, v in viewitems(self.type2str):
             if k & self.access_type != 0:
                 bp_type += v
-        return "Memory BP @0x%08x, Size 0x%08x, Type %s" % (self.addr,
-                                                            self.size,
-                                                            bp_type)
+        return "Memory BP @0x%08x, Size 0x%08x, Type %s" % (
+            self.addr,
+            self.size,
+            bp_type
+        )
 
     @classmethod
     def get_access_type(cls, read=False, write=False):
         value = 0
-        for k, v in cls.type2str.items():
+        for k, v in viewitems(cls.type2str):
             if v == "R" and read is True:
                 value += k
             if v == "W" and write is True:
@@ -146,10 +153,10 @@ class Debugguer(object):
             return DebugBreakpointTerminate(res)
 
         if isinstance(res, DebugBreakpointSoft):
-            print "Breakpoint reached @0x%08x" % res.addr
+            print("Breakpoint reached @0x%08x" % res.addr)
         elif isinstance(res, ExceptionHandle):
             if res == ExceptionHandle.memoryBreakpoint():
-                print "Memory breakpoint reached!"
+                print("Memory breakpoint reached!")
 
                 # Remove flag
                 except_flag = self.myjit.vm.get_exception()
@@ -196,7 +203,7 @@ class Debugguer(object):
 
     def on_step(self):
         for addr, size in self.mem_watched:
-            print "@0x%08x:" % addr
+            print("@0x%08x:" % addr)
             self.get_mem(addr, size)
 
     def get_reg_value(self, reg_name):
@@ -238,20 +245,20 @@ class DebugCmd(cmd.Cmd, object):
     def print_breakpoints(self):
         bp_list = self.dbg.bp_list
         if len(bp_list) == 0:
-            print "No breakpoints."
+            print("No breakpoints.")
         else:
             for i, b in enumerate(bp_list):
-                print "%d\t0x%08x" % (i, b.addr)
+                print("%d\t0x%08x" % (i, b.addr))
 
     def print_watchmems(self):
         watch_list = self.dbg.mem_watched
         if len(watch_list) == 0:
-            print "No memory watchpoints."
+            print("No memory watchpoints.")
         else:
-            print "Num\tAddress  \tSize"
+            print("Num\tAddress  \tSize")
             for i, w in enumerate(watch_list):
                 addr, size = w
-                print "%d\t0x%08x\t0x%08x" % (i, addr, size)
+                print("%d\t0x%08x\t0x%08x" % (i, addr, size))
 
     def print_registers(self):
         regs = self.dbg.get_gpreg_all()
@@ -259,17 +266,21 @@ class DebugCmd(cmd.Cmd, object):
         # Display settings
         title1 = "Registers"
         title2 = "Values"
-        max_name_len = max(map(len, regs.keys() + [title1]))
+        max_name_len = max(map(len, list(regs) + [title1]))
 
         # Print value table
         s = "%s%s    |    %s" % (
             title1, " " * (max_name_len - len(title1)), title2)
-        print s
-        print "-" * len(s)
-        for name, value in sorted(regs.items(), key=lambda x: x[0]):
-            print "%s%s    |    %s" % (name,
-                                       " " * (max_name_len - len(name)),
-                                       hex(value).replace("L", ""))
+        print(s)
+        print("-" * len(s))
+        for name, value in sorted(viewitems(regs), key=lambda x: x[0]):
+            print(
+                "%s%s    |    %s" % (
+                    name,
+                    " " * (max_name_len - len(name)),
+                    hex(value).replace("L", "")
+                )
+            )
 
     def add_breakpoints(self, bp_addr):
         for addr in bp_addr:
@@ -281,35 +292,41 @@ class DebugCmd(cmd.Cmd, object):
                     good = False
                     break
             if good is False:
-                print "Breakpoint 0x%08x already set (%d)" % (addr, i)
+                print("Breakpoint 0x%08x already set (%d)" % (addr, i))
             else:
                 l = len(self.dbg.bp_list)
                 self.dbg.add_breakpoint(addr)
-                print "Breakpoint 0x%08x successfully added ! (%d)" % (addr, l)
+                print("Breakpoint 0x%08x successfully added ! (%d)" % (addr, l))
 
-    display_mode = {"mn": None,
-                    "regs": None,
-                    "newbloc": None}
+    display_mode = {
+        "mn": None,
+        "regs": None,
+        "newbloc": None
+    }
 
     def update_display_mode(self):
-        self.display_mode = {"mn": self.dbg.myjit.jit.log_mn,
-                             "regs": self.dbg.myjit.jit.log_regs,
-                             "newbloc": self.dbg.myjit.jit.log_newbloc}
+        self.display_mode = {
+            "mn": self.dbg.myjit.jit.log_mn,
+            "regs": self.dbg.myjit.jit.log_regs,
+            "newbloc": self.dbg.myjit.jit.log_newbloc
+        }
 
     # Command line methods
     def print_warning(self, s):
-        print self.color_r + s + self.color_e
+        print(self.color_r + s + self.color_e)
 
     def onecmd(self, line):
-        cmd_translate = {"h": "help",
-                         "q": "exit",
-                         "e": "exit",
-                         "!": "exec",
-                         "r": "run",
-                         "i": "info",
-                         "b": "breakpoint",
-                         "s": "step",
-                         "d": "dump"}
+        cmd_translate = {
+            "h": "help",
+            "q": "exit",
+            "e": "exit",
+            "!": "exec",
+            "r": "run",
+            "i": "info",
+            "b": "breakpoint",
+            "s": "step",
+            "d": "dump"
+        }
 
         if len(line) >= 2 and \
            line[1] == " " and \
@@ -342,12 +359,12 @@ class DebugCmd(cmd.Cmd, object):
         self.update_display_mode()
 
     def help_display(self):
-        print "Enable/Disable tracing."
-        print "Usage: display <mode1> <mode2> ... on|off"
-        print "Available modes are:"
+        print("Enable/Disable tracing.")
+        print("Usage: display <mode1> <mode2> ... on|off")
+        print("Available modes are:")
         for k in self.display_mode:
-            print "\t%s" % k
-        print "Use 'info display' to get current values"
+            print("\t%s" % k)
+        print("Use 'info display' to get current values")
 
     def do_watchmem(self, arg):
         if arg == "":
@@ -365,21 +382,23 @@ class DebugCmd(cmd.Cmd, object):
         self.dbg.watch_mem(addr, size)
 
     def help_watchmem(self):
-        print "Add a memory watcher."
-        print "Usage: watchmem <addr> [size]"
-        print "Use 'info watchmem' to get current memory watchers"
+        print("Add a memory watcher.")
+        print("Usage: watchmem <addr> [size]")
+        print("Use 'info watchmem' to get current memory watchers")
 
     def do_info(self, arg):
-        av_info = ["registers",
-                   "display",
-                   "breakpoints",
-                   "watchmem"]
+        av_info = [
+            "registers",
+            "display",
+            "breakpoints",
+            "watchmem"
+        ]
 
         if arg == "":
-            print "'info' must be followed by the name of an info command."
-            print "List of info subcommands:"
+            print("'info' must be followed by the name of an info command.")
+            print("List of info subcommands:")
             for k in av_info:
-                print "\t%s" % k
+                print("\t%s" % k)
 
         if arg.startswith("b"):
             # Breakpoint
@@ -388,8 +407,8 @@ class DebugCmd(cmd.Cmd, object):
         if arg.startswith("d"):
             # Display
             self.update_display_mode()
-            for k, v in self.display_mode.items():
-                print "%s\t\t%s" % (k, v)
+            for k, v in viewitems(self.display_mode):
+                print("%s\t\t%s" % (k, v))
 
         if arg.startswith("w"):
             # Watchmem
@@ -400,9 +419,9 @@ class DebugCmd(cmd.Cmd, object):
             self.print_registers()
 
     def help_info(self):
-        print "Generic command for showing things about the program being"
-        print "debugged. Use 'info' without arguments to get the list of"
-        print "available subcommands."
+        print("Generic command for showing things about the program being")
+        print("debugged. Use 'info' without arguments to get the list of")
+        print("available subcommands.")
 
     def do_breakpoint(self, arg):
         if arg == "":
@@ -412,23 +431,23 @@ class DebugCmd(cmd.Cmd, object):
             self.add_breakpoints(addrs)
 
     def help_breakpoint(self):
-        print "Add breakpoints to argument addresses."
-        print "Example:"
-        print "\tbreakpoint 0x11223344"
-        print "\tbreakpoint 1122 0xabcd"
+        print("Add breakpoints to argument addresses.")
+        print("Example:")
+        print("\tbreakpoint 0x11223344")
+        print("\tbreakpoint 1122 0xabcd")
 
     def do_step(self, arg):
         if arg == "":
             nb = 1
         else:
             nb = int(arg)
-        for _ in xrange(nb):
+        for _ in range(nb):
             self.dbg.step()
 
     def help_step(self):
-        print "Step program until it reaches a different source line."
-        print "Argument N means do this N times (or till program stops"
-        print "for another reason)."
+        print("Step program until it reaches a different source line.")
+        print("Argument N means do this N times (or till program stops")
+        print("for another reason).")
 
     def do_dump(self, arg):
         if arg == "":
@@ -444,36 +463,36 @@ class DebugCmd(cmd.Cmd, object):
             self.dbg.get_mem(addr, size)
 
     def help_dump(self):
-        print "Dump <addr> [size]. Dump size bytes at addr."
+        print("Dump <addr> [size]. Dump size bytes at addr.")
 
     def do_run(self, _):
         self.dbg.run()
 
     def help_run(self):
-        print "Launch or continue the current program"
+        print("Launch or continue the current program")
 
     def do_exit(self, _):
         return True
 
     def do_exec(self, line):
         try:
-            print eval(line)
-        except Exception, error:
-            print "*** Error: %s" % error
+            print(eval(line))
+        except Exception as error:
+            print("*** Error: %s" % error)
 
     def help_exec(self):
-        print "Exec a python command."
-        print "You can also use '!' shortcut."
+        print("Exec a python command.")
+        print("You can also use '!' shortcut.")
 
     def help_exit(self):
-        print "Exit the interpreter."
-        print "You can also use the Ctrl-D shortcut."
+        print("Exit the interpreter.")
+        print("You can also use the Ctrl-D shortcut.")
 
     def help_help(self):
-        print "Print help"
+        print("Print help")
 
     def postloop(self):
-        print '\nGoodbye !'
+        print('\nGoodbye !')
         super(DebugCmd, self).postloop()
 
     do_EOF = do_exit
diff --git a/miasm2/analysis/depgraph.py b/miasm2/analysis/depgraph.py
index 4e5f0433..4bfae67f 100644
--- a/miasm2/analysis/depgraph.py
+++ b/miasm2/analysis/depgraph.py
@@ -1,5 +1,9 @@
 """Provide dependency graph"""
 
+from functools import total_ordering
+
+from future.utils import viewitems
+
 from miasm2.expression.expression import ExprInt, ExprLoc, ExprAssign
 from miasm2.core.graph import DiGraph
 from miasm2.core.locationdb import LocationDB
@@ -14,7 +18,7 @@ try:
 except ImportError:
     pass
 
-
+@total_ordering
 class DependencyNode(object):
 
     """Node elements of a DependencyGraph
@@ -50,16 +54,17 @@ class DependencyNode(object):
                 self.element == depnode.element and
                 self.line_nb == depnode.line_nb)
 
-    def __ne__(self, other):
-        return not self.__eq__(other)
+    def __ne__(self, depnode):
+        # required Python 2.7.14
+        return not self == depnode
 
-    def __cmp__(self, node):
+    def __lt__(self, node):
         """Compares @self with @node."""
         if not isinstance(node, self.__class__):
-            return cmp(self.__class__, node.__class__)
+            return NotImplemented
 
-        return cmp((self.loc_key, self.element, self.line_nb),
-                   (node.loc_key, node.element, node.line_nb))
+        return ((self.loc_key, self.element, self.line_nb) <
+                (node.loc_key, node.element, node.line_nb))
 
     def __str__(self):
         """Returns a string representation of DependencyNode"""
@@ -96,7 +101,7 @@ class DependencyState(object):
     def __init__(self, loc_key, pending, line_nb=None):
         self.loc_key = loc_key
         self.history = [loc_key]
-        self.pending = {k: set(v) for k, v in pending.iteritems()}
+        self.pending = {k: set(v) for k, v in viewitems(pending)}
         self.line_nb = line_nb
         self.links = set()
 
@@ -104,9 +109,11 @@ class DependencyState(object):
         self._graph = None
 
     def __repr__(self):
-        return "<State: %r (%r) (%r)>" % (self.loc_key,
-                                          self.pending,
-                                          self.links)
+        return "<State: %r (%r) (%r)>" % (
+            self.loc_key,
+            self.pending,
+            self.links
+        )
 
     def extend(self, loc_key):
         """Return a copy of itself, with itself in history
@@ -129,7 +136,7 @@ class DependencyState(object):
                 graph.add_node(node_a)
             else:
                 graph.add_edge(node_a, node_b)
-        for parent, sons in self.pending.iteritems():
+        for parent, sons in viewitems(self.pending):
             for son in sons:
                 graph.add_edge(parent, son)
         return graph
@@ -148,7 +155,7 @@ class DependencyState(object):
 
     def add_pendings(self, future_pending):
         """Add @future_pending to the state"""
-        for node, depnodes in future_pending.iteritems():
+        for node, depnodes in viewitems(future_pending):
             if node not in self.pending:
                 self.pending[node] = depnodes
             else:
@@ -263,7 +270,7 @@ class DependencyResult(DependencyState):
             line2elements.setdefault(depnode.line_nb,
                                      set()).add(depnode.element)
 
-        for line_nb, elements in sorted(line2elements.iteritems()):
+        for line_nb, elements in sorted(viewitems(line2elements)):
             if max_line is not None and line_nb >= max_line:
                 break
             assignmnts = {}
@@ -385,8 +392,10 @@ class DependencyResultImplicit(DependencyResult):
         self._solver = solver
 
         # Return only inputs values (others could be wrongs)
-        return {element: symb_exec.eval_expr(element)
-                for element in self.inputs}
+        return {
+            element: symb_exec.eval_expr(element)
+            for element in self.inputs
+        }
 
     @property
     def is_satisfiable(self):
@@ -562,7 +571,7 @@ class DependencyGraph(object):
         """Track pending expression in an assignblock"""
         future_pending = {}
         node_resolved = set()
-        for dst, src in assignblk.iteritems():
+        for dst, src in viewitems(assignblk):
             # Only track pending
             if dst not in state.pending:
                 continue
diff --git a/miasm2/analysis/disasm_cb.py b/miasm2/analysis/disasm_cb.py
index d3278cb4..36e120b6 100644
--- a/miasm2/analysis/disasm_cb.py
+++ b/miasm2/analysis/disasm_cb.py
@@ -1,5 +1,9 @@
 #-*- coding:utf-8 -*-
 
+from __future__ import print_function
+
+from future.utils import viewvalues
+
 from miasm2.expression.expression import ExprInt, ExprId, ExprMem, match_expr
 from miasm2.expression.simplifications import expr_simp
 from miasm2.core.asmblock import AsmConstraintNext, AsmConstraintTo
@@ -27,13 +31,12 @@ def arm_guess_subcall(
     sp = LocationDB()
     ir_arch = ira(sp)
     ircfg = ira.new_ircfg()
-    print '###'
-    print cur_bloc
+    print('###')
+    print(cur_bloc)
     ir_arch.add_asmblock_to_ircfg(cur_bloc, ircfg)
 
-    ir_blocks = ircfg.blocks.values()
     to_add = set()
-    for irblock in ir_blocks:
+    for irblock in viewvalues(ircfg.blocks):
         pc_val = None
         lr_val = None
         for exprs in irblock:
@@ -72,8 +75,7 @@ def arm_guess_jump_table(
     ircfg = ira.new_ircfg()
     ir_arch.add_asmblock_to_ircfg(cur_bloc, ircfg)
 
-    ir_blocks = ircfg.blocks.values()
-    for irblock in ir_blocks:
+    for irblock in viewvalues(ircfg.blocks):
         pc_val = None
         for exprs in irblock:
             for e in exprs:
@@ -84,18 +86,18 @@ def arm_guess_jump_table(
         if not isinstance(pc_val, ExprMem):
             continue
         assert(pc_val.size == 32)
-        print pc_val
+        print(pc_val)
         ad = pc_val.arg
         ad = expr_simp(ad)
-        print ad
+        print(ad)
         res = match_expr(ad, jra + jrb, set([jra, jrb]))
         if res is False:
             raise NotImplementedError('not fully functional')
-        print res
+        print(res)
         if not isinstance(res[jrb], ExprInt):
             raise NotImplementedError('not fully functional')
         base_ad = int(res[jrb])
-        print base_ad
+        print(base_ad)
         addrs = set()
         i = -1
         max_table_entry = 10000
@@ -109,7 +111,7 @@ def arm_guess_jump_table(
             if abs(ad - base_ad) > max_diff_addr:
                 break
             addrs.add(ad)
-        print [hex(x) for x in addrs]
+        print([hex(x) for x in addrs])
 
         for ad in addrs:
             offsets_to_dis.add(ad)
diff --git a/miasm2/analysis/dse.py b/miasm2/analysis/dse.py
index 5eb924d7..fee85984 100644
--- a/miasm2/analysis/dse.py
+++ b/miasm2/analysis/dse.py
@@ -47,7 +47,7 @@ Here are a few remainings TODO:
    the solver for reducing the possible values thanks to its accumulated
    constraints.
 """
-
+from builtins import range
 from collections import namedtuple
 
 try:
@@ -55,6 +55,9 @@ try:
 except ImportError:
     z3 = None
 
+from future.utils import viewitems
+
+from miasm2.core.utils import encode_hex, force_bytes
 from miasm2.expression.expression import ExprMem, ExprInt, ExprCompose, \
     ExprAssign, ExprId, ExprLoc, LocKey
 from miasm2.core.bin_stream import bin_stream_vm
@@ -111,7 +114,7 @@ class ESETrackModif(EmulatedSymbExec):
 
         # Split access in atomic accesses
         out = []
-        for addr in xrange(dst_addr, dst_addr + (expr_mem.size / 8)):
+        for addr in range(dst_addr, dst_addr + expr_mem.size // 8):
             if addr in self.dse_memory_range:
                 # Symbolize memory access
                 out.append(self.dse_memory_to_expr(addr))
@@ -249,14 +252,18 @@ class DSEEngine(object):
 
         Known functions will be looked by {name}_symb in the @namespace
         """
+        namespace = dict(
+            (force_bytes(name), func) for name, func in viewitems(namespace)
+        )
 
         # lambda cannot contain statement
         def default_func(dse):
-            fname = "%s_symb" % libimp.fad2cname[dse.jitter.pc]
+            fname = b"%s_symb" % libimp.fad2cname[dse.jitter.pc]
             raise RuntimeError("Symbolic stub '%s' not found" % fname)
 
-        for addr, fname in libimp.fad2cname.iteritems():
-            fname = "%s_symb" % fname
+        for addr, fname in viewitems(libimp.fad2cname):
+            fname = force_bytes(fname)
+            fname = b"%s_symb" % fname
             func = namespace.get(fname, None)
             if func is not None:
                 self.add_handler(addr, func)
@@ -292,9 +299,11 @@ class DSEEngine(object):
                     if value != symb_value:
                         errors.append(DriftInfo(symbol, symb_value, value))
             elif symbol.is_mem() and symbol.ptr.is_int():
-                value_chr = self.jitter.vm.get_mem(int(symbol.ptr),
-                                                   symbol.size / 8)
-                exp_value = int(value_chr[::-1].encode("hex"), 16)
+                value_chr = self.jitter.vm.get_mem(
+                    int(symbol.ptr),
+                    symbol.size // 8
+                )
+                exp_value = int(encode_hex(value_chr[::-1]), 16)
                 if exp_value != symb_value:
                     errors.append(DriftInfo(symbol, symb_value, exp_value))
 
@@ -410,14 +419,16 @@ class DSEEngine(object):
         if memory:
             self.jitter.vm.reset_memory_page_pool()
             self.jitter.vm.reset_code_bloc_pool()
-            for addr, metadata in snapshot["mem"].iteritems():
-                self.jitter.vm.add_memory_page(addr,
-                                               metadata["access"],
-                                               metadata["data"])
+            for addr, metadata in viewitems(snapshot["mem"]):
+                self.jitter.vm.add_memory_page(
+                    addr,
+                    metadata["access"],
+                    metadata["data"]
+                )
 
         # Restore registers
         self.jitter.pc = snapshot["regs"][self.ir_arch.pc.name]
-        for reg, value in snapshot["regs"].iteritems():
+        for reg, value in viewitems(snapshot["regs"]):
             setattr(self.jitter.cpu, reg, value)
 
         # Reset intern elements
@@ -426,16 +437,16 @@ class DSEEngine(object):
         self.jitter.bs._atomic_mode = False
 
         # Reset symb exec
-        for key, _ in self.symb.symbols.items():
+        for key, _ in list(viewitems(self.symb.symbols)):
             del self.symb.symbols[key]
-        for expr, value in snapshot["symb"].items():
+        for expr, value in viewitems(snapshot["symb"]):
             self.symb.symbols[expr] = value
 
     def update_state(self, assignblk):
         """From this point, assume @assignblk in the symbolic execution
         @assignblk: AssignBlock/{dst -> src}
         """
-        for dst, src in assignblk.iteritems():
+        for dst, src in viewitems(assignblk):
             self.symb.apply_change(dst, src)
 
     def _update_state_from_concrete_symb(self, symbexec, cpu=True, mem=False):
@@ -534,8 +545,10 @@ class DSEPathConstraint(DSEEngine):
 
     def take_snapshot(self, *args, **kwargs):
         snap = super(DSEPathConstraint, self).take_snapshot(*args, **kwargs)
-        snap["new_solutions"] = {dst: src.copy
-                                 for dst, src in self.new_solutions.iteritems()}
+        snap["new_solutions"] = {
+            dst: src.copy
+            for dst, src in viewitems(self.new_solutions)
+        }
         snap["cur_constraints"] = self.cur_solver.assertions()
         if self._produce_solution_strategy == self.PRODUCE_SOLUTION_PATH_COV:
             snap["_history"] = list(self._history)
@@ -650,9 +663,11 @@ class DSEPathConstraint(DSEEngine):
                             # if addr (- [a, b], then @size[addr] reachables
                             # values are in @8[a, b + size[
                             for start, stop in addr_range:
-                                stop += (expr.size / 8) - 1
-                                full_range = ModularIntervals(symb_pc.size,
-                                                              [(start, stop)])
+                                stop += expr.size // 8 - 1
+                                full_range = ModularIntervals(
+                                    symb_pc.size,
+                                    [(start, stop)]
+                                )
                                 memory_to_add.update(full_range)
                     path_constraint.add(eaff)
 
@@ -662,7 +677,7 @@ class DSEPathConstraint(DSEEngine):
 
                 # Inject memory
                 for start, stop in memory_to_add:
-                    for address in xrange(start, stop + 1):
+                    for address in range(start, stop + 1):
                         expr_mem = ExprMem(ExprInt(address,
                                                    self.ir_arch.pc.size),
                                            8)
diff --git a/miasm2/analysis/expression_range.py b/miasm2/analysis/expression_range.py
index f09a18d0..8f498549 100644
--- a/miasm2/analysis/expression_range.py
+++ b/miasm2/analysis/expression_range.py
@@ -1,5 +1,8 @@
 """Naive range analysis for expression"""
 
+from future.builtins import zip
+from functools import reduce
+
 from miasm2.analysis.modularintervals import ModularIntervals
 
 _op_range_handler = {
@@ -44,9 +47,11 @@ def expr_range(expr):
         # Otherwise, overapproximate (ie. full range interval)
         if expr.op in _op_range_handler:
             sub_ranges = [expr_range(arg) for arg in expr.args]
-            return reduce(_op_range_handler[expr.op],
-                          (sub_range for sub_range in sub_ranges[1:]),
-                          sub_ranges[0])
+            return reduce(
+                _op_range_handler[expr.op],
+                (sub_range for sub_range in sub_ranges[1:]),
+                sub_ranges[0]
+            )
         elif expr.op == "-":
             assert len(expr.args) == 1
             return - expr_range(expr.args[0])
diff --git a/miasm2/analysis/gdbserver.py b/miasm2/analysis/gdbserver.py
index 6c630f88..61ee8955 100644
--- a/miasm2/analysis/gdbserver.py
+++ b/miasm2/analysis/gdbserver.py
@@ -1,10 +1,15 @@
 #-*- coding:utf-8 -*-
 
+from __future__ import print_function
+from future.builtins import map, range
+
+from miasm2.core.utils import decode_hex, encode_hex, int_to_byte
+
 import socket
 import struct
 import time
 import logging
-from StringIO import StringIO
+from io import BytesIO
 import miasm2.analysis.debugging as debugging
 from miasm2.jitter.jitload import ExceptionHandle
 
@@ -15,7 +20,7 @@ class GdbServer(object):
 
     general_registers_order = []
     general_registers_size = {}  # RegName : Size in octet
-    status = "S05"
+    status = b"S05"
 
     def __init__(self, dbg, port=4455):
         server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@@ -28,242 +33,243 @@ class GdbServer(object):
     # Communication methods
 
     def compute_checksum(self, data):
-        return chr(sum(map(ord, data)) % 256).encode("hex")
+        return encode_hex(int_to_byte(sum(map(ord, data)) % 256))
 
     def get_messages(self):
-        all_data = ""
-        data = self.sock.recv(4096)
-        all_data += data
-        while (len(data) == 4096 or data == ""):
-            if data == "":
-                # Avoid consuming CPU
-                time.sleep(0.001)
-                continue
+        all_data = b""
+        while True:
             data = self.sock.recv(4096)
+            if not data:
+                break
             all_data += data
 
         logging.debug("<- %r", all_data)
         self.recv_queue += self.parse_messages(all_data)
 
     def parse_messages(self, data):
-        buf = StringIO(data)
-
+        buf = BytesIO(data)
         msgs = []
 
         while (buf.tell() < buf.len):
             token = buf.read(1)
-            if token == "+":
+            if token == b"+":
                 continue
-            if token == "-":
+            if token == b"-":
                 raise NotImplementedError("Resend packet")
-            if token == "$":
-                packet_data = ""
+            if token == b"$":
+                packet_data = b""
                 c = buf.read(1)
-                while c != "#":
+                while c != b"#":
                     packet_data += c
                     c = buf.read(1)
                 checksum = buf.read(2)
                 if checksum != self.compute_checksum(packet_data):
                     raise ValueError("Incorrect checksum")
-
                 msgs.append(packet_data)
 
         return msgs
 
     def send_string(self, s):
-        self.send_queue.append("O" + s.encode("hex"))
+        self.send_queue.append(b"O" + encode_hex(s))
 
     def process_messages(self):
 
         while self.recv_queue:
             msg = self.recv_queue.pop(0)
-            buf = StringIO(msg)
+            buf = BytesIO(msg)
             msg_type = buf.read(1)
 
-            self.send_queue.append("+")
+            self.send_queue.append(b"+")
 
-            if msg_type == "q":
-                if msg.startswith("qSupported"):
-                    self.send_queue.append("PacketSize=3fff")
-                elif msg.startswith("qC"):
+            if msg_type == b"q":
+                if msg.startswith(b"qSupported"):
+                    self.send_queue.append(b"PacketSize=3fff")
+                elif msg.startswith(b"qC"):
                     # Current thread
-                    self.send_queue.append("")
-                elif msg.startswith("qAttached"):
+                    self.send_queue.append(b"")
+                elif msg.startswith(b"qAttached"):
                     # Not supported
-                    self.send_queue.append("")
-                elif msg.startswith("qTStatus"):
+                    self.send_queue.append(b"")
+                elif msg.startswith(b"qTStatus"):
                     # Not supported
-                    self.send_queue.append("")
-                elif msg.startswith("qfThreadInfo"):
+                    self.send_queue.append(b"")
+                elif msg.startswith(b"qfThreadInfo"):
                     # Not supported
-                    self.send_queue.append("")
+                    self.send_queue.append(b"")
                 else:
                     raise NotImplementedError()
 
-            elif msg_type == "H":
+            elif msg_type == b"H":
                 # Set current thread
-                self.send_queue.append("OK")
+                self.send_queue.append(b"OK")
 
-            elif msg_type == "?":
+            elif msg_type == b"?":
                 # Report why the target halted
                 self.send_queue.append(self.status)  # TRAP signal
 
-            elif msg_type == "g":
+            elif msg_type == b"g":
                 # Report all general register values
                 self.send_queue.append(self.report_general_register_values())
 
-            elif msg_type == "p":
+            elif msg_type == b"p":
                 # Read a specific register
                 reg_num = int(buf.read(), 16)
                 self.send_queue.append(self.read_register(reg_num))
 
-            elif msg_type == "P":
+            elif msg_type == b"P":
                 # Set a specific register
-                reg_num, value = buf.read().split("=")
+                reg_num, value = buf.read().split(b"=")
                 reg_num = int(reg_num, 16)
-                value = int(value.decode("hex")[::-1].encode("hex"), 16)
+                value = int(encode_hex(decode_hex(value)[::-1]), 16)
                 self.set_register(reg_num, value)
-                self.send_queue.append("OK")
+                self.send_queue.append(b"OK")
 
-            elif msg_type == "m":
+            elif msg_type == b"m":
                 # Read memory
-                addr, size = map(lambda x: int(x, 16), buf.read().split(","))
+                addr, size = (int(x, 16) for x in buf.read().split(b",", 1))
                 self.send_queue.append(self.read_memory(addr, size))
 
-            elif msg_type == "k":
+            elif msg_type == b"k":
                 # Kill
                 self.sock.close()
                 self.send_queue = []
                 self.sock = None
 
-            elif msg_type == "!":
+            elif msg_type == b"!":
                 # Extending debugging will be used
-                self.send_queue.append("OK")
+                self.send_queue.append(b"OK")
 
-            elif msg_type == "v":
-                if msg == "vCont?":
+            elif msg_type == b"v":
+                if msg == b"vCont?":
                     # Is vCont supported ?
-                    self.send_queue.append("")
+                    self.send_queue.append(b"")
 
-            elif msg_type == "s":
+            elif msg_type == b"s":
                 # Step
                 self.dbg.step()
-                self.send_queue.append("S05")  # TRAP signal
+                self.send_queue.append(b"S05")  # TRAP signal
 
-            elif msg_type == "Z":
+            elif msg_type == b"Z":
                 # Add breakpoint or watchpoint
                 bp_type = buf.read(1)
-                if bp_type == "0":
+                if bp_type == b"0":
                     # Exec breakpoint
-                    assert(buf.read(1) == ",")
-                    addr, size = map(
-                        lambda x: int(x, 16), buf.read().split(","))
+                    assert(buf.read(1) == b",")
+                    addr, size = (int(x, 16) for x in buf.read().split(b",", 1))
 
                     if size != 1:
                         raise NotImplementedError("Bigger size")
                     self.dbg.add_breakpoint(addr)
-                    self.send_queue.append("OK")
+                    self.send_queue.append(b"OK")
 
-                elif bp_type == "1":
+                elif bp_type == b"1":
                     # Hardware BP
-                    assert(buf.read(1) == ",")
-                    addr, size = map(
-                        lambda x: int(x, 16), buf.read().split(","))
-
-                    self.dbg.add_memory_breakpoint(addr, size,
-                                                   read=True,
-                                                   write=True)
-                    self.send_queue.append("OK")
-
-                elif bp_type in ["2", "3", "4"]:
+                    assert(buf.read(1) == b",")
+                    addr, size = (int(x, 16) for x in buf.read().split(b",", 1))
+
+                    self.dbg.add_memory_breakpoint(
+                        addr,
+                        size,
+                        read=True,
+                        write=True
+                    )
+                    self.send_queue.append(b"OK")
+
+                elif bp_type in [b"2", b"3", b"4"]:
                     # Memory breakpoint
-                    assert(buf.read(1) == ",")
-                    read = bp_type in ["3", "4"]
-                    write = bp_type in ["2", "4"]
-                    addr, size = map(
-                        lambda x: int(x, 16), buf.read().split(","))
-
-                    self.dbg.add_memory_breakpoint(addr, size,
-                                                   read=read,
-                                                   write=write)
-                    self.send_queue.append("OK")
+                    assert(buf.read(1) == b",")
+                    read = bp_type in [b"3", b"4"]
+                    write = bp_type in [b"2", b"4"]
+                    addr, size = (int(x, 16) for x in buf.read().split(b",", 1))
+
+                    self.dbg.add_memory_breakpoint(
+                        addr,
+                        size,
+                        read=read,
+                        write=write
+                    )
+                    self.send_queue.append(b"OK")
 
                 else:
                     raise ValueError("Impossible value")
 
-            elif msg_type == "z":
+            elif msg_type == b"z":
                 # Remove breakpoint or watchpoint
                 bp_type = buf.read(1)
-                if bp_type == "0":
+                if bp_type == b"0":
                     # Exec breakpoint
-                    assert(buf.read(1) == ",")
-                    addr, size = map(
-                        lambda x: int(x, 16), buf.read().split(","))
+                    assert(buf.read(1) == b",")
+                    addr, size = (int(x, 16) for x in buf.read().split(b",", 1))
 
                     if size != 1:
                         raise NotImplementedError("Bigger size")
                     dbgsoft = self.dbg.get_breakpoint_by_addr(addr)
                     assert(len(dbgsoft) == 1)
                     self.dbg.remove_breakpoint(dbgsoft[0])
-                    self.send_queue.append("OK")
+                    self.send_queue.append(b"OK")
 
-                elif bp_type == "1":
+                elif bp_type == b"1":
                     # Hardware BP
-                    assert(buf.read(1) == ",")
-                    addr, size = map(
-                        lambda x: int(x, 16), buf.read().split(","))
+                    assert(buf.read(1) == b",")
+                    addr, size = (int(x, 16) for x in buf.read().split(b",", 1))
                     self.dbg.remove_memory_breakpoint_by_addr_access(
-                        addr, read=True, write=True)
-                    self.send_queue.append("OK")
+                        addr,
+                        read=True,
+                        write=True
+                    )
+                    self.send_queue.append(b"OK")
 
-                elif bp_type in ["2", "3", "4"]:
+                elif bp_type in [b"2", b"3", b"4"]:
                     # Memory breakpoint
-                    assert(buf.read(1) == ",")
-                    read = bp_type in ["3", "4"]
-                    write = bp_type in ["2", "4"]
-                    addr, size = map(
-                        lambda x: int(x, 16), buf.read().split(","))
+                    assert(buf.read(1) == b",")
+                    read = bp_type in [b"3", b"4"]
+                    write = bp_type in [b"2", b"4"]
+                    addr, size = (int(x, 16) for x in buf.read().split(b",", 1))
 
                     self.dbg.remove_memory_breakpoint_by_addr_access(
-                        addr, read=read, write=write)
-                    self.send_queue.append("OK")
+                        addr,
+                        read=read,
+                        write=write
+                    )
+                    self.send_queue.append(b"OK")
 
                 else:
                     raise ValueError("Impossible value")
 
-            elif msg_type == "c":
+            elif msg_type == b"c":
                 # Continue
-                self.status = ""
+                self.status = b""
                 self.send_messages()
                 ret = self.dbg.run()
                 if isinstance(ret, debugging.DebugBreakpointSoft):
-                    self.status = "S05"
-                    self.send_queue.append("S05")  # TRAP signal
+                    self.status = b"S05"
+                    self.send_queue.append(b"S05")  # TRAP signal
                 elif isinstance(ret, ExceptionHandle):
                     if ret == ExceptionHandle.memoryBreakpoint():
-                        self.status = "S05"
-                        self.send_queue.append("S05")
+                        self.status = b"S05"
+                        self.send_queue.append(b"S05")
                     else:
                         raise NotImplementedError("Unknown Except")
                 elif isinstance(ret, debugging.DebugBreakpointTerminate):
                     # Connexion should close, but keep it running as a TRAP
                     # The connexion will be close on instance destruction
-                    print ret
-                    self.status = "S05"
-                    self.send_queue.append("S05")
+                    print(ret)
+                    self.status = b"S05"
+                    self.send_queue.append(b"S05")
                 else:
                     raise NotImplementedError()
 
             else:
                 raise NotImplementedError(
-                    "Not implemented: message type '%s'" % msg_type)
+                    "Not implemented: message type %r" % msg_type
+                )
 
     def send_messages(self):
         for msg in self.send_queue:
-            if msg == "+":
-                data = "+"
+            if msg == b"+":
+                data = b"+"
             else:
-                data = "$%s#%s" % (msg, self.compute_checksum(msg))
+                data = b"$%s#%s" % (msg, self.compute_checksum(msg))
             logging.debug("-> %r", data)
             self.sock.send(data)
         self.send_queue = []
@@ -272,7 +278,7 @@ class GdbServer(object):
         self.recv_queue = []
         self.send_queue = []
 
-        self.send_string("Test\n")
+        self.send_string(b"Test\n")
 
         while (self.sock):
             self.get_messages()
@@ -285,8 +291,8 @@ class GdbServer(object):
 
     # Debugguer processing methods
     def report_general_register_values(self):
-        s = ""
-        for i in xrange(len(self.general_registers_order)):
+        s = b""
+        for i in range(len(self.general_registers_order)):
             s += self.read_register(i)
         return s
 
@@ -307,7 +313,7 @@ class GdbServer(object):
         else:
             raise NotImplementedError("Unknown size")
 
-        return struct.pack(pack_token, reg_value).encode("hex")
+        return encode_hex(struct.pack(pack_token, reg_value))
 
     def set_register(self, reg_num, value):
         reg_name = self.general_registers_order[reg_num]
@@ -319,39 +325,44 @@ class GdbServer(object):
     def read_memory(self, addr, size):
         except_flag_vm = self.dbg.myjit.vm.get_exception()
         try:
-            return self.dbg.get_mem_raw(addr, size).encode("hex")
+            return encode_hex(self.dbg.get_mem_raw(addr, size))
         except RuntimeError:
             self.dbg.myjit.vm.set_exception(except_flag_vm)
-            return "00" * size
+            return b"00" * size
 
 
 class GdbServer_x86_32(GdbServer):
 
     "Extend GdbServer for x86 32bits purposes"
 
-    general_registers_order = ["EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI",
-                               "EDI", "EIP", "EFLAGS", "CS", "SS", "DS", "ES",
-                               "FS", "GS"]
-
-    general_registers_size = {"EAX": 4,
-                              "ECX": 4,
-                              "EDX": 4,
-                              "EBX": 4,
-                              "ESP": 4,
-                              "EBP": 4,
-                              "ESI": 4,
-                              "EDI": 4,
-                              "EIP": 4,
-                              "EFLAGS": 2,
-                              "CS": 2,
-                              "SS": 2,
-                              "DS": 2,
-                              "ES": 2,
-                              "FS": 2,
-                              "GS": 2}
+    general_registers_order = [
+        "EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI",
+        "EDI", "EIP", "EFLAGS", "CS", "SS", "DS", "ES",
+        "FS", "GS"
+    ]
+
+    general_registers_size = {
+        "EAX": 4,
+        "ECX": 4,
+        "EDX": 4,
+        "EBX": 4,
+        "ESP": 4,
+        "EBP": 4,
+        "ESI": 4,
+        "EDI": 4,
+        "EIP": 4,
+        "EFLAGS": 2,
+        "CS": 2,
+        "SS": 2,
+        "DS": 2,
+        "ES": 2,
+        "FS": 2,
+        "GS": 2
+    }
 
     register_ignore = [
-        "tf", "i_f", "nt", "rf", "vm", "ac", "vif", "vip", "i_d"]
+        "tf", "i_f", "nt", "rf", "vm", "ac", "vif", "vip", "i_d"
+    ]
 
     def read_register_by_name(self, reg_name):
         sup_func = super(GdbServer_x86_32, self).read_register_by_name
@@ -364,7 +375,8 @@ class GdbServer_x86_32(GdbServer):
         if reg_name == "EFLAGS":
             val = 0
             eflags_args = [
-                "cf", 1, "pf", 0, "af", 0, "zf", "nf", "tf", "i_f", "df", "of"]
+                "cf", 1, "pf", 0, "af", 0, "zf", "nf", "tf", "i_f", "df", "of"
+            ]
             eflags_args += ["nt", 0, "rf", "vm", "ac", "vif", "vip", "i_d"]
             eflags_args += [0] * 10
 
@@ -387,26 +399,30 @@ class GdbServer_msp430(GdbServer):
 
     "Extend GdbServer for msp430 purposes"
 
-    general_registers_order = ["PC", "SP", "SR", "R3", "R4", "R5", "R6", "R7",
-                               "R8", "R9", "R10", "R11", "R12", "R13", "R14",
-                               "R15"]
-
-    general_registers_size = {"PC": 2,
-                              "SP": 2,
-                              "SR": 2,
-                              "R3": 2,
-                              "R4": 2,
-                              "R5": 2,
-                              "R6": 2,
-                              "R7": 2,
-                              "R8": 2,
-                              "R9": 2,
-                              "R10": 2,
-                              "R11": 2,
-                              "R12": 2,
-                              "R13": 2,
-                              "R14": 2,
-                              "R15": 2}
+    general_registers_order = [
+        "PC", "SP", "SR", "R3", "R4", "R5", "R6", "R7",
+        "R8", "R9", "R10", "R11", "R12", "R13", "R14",
+        "R15"
+    ]
+
+    general_registers_size = {
+        "PC": 2,
+        "SP": 2,
+        "SR": 2,
+        "R3": 2,
+        "R4": 2,
+        "R5": 2,
+        "R6": 2,
+        "R7": 2,
+        "R8": 2,
+        "R9": 2,
+        "R10": 2,
+        "R11": 2,
+        "R12": 2,
+        "R13": 2,
+        "R14": 2,
+        "R15": 2
+    }
 
     def read_register_by_name(self, reg_name):
         sup_func = super(GdbServer_msp430, self).read_register_by_name
diff --git a/miasm2/analysis/modularintervals.py b/miasm2/analysis/modularintervals.py
index 83890f19..2195598b 100644
--- a/miasm2/analysis/modularintervals.py
+++ b/miasm2/analysis/modularintervals.py
@@ -1,4 +1,7 @@
 """Intervals with a maximum size, supporting modular arithmetic"""
+
+from future.builtins import range
+from builtins import int as int_types
 from itertools import product
 
 from miasm2.core.interval import interval
@@ -59,7 +62,7 @@ class ModularIntervals(object):
         """Check and promote the second argument from integer to
         ModularIntervals with one value"""
         def ret_func(self, target):
-            if isinstance(target, (int, long)):
+            if isinstance(target, int_types):
                 target = ModularIntervals(self.size, interval([(target, target)]))
             if not isinstance(target, ModularIntervals):
                 raise TypeError("Unsupported operation with %s" % target.__class__)
@@ -336,7 +339,7 @@ class ModularIntervals(object):
         shifter &= interval([(0, self.size)])
         ret = interval()
         for shift_range in shifter:
-            for shift in xrange(shift_range[0], shift_range[1] + 1):
+            for shift in range(shift_range[0], shift_range[1] + 1):
                 for x_min, x_max in self.intervals:
                     ret += self._range_shift_uniq(x_min, x_max, shift, operation)
         return self.__class__(self.size, ret)
@@ -372,7 +375,7 @@ class ModularIntervals(object):
         shifter %= self.size
         ret = interval()
         for shift_range in shifter:
-            for shift in xrange(shift_range[0], shift_range[1] + 1):
+            for shift in range(shift_range[0], shift_range[1] + 1):
                 for x_min, x_max in self.intervals:
                     ret += self._range_rotate_uniq(x_min, x_max, shift,
                                                    operation)
@@ -446,7 +449,7 @@ class ModularIntervals(object):
         @modulo: integer
         """
 
-        if not isinstance(modulo, (int, long)):
+        if not isinstance(modulo, int_types):
             raise TypeError("Modulo with %s is not supported" % modulo.__class__)
         return self._integer_modulo(modulo)
 
diff --git a/miasm2/analysis/outofssa.py b/miasm2/analysis/outofssa.py
index 6355aeb2..41c665af 100644
--- a/miasm2/analysis/outofssa.py
+++ b/miasm2/analysis/outofssa.py
@@ -1,3 +1,5 @@
+from future.utils import viewitems, viewvalues
+
 from miasm2.expression.expression import ExprId
 from miasm2.ir.ir import IRBlock, AssignBlock
 from miasm2.analysis.ssa import get_phi_sources_parent_block, \
@@ -59,7 +61,7 @@ class UnSSADiGraph(object):
         """
         ircfg = self.ssa.graph
 
-        for irblock in ircfg.blocks.values():
+        for irblock in list(viewvalues(ircfg.blocks)):
             if not irblock_has_phi(irblock):
                 continue
 
@@ -82,7 +84,7 @@ class UnSSADiGraph(object):
                 for parent, src in self.phi_parent_sources[dst]:
                     parent_to_parallel_copies.setdefault(parent, {})[new_var] = src
 
-            for parent, parallel_copies in parent_to_parallel_copies.iteritems():
+            for parent, parallel_copies in viewitems(parent_to_parallel_copies):
                 parent = ircfg.blocks[parent]
                 assignblks = list(parent)
                 assignblks.append(AssignBlock(parallel_copies, parent[-1].instr))
@@ -104,10 +106,10 @@ class UnSSADiGraph(object):
         node
         """
         ircfg = self.ssa.graph
-        for irblock in ircfg.blocks.itervalues():
+        for irblock in viewvalues(ircfg.blocks):
             if not irblock_has_phi(irblock):
                 continue
-            for dst, sources in irblock[0].iteritems():
+            for dst, sources in viewitems(irblock[0]):
                 assert sources.is_op('Phi')
                 new_var = self.create_copy_var(dst)
                 self.phi_new_var[dst] = new_var
@@ -130,7 +132,7 @@ class UnSSADiGraph(object):
         """
         Generate trivial coalescing of phi variable and itself
         """
-        for phi_new_var in self.phi_new_var.itervalues():
+        for phi_new_var in viewvalues(self.phi_new_var):
             self.merge_state.setdefault(phi_new_var, set([phi_new_var]))
 
     def order_ssa_var_dom(self):
@@ -303,7 +305,7 @@ class UnSSADiGraph(object):
         assignments.
         @parent: Optional parent location of the phi source for liveness tests
         """
-        for dst, src in parallel_copies.iteritems():
+        for dst, src in viewitems(parallel_copies):
             dst_merge = self.merge_state.setdefault(dst, set([dst]))
             src_merge = self.merge_state.setdefault(src, set([src]))
             if not self.merge_sets_interfere(dst_merge, src_merge, parent):
@@ -317,7 +319,7 @@ class UnSSADiGraph(object):
         ircfg = self.ssa.graph
 
         # Run coalesce on the post phi parallel copy
-        for irblock in ircfg.blocks.values():
+        for irblock in viewvalues(ircfg.blocks):
             if not irblock_has_phi(irblock):
                 continue
             parallel_copies = {}
@@ -335,7 +337,7 @@ class UnSSADiGraph(object):
                 for parent, src in self.phi_parent_sources[dst]:
                     parent_to_parallel_copies.setdefault(parent, {})[new_var] = src
 
-            for parent, parallel_copies in parent_to_parallel_copies.iteritems():
+            for parent, parallel_copies in viewitems(parent_to_parallel_copies):
                 self.aggressive_coalesce_parallel_copy(parallel_copies, parent)
 
     def get_best_merge_set_name(self, merge_set):
@@ -363,7 +365,7 @@ class UnSSADiGraph(object):
 
         # Elect representative for merge sets
         merge_set_to_name = {}
-        for merge_set in self.merge_state.itervalues():
+        for merge_set in viewvalues(self.merge_state):
             frozen_merge_set = frozenset(merge_set)
             merge_sets.add(frozen_merge_set)
             var_name = self.get_best_merge_set_name(merge_set)
@@ -384,10 +386,10 @@ class UnSSADiGraph(object):
         @ircfg: IRDiGraph instance
         """
 
-        for irblock in self.ssa.graph.blocks.values():
+        for irblock in list(viewvalues(self.ssa.graph.blocks)):
             assignblks = list(irblock)
             out = {}
-            for dst, src in assignblks[0].iteritems():
+            for dst, src in viewitems(assignblks[0]):
                 if src.is_op('Phi'):
                     assert set([dst]) == set(src.args)
                     continue
@@ -399,11 +401,11 @@ class UnSSADiGraph(object):
         """
         Remove trivial expressions (a=a) in the current graph
         """
-        for irblock in self.ssa.graph.blocks.values():
+        for irblock in list(viewvalues(self.ssa.graph.blocks)):
             assignblks = list(irblock)
             for i, assignblk in enumerate(assignblks):
                 out = {}
-                for dst, src in assignblk.iteritems():
+                for dst, src in viewitems(assignblk):
                     if dst == src:
                         continue
                     out[dst] = src
diff --git a/miasm2/analysis/sandbox.py b/miasm2/analysis/sandbox.py
index ccffd529..d3e8fce1 100644
--- a/miasm2/analysis/sandbox.py
+++ b/miasm2/analysis/sandbox.py
@@ -1,13 +1,20 @@
+from __future__ import print_function
+from builtins import range
+
 import os
 import logging
 from argparse import ArgumentParser
 
+from future.utils import viewitems, viewvalues
+
+from miasm2.core.utils import force_bytes
 from miasm2.analysis.machine import Machine
 from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE
 from miasm2.analysis import debugging
 from miasm2.jitter.jitload import log_func
 
 
+
 class Sandbox(object):
 
     """
@@ -112,7 +119,7 @@ class Sandbox(object):
 
             if self.options.gdbserver:
                 port = self.options.gdbserver
-                print "Listen on port %d" % port
+                print("Listen on port %d" % port)
                 gdb = self.machine.gdbserver(dbg, port)
                 self.gdb = gdb
                 gdb.run()
@@ -184,7 +191,7 @@ class OS_Win(OS):
         from miasm2.jitter.loader.pe import vm_load_pe, vm_load_pe_libs,\
             preload_pe, libimp_pe, vm_load_pe_and_dependencies
         from miasm2.os_dep import win_api_x86_32, win_api_x86_32_seh
-        methods = win_api_x86_32.__dict__
+        methods = dict((name.encode(),func) for name, func in viewitems(win_api_x86_32.__dict__))
         methods.update(custom_methods)
 
         super(OS_Win, self).__init__(methods, *args, **kwargs)
@@ -199,33 +206,42 @@ class OS_Win(OS):
 
         # Load main pe
         with open(self.fname, "rb") as fstream:
-            self.pe = vm_load_pe(self.jitter.vm, fstream.read(),
-                                 load_hdr=self.options.load_hdr,
-                                 name=self.fname,
-                                 **kwargs)
+            self.pe = vm_load_pe(
+                self.jitter.vm,
+                fstream.read(),
+                load_hdr=self.options.load_hdr,
+                name=self.fname,
+                **kwargs
+            )
             self.name2module[fname_basename] = self.pe
 
         # Load library
         if self.options.loadbasedll:
 
             # Load libs in memory
-            self.name2module.update(vm_load_pe_libs(self.jitter.vm,
-                                                    self.ALL_IMP_DLL,
-                                                    libs,
-                                                    self.modules_path,
-                                                    **kwargs))
+            self.name2module.update(
+                vm_load_pe_libs(
+                    self.jitter.vm,
+                    self.ALL_IMP_DLL,
+                    libs,
+                    self.modules_path,
+                    **kwargs
+                )
+            )
 
             # Patch libs imports
-            for pe in self.name2module.itervalues():
+            for pe in viewvalues(self.name2module):
                 preload_pe(self.jitter.vm, pe, libs)
 
         if self.options.dependencies:
-            vm_load_pe_and_dependencies(self.jitter.vm,
-                                        fname_basename,
-                                        self.name2module,
-                                        libs,
-                                        self.modules_path,
-                                        **kwargs)
+            vm_load_pe_and_dependencies(
+                self.jitter.vm,
+                fname_basename,
+                self.name2module,
+                libs,
+                self.modules_path,
+                **kwargs
+            )
 
         win_api_x86_32.winobjs.current_pe = self.pe
 
@@ -275,8 +291,12 @@ class OS_Linux(OS):
         self.libs = libimp_elf()
 
         with open(self.fname, "rb") as fstream:
-            self.elf = vm_load_elf(self.jitter.vm, fstream.read(),
-                                   name=self.fname, **kwargs)
+            self.elf = vm_load_elf(
+                self.jitter.vm,
+                fstream.read(),
+                name=self.fname,
+                **kwargs
+            )
         preload_elf(self.jitter.vm, self.elf, self.libs)
 
         self.entry_point = self.elf.Ehdr.entry
@@ -325,7 +345,8 @@ class OS_Linux_str(OS):
         self.options.load_base_addr = int(self.options.load_base_addr, 0)
         self.jitter.vm.add_memory_page(
             self.options.load_base_addr, PAGE_READ | PAGE_WRITE, data,
-            "Initial Str")
+            "Initial Str"
+        )
 
         # Library calls handler
         self.jitter.add_lib_handler(libs, methods)
@@ -516,14 +537,17 @@ class Sandbox_Win_x86_64(Sandbox, Arch_x86_64, OS_Win):
         Sandbox.__init__(self, *args, **kwargs)
 
         # reserve stack for local reg
-        for _ in xrange(0x4):
+        for _ in range(0x4):
             self.jitter.push_uint64_t(0)
 
         # Pre-stack return address
         self.jitter.push_uint64_t(self.CALL_FINISH_ADDR)
 
         # Set the runtime guard
-        self.jitter.add_breakpoint(self.CALL_FINISH_ADDR, self.__class__.code_sentinelle)
+        self.jitter.add_breakpoint(
+            self.CALL_FINISH_ADDR,
+            self.__class__.code_sentinelle
+        )
 
     def run(self, addr=None):
         """
@@ -552,14 +576,16 @@ class Sandbox_Linux_x86_32(Sandbox, Arch_x86_32, OS_Linux):
         if self.options.mimic_env:
             env_ptrs = []
             for env in self.envp:
-                env += "\x00"
+                env = force_bytes(env)
+                env += b"\x00"
                 self.jitter.cpu.ESP -= len(env)
                 ptr = self.jitter.cpu.ESP
                 self.jitter.vm.set_mem(ptr, env)
                 env_ptrs.append(ptr)
             argv_ptrs = []
             for arg in self.argv:
-                arg += "\x00"
+                arg = force_bytes(arg)
+                arg += b"\x00"
                 self.jitter.cpu.ESP -= len(arg)
                 ptr = self.jitter.cpu.ESP
                 self.jitter.vm.set_mem(ptr, arg)
@@ -577,7 +603,10 @@ class Sandbox_Linux_x86_32(Sandbox, Arch_x86_32, OS_Linux):
             self.jitter.push_uint32_t(self.CALL_FINISH_ADDR)
 
         # Set the runtime guard
-        self.jitter.add_breakpoint(self.CALL_FINISH_ADDR, self.__class__.code_sentinelle)
+        self.jitter.add_breakpoint(
+            self.CALL_FINISH_ADDR,
+            self.__class__.code_sentinelle
+        )
 
     def run(self, addr=None):
         """
@@ -607,14 +636,16 @@ class Sandbox_Linux_x86_64(Sandbox, Arch_x86_64, OS_Linux):
         if self.options.mimic_env:
             env_ptrs = []
             for env in self.envp:
-                env += "\x00"
+                env = force_bytes(env)
+                env += b"\x00"
                 self.jitter.cpu.RSP -= len(env)
                 ptr = self.jitter.cpu.RSP
                 self.jitter.vm.set_mem(ptr, env)
                 env_ptrs.append(ptr)
             argv_ptrs = []
             for arg in self.argv:
-                arg += "\x00"
+                arg = force_bytes(arg)
+                arg += b"\x00"
                 self.jitter.cpu.RSP -= len(arg)
                 ptr = self.jitter.cpu.RSP
                 self.jitter.vm.set_mem(ptr, arg)
@@ -632,7 +663,10 @@ class Sandbox_Linux_x86_64(Sandbox, Arch_x86_64, OS_Linux):
             self.jitter.push_uint64_t(self.CALL_FINISH_ADDR)
 
         # Set the runtime guard
-        self.jitter.add_breakpoint(self.CALL_FINISH_ADDR, self.__class__.code_sentinelle)
+        self.jitter.add_breakpoint(
+            self.CALL_FINISH_ADDR,
+            self.__class__.code_sentinelle
+        )
 
     def run(self, addr=None):
         """
@@ -661,14 +695,16 @@ class Sandbox_Linux_arml(Sandbox, Arch_arml, OS_Linux):
         if self.options.mimic_env:
             env_ptrs = []
             for env in self.envp:
-                env += "\x00"
+                env = force_bytes(env)
+                env += b"\x00"
                 self.jitter.cpu.SP -= len(env)
                 ptr = self.jitter.cpu.SP
                 self.jitter.vm.set_mem(ptr, env)
                 env_ptrs.append(ptr)
             argv_ptrs = []
             for arg in self.argv:
-                arg += "\x00"
+                arg = force_bytes(arg)
+                arg += b"\x00"
                 self.jitter.cpu.SP -= len(arg)
                 ptr = self.jitter.cpu.SP
                 self.jitter.vm.set_mem(ptr, arg)
@@ -688,7 +724,10 @@ class Sandbox_Linux_arml(Sandbox, Arch_arml, OS_Linux):
         self.jitter.cpu.LR = self.CALL_FINISH_ADDR
 
         # Set the runtime guard
-        self.jitter.add_breakpoint(self.CALL_FINISH_ADDR, self.__class__.code_sentinelle)
+        self.jitter.add_breakpoint(
+            self.CALL_FINISH_ADDR,
+            self.__class__.code_sentinelle
+        )
 
     def run(self, addr=None):
         if addr is None and self.options.address is None:
@@ -714,14 +753,16 @@ class Sandbox_Linux_armtl(Sandbox, Arch_armtl, OS_Linux):
         if self.options.mimic_env:
             env_ptrs = []
             for env in self.envp:
-                env += "\x00"
+                env = force_bytes(env)
+                env += b"\x00"
                 self.jitter.cpu.SP -= len(env)
                 ptr = self.jitter.cpu.SP
                 self.jitter.vm.set_mem(ptr, env)
                 env_ptrs.append(ptr)
             argv_ptrs = []
             for arg in self.argv:
-                arg += "\x00"
+                arg = force_bytes(arg)
+                arg += b"\x00"
                 self.jitter.cpu.SP -= len(arg)
                 ptr = self.jitter.cpu.SP
                 self.jitter.vm.set_mem(ptr, arg)
@@ -741,7 +782,10 @@ class Sandbox_Linux_armtl(Sandbox, Arch_armtl, OS_Linux):
         self.jitter.cpu.LR = self.CALL_FINISH_ADDR
 
         # Set the runtime guard
-        self.jitter.add_breakpoint(self.CALL_FINISH_ADDR, self.__class__.code_sentinelle)
+        self.jitter.add_breakpoint(
+            self.CALL_FINISH_ADDR,
+            self.__class__.code_sentinelle
+        )
 
     def run(self, addr=None):
         if addr is None and self.options.address is None:
@@ -768,14 +812,16 @@ class Sandbox_Linux_mips32b(Sandbox, Arch_mips32b, OS_Linux):
         if self.options.mimic_env:
             env_ptrs = []
             for env in self.envp:
-                env += "\x00"
+                env = force_bytes(env)
+                env += b"\x00"
                 self.jitter.cpu.SP -= len(env)
                 ptr = self.jitter.cpu.SP
                 self.jitter.vm.set_mem(ptr, env)
                 env_ptrs.append(ptr)
             argv_ptrs = []
             for arg in self.argv:
-                arg += "\x00"
+                arg = force_bytes(arg)
+                arg += b"\x00"
                 self.jitter.cpu.SP -= len(arg)
                 ptr = self.jitter.cpu.SP
                 self.jitter.vm.set_mem(ptr, arg)
@@ -792,7 +838,10 @@ class Sandbox_Linux_mips32b(Sandbox, Arch_mips32b, OS_Linux):
         self.jitter.cpu.RA = 0x1337beef
 
         # Set the runtime guard
-        self.jitter.add_breakpoint(0x1337beef, self.__class__.code_sentinelle)
+        self.jitter.add_breakpoint(
+            0x1337beef,
+            self.__class__.code_sentinelle
+        )
 
     def run(self, addr=None):
         if addr is None and self.options.address is None:
@@ -850,14 +899,16 @@ class Sandbox_Linux_aarch64l(Sandbox, Arch_aarch64l, OS_Linux):
         if self.options.mimic_env:
             env_ptrs = []
             for env in self.envp:
-                env += "\x00"
+                env = force_bytes(env)
+                env += b"\x00"
                 self.jitter.cpu.SP -= len(env)
                 ptr = self.jitter.cpu.SP
                 self.jitter.vm.set_mem(ptr, env)
                 env_ptrs.append(ptr)
             argv_ptrs = []
             for arg in self.argv:
-                arg += "\x00"
+                arg = force_bytes(arg)
+                arg += b"\x00"
                 self.jitter.cpu.SP -= len(arg)
                 ptr = self.jitter.cpu.SP
                 self.jitter.vm.set_mem(ptr, arg)
@@ -874,7 +925,10 @@ class Sandbox_Linux_aarch64l(Sandbox, Arch_aarch64l, OS_Linux):
         self.jitter.cpu.LR = self.CALL_FINISH_ADDR
 
         # Set the runtime guard
-        self.jitter.add_breakpoint(self.CALL_FINISH_ADDR, self.__class__.code_sentinelle)
+        self.jitter.add_breakpoint(
+            self.CALL_FINISH_ADDR,
+            self.__class__.code_sentinelle
+        )
 
     def run(self, addr=None):
         if addr is None and self.options.address is None:
@@ -911,14 +965,16 @@ class Sandbox_Linux_ppc32b(Sandbox, Arch_ppc32b, OS_Linux):
         if self.options.mimic_env:
             env_ptrs = []
             for env in self.envp:
-                env += "\x00"
+                env = force_bytes(env)
+                env += b"\x00"
                 self.jitter.cpu.R1 -= len(env)
                 ptr = self.jitter.cpu.R1
                 self.jitter.vm.set_mem(ptr, env)
                 env_ptrs.append(ptr)
             argv_ptrs = []
             for arg in self.argv:
-                arg += "\x00"
+                arg = force_bytes(arg)
+                arg += b"\x00"
                 self.jitter.cpu.R1 -= len(arg)
                 ptr = self.jitter.cpu.R1
                 self.jitter.vm.set_mem(ptr, arg)
@@ -947,8 +1003,10 @@ class Sandbox_Linux_ppc32b(Sandbox, Arch_ppc32b, OS_Linux):
         self.jitter.cpu.LR = self.CALL_FINISH_ADDR
 
         # Set the runtime guard
-        self.jitter.add_breakpoint(self.CALL_FINISH_ADDR,
-                                   self.__class__.code_sentinelle)
+        self.jitter.add_breakpoint(
+            self.CALL_FINISH_ADDR,
+            self.__class__.code_sentinelle
+        )
 
     def run(self, addr=None):
         """
diff --git a/miasm2/analysis/simplifier.py b/miasm2/analysis/simplifier.py
index ca8e74fb..10d5e092 100644
--- a/miasm2/analysis/simplifier.py
+++ b/miasm2/analysis/simplifier.py
@@ -24,7 +24,7 @@ log.setLevel(logging.WARNING)
 def fix_point(func):
     @wraps(func)
     def ret_func(self, ircfg, head):
-        log.debug('[%s]: start', func.func_name)
+        log.debug('[%s]: start', func.__name__)
         has_been_modified = False
         modified = True
         while modified:
@@ -32,7 +32,7 @@ def fix_point(func):
             has_been_modified |= modified
         log.debug(
             '[%s]: stop %r',
-            func.func_name,
+            func.__name__,
             has_been_modified
         )
         return has_been_modified
diff --git a/miasm2/analysis/ssa.py b/miasm2/analysis/ssa.py
index 501cdd5e..54d17dc1 100644
--- a/miasm2/analysis/ssa.py
+++ b/miasm2/analysis/ssa.py
@@ -1,4 +1,5 @@
 from collections import deque
+from future.utils import viewitems, viewvalues
 
 from miasm2.expression.expression import ExprId, ExprAssign, ExprOp, \
     ExprLoc, get_expr_ids
@@ -246,7 +247,7 @@ class SSA(object):
             instructions = []
             # insert SSA instructions
             for _ in assignblk:
-                instructions.append(ssa_iter.next())
+                instructions.append(next(ssa_iter))
             # replace instructions of assignblock in IRBlock
             new_irs.append(AssignBlock(instructions, assignblk.instr))
         return IRBlock(irblock.loc_key, new_irs)
@@ -576,7 +577,7 @@ class SSADiGraph(SSA):
         # if successor is in block's dominance frontier
         if successor in self._phinodes:
             # walk over all variables on LHS
-            for dst, src in self._phinodes[successor].iteritems():
+            for dst, src in list(viewitems(self._phinodes[successor])):
                 # transform variable on RHS in non-SSA form
                 expr = self.reverse_variable(dst)
                 # transform expr into it's SSA form using current stack
@@ -618,7 +619,7 @@ class SSADiGraph(SSA):
         """
         var_to_insert = set()
         for loc_key in self._phinodes:
-            for dst, sources in self._phinodes[loc_key].iteritems():
+            for dst, sources in viewitems(self._phinodes[loc_key]):
                 for src in sources.args:
                     if src in self.ssa_variable_to_expr:
                         continue
@@ -641,14 +642,14 @@ class SSADiGraph(SSA):
 
         # Updt structure
         for loc_key in self._phinodes:
-            for dst, sources in self._phinodes[loc_key].items():
+            for dst, sources in viewitems(self._phinodes[loc_key]):
                 self._phinodes[loc_key][dst] = sources.replace_expr(var_to_newname)
 
-        for var, (loc_key, index) in self.ssa_to_location.items():
+        for var, (loc_key, index) in list(viewitems(self.ssa_to_location)):
             if loc_key == head:
                 self.ssa_to_location[var] = loc_key, index + 1
 
-        for newname, var in newname_to_var.iteritems():
+        for newname, var in viewitems(newname_to_var):
             self.ssa_to_location[newname] = head, 0
             self.ssa_variable_to_expr[newname] = var
             self.expressions[newname] = var
@@ -661,7 +662,7 @@ def irblock_has_phi(irblock):
     """
     if not irblock.assignblks:
         return False
-    for src in irblock[0].itervalues():
+    for src in viewvalues(irblock[0]):
         return src.is_op('Phi')
     return False
 
@@ -765,7 +766,7 @@ class UnSSADiGraph(object):
         """
         ircfg = self.ssa.graph
 
-        for irblock in ircfg.blocks.values():
+        for irblock in list(viewvalues(ircfg.blocks)):
             if not irblock_has_phi(irblock):
                 continue
 
@@ -788,7 +789,7 @@ class UnSSADiGraph(object):
                 for parent, src in self.phi_parent_sources[dst]:
                     parent_to_parallel_copies.setdefault(parent, {})[new_var] = src
 
-            for parent, parallel_copies in parent_to_parallel_copies.iteritems():
+            for parent, parallel_copies in viewitems(parent_to_parallel_copies):
                 parent = ircfg.blocks[parent]
                 assignblks = list(parent)
                 assignblks.append(AssignBlock(parallel_copies, parent[-1].instr))
@@ -810,10 +811,10 @@ class UnSSADiGraph(object):
         node
         """
         ircfg = self.ssa.graph
-        for irblock in ircfg.blocks.itervalues():
+        for irblock in viewvalues(ircfg.blocks):
             if not irblock_has_phi(irblock):
                 continue
-            for dst, sources in irblock[0].iteritems():
+            for dst, sources in viewitems(irblock[0]):
                 assert sources.is_op('Phi')
                 new_var = self.create_copy_var(dst)
                 self.phi_new_var[dst] = new_var
@@ -836,7 +837,7 @@ class UnSSADiGraph(object):
         """
         Generate trivial coalescing of phi variable and itself
         """
-        for phi_new_var in self.phi_new_var.itervalues():
+        for phi_new_var in viewvalues(self.phi_new_var):
             self.merge_state.setdefault(phi_new_var, set([phi_new_var]))
 
     def order_ssa_var_dom(self):
@@ -1009,7 +1010,7 @@ class UnSSADiGraph(object):
         assignments.
         @parent: Optional parent location of the phi source for liveness tests
         """
-        for dst, src in parallel_copies.iteritems():
+        for dst, src in viewitems(parallel_copies):
             dst_merge = self.merge_state.setdefault(dst, set([dst]))
             src_merge = self.merge_state.setdefault(src, set([src]))
             if not self.merge_sets_interfere(dst_merge, src_merge, parent):
@@ -1023,7 +1024,7 @@ class UnSSADiGraph(object):
         ircfg = self.ssa.graph
 
         # Run coalesce on the post phi parallel copy
-        for irblock in ircfg.blocks.values():
+        for irblock in viewvalues(ircfg.blocks):
             if not irblock_has_phi(irblock):
                 continue
             parallel_copies = {}
@@ -1041,7 +1042,7 @@ class UnSSADiGraph(object):
                 for parent, src in self.phi_parent_sources[dst]:
                     parent_to_parallel_copies.setdefault(parent, {})[new_var] = src
 
-            for parent, parallel_copies in parent_to_parallel_copies.iteritems():
+            for parent, parallel_copies in viewitems(parent_to_parallel_copies):
                 self.aggressive_coalesce_parallel_copy(parallel_copies, parent)
 
     def get_best_merge_set_name(self, merge_set):
@@ -1069,7 +1070,7 @@ class UnSSADiGraph(object):
 
         # Elect representative for merge sets
         merge_set_to_name = {}
-        for merge_set in self.merge_state.itervalues():
+        for merge_set in viewvalues(self.merge_state):
             frozen_merge_set = frozenset(merge_set)
             merge_sets.add(frozen_merge_set)
             var_name = self.get_best_merge_set_name(merge_set)
@@ -1090,10 +1091,10 @@ class UnSSADiGraph(object):
         @ircfg: IRDiGraph instance
         """
 
-        for irblock in self.ssa.graph.blocks.values():
+        for irblock in list(viewvalues(self.ssa.graph.blocks)):
             assignblks = list(irblock)
             out = {}
-            for dst, src in assignblks[0].iteritems():
+            for dst, src in viewitems(assignblks[0]):
                 if src.is_op('Phi'):
                     assert set([dst]) == set(src.args)
                     continue
@@ -1105,11 +1106,11 @@ class UnSSADiGraph(object):
         """
         Remove trivial expressions (a=a) in the current graph
         """
-        for irblock in self.ssa.graph.blocks.values():
+        for irblock in list(viewvalues(self.ssa.graph.blocks)):
             assignblks = list(irblock)
             for i, assignblk in enumerate(assignblks):
                 out = {}
-                for dst, src in assignblk.iteritems():
+                for dst, src in viewitems(assignblk):
                     if dst == src:
                         continue
                     out[dst] = src
diff --git a/miasm2/arch/aarch64/arch.py b/miasm2/arch/aarch64/arch.py
index 015464d6..3a4f6446 100644
--- a/miasm2/arch/aarch64/arch.py
+++ b/miasm2/arch/aarch64/arch.py
@@ -1,13 +1,16 @@
 #-*- coding:utf-8 -*-
 
+from builtins import range
+from future.utils import viewitems, viewvalues
+
 import logging
 from pyparsing import *
 from miasm2.expression import expression as m2_expr
 from miasm2.core.cpu import *
 from collections import defaultdict
 from miasm2.core.bin_stream import bin_stream
-import regs as regs_module
-from regs import *
+from miasm2.arch.aarch64 import regs as regs_module
+from miasm2.arch.aarch64.regs import *
 from miasm2.core.cpu import log as log_cpu
 from miasm2.expression.modint import uint32, uint64, mod_size2int
 from miasm2.core.asm_ast import AstInt, AstId, AstMem, AstOp
@@ -182,7 +185,7 @@ def cb_deref_nooff(t):
 def cb_deref_post(t):
     assert len(t) == 2
     if isinstance(t[1], AstId) and isinstance(t[1].name, ExprId):
-        raise StopIteration
+        return
     result = AstOp("postinc", *t)
     return result
 
@@ -190,7 +193,7 @@ def cb_deref_post(t):
 def cb_deref_pre(t):
     assert len(t) == 2
     if isinstance(t[1], AstId) and isinstance(t[1].name, ExprId):
-        raise StopIteration
+        return
     result = AstOp("preinc", *t)
     return result
 
@@ -198,7 +201,7 @@ def cb_deref_pre(t):
 def cb_deref_pre_wb(t):
     assert len(t) == 2
     if isinstance(t[1], AstId) and isinstance(t[1].name, ExprId):
-        raise StopIteration
+        return
     result = AstOp("preinc_wb", *t)
     return result
 
@@ -234,7 +237,7 @@ def cb_deref_ext2op(t):
 deref_ext2 = (LBRACK + gpregs_32_64 + COMMA + gpregs_32_64 + Optional(all_extend2_t + base_expr) + RBRACK).setParseAction(cb_deref_ext2op)
 
 
-class additional_info:
+class additional_info(object):
 
     def __init__(self):
         self.except_on_instr = False
@@ -275,7 +278,7 @@ class aarch64_arg(m_arg):
             if isinstance(value.name, ExprId):
                 fixed_size.add(value.name.size)
                 return value.name
-            loc_key = loc_db.get_or_create_name_location(value.name)
+            loc_key = loc_db.get_or_create_name_location(value.name.encode())
             return m2_expr.ExprLoc(loc_key, size_hint)
         if isinstance(value, AstInt):
             assert size_hint is not None
@@ -446,7 +449,7 @@ class mn_aarch64(cls_mn):
         if n > bs.getlen() * 8:
             raise ValueError('not enough bits %r %r' % (n, len(bs.bin) * 8))
         while n:
-            offset = start / 8
+            offset = start // 8
             n_offset = cls.endian_offset(attrib, offset)
             c = cls.getbytes(bs, n_offset, 1)
             if not c:
@@ -897,11 +900,14 @@ class aarch64_gpreg_ext(reg_noarg, aarch64_arg):
                            reg, m2_expr.ExprInt(self.parent.imm.value, reg.size))
         return True
 
-EXT2_OP = {0b010: 'UXTW',
-           0b011: 'LSL',
-           0b110: 'SXTW',
-           0b111: 'SXTX'}
-EXT2_OP_INV = dict([(items[1], items[0]) for items in EXT2_OP.items()])
+EXT2_OP = {
+    0b010: 'UXTW',
+    0b011: 'LSL',
+    0b110: 'SXTW',
+    0b111: 'SXTX'
+}
+
+EXT2_OP_INV = dict((value, key) for key, value in viewitems(EXT2_OP))
 
 
 class aarch64_gpreg_ext2(reg_noarg, aarch64_arg):
@@ -933,7 +939,7 @@ class aarch64_gpreg_ext2(reg_noarg, aarch64_arg):
             reg = arg1
             self.parent.option.value = 0b011
             is_reg = True
-        elif isinstance(arg1, m2_expr.ExprOp) and arg1.op in EXT2_OP.values():
+        elif isinstance(arg1, m2_expr.ExprOp) and arg1.op in viewvalues(EXT2_OP):
             reg = arg1.args[0]
         else:
             return False
@@ -1069,10 +1075,15 @@ class bits(object):
 
     def __init__(self, size, value):
         """Instantiate a bitvector of size @size with value @value"""
-        self.size = size
+        value = int(value)
+        self.size = int(size)
         if value & self.mask != value:
-            raise ValueError("Value %s is too large for %d bits",
-                             hex(value), size)
+            raise ValueError(
+                "Value %r is too large for %r bits (mask %r)",
+                value,
+                size,
+                self.mask
+            )
         self.value = value
 
     def concat_left(self, other_bits):
@@ -1123,11 +1134,11 @@ class bits(object):
 
     def __str__(self):
         return "'%s'" % "".join('1' if self.value & (1 << i) else '0'
-                                for i in reversed(xrange(self.size)))
+                                for i in reversed(range(self.size)))
 
 # From J1-6035
 def HighestSetBit(x):
-    for i in reversed(xrange(x.size)):
+    for i in reversed(range(x.size)):
         if x.value & (1 << i):
             return i
     return - 1
@@ -1198,7 +1209,7 @@ def DecodeBitMasks(M, immN, imms, immr, immediate):
 def EncodeBitMasks(wmask):
     # Find replicate
     M = wmask.size
-    for i in xrange(1, M + 1):
+    for i in range(1, M + 1):
         if M % i != 0:
             continue
         if wmask == Replicate(wmask[:i], M):
@@ -1211,7 +1222,7 @@ def EncodeBitMasks(wmask):
     esize = welem_after_ror.size
     S = welem_after_ror.pop_count - 1
     welem = ZeroExtend(Ones(S + 1), esize)
-    for i in xrange(welem_after_ror.size):
+    for i in range(welem_after_ror.size):
         if ROR(welem, i) == welem_after_ror:
             break
     else:
@@ -1219,7 +1230,7 @@ def EncodeBitMasks(wmask):
     R = i
 
     # Find len value
-    for i in xrange(M):
+    for i in range(M):
         if (1 << i) == esize:
             break
     else:
@@ -1340,7 +1351,7 @@ class aarch64_imm_hw(aarch64_arg):
             return False
         value = int(self.expr)
         mask = (1 << size) - 1
-        for i in xrange(size / 16):
+        for i in range(size // 16):
             if ((0xffff << (i * 16)) ^ mask) & value:
                 continue
             self.parent.hw.value = i
@@ -1384,10 +1395,10 @@ class aarch64_imm_hw_sc(aarch64_arg):
         arg, amount = [int(arg) for arg in self.expr.args]
         if arg > 0xFFFF:
             return False
-        if amount % 16 or amount / 16 > 4:
+        if amount % 16 or amount // 16 > 4:
             return False
         self.value = arg
-        self.parent.hw.value = amount / 16
+        self.parent.hw.value = amount // 16
         return True
 
 
@@ -1852,8 +1863,8 @@ bcond = bs_mod_name(l=4, fname='cond', mn_mod=['EQ', 'NE', 'CS', 'CC',
                                                'HI', 'LS', 'GE', 'LT',
                                                'GT', 'LE', 'AL', 'NV'])
 
-cond_arg = bs(l=4, cls=(aarch64_cond_arg,), fname=cond)
-cond_inv_arg = bs(l=4, cls=(aarch64_cond_inv_arg,), fname=cond)
+cond_arg = bs(l=4, cls=(aarch64_cond_arg,), fname="cond")
+cond_inv_arg = bs(l=4, cls=(aarch64_cond_inv_arg,), fname="cond")
 # unconditional branch (ret)
 aarch64op("br", [bs('1101011'), bs('0000'), bs('11111'), bs('000000'), rn64, bs('00000')], [rn64])
 aarch64op("blr", [bs('1101011'), bs('0001'), bs('11111'), bs('000000'), rn64, bs('00000')], [rn64])
@@ -2037,7 +2048,7 @@ aarch64op("fcvt",  [bs('000'), bs('11110'), bs('01'), bs('1'), bs('0001'), bs('0
 
 
 
-swapargs = bs_swapargs(l=1, fname="swap", mn_mod=range(1 << 1))
+swapargs = bs_swapargs(l=1, fname="swap", mn_mod=list(range(1 << 1)))
 
 aarch64op("fmov",  [bs('0'), bs('00'), bs('11110'), bs('00'), bs('1'), bs('00'), bs('110'), bs('000000'), sn32, rd32], [rd32, sn32])
 aarch64op("fmov",  [bs('0'), bs('00'), bs('11110'), bs('00'), bs('1'), bs('00'), bs('111'), bs('000000'), rn32, sd32], [sd32, rn32])
diff --git a/miasm2/arch/aarch64/jit.py b/miasm2/arch/aarch64/jit.py
index 9873464a..57b896d3 100644
--- a/miasm2/arch/aarch64/jit.py
+++ b/miasm2/arch/aarch64/jit.py
@@ -1,3 +1,4 @@
+from builtins import range
 import logging
 
 from miasm2.jitter.jitload import Jitter, named_arguments
@@ -35,9 +36,9 @@ class jitter_aarch64l(Jitter):
     @named_arguments
     def func_args_stdcall(self, n_args):
         args = []
-        for i in xrange(min(n_args, self.max_reg_arg)):
+        for i in range(min(n_args, self.max_reg_arg)):
             args.append(getattr(self.cpu, 'X%d' % i))
-        for i in xrange(max(0, n_args - self.max_reg_arg)):
+        for i in range(max(0, n_args - self.max_reg_arg)):
             args.append(self.get_stack_arg(i))
         ret_ad = self.cpu.LR
         return ret_ad, args
@@ -56,9 +57,9 @@ class jitter_aarch64l(Jitter):
         return arg
 
     def func_prepare_stdcall(self, ret_addr, *args):
-        for index in xrange(min(len(args), 4)):
+        for index in range(min(len(args), 4)):
             setattr(self.cpu, 'X%d' % index, args[index])
-        for index in xrange(4, len(args)):
+        for index in range(4, len(args)):
             self.vm.set_mem(self.cpu.SP + 8 * (index - 4), pck64(args[index]))
         self.cpu.LR = ret_addr
 
diff --git a/miasm2/arch/aarch64/regs.py b/miasm2/arch/aarch64/regs.py
index 1c693b4c..7ddcc0b8 100644
--- a/miasm2/arch/aarch64/regs.py
+++ b/miasm2/arch/aarch64/regs.py
@@ -1,5 +1,6 @@
 #-*- coding:utf-8 -*-
 
+from builtins import range
 from miasm2.expression.expression import ExprId
 from miasm2.core.cpu import gen_reg, gen_regs
 
@@ -7,40 +8,40 @@ exception_flags = ExprId('exception_flags', 32)
 interrupt_num = ExprId('interrupt_num', 32)
 
 
-gpregs32_str = ["W%d" % i for i in xrange(0x1f)] + ["WSP"]
+gpregs32_str = ["W%d" % i for i in range(0x1f)] + ["WSP"]
 gpregs32_expr, gpregs32_init, gpregs32_info = gen_regs(
     gpregs32_str, globals(), 32)
 
-gpregs64_str = ["X%d" % i for i in xrange(0x1E)] + ["LR", "SP"]
+gpregs64_str = ["X%d" % i for i in range(0x1E)] + ["LR", "SP"]
 gpregs64_expr, gpregs64_init, gpregs64_info = gen_regs(
     gpregs64_str, globals(), 64)
 
 
-gpregsz32_str = ["W%d" % i for i in xrange(0x1f)] + ["WZR"]
+gpregsz32_str = ["W%d" % i for i in range(0x1f)] + ["WZR"]
 gpregsz32_expr, gpregsz32_init, gpregsz32_info = gen_regs(
     gpregsz32_str, globals(), 32)
 
-gpregsz64_str = ["X%d" % i for i in xrange(0x1e)] + ["LR", "XZR"]
+gpregsz64_str = ["X%d" % i for i in range(0x1e)] + ["LR", "XZR"]
 gpregsz64_expr, gpregsz64_init, gpregsz64_info = gen_regs(
     gpregsz64_str, globals(), 64)
 
-cr_str = ["c%d" % i for i in xrange(0xf)]
+cr_str = ["c%d" % i for i in range(0xf)]
 cr_expr, cr_init, cr_info = gen_regs(cr_str, globals(), 32)
 
 
-simd08_str = ["B%d" % i for i in xrange(0x20)]
+simd08_str = ["B%d" % i for i in range(0x20)]
 simd08_expr, simd08_init, simd08_info = gen_regs(simd08_str, globals(), 8)
 
-simd16_str = ["H%d" % i for i in xrange(0x20)]
+simd16_str = ["H%d" % i for i in range(0x20)]
 simd16_expr, simd16_init, simd16_info = gen_regs(simd16_str, globals(), 16)
 
-simd32_str = ["S%d" % i for i in xrange(0x20)]
+simd32_str = ["S%d" % i for i in range(0x20)]
 simd32_expr, simd32_init, simd32_info = gen_regs(simd32_str, globals(), 32)
 
-simd64_str = ["D%d" % i for i in xrange(0x20)]
+simd64_str = ["D%d" % i for i in range(0x20)]
 simd64_expr, simd64_init, simd64_info = gen_regs(simd64_str, globals(), 64)
 
-simd128_str = ["Q%d" % i for i in xrange(0x20)]
+simd128_str = ["Q%d" % i for i in range(0x20)]
 simd128_expr, simd128_init, simd128_info = gen_regs(
     simd128_str, globals(), 128)
 
diff --git a/miasm2/arch/aarch64/sem.py b/miasm2/arch/aarch64/sem.py
index 7052f423..a840f6b6 100644
--- a/miasm2/arch/aarch64/sem.py
+++ b/miasm2/arch/aarch64/sem.py
@@ -1,3 +1,6 @@
+from builtins import range
+from future.utils import viewitems
+
 from miasm2.expression.expression import ExprId, ExprInt, ExprLoc, ExprMem, \
     ExprCond, ExprCompose, ExprOp, ExprAssign
 from miasm2.ir.ir import IntermediateRepresentation, IRBlock, AssignBlock
@@ -675,7 +678,7 @@ def stp(ir, instr, arg1, arg2, arg3):
     addr, updt = get_mem_access(arg3)
     e.append(ExprAssign(ExprMem(addr, arg1.size), arg1))
     e.append(
-        ExprAssign(ExprMem(addr + ExprInt(arg1.size / 8, addr.size), arg2.size), arg2))
+        ExprAssign(ExprMem(addr + ExprInt(arg1.size // 8, addr.size), arg2.size), arg2))
     if updt:
         e.append(updt)
     return e, []
@@ -686,7 +689,7 @@ def ldp(ir, instr, arg1, arg2, arg3):
     addr, updt = get_mem_access(arg3)
     e.append(ExprAssign(arg1, ExprMem(addr, arg1.size)))
     e.append(
-        ExprAssign(arg2, ExprMem(addr + ExprInt(arg1.size / 8, addr.size), arg2.size)))
+        ExprAssign(arg2, ExprMem(addr + ExprInt(arg1.size // 8, addr.size), arg2.size)))
     if updt:
         e.append(updt)
     return e, []
@@ -1012,7 +1015,7 @@ def nop():
 
 def rev(ir, instr, arg1, arg2):
     out = []
-    for i in xrange(0, arg2.size, 8):
+    for i in range(0, arg2.size, 8):
         out.append(arg2[i:i+8])
     out.reverse()
     e = []
@@ -1023,7 +1026,7 @@ def rev(ir, instr, arg1, arg2):
 
 def rev16(ir, instr, arg1, arg2):
     out = []
-    for i in xrange(0, arg2.size / 8):
+    for i in range(0, arg2.size // 8):
         index = (i & ~1) + (1 - (i & 1))
         out.append(arg2[index * 8:(index + 1) * 8])
     e = []
@@ -1248,8 +1251,8 @@ def casp(ir, instr, arg1, arg2, arg3):
     blk_store = IRBlock(loc_store.loc_key, [AssignBlock(e_store, instr)])
 
     e_do = []
-    e_do.append(ExprAssign(regs[index1], data[:data.size / 2]))
-    e_do.append(ExprAssign(regs[index1 + 1], data[data.size / 2:]))
+    e_do.append(ExprAssign(regs[index1], data[:data.size // 2]))
+    e_do.append(ExprAssign(regs[index1 + 1], data[data.size // 2:]))
     e_do.append(ExprAssign(ir.IRDst, loc_next))
     blk_do = IRBlock(loc_do.loc_key, [AssignBlock(e_do, instr)])
 
@@ -1399,7 +1402,7 @@ def get_mnemo_expr(ir, instr, *args):
     return instr, extra_ir
 
 
-class aarch64info:
+class aarch64info(object):
     mode = "aarch64"
     # offset
 
@@ -1438,7 +1441,7 @@ class ir_aarch64l(IntermediateRepresentation):
         irs = []
         for assignblk in irblock:
             new_assignblk = dict(assignblk)
-            for dst, src in assignblk.iteritems():
+            for dst, src in viewitems(assignblk):
                 del(new_assignblk[dst])
                 # Special case for 64 bits:
                 # If destination is a 32 bit reg, zero extend the 64 bit reg
@@ -1480,8 +1483,10 @@ class ir_aarch64l(IntermediateRepresentation):
         for irblock in extra_ir:
             irs = []
             for assignblk in irblock:
-                new_dsts = {dst:src for dst, src in assignblk.iteritems()
-                                if dst not in regs_to_fix}
+                new_dsts = {
+                    dst:src for dst, src in viewitems(assignblk)
+                    if dst not in regs_to_fix
+                }
                 irs.append(AssignBlock(new_dsts, assignblk.instr))
             new_irblocks.append(IRBlock(irblock.loc_key, irs))
 
diff --git a/miasm2/arch/arm/arch.py b/miasm2/arch/arm/arch.py
index c50748e4..3cafad59 100644
--- a/miasm2/arch/arm/arch.py
+++ b/miasm2/arch/arm/arch.py
@@ -1,5 +1,8 @@
 #-*- coding:utf-8 -*-
 
+from builtins import range
+from future.utils import viewitems
+
 import logging
 from pyparsing import *
 from miasm2.expression.expression import *
@@ -24,7 +27,7 @@ reg_dum = ExprId('DumReg', 32)
 PC, _ = gen_reg('PC')
 
 # GP
-regs_str = ['R%d' % r for r in xrange(0x10)]
+regs_str = ['R%d' % r for r in range(0x10)]
 regs_str[13] = 'SP'
 regs_str[14] = 'LR'
 regs_str[15] = 'PC'
@@ -49,9 +52,9 @@ gpregs_nosp = reg_info(regs_str[:13] + [str(reg_dum), regs_str[14], regs_str[15]
 sr_flags = "cxsf"
 cpsr_regs_str = []
 spsr_regs_str = []
-for i in xrange(0x10):
+for i in range(0x10):
     o = ""
-    for j in xrange(4):
+    for j in range(4):
         if i & (1 << j):
             o += sr_flags[j]
     cpsr_regs_str.append("CPSR_%s" % o)
@@ -69,13 +72,13 @@ cpsr_regs = reg_info(cpsr_regs_str, cpsr_regs_expr)
 spsr_regs = reg_info(spsr_regs_str, spsr_regs_expr)
 
 # CP
-cpregs_str = ['c%d' % r for r in xrange(0x10)]
+cpregs_str = ['c%d' % r for r in range(0x10)]
 cpregs_expr = [ExprId(x, 32) for x in cpregs_str]
 
 cp_regs = reg_info(cpregs_str, cpregs_expr)
 
 # P
-pregs_str = ['p%d' % r for r in xrange(0x10)]
+pregs_str = ['p%d' % r for r in range(0x10)]
 pregs_expr = [ExprId(x, 32) for x in pregs_str]
 
 p_regs = reg_info(pregs_str, pregs_expr)
@@ -110,7 +113,7 @@ def cb_tok_reg_duo(tokens):
     i1 = gpregs.expr.index(tokens[0].name)
     i2 = gpregs.expr.index(tokens[1].name)
     o = []
-    for i in xrange(i1, i2 + 1):
+    for i in range(i1, i2 + 1):
         o.append(AstId(gpregs.expr[i]))
     return o
 
@@ -155,7 +158,7 @@ allshifts_armt = ['<<', '>>', 'a>>', '>>>', 'rrx']
 shift2expr_dct = {'LSL': '<<', 'LSR': '>>', 'ASR': 'a>>',
                   'ROR': ">>>", 'RRX': "rrx"}
 
-expr2shift_dct = dict([(x[1], x[0]) for x in shift2expr_dct.items()])
+expr2shift_dct = dict((value, key) for key, value in viewitems(shift2expr_dct))
 
 
 def op_shift2expr(tokens):
@@ -321,13 +324,13 @@ def permut_args(order, args):
     for i, x in enumerate(order):
         l.append((x.__class__, i))
     l = dict(l)
-    out = [None for x in xrange(len(args))]
+    out = [None for x in range(len(args))]
     for a in args:
         out[l[a.__class__]] = a
     return out
 
 
-class additional_info:
+class additional_info(object):
 
     def __init__(self):
         self.except_on_instr = False
@@ -400,8 +403,10 @@ class instruction_arm(instruction):
         else:
             r, s = expr.args[0].args
         if isinstance(s, ExprOp) and s.op in expr2shift_dct:
-            s = ' '.join([str(x)
-                for x in s.args[0], expr2shift_dct[s.op], s.args[1]])
+            s = ' '.join(
+                str(x)
+                for x in (s.args[0], expr2shift_dct[s.op], s.args[1])
+            )
 
         if isinstance(expr, ExprOp) and expr.op == 'postinc':
             o = '[%s]' % r
@@ -563,7 +568,7 @@ class instruction_armt(instruction_arm):
 
     def get_asm_offset(self, expr):
         # ADR XXX, PC, imm => PC is 4 aligned + imm
-        new_offset = ((self.offset+self.l)/4)*4
+        new_offset = ((self.offset + self.l) // 4) * 4
         return ExprInt(new_offset, expr.size)
 
 
@@ -610,7 +615,7 @@ class mn_arm(cls_mn):
         if n > bs.getlen() * 8:
             raise ValueError('not enough bits %r %r' % (n, len(bs.bin) * 8))
         while n:
-            offset = start / 8
+            offset = start // 8
             n_offset = cls.endian_offset(attrib, offset)
             c = cls.getbytes(bs, n_offset, 1)
             if not c:
@@ -711,7 +716,7 @@ class mn_armt(cls_mn):
         if n > bs.getlen() * 8:
             raise ValueError('not enough bits %r %r' % (n, len(bs.bin) * 8))
         while n:
-            offset = start / 8
+            offset = start // 8
             n_offset = cls.endian_offset(attrib, offset)
             c = cls.getbytes(bs, n_offset, 1)
             if not c:
@@ -784,7 +789,7 @@ class arm_arg(m_arg):
                 return arg.name
             if arg.name in gpregs.str:
                 return None
-            loc_key = loc_db.get_or_create_name_location(arg.name)
+            loc_key = loc_db.get_or_create_name_location(arg.name.encode())
             return ExprLoc(loc_key, 32)
         if isinstance(arg, AstOp):
             args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
@@ -1025,10 +1030,10 @@ class arm_op2(arm_arg):
     def str_to_imm_rot_form(self, s, neg=False):
         if neg:
             s = -s & 0xffffffff
-        for i in xrange(0, 32, 2):
+        for i in range(0, 32, 2):
             v = myrol32(s, i)
             if 0 <= v < 0x100:
-                return ((i / 2) << 8) | v
+                return ((i // 2) << 8) | v
         return None
 
     def decode(self, v):
@@ -1267,7 +1272,7 @@ class arm_rlist(arm_arg):
     def decode(self, v):
         v = v & self.lmask
         out = []
-        for i in xrange(0x10):
+        for i in range(0x10):
             if 1 << i & v:
                 out.append(gpregs.expr[i])
         if not out:
@@ -1616,7 +1621,7 @@ data_test_name = {'TST': 8, 'TEQ': 9, 'CMP': 10, 'CMN': 11}
 
 data_name = {}
 for i, n in enumerate(op_list):
-    if n in data_mov_name.keys() + data_test_name.keys():
+    if n in list(data_mov_name) + list(data_test_name):
         continue
     data_name[n] = i
 bs_data_name = bs_name(l=4, name=data_name)
@@ -1740,7 +1745,7 @@ class arm_rm_rot2(arm_arg):
             value = int(value)
             if not value in [8, 16, 24]:
                 return False
-            self.parent.rot2.value = value / 8
+            self.parent.rot2.value = value // 8
         return True
 
 class arm_gpreg_nopc(reg_noarg):
@@ -2052,7 +2057,7 @@ class armt_rlist(arm_arg):
     def decode(self, v):
         v = v & self.lmask
         out = []
-        for i in xrange(0x10):
+        for i in range(0x10):
             if 1 << i & v:
                 out.append(gpregs.expr[i])
         if not out:
@@ -2093,7 +2098,7 @@ class armt_rlist13(armt_rlist):
     def decode(self, v):
         v = v & self.lmask
         out = []
-        for i in xrange(13):
+        for i in range(13):
             if 1 << i & v:
                 out.append(gpregs_l_13.expr[i])
 
@@ -2141,7 +2146,7 @@ class armt_rlist13_pc_lr(armt_rlist):
     def decode(self, v):
         v = v & self.lmask
         out = []
-        for i in xrange(13):
+        for i in range(13):
             if 1 << i & v:
                 out.append(gpregs_l_13.expr[i])
 
@@ -2184,7 +2189,7 @@ class armt_rlist_pclr(armt_rlist):
     def decode(self, v):
         v = v & self.lmask
         out = []
-        for i in xrange(0x10):
+        for i in range(0x10):
             if 1 << i & v:
                 out.append(gpregs.expr[i])
 
@@ -2522,7 +2527,7 @@ class armt2_imm12(arm_imm):
             value = (3 << 8) | ((v >> 16) & 0xff)
         else:
             # rol encoding
-            for i in xrange(32):
+            for i in range(32):
                 o = myrol32(v, i)
                 if 0x80 <= o <= 0xFF:
                     value = (i << 7) | (o & 0x7F)
@@ -2860,7 +2865,7 @@ class armt_itmask(bs_divert):
     def divert(self, i, candidates):
         out = []
         for cls, _, bases, dct, fields in candidates:
-            for value in xrange(1, 0x10):
+            for value in range(1, 0x10):
                 nfields = fields[:]
                 s = int2bin(value, self.args['l'])
                 args = dict(self.args)
@@ -2881,7 +2886,7 @@ class armt_itmask(bs_divert):
         values = ['E', 'T']
         if inv== 1:
             values.reverse()
-        for index in xrange(3 - count):
+        for index in range(3 - count):
             if value & (1 << (3 - index)):
                 out.append(values[0])
             else:
@@ -2896,7 +2901,7 @@ class armt_cond_lsb(bs_divert):
     def divert(self, i, candidates):
         out = []
         for cls, _, bases, dct, fields in candidates:
-            for value in xrange(2):
+            for value in range(2):
                 nfields = fields[:]
                 s = int2bin(value, self.args['l'])
                 args = dict(self.args)
diff --git a/miasm2/arch/arm/disasm.py b/miasm2/arch/arm/disasm.py
index 5e21778d..2a443cc2 100644
--- a/miasm2/arch/arm/disasm.py
+++ b/miasm2/arch/arm/disasm.py
@@ -1,3 +1,5 @@
+from future.utils import viewvalues
+
 from miasm2.core.asmblock import AsmConstraint, disasmEngine
 from miasm2.arch.arm.arch import mn_arm, mn_armt
 
@@ -19,7 +21,7 @@ def cb_arm_fix_call(mn, cur_bloc, loc_db, offsets_to_dis, *args, **kwargs):
     if l2.name != "MOV":
         return
 
-    values = mn.pc.values()
+    values = viewvalues(mn.pc)
     if not l1.args[0] in values:
         return
     if not l2.args[1] in values:
diff --git a/miasm2/arch/arm/jit.py b/miasm2/arch/arm/jit.py
index 06fba210..128baffb 100644
--- a/miasm2/arch/arm/jit.py
+++ b/miasm2/arch/arm/jit.py
@@ -1,3 +1,4 @@
+from builtins import range
 import logging
 
 from miasm2.jitter.jitload import Jitter, named_arguments
@@ -85,7 +86,7 @@ class jitter_arml(Jitter):
 
     @named_arguments
     def func_args_stdcall(self, n_args):
-        args = [self.get_arg_n_stdcall(i) for i in xrange(n_args)]
+        args = [self.get_arg_n_stdcall(i) for i in range(n_args)]
         ret_ad = self.cpu.LR
         return ret_ad, args
 
@@ -98,9 +99,9 @@ class jitter_arml(Jitter):
         return True
 
     def func_prepare_stdcall(self, ret_addr, *args):
-        for index in xrange(min(len(args), 4)):
+        for index in range(min(len(args), 4)):
             setattr(self.cpu, 'R%d' % index, args[index])
-        for index in reversed(xrange(4, len(args))):
+        for index in reversed(range(4, len(args))):
             self.push_uint32_t(args[index])
         self.cpu.LR = ret_addr
 
diff --git a/miasm2/arch/arm/regs.py b/miasm2/arch/arm/regs.py
index e20b00bd..f39f2161 100644
--- a/miasm2/arch/arm/regs.py
+++ b/miasm2/arch/arm/regs.py
@@ -1,11 +1,12 @@
 #-*- coding:utf-8 -*-
 
+from builtins import range
 from miasm2.expression.expression import *
 
 
 # GP
 
-regs32_str = ["R%d" % i for i in xrange(13)] + ["SP", "LR", "PC"]
+regs32_str = ["R%d" % i for i in range(13)] + ["SP", "LR", "PC"]
 regs32_expr = [ExprId(x, 32) for x in regs32_str]
 
 exception_flags = ExprId('exception_flags', 32)
diff --git a/miasm2/arch/arm/sem.py b/miasm2/arch/arm/sem.py
index 782a99fb..6622a42a 100644
--- a/miasm2/arch/arm/sem.py
+++ b/miasm2/arch/arm/sem.py
@@ -1,3 +1,6 @@
+from builtins import range
+from future.utils import viewitems, viewvalues
+
 from miasm2.expression.expression import *
 from miasm2.ir.ir import IntermediateRepresentation, IRBlock, AssignBlock
 from miasm2.arch.arm.arch import mn_arm, mn_armt
@@ -1053,7 +1056,7 @@ def rors(ir, instr, a, b):
 def push(ir, instr, a):
     e = []
     regs = list(a.args)
-    for i in xrange(len(regs)):
+    for i in range(len(regs)):
         r = SP + ExprInt(-4 * len(regs) + 4 * i, 32)
         e.append(ExprAssign(ExprMem(r, 32), regs[i]))
     r = SP + ExprInt(-4 * len(regs), 32)
@@ -1065,7 +1068,7 @@ def pop(ir, instr, a):
     e = []
     regs = list(a.args)
     dst = None
-    for i in xrange(len(regs)):
+    for i in range(len(regs)):
         r = SP + ExprInt(4 * i, 32)
         e.append(ExprAssign(regs[i], ExprMem(r, 32)))
         if regs[i] == ir.pc:
@@ -1271,7 +1274,7 @@ def uadd8(ir, instr, a, b, c):
     e = []
     sums = []
     ges = []
-    for i in xrange(0, 32, 8):
+    for i in range(0, 32, 8):
         sums.append(b[i:i+8] + c[i:i+8])
         ges.append((b[i:i+8].zeroExtend(9) + c[i:i+8].zeroExtend(9))[8:9])
 
@@ -1286,7 +1289,7 @@ def sel(ir, instr, a, b, c):
     e = []
     cond = nf ^ of ^ ExprInt(1, 1)
     parts = []
-    for i in xrange(4):
+    for i in range(4):
         parts.append(ExprCond(ge_regs[i], b[i*8:(i+1)*8], c[i*8:(i+1)*8]))
     result = ExprCompose(*parts)
     e.append(ExprAssign(a, result))
@@ -1382,7 +1385,7 @@ cond_dct = {
     # COND_NV: "NV",
 }
 
-cond_dct_inv = dict((name, num) for num, name in cond_dct.iteritems())
+cond_dct_inv = dict((name, num) for num, name in viewitems(cond_dct))
 
 
 """
@@ -1425,7 +1428,7 @@ tab_cond = {COND_EQ: ExprOp("CC_EQ", zf),
 
 
 def is_pc_written(ir, instr_ir):
-    all_pc = ir.mn.pc.values()
+    all_pc = viewvalues(ir.mn.pc)
     for ir in instr_ir:
         if ir.dst in all_pc:
             return True, ir.dst
@@ -1613,8 +1616,8 @@ mn_cond_x = [mnemo_condm0,
              mnemo_condm2]
 
 for index, mn_base in enumerate(mn_cond_x):
-    for mn, mf in mn_base.items():
-        for cond, cn in cond_dct.items():
+    for mn, mf in viewitems(mn_base):
+        for cond, cn in viewitems(cond_dct):
             if cond == COND_AL:
                 cn = ""
             cn = cn.lower()
@@ -1625,7 +1628,7 @@ for index, mn_base in enumerate(mn_cond_x):
             # print mn_mod
             mnemo_func_cond[mn_mod] = cond, mf
 
-for name, mf in mnemo_nocond.items():
+for name, mf in viewitems(mnemo_nocond):
     mnemo_func_cond[name] = COND_AL, mf
 
 
@@ -1652,7 +1655,7 @@ def get_mnemo_expr(ir, instr, *args):
 get_arm_instr_expr = get_mnemo_expr
 
 
-class arminfo:
+class arminfo(object):
     mode = "arm"
     # offset
 
@@ -1775,7 +1778,7 @@ class ir_arml(IntermediateRepresentation):
                 for assignment in assignments:
                     assignment = AssignBlock(
                         {
-                            dst:src for (dst, src) in assignment.iteritems()
+                            dst: src for (dst, src) in viewitems(assignment)
                             if dst not in [zf, nf, of, cf]
                         },
                         assignment.instr
@@ -1789,7 +1792,7 @@ class ir_arml(IntermediateRepresentation):
                     for tmp_assignment in irblock:
                         assignment = AssignBlock(
                             {
-                                dst:src for (dst, src) in assignment.iteritems()
+                                dst: src for (dst, src) in viewitems(assignment)
                                 if dst not in [zf, nf, of, cf]
                             },
                             assignment.instr
diff --git a/miasm2/arch/mep/arch.py b/miasm2/arch/mep/arch.py
index e4d66a63..2266b596 100644
--- a/miasm2/arch/mep/arch.py
+++ b/miasm2/arch/mep/arch.py
@@ -1,6 +1,7 @@
 # Toshiba MeP-c4 - miasm architecture definition
 # Guillaume Valadon <guillaume@valadon.net>
 
+from builtins import range
 from miasm2.core.cpu import *
 from miasm2.core.utils import Disasm_Exception
 from miasm2.expression.expression import Expr, ExprId, ExprInt, ExprLoc, \
@@ -279,7 +280,7 @@ class instruction_mep(instruction):
         self.args[num] = ExprInt(off, 32)
 
 
-class mep_additional_info:
+class mep_additional_info(object):
     """Additional MeP instructions information
     """
 
@@ -432,7 +433,7 @@ class mn_mep(cls_mn):
         o = 0  # the returned value
         while n:
             # Get a byte, the offset is adjusted according to the endianness
-            offset = start / 8  # the offset in bytes
+            offset = start // 8  # the offset in bytes
             n_offset = cls.endian_offset(attrib, offset)  # the adjusted offset
             c = cls.getbytes(bitstream, n_offset, 1)
             if not c:
@@ -552,7 +553,7 @@ class mep_arg(m_arg):
                 return arg.name
             if isinstance(arg.name, str) and arg.name in gpr_names:
                 return None  # GV: why?
-            loc_key = loc_db.get_or_create_name_location(arg.name)
+            loc_key = loc_db.get_or_create_name_location(arg.name.encode())
             return ExprLoc(loc_key, 32)
 
         elif isinstance(arg, AstMem):
diff --git a/miasm2/arch/mep/regs.py b/miasm2/arch/mep/regs.py
index a515e76a..88248823 100644
--- a/miasm2/arch/mep/regs.py
+++ b/miasm2/arch/mep/regs.py
@@ -1,6 +1,7 @@
 # Toshiba MeP-c4 - miasm registers definition
 # Guillaume Valadon <guillaume@valadon.net>
 
+from builtins import range
 from miasm2.expression.expression import ExprId
 from miasm2.core.cpu import reg_info, gen_reg, gen_regs
 
@@ -19,7 +20,7 @@ in_erepeat_init = ExprId("take_jmp_init", 32)
 
 
 # General-purpose registers (R0 to R15) names
-gpr_names = ["R%d" % r for r in xrange(13)]  # register names
+gpr_names = ["R%d" % r for r in range(13)]  # register names
 gpr_names += ["TP", "GP", "SP"]  # according to the manual GP does not exist
 gpr_exprs, gpr_inits, gpr_infos = gen_regs(gpr_names, globals())  # sz=32 bits (default)
 
@@ -53,7 +54,7 @@ RPC = csr_exprs[6]  # Repeat Counter. On MeP, it is the special register R6
 
 # Coprocesssor general-purpose registers (C0 to C15) names
 # Note: a processor extension allows up to 32 coprocessor general-purpose registers
-copro_gpr_names = ["C%d" % r for r in xrange(32)]  # register names
+copro_gpr_names = ["C%d" % r for r in range(32)]  # register names
 copro_gpr_exprs, copro_gpr_inits, copro_gpr_infos = gen_regs(copro_gpr_names, globals())
 
 
diff --git a/miasm2/arch/mep/sem.py b/miasm2/arch/mep/sem.py
index fb67becd..c346c535 100644
--- a/miasm2/arch/mep/sem.py
+++ b/miasm2/arch/mep/sem.py
@@ -929,15 +929,15 @@ def div(rn, rm):
     tmp_rm_inv = rm_inv if rm_inv else i32(1)
 
     # Results if only rn, or rm is negative
-    LO_rn_neg = (~(rn_inv / tmp_rm) + i32(1)) if sign_rn else (~(rn / tmp_rm_inv) + i32(1))
+    LO_rn_neg = (~(rn_inv // tmp_rm) + i32(1)) if sign_rn else (~(rn // tmp_rm_inv) + i32(1))
     HI_rn_neg = (~(rn_inv % tmp_rm) + i32(1)) if sign_rn else (~(rn % tmp_rm_inv) + i32(1))
 
     # Results if both numbers are positive
-    LO_pos = rn / tmp_rm if are_both_pos else LO_rn_neg
+    LO_pos = rn // tmp_rm if are_both_pos else LO_rn_neg
     HI_pos = rn % tmp_rm if are_both_pos else HI_rn_neg
 
     # Results if both numbers are negative
-    LO_neg = rn_inv / tmp_rm_inv if are_both_neg else LO_pos
+    LO_neg = rn_inv // tmp_rm_inv if are_both_neg else LO_pos
     HI_neg = rn_inv % tmp_rm_inv if are_both_neg else HI_pos
 
     # Results if rm is equal to zero
@@ -954,7 +954,7 @@ def divu(rn, rm):
     # LO <- Rn / Rm, HI <- Rn % Rm (Unsigned)
 
     tmp_rm = rm if rm else i32(1)  # used to delay the arithmetic computations
-    LO = rn / tmp_rm if rm else LO
+    LO = rn // tmp_rm if rm else LO
     HI = rn % tmp_rm if rm else HI
 
     exception_flags = i32(0) if rm else i32(EXCEPT_DIV_BY_ZERO)
diff --git a/miasm2/arch/mips32/arch.py b/miasm2/arch/mips32/arch.py
index 75a1aff0..6046b12c 100644
--- a/miasm2/arch/mips32/arch.py
+++ b/miasm2/arch/mips32/arch.py
@@ -42,7 +42,7 @@ deref_nooff = (LPARENTHESIS + gpregs.parser + RPARENTHESIS).setParseAction(cb_de
 deref = deref_off | deref_nooff
 
 
-class additional_info:
+class additional_info(object):
     def __init__(self):
         self.except_on_instr = False
 
@@ -200,7 +200,7 @@ class mn_mips32(cpu.cls_mn):
             return 0
         o = 0
         while n:
-            offset = start / 8
+            offset = start // 8
             n_offset = cls.endian_offset(attrib, offset)
             c = cls.getbytes(bitstream, n_offset, 1)
             if not c:
@@ -265,7 +265,7 @@ class mips32_arg(cpu.m_arg):
                 return arg.name
             if arg.name in gpregs.str:
                 return None
-            loc_key = loc_db.get_or_create_name_location(arg.name)
+            loc_key = loc_db.get_or_create_name_location(arg.name.encode())
             return ExprLoc(loc_key, 32)
         if isinstance(arg, AstOp):
             args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
diff --git a/miasm2/arch/mips32/jit.py b/miasm2/arch/mips32/jit.py
index 4abe0cd4..04690a3e 100644
--- a/miasm2/arch/mips32/jit.py
+++ b/miasm2/arch/mips32/jit.py
@@ -1,3 +1,4 @@
+from builtins import range
 import logging
 
 from miasm2.jitter.jitload import Jitter, named_arguments
@@ -109,7 +110,7 @@ class jitter_mips32l(Jitter):
 
     @named_arguments
     def func_args_stdcall(self, n_args):
-        args = [self.get_arg_n_stdcall(i) for i in xrange(n_args)]
+        args = [self.get_arg_n_stdcall(i) for i in range(n_args)]
         ret_ad = self.cpu.RA
         return ret_ad, args
 
@@ -122,9 +123,9 @@ class jitter_mips32l(Jitter):
         return True
 
     def func_prepare_stdcall(self, ret_addr, *args):
-        for index in xrange(min(len(args), 4)):
+        for index in range(min(len(args), 4)):
             setattr(self.cpu, 'A%d' % index, args[index])
-        for index in xrange(4, len(args)):
+        for index in range(4, len(args)):
             self.vm.set_mem(self.cpu.SP + 4 * (index - 4), pck32(args[index]))
         self.cpu.RA = ret_addr
 
diff --git a/miasm2/arch/mips32/regs.py b/miasm2/arch/mips32/regs.py
index ddaaff79..d1d14bdc 100644
--- a/miasm2/arch/mips32/regs.py
+++ b/miasm2/arch/mips32/regs.py
@@ -1,5 +1,6 @@
 #-*- coding:utf-8 -*-
 
+from builtins import range
 from miasm2.expression.expression import ExprId
 from miasm2.core.cpu import gen_reg, gen_regs
 
@@ -16,19 +17,19 @@ PC_init = ExprId("PC_init", 32)
 PC_FETCH_init = ExprId("PC_FETCH_init", 32)
 
 regs32_str = ["ZERO", 'AT', 'V0', 'V1'] +\
-    ['A%d'%i for i in xrange(4)] +\
-    ['T%d'%i for i in xrange(8)] +\
-    ['S%d'%i for i in xrange(8)] +\
-    ['T%d'%i for i in xrange(8, 10)] +\
+    ['A%d'%i for i in range(4)] +\
+    ['T%d'%i for i in range(8)] +\
+    ['S%d'%i for i in range(8)] +\
+    ['T%d'%i for i in range(8, 10)] +\
     ['K0', 'K1'] +\
     ['GP', 'SP', 'FP', 'RA']
 
 regs32_expr = [ExprId(x, 32) for x in regs32_str]
 ZERO = regs32_expr[0]
 
-regs_flt_str = ['F%d'%i for i in xrange(0x20)]
+regs_flt_str = ['F%d'%i for i in range(0x20)]
 
-regs_fcc_str = ['FCC%d'%i for i in xrange(8)]
+regs_fcc_str = ['FCC%d'%i for i in range(8)]
 
 R_LO = ExprId('R_LO', 32)
 R_HI = ExprId('R_HI', 32)
@@ -37,7 +38,7 @@ R_LO_init = ExprId('R_LO_init', 32)
 R_HI_init = ExprId('R_HI_init', 32)
 
 
-cpr0_str = ["CPR0_%d"%x for x in xrange(0x100)]
+cpr0_str = ["CPR0_%d"%x for x in range(0x100)]
 cpr0_str[0] = "INDEX"
 cpr0_str[16] = "ENTRYLO0"
 cpr0_str[24] = "ENTRYLO1"
diff --git a/miasm2/arch/msp430/arch.py b/miasm2/arch/msp430/arch.py
index f0db98f3..fd31f6c4 100644
--- a/miasm2/arch/msp430/arch.py
+++ b/miasm2/arch/msp430/arch.py
@@ -1,5 +1,7 @@
 #-*- coding:utf-8 -*-
 
+from builtins import range
+
 import logging
 from pyparsing import *
 from miasm2.expression.expression import *
@@ -69,7 +71,7 @@ class msp430_arg(m_arg):
                 index = gpregs.str.index(name)
                 reg = gpregs.expr[index]
                 return reg
-            loc_key = loc_db.get_or_create_name_location(value.name)
+            loc_key = loc_db.get_or_create_name_location(value.name.encode())
             return ExprLoc(loc_key, 16)
         if isinstance(value, AstOp):
             args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in value.args]
@@ -86,7 +88,7 @@ class msp430_arg(m_arg):
         return None
 
 
-class additional_info:
+class additional_info(object):
 
     def __init__(self):
         self.except_on_instr = False
@@ -238,7 +240,7 @@ class mn_msp430(cls_mn):
         if n > bs.getlen() * 8:
             raise ValueError('not enough bits %r %r' % (n, len(bs.bin) * 8))
         while n:
-            i = start / 8
+            i = start // 8
             c = cls.getbytes(bs, i)
             if not c:
                 raise IOError
@@ -255,8 +257,8 @@ class mn_msp430(cls_mn):
 
     @classmethod
     def getbytes(cls, bs, offset, l=1):
-        out = ""
-        for _ in xrange(l):
+        out = b""
+        for _ in range(l):
             n_offset = (offset & ~1) + 1 - offset % 2
             out += bs.getbytes(n_offset, 1)
             offset += 1
@@ -266,7 +268,7 @@ class mn_msp430(cls_mn):
         tmp = super(mn_msp430, self).decoded2bytes(result)
         out = []
         for x in tmp:
-            o = ""
+            o = b""
             while x:
                 o += x[:2][::-1]
                 x = x[2:]
@@ -524,7 +526,7 @@ class msp430_offs(imm_noarg, msp430_arg):
     def encodeval(self, v):
         plen = self.parent.l + self.l
         assert(plen % 8 == 0)
-        v -= plen / 8
+        v -= plen // 8
         if v % 2 != 0:
             return False
         return v >> 1
diff --git a/miasm2/arch/msp430/regs.py b/miasm2/arch/msp430/regs.py
index 11385779..a3e714b2 100644
--- a/miasm2/arch/msp430/regs.py
+++ b/miasm2/arch/msp430/regs.py
@@ -1,10 +1,11 @@
+from builtins import range
 from miasm2.expression.expression import *
 from miasm2.core.cpu import reg_info
 
 
 # GP
 
-regs16_str = ["PC", "SP", "SR"] + ["R%d" % i for i in xrange(3, 16)]
+regs16_str = ["PC", "SP", "SR"] + ["R%d" % i for i in range(3, 16)]
 regs16_expr = [ExprId(x, 16) for x in regs16_str]
 
 exception_flags = ExprId('exception_flags', 32)
diff --git a/miasm2/arch/msp430/sem.py b/miasm2/arch/msp430/sem.py
index e0110d24..b939c224 100644
--- a/miasm2/arch/msp430/sem.py
+++ b/miasm2/arch/msp430/sem.py
@@ -96,10 +96,10 @@ def mng_autoinc(a, b, size):
         return e, a, b
 
     a_r = a.args[0]
-    e.append(ExprAssign(a_r, a_r + ExprInt(size / 8, a_r.size)))
+    e.append(ExprAssign(a_r, a_r + ExprInt(size // 8, a_r.size)))
     a = ExprMem(a_r, size)
     if isinstance(b, ExprMem) and a_r in b.arg:
-        b = ExprMem(b.arg + ExprInt(size / 8, 16), b.size)
+        b = ExprMem(b.arg + ExprInt(size // 8, 16), b.size)
     return e, a, b
 
 # Mnemonics
diff --git a/miasm2/arch/ppc/arch.py b/miasm2/arch/ppc/arch.py
index 37acc1c5..e7661371 100644
--- a/miasm2/arch/ppc/arch.py
+++ b/miasm2/arch/ppc/arch.py
@@ -1,3 +1,4 @@
+from builtins import range
 
 import logging
 from pyparsing import *
@@ -40,7 +41,7 @@ class ppc_arg(m_arg):
                 return arg.name
             if arg.name in gpregs.str:
                 return None
-            loc_key = loc_db.get_or_create_name_location(arg.name)
+            loc_key = loc_db.get_or_create_name_location(arg.name.encode())
             return ExprLoc(loc_key, 32)
         if isinstance(arg, AstOp):
             args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
@@ -57,7 +58,7 @@ class ppc_arg(m_arg):
         return None
 
 
-class additional_info:
+class additional_info(object):
 
     def __init__(self):
         self.except_on_instr = False
@@ -227,7 +228,7 @@ class mn_ppc(cls_mn):
         if n > bs.getlen() * 8:
             raise ValueError('not enough bits %r %r' % (n, len(bs.bin) * 8))
         while n:
-            offset = start / 8
+            offset = start // 8
             n_offset = cls.endian_offset(attrib, offset)
             c = cls.getbytes(bs, n_offset, 1)
             if not c:
@@ -468,7 +469,7 @@ def ppc_bo_bi_to_mnemo(bo, bi, prefer_taken=True, default_taken=True):
 
 def ppc_all_bo_bi():
     for bo in [0, 2, 4, 8, 10, 12, 16, 18, 20]:
-        for bi in xrange(4):
+        for bi in range(4):
             yield bo, bi
 
 class ppc_divert_conditional_branch(bs_divert):
diff --git a/miasm2/arch/ppc/jit.py b/miasm2/arch/ppc/jit.py
index 14c203a9..8dc4aa99 100644
--- a/miasm2/arch/ppc/jit.py
+++ b/miasm2/arch/ppc/jit.py
@@ -1,3 +1,4 @@
+from builtins import range
 from miasm2.jitter.jitload import Jitter, named_arguments
 from miasm2.core.locationdb import LocationDB
 from miasm2.arch.ppc.sem import ir_ppc32b
@@ -34,7 +35,7 @@ class jitter_ppc32b(Jitter):
 
     @named_arguments
     def func_args_systemv(self, n_args):
-        args = [self.get_arg_n_systemv(i) for i in xrange(n_args)]
+        args = [self.get_arg_n_systemv(i) for i in range(n_args)]
         ret_ad = self.cpu.LR
         return ret_ad, args
 
@@ -47,9 +48,9 @@ class jitter_ppc32b(Jitter):
         return True
 
     def func_prepare_systemv(self, ret_addr, *args):
-        for index in xrange(min(len(args), self.max_reg_arg)):
+        for index in range(min(len(args), self.max_reg_arg)):
             setattr(self.cpu, 'R%d' % (index + 3), args[index])
-        for index in xrange(len(args) - 1, self.max_reg_arg - 1, -1):
+        for index in range(len(args) - 1, self.max_reg_arg - 1, -1):
             self.push_uint32_t(args[index])
 
         # reserve room for LR save word and backchain
diff --git a/miasm2/arch/ppc/regs.py b/miasm2/arch/ppc/regs.py
index 70b49f82..e70afce2 100644
--- a/miasm2/arch/ppc/regs.py
+++ b/miasm2/arch/ppc/regs.py
@@ -1,4 +1,5 @@
 
+from builtins import range
 from miasm2.expression.expression import *
 from miasm2.core.cpu import gen_reg, gen_regs
 
@@ -14,13 +15,13 @@ SPR_ACCESS_SPR_OFF  = 0
 SPR_ACCESS_GPR_MASK = 0x0001F000
 SPR_ACCESS_GPR_OFF  = 12
 
-gpregs_str = ["R%d" % i for i in xrange(32)]
+gpregs_str = ["R%d" % i for i in range(32)]
 gpregs_expr, gpregs_init, gpregs = gen_regs(gpregs_str, globals(), 32)
 
-crfregs_str = ["CR%d" % i for i in xrange(8)]
+crfregs_str = ["CR%d" % i for i in range(8)]
 crfregs_expr, crfregs_init, crfregs = gen_regs(crfregs_str, globals(), 4)
 
-crfbitregs_str = ["CR%d_%s" % (i, flag) for i in xrange(8)
+crfbitregs_str = ["CR%d_%s" % (i, flag) for i in range(8)
                   for flag in ['LT', 'GT', 'EQ', 'SO'] ]
 crfbitregs_expr, crfbitregs_init, crfbitregs = gen_regs(crfbitregs_str,
                                                         globals(), 1)
@@ -38,8 +39,8 @@ otherregs_str = ["PC", "CTR", "LR" ]
 otherregs_expr, otherregs_init, otherregs = gen_regs(otherregs_str,
                                                      globals(), 32)
 
-superregs_str = (["SPRG%d" % i for i in xrange(4)] +
-                 ["SRR%d" % i for i in xrange(2)] +
+superregs_str = (["SPRG%d" % i for i in range(4)] +
+                 ["SRR%d" % i for i in range(2)] +
                  ["DAR", "DSISR", "MSR", "PIR", "PVR",
                   "DEC", "TBL", "TBU"])
 superregs_expr, superregs_init, superregs = gen_regs(superregs_str,
diff --git a/miasm2/arch/ppc/sem.py b/miasm2/arch/ppc/sem.py
index 558450b2..ef44ffe3 100644
--- a/miasm2/arch/ppc/sem.py
+++ b/miasm2/arch/ppc/sem.py
@@ -1,3 +1,6 @@
+from __future__ import print_function
+from builtins import range
+
 import miasm2.expression.expression as expr
 from miasm2.ir.ir import AssignBlock, IntermediateRepresentation, IRBlock
 from miasm2.arch.ppc.arch import mn_ppc
@@ -15,7 +18,7 @@ spr_dict = {
 crf_dict = dict((ExprId("CR%d" % i, 4),
                  dict( (bit, ExprId("CR%d_%s" % (i, bit), 1))
                        for bit in ['LT', 'GT', 'EQ', 'SO' ] ))
-                for i in xrange(8) )
+                for i in range(8) )
 
 ctx = {
     'crf_dict': crf_dict,
@@ -112,7 +115,7 @@ def mn_do_cntlzw(ir, instr, ra, rs):
 
 def crbit_to_reg(bit):
     bit = bit.arg.arg
-    crid = bit / 4
+    crid = bit // 4
     bitname = [ 'LT', 'GT', 'EQ', 'SO' ][bit % 4]
     return all_regs_ids_byname["CR%d_%s" % (crid, bitname)]
 
@@ -217,8 +220,8 @@ def mn_do_exts(ir, instr, ra, rs):
     return ret, []
 
 def byte_swap(expr):
-    nbytes = expr.size / 8
-    bytes = [ expr[i*8:i*8+8] for i in xrange(nbytes - 1, -1, -1) ]
+    nbytes = expr.size // 8
+    bytes = [ expr[i*8:i*8+8] for i in range(nbytes - 1, -1, -1) ]
     return ExprCompose(bytes)
 
 def mn_do_load(ir, instr, arg1, arg2, arg3=None):
@@ -325,7 +328,7 @@ def mn_do_mcrxr(ir, instr, crfd):
 
 def mn_do_mfcr(ir, instr, rd):
     return ([ ExprAssign(rd, ExprCompose(*[ all_regs_ids_byname["CR%d_%s" % (i, b)]
-                                        for i in xrange(7, -1, -1)
+                                        for i in range(7, -1, -1)
                                         for b in ['SO', 'EQ', 'GT', 'LT']]))],
             [])
 
@@ -350,7 +353,7 @@ def mn_mfspr(ir, instr, arg1, arg2):
 def mn_mtcrf(ir, instr, crm, rs):
     ret = []
 
-    for i in xrange(8):
+    for i in range(8):
         if crm.arg.arg & (1 << (7 - i)):
             j = (28 - 4 * i) + 3
             for b in ['LT', 'GT', 'EQ', 'SO']:
@@ -361,7 +364,7 @@ def mn_mtcrf(ir, instr, crm, rs):
     return ret, []
 
 def mn_mtmsr(ir, instr, rs):
-    print "%08x: MSR assigned" % instr.offset
+    print("%08x: MSR assigned" % instr.offset)
     return [ ExprAssign(MSR, rs) ], []
 
 def mn_mtspr(ir, instr, arg1, arg2):
@@ -746,7 +749,7 @@ def mn_do_cond_branch(ir, instr, dest):
     return ret, []
 
 def mn_do_nop_warn(ir, instr, *args):
-    print "Warning, instruction %s implemented as NOP" % instr
+    print("Warning, instruction %s implemented as NOP" % instr)
     return [], []
 
 @sbuild.parse
diff --git a/miasm2/arch/sh4/arch.py b/miasm2/arch/sh4/arch.py
index 88d734a3..c7ff6ab0 100644
--- a/miasm2/arch/sh4/arch.py
+++ b/miasm2/arch/sh4/arch.py
@@ -1,5 +1,8 @@
 #-*- coding:utf-8 -*-
 
+from __future__ import print_function
+from builtins import range
+
 from pyparsing import *
 from miasm2.core.cpu import *
 from miasm2.expression.expression import *
@@ -102,7 +105,7 @@ class sh4_arg(m_arg):
                 return arg.name
             if arg.name in gpregs.str:
                 return None
-            loc_key = loc_db.get_or_create_name_location(arg.name)
+            loc_key = loc_db.get_or_create_name_location(arg.name.encode())
             return ExprLoc(loc_key, 32)
         if isinstance(arg, AstOp):
             args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
@@ -235,7 +238,7 @@ class sh4_dgpreg_imm(sh4_dgpreg):
         p = self.parent
         r = gpregs.expr[v]
         s = self.sz
-        d = ExprInt(p.disp.value * s / 8, 32)
+        d = ExprInt((p.disp.value * s) // 8, 32)
         e = ExprMem(r + d, s)
         self.expr = e
         return True
@@ -258,7 +261,7 @@ class sh4_dgpreg_imm(sh4_dgpreg):
             if not isinstance(res[jrb], ExprInt):
                 return False
             d = int(res[jrb])
-            p.disp.value = d / (s / 8)
+            p.disp.value = d // (s // 8)
             if not res[jra] in gpregs.expr:
                 return False
             v = gpregs.expr.index(res[jra])
@@ -301,7 +304,7 @@ class sh4_dpc16imm(sh4_dgpreg):
         return True
 
     def calcdisp(self, v):
-        v = (int(v) - 4) / 2
+        v = (int(v) - 4) // 2
         if not 0 < v <= 0xff:
             return None
         return v
@@ -324,7 +327,7 @@ class sh4_dgbrimm8(sh4_dgpreg):
 
     def decode(self, v):
         s = self.sz
-        self.expr = ExprMem(GBR + ExprInt(v * s / 8, 32), s)
+        self.expr = ExprMem(GBR + ExprInt((v * s) // 8, 32), s)
         return True
 
     def encode(self):
@@ -338,7 +341,7 @@ class sh4_dgbrimm8(sh4_dgpreg):
             return False
         if not isinstance(res[jra], ExprInt):
             return False
-        self.value = int(res[jra]) / (s / 8)
+        self.value = int(res[jra]) // (s // 8)
         return True
 
 
@@ -351,7 +354,7 @@ class sh4_dpc32imm(sh4_dpc16imm):
         return True
 
     def calcdisp(self, v):
-        v = (int(v) - 4) / 4
+        v = (int(v) - 4) // 4
         if not 0 < v <= 0xff:
             return None
         return v
@@ -383,13 +386,13 @@ class sh4_pc32imm(sh4_arg):
             return False
         if not isinstance(res[jra], ExprInt):
             return False
-        v = (int(res[jra]) - 4) / 4
+        v = (int(res[jra]) - 4) // 4
         if v is None:
             return False
         self.value = v
         return True
 
-class additional_info:
+class additional_info(object):
 
     def __init__(self):
         self.except_on_instr = False
@@ -423,8 +426,10 @@ class instruction_sh4(instruction):
             elif ptr.op == "postinc":
                 s = '%s+' % ptr.args[0]
             else:
-                s = ','.join([str(x).replace('(', '').replace(')', '')
-                              for x in ptr.args])
+                s = ','.join(
+                    str(x).replace('(', '').replace(')', '')
+                    for x in ptr.args
+                )
                 s = "(%s)"%s
             s = "@%s" % s
         elif isinstance(ptr, ExprId):
@@ -473,11 +478,11 @@ class instruction_sh4(instruction):
             log.debug('dyn dst %r', e)
             return
         off = e.arg - (self.offset + 4 + self.l)
-        print hex(off)
+        print(hex(off))
         if int(off % 4):
             raise ValueError('strange offset! %r' % off)
         self.args[0] = ExprInt(off, 32)
-        print 'final', self.args[0]
+        print('final', self.args[0])
 
     def get_args_expr(self):
         args = [a for a in self.args]
@@ -510,7 +515,7 @@ class mn_sh4(cls_mn):
         if n > bs.getlen() * 8:
             raise ValueError('not enough bits %r %r' % (n, len(bs.bin) * 8))
         while n:
-            i = start / 8
+            i = start // 8
             c = cls.getbytes(bs, i)
             if not c:
                 raise IOError
@@ -527,8 +532,8 @@ class mn_sh4(cls_mn):
 
     @classmethod
     def getbytes(cls, bs, offset, l=1):
-        out = ""
-        for _ in xrange(l):
+        out = b""
+        for _ in range(l):
             n_offset = (offset & ~1) + 1 - offset % 2
             out += bs.getbytes(n_offset, 1)
             offset += 1
diff --git a/miasm2/arch/sh4/regs.py b/miasm2/arch/sh4/regs.py
index 148e74ba..c294eb8c 100644
--- a/miasm2/arch/sh4/regs.py
+++ b/miasm2/arch/sh4/regs.py
@@ -1,20 +1,21 @@
+from builtins import range
 from miasm2.expression.expression import *
 from miasm2.core.cpu import reg_info, gen_reg
 
 # GP
-gpregs_str = ['R%d' % r for r in xrange(0x10)]
+gpregs_str = ['R%d' % r for r in range(0x10)]
 gpregs_expr = [ExprId(x, 32) for x in gpregs_str]
 gpregs = reg_info(gpregs_str, gpregs_expr)
 
-bgpregs_str = ['R%d_BANK' % r for r in xrange(0x8)]
+bgpregs_str = ['R%d_BANK' % r for r in range(0x8)]
 bgpregs_expr = [ExprId(x, 32) for x in bgpregs_str]
 bgpregs = reg_info(bgpregs_str, bgpregs_expr)
 
-fregs_str = ['FR%d' % r for r in xrange(0x10)]
+fregs_str = ['FR%d' % r for r in range(0x10)]
 fregs_expr = [ExprId(x, 32) for x in fregs_str]
 fregs = reg_info(fregs_str, fregs_expr)
 
-dregs_str = ['DR%d' % r for r in xrange(0x8)]
+dregs_str = ['DR%d' % r for r in range(0x8)]
 dregs_expr = [ExprId(x, 32) for x in dregs_str]
 dregs = reg_info(dregs_str, dregs_expr)
 
diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py
index b625647e..7a2c371c 100644
--- a/miasm2/arch/x86/arch.py
+++ b/miasm2/arch/x86/arch.py
@@ -1,6 +1,12 @@
 #-*- coding:utf-8 -*-
 
+from __future__ import print_function
+from builtins import range
 import re
+
+from future.utils import viewitems
+
+from miasm2.core.utils import int_to_byte
 from miasm2.expression.expression import *
 from pyparsing import *
 from miasm2.core.cpu import *
@@ -123,7 +129,7 @@ replace_regs = {16: replace_regs16,
 
 
 segm2enc = {CS: 1, SS: 2, DS: 3, ES: 4, FS: 5, GS: 6}
-enc2segm = dict([(x[1], x[0]) for x in segm2enc.items()])
+enc2segm = dict((value, key) for key, value in viewitems(segm2enc))
 
 segm_info = reg_info_dct(enc2segm)
 
@@ -215,7 +221,7 @@ XMMWORD = Literal('XMMWORD')
 MEMPREFIX2SIZE = {'BYTE': 8, 'WORD': 16, 'DWORD': 32,
                   'QWORD': 64, 'TBYTE': 80, 'XMMWORD': 128}
 
-SIZE2MEMPREFIX = dict((x[1], x[0]) for x in MEMPREFIX2SIZE.items())
+SIZE2MEMPREFIX = dict((value, key) for key, value in viewitems(MEMPREFIX2SIZE))
 
 def cb_deref_mem(tokens):
     if len(tokens) == 2:
@@ -272,7 +278,7 @@ class x86_arg(m_arg):
             if value.name in ["FAR"]:
                 return None
 
-            loc_key = loc_db.get_or_create_name_location(value.name)
+            loc_key = loc_db.get_or_create_name_location(value.name.encode())
             return ExprLoc(loc_key, size_hint)
         if isinstance(value, AstOp):
             # First pass to retrieve fixed_size
@@ -430,13 +436,13 @@ repeat_mn = ["INS", "OUTS",
              ]
 
 
-class group:
+class group(object):
 
     def __init__(self):
         self.value = None
 
 
-class additional_info:
+class additional_info(object):
 
     def __init__(self):
         self.except_on_instr = False
@@ -446,7 +452,7 @@ class additional_info:
         self.stk = False
         self.v_opmode = None
         self.v_admode = None
-        self.prefixed = ''
+        self.prefixed = b''
 
 
 class instruction_x86(instruction):
@@ -537,7 +543,7 @@ class instruction_x86(instruction):
         self.additional_info.v_opmode = c.v_opmode()
         self.additional_info.v_admode = c.v_admode()
         self.additional_info.prefix = c.prefix
-        self.additional_info.prefixed = getattr(c, "prefixed", "")
+        self.additional_info.prefixed = getattr(c, "prefixed", b"")
 
     def __str__(self):
         return self.to_string()
@@ -547,13 +553,13 @@ class instruction_x86(instruction):
         if self.additional_info.g1.value & 1:
             o = "LOCK %s" % o
         if self.additional_info.g1.value & 2:
-            if getattr(self.additional_info.prefixed, 'default', "") != "\xF2":
+            if getattr(self.additional_info.prefixed, 'default', b"") != b"\xF2":
                 o = "REPNE %s" % o
         if self.additional_info.g1.value & 8:
-            if getattr(self.additional_info.prefixed, 'default', "") != "\xF3":
+            if getattr(self.additional_info.prefixed, 'default', b"") != b"\xF3":
                 o = "REP %s" % o
         elif self.additional_info.g1.value & 4:
-            if getattr(self.additional_info.prefixed, 'default', "") != "\xF3":
+            if getattr(self.additional_info.prefixed, 'default', b"") != b"\xF3":
                 o = "REPE %s" % o
         return o
 
@@ -650,7 +656,7 @@ class mn_x86(cls_mn):
         info.g2.value = self.g2.value
         info.stk = hasattr(self, 'stk')
         info.v_opmode = self.v_opmode()
-        info.prefixed = ""
+        info.prefixed = b""
         if hasattr(self, 'prefixed'):
             info.prefixed = self.prefixed.default
         return info
@@ -705,40 +711,40 @@ class mn_x86(cls_mn):
                         'rex_r': 0,
                         'rex_x': 0,
                         'rex_b': 0,
-                        'prefix': "",
-                        'prefixed': "",
+                        'prefix': b"",
+                        'prefixed': b"",
                         }
         while True:
             c = v.getbytes(offset)
-            if c == '\x66':
+            if c == b'\x66':
                 pre_dis_info['opmode'] = 1
-            elif c == '\x67':
+            elif c == b'\x67':
                 pre_dis_info['admode'] = 1
-            elif c == '\xf0':
+            elif c == b'\xf0':
                 pre_dis_info['g1'] = 1
-            elif c == '\xf2':
+            elif c == b'\xf2':
                 pre_dis_info['g1'] = 2
-            elif c == '\xf3':
+            elif c == b'\xf3':
                 pre_dis_info['g1'] = 12
 
-            elif c == '\x2e':
+            elif c == b'\x2e':
                 pre_dis_info['g2'] = 1
-            elif c == '\x36':
+            elif c == b'\x36':
                 pre_dis_info['g2'] = 2
-            elif c == '\x3e':
+            elif c == b'\x3e':
                 pre_dis_info['g2'] = 3
-            elif c == '\x26':
+            elif c == b'\x26':
                 pre_dis_info['g2'] = 4
-            elif c == '\x64':
+            elif c == b'\x64':
                 pre_dis_info['g2'] = 5
-            elif c == '\x65':
+            elif c == b'\x65':
                 pre_dis_info['g2'] = 6
 
             else:
                 break
             pre_dis_info['prefix'] += c
             offset += 1
-        if mode == 64 and c in '@ABCDEFGHIJKLMNO':
+        if mode == 64 and c in b'@ABCDEFGHIJKLMNO':
             x = ord(c)
             pre_dis_info['rex_p'] = 1
             pre_dis_info['rex_w'] = (x >> 3) & 1
@@ -746,7 +752,7 @@ class mn_x86(cls_mn):
             pre_dis_info['rex_x'] = (x >> 1) & 1
             pre_dis_info['rex_b'] = (x >> 0) & 1
             offset += 1
-        elif pre_dis_info.get('g1', None) == 12 and c in ['\xa6', '\xa7', '\xae', '\xaf']:
+        elif pre_dis_info.get('g1', None) == 12 and c in [b'\xa6', b'\xa7', b'\xae', b'\xaf']:
             pre_dis_info['g1'] = 4
         return pre_dis_info, v, mode, offset, offset - offset_o
 
@@ -793,14 +799,14 @@ class mn_x86(cls_mn):
     def add_pre_dis_info(self, pre_dis_info=None):
         if pre_dis_info is None:
             return True
-        if hasattr(self, "prefixed") and self.prefixed.default == "\x66":
+        if hasattr(self, "prefixed") and self.prefixed.default == b"\x66":
             pre_dis_info['opmode'] = 0
         self.opmode = pre_dis_info['opmode']
         self.admode = pre_dis_info['admode']
 
         if hasattr(self, 'no_xmm_pref') and\
                 pre_dis_info['prefix'] and\
-                pre_dis_info['prefix'][-1] in '\x66\xf2\xf3':
+                pre_dis_info['prefix'][-1] in b'\x66\xf2\xf3':
             return False
         if (hasattr(self, "prefixed") and
             not pre_dis_info['prefix'].endswith(self.prefixed.default)):
@@ -831,7 +837,7 @@ class mn_x86(cls_mn):
 
 
     def gen_prefix(self):
-        v = ""
+        v = b""
         rex = 0x40
         if self.g1.value is None:
             self.g1.value = 0
@@ -847,36 +853,40 @@ class mn_x86(cls_mn):
         if self.rex_b.value:
             rex |= 0x1
         if rex != 0x40 or self.rex_p.value == 1:
-            v = chr(rex) + v
+            v = int_to_byte(rex) + v
             if hasattr(self, 'no_rex'):
                 return None
 
-
-
         if hasattr(self, 'prefixed'):
             v = self.prefixed.default + v
 
         if self.g1.value & 1:
-            v = "\xf0" + v
+            v = b"\xf0" + v
         if self.g1.value & 2:
             if hasattr(self, 'no_xmm_pref'):
                 return None
-            v = "\xf2" + v
+            v = b"\xf2" + v
         if self.g1.value & 12:
             if hasattr(self, 'no_xmm_pref'):
                 return None
-            v = "\xf3" + v
+            v = b"\xf3" + v
         if self.g2.value:
-            v = {1: '\x2e', 2: '\x36', 3: '\x3e', 4:
-                 '\x26', 5: '\x64', 6: '\x65'}[self.g2.value] + v
+            v = {
+                1: b'\x2e',
+                2: b'\x36',
+                3: b'\x3e',
+                4: b'\x26',
+                5: b'\x64',
+                6: b'\x65'
+            }[self.g2.value] + v
         # mode prefix
         if hasattr(self, "admode") and self.admode:
-            v = "\x67" + v
+            v = b"\x67" + v
 
         if hasattr(self, "opmode") and self.opmode:
             if hasattr(self, 'no_xmm_pref'):
                 return None
-            v = "\x66" + v
+            v = b"\x66" + v
         return v
 
     def encodefields(self, decoded):
@@ -1436,25 +1446,25 @@ def gen_modrm_form():
     sib_u32 = [{f_isad: True} for i in range(0x100)]
 
     sib_u64 = []
-    for rex_x in xrange(2):
+    for rex_x in range(2):
         o = []
-        for rex_b in xrange(2):
+        for rex_b in range(2):
             x = [{f_isad: True} for i in range(0x100)]
             o.append(x)
         sib_u64.append(o)
 
     sib_u64_ebp = []
-    for rex_x in xrange(2):
+    for rex_x in range(2):
         o = []
-        for rex_b in xrange(2):
+        for rex_b in range(2):
             x = [{f_isad: True} for i in range(0x100)]
             o.append(x)
         sib_u64_ebp.append(o)
 
     sib_64_s08_ebp = []
-    for rex_x in xrange(2):
+    for rex_x in range(2):
         o = []
-        for rex_b in xrange(2):
+        for rex_b in range(2):
             x = [{f_isad: True} for i in range(0x100)]
             o.append(x)
         sib_64_s08_ebp.append(o)
@@ -1479,17 +1489,17 @@ def gen_modrm_form():
                 elif sib_rez == sib_u32:
                     sib_rez[index][f_imm] = f_u32
                 elif sib_rez == sib_u64_ebp:
-                    for rex_b in xrange(2):
-                        for rex_x in xrange(2):
+                    for rex_b in range(2):
+                        for rex_x in range(2):
                             sib_rez[rex_x][rex_b][index][f_imm] = f_u32
                             sib_rez[rex_x][rex_b][index][ebp + 8 * rex_b] = 1
                 elif sib_rez == sib_u64:
-                    for rex_b in xrange(2):
-                        for rex_x in xrange(2):
+                    for rex_b in range(2):
+                        for rex_x in range(2):
                             sib_rez[rex_x][rex_b][index][f_imm] = f_u32
                 elif sib_rez == sib_64_s08_ebp:
-                    for rex_b in xrange(2):
-                        for rex_x in xrange(2):
+                    for rex_b in range(2):
+                        for rex_x in range(2):
                             sib_rez[rex_x][rex_b][index][f_imm] = f_s08
                             sib_rez[rex_x][rex_b][index][ebp + 8 * rex_b] = 1
 
@@ -1503,17 +1513,17 @@ def gen_modrm_form():
                 elif sib_rez == sib_u32:
                     sib_rez[index][b] = 1
                 elif sib_rez == sib_u64_ebp:
-                    for rex_b in xrange(2):
-                        for rex_x in xrange(2):
+                    for rex_b in range(2):
+                        for rex_x in range(2):
                             sib_rez[rex_x][rex_b][index][b + 8 * rex_b] = 1
                             sib_rez[rex_x][rex_b][index][f_imm] = f_u32
                 elif sib_rez == sib_u64:
-                    for rex_b in xrange(2):
-                        for rex_x in xrange(2):
+                    for rex_b in range(2):
+                        for rex_x in range(2):
                             sib_rez[rex_x][rex_b][index][b + 8 * rex_b] = 1
                 elif sib_rez == sib_64_s08_ebp:
-                    for rex_b in xrange(2):
-                        for rex_x in xrange(2):
+                    for rex_b in range(2):
+                        for rex_x in range(2):
                             sib_rez[rex_x][rex_b][index][f_imm] = f_s08
                             sib_rez[rex_x][rex_b][index][b + 8 * rex_b] = 1
 
@@ -1526,8 +1536,8 @@ def gen_modrm_form():
                     sib_rez[index][tmp] = 0  # 1 << ss
                 sib_rez[index][tmp] += 1 << ss
             else:
-                for rex_b in xrange(2):
-                    for rex_x in xrange(2):
+                for rex_b in range(2):
+                    for rex_x in range(2):
                         tmp = i + 8 * rex_x
                         if i == 0b100 and rex_x == 0:
                             continue
@@ -1649,18 +1659,16 @@ def gen_modrm_form():
                   32: defaultdict(list),
                   64: defaultdict(list),
                   }
-    for size, db_afs in byte2modrm.items():
+    for size, db_afs in viewitems(byte2modrm):
         for i, modrm in enumerate(db_afs):
             if not isinstance(modrm, list):
-                modrm = modrm.items()
-                modrm.sort()
-                modrm = tuple(modrm)
+                # We only need sort for determinism
+                modrm = tuple(sorted(viewitems(modrm), key=str))
                 modrm2byte[size][modrm].append(i)
                 continue
             for j, modrm_f in enumerate(modrm):
-                modrm_f = modrm_f.items()
-                modrm_f.sort()
-                modrm_f = tuple(modrm_f)
+                # We only need sort for determinism
+                modrm_f = tuple(sorted(viewitems(modrm_f), key=str))
                 modrm2byte[size][modrm_f].append((i, j))
 
     return byte2modrm, modrm2byte
@@ -1870,7 +1878,7 @@ def expr2modrm(expr, parent, w8, sx=0, xmm=0, mm=0, bnd=0):
 def modrm2expr(modrm, parent, w8, sx=0, xmm=0, mm=0, bnd=0):
     o = []
     if not modrm[f_isad]:
-        modrm_k = [x[0] for x in modrm.iteritems() if x[1] == 1]
+        modrm_k = [key for key, value in viewitems(modrm) if value == 1]
         if len(modrm_k) != 1:
             raise ValueError('strange reg encoding %r' % modrm)
         modrm_k = modrm_k[0]
@@ -1895,8 +1903,8 @@ def modrm2expr(modrm, parent, w8, sx=0, xmm=0, mm=0, bnd=0):
         return expr
     admode = parent.v_admode()
     opmode = parent.v_opmode()
-    for modrm_k, scale in modrm.items():
-        if isinstance(modrm_k, (int, long)):
+    for modrm_k, scale in viewitems(modrm):
+        if isinstance(modrm_k, int):
             expr = size2gpregs[admode].expr[modrm_k]
             if scale != 1:
                 expr = ExprInt(scale, admode) * expr
@@ -1965,9 +1973,9 @@ class x86_rm_arg(x86_arg):
     def gen_cand(self, v_cand, admode):
         if not admode in modrm2byte:
             # XXX TODO: 64bit
-            raise StopIteration
+            return
         if not v_cand:
-            raise StopIteration
+            return
 
         p = self.parent
         o_rex_x = p.rex_x.value
@@ -1995,9 +2003,8 @@ class x86_rm_arg(x86_arg):
 
                 v[f_imm] = size
             vo = v
-            v = v.items()
-            v.sort()
-            v = tuple(v)
+            # We only need sort for determinism
+            v = tuple(sorted(viewitems(v), key=str))
             admode = 64 if p.mode == 64 else admode
             if not v in modrm2byte[admode]:
                 continue
@@ -2047,11 +2054,11 @@ class x86_rm_arg(x86_arg):
 
                 yield True
 
-        raise StopIteration
+        return
 
     def encode(self):
         if isinstance(self.expr, ExprInt):
-            raise StopIteration
+            return
         p = self.parent
         admode = p.v_admode()
         mode = self.expr.size
@@ -2091,11 +2098,11 @@ class x86_rm_mem_far(x86_rm_arg):
     def encode(self):
         if not (isinstance(self.expr, m2_expr.ExprOp) and
                 self.expr.op == 'far'):
-            raise StopIteration
+            return
 
         expr = self.expr.args[0]
         if isinstance(expr, ExprInt):
-            raise StopIteration
+            return
         p = self.parent
         admode = p.v_admode()
         mode = expr.size
@@ -2115,7 +2122,7 @@ class x86_rm_w8(x86_rm_arg):
 
     def encode(self):
         if isinstance(self.expr, ExprInt):
-            raise StopIteration
+            return
         p = self.parent
         if p.w8.value is None:
             if self.expr.size == 8:
@@ -2140,7 +2147,7 @@ class x86_rm_sx(x86_rm_arg):
 
     def encode(self):
         if isinstance(self.expr, ExprInt):
-            raise StopIteration
+            return
         p = self.parent
         if p.w8.value is None:
             if self.expr.size == 8:
@@ -2164,7 +2171,7 @@ class x86_rm_sxd(x86_rm_arg):
 
     def encode(self):
         if isinstance(self.expr, ExprInt):
-            raise StopIteration
+            return
         p = self.parent
         v_cand, segm, ok = expr2modrm(self.expr, p, 1, 2)
         if segm:
@@ -2195,10 +2202,10 @@ class x86_rm_sd(x86_rm_arg):
 
     def encode(self):
         if isinstance(self.expr, ExprInt):
-            raise StopIteration
+            return
         p = self.parent
         if not self.expr.size in [32, 64]:
-            raise StopIteration
+            return
         self.set_s_value(0)
         v_cand, segm, ok = expr2modrm(self.expr, p, 1)
         for x in self.gen_cand(v_cand, p.v_admode()):
@@ -2214,7 +2221,7 @@ class x86_rm_wd(x86_rm_sd):
 
     def encode(self):
         if isinstance(self.expr, ExprInt):
-            raise StopIteration
+            return
         p = self.parent
         p.wd.value = 0
         v_cand, segm, ok = expr2modrm(self.expr, p, 1)
@@ -2237,7 +2244,7 @@ class x86_rm_08(x86_rm_arg):
 
     def encode(self):
         if isinstance(self.expr, ExprInt):
-            raise StopIteration
+            return
         p = self.parent
         v_cand, segm, ok = expr2modrm(self.expr, p, 0, 0, 0, 0)
         for x in self.gen_cand(v_cand, p.v_admode()):
@@ -2257,7 +2264,7 @@ class x86_rm_reg_m08(x86_rm_arg):
 
     def encode(self):
         if isinstance(self.expr, ExprInt):
-            raise StopIteration
+            return
         p = self.parent
         if isinstance(self.expr, ExprMem):
             expr = ExprMem(self.expr.ptr, 32)
@@ -2284,7 +2291,7 @@ class x86_rm_m64(x86_rm_arg):
 
     def encode(self):
         if isinstance(self.expr, ExprInt):
-            raise StopIteration
+            return
         p = self.parent
         v_cand, segm, ok = expr2modrm(self.expr, p, 0, 0, 0, 1)
         for x in self.gen_cand(v_cand, p.v_admode()):
@@ -2296,9 +2303,9 @@ class x86_rm_m80(x86_rm_m64):
 
     def encode(self):
         if isinstance(self.expr, ExprInt):
-            raise StopIteration
+            return
         if not isinstance(self.expr, ExprMem) or self.expr.size != self.msize:
-            raise StopIteration
+            return
         p = self.parent
         mode = p.mode
         if mode == 64:
@@ -2320,7 +2327,7 @@ class x86_rm_m08(x86_rm_arg):
 
     def encode(self):
         if self.expr.size != 8:
-            raise StopIteration
+            return
         p = self.parent
         mode = p.mode
         v_cand, segm, ok = expr2modrm(self.expr, p, 0)
@@ -2354,9 +2361,9 @@ class x86_rm_mm(x86_rm_m80):
     def encode(self):
         expr = self.expr
         if isinstance(expr, ExprInt):
-            raise StopIteration
+            return
         if isinstance(expr, ExprMem) and expr.size != self.msize:
-            raise StopIteration
+            return
         p = self.parent
         mode = p.mode
         if mode == 64:
@@ -2458,7 +2465,7 @@ class x86_rm_reg_noarg(object):
                 self.parent.w8.value = 0
             return start, stop
         try:
-            result, start, stop = self.parser.scanString(text).next()
+            result, start, stop = next(self.parser.scanString(text))
         except StopIteration:
             return None, None
         expr = self.asm_ast_to_expr(result[0], loc_db)
@@ -2753,7 +2760,7 @@ class bs_cond_imm(bs_cond_scale, x86_arg):
             expr, start, stop = parser_result[self.parser]
         else:
             try:
-                expr, start, stop = self.parser.scanString(text).next()
+                expr, start, stop = next(self.parser.scanString(text))
             except StopIteration:
                 expr = None
         self.expr = expr
@@ -2788,7 +2795,7 @@ class bs_cond_imm(bs_cond_scale, x86_arg):
 
     def encode(self):
         if not isinstance(self.expr, ExprInt):
-            raise StopIteration
+            return
         arg0_expr = self.parent.args[0].expr
         self.parent.rex_w.value = 0
         # special case for push
@@ -2800,10 +2807,10 @@ class bs_cond_imm(bs_cond_scale, x86_arg):
             self.l = l
             mask = ((1 << self.l) - 1)
             if v != sign_ext(v & mask, self.l, l):
-                raise StopIteration
+                return
             self.value = swap_uint(self.l, v & ((1 << self.l) - 1))
             yield True
-            raise StopIteration
+            return
 
         # assume 2 args; use first arg to guess op size
         if arg0_expr.size == 64:
@@ -2813,7 +2820,7 @@ class bs_cond_imm(bs_cond_scale, x86_arg):
         v = int(self.expr)
         if arg0_expr.size == 8:
             if not hasattr(self.parent, 'w8'):
-                raise StopIteration
+                return
             self.parent.w8.value = 0
             l = 8
             if hasattr(self.parent, 'se'):
@@ -2838,7 +2845,7 @@ class bs_cond_imm(bs_cond_scale, x86_arg):
 
         mask = ((1 << self.l) - 1)
         if v != sign_ext(v & mask, self.l, l):
-            raise StopIteration
+            return
         self.value = swap_uint(self.l, v & ((1 << self.l) - 1))
         yield True
 
@@ -2880,7 +2887,7 @@ class bs_rel_off(bs_cond_imm):
             expr, start, stop = parser_result[self.parser]
         else:
             try:
-                expr, start, stop = self.parser.scanString(text).next()
+                expr, start, stop = next(self.parser.scanString(text))
             except StopIteration:
                 expr = None
         self.expr = expr
@@ -2901,7 +2908,7 @@ class bs_rel_off(bs_cond_imm):
 
     def encode(self):
         if not isinstance(self.expr, ExprInt):
-            raise StopIteration
+            return
         arg0_expr = self.parent.args[0].expr
         if self.l == 0:
             l = self.parent.v_opmode()
@@ -2911,14 +2918,14 @@ class bs_rel_off(bs_cond_imm):
         parent_len = len(prefix) * 8 + self.parent.l + self.l
         assert(parent_len % 8 == 0)
 
-        v = int(self.expr.arg - parent_len/8)
+        v = int(self.expr.arg) - parent_len // 8
         if prefix is None:
-            raise StopIteration
+            return
         mask = ((1 << self.l) - 1)
         if self.l > l:
-            raise StopIteration
+            return
         if v != sign_ext(v & mask, self.l, l):
-            raise StopIteration
+            return
         self.value = swap_uint(self.l, v & ((1 << self.l) - 1))
         yield True
 
@@ -2939,7 +2946,7 @@ class bs_s08(bs_rel_off):
 
     def encode(self):
         if not isinstance(self.expr, ExprInt):
-            raise StopIteration
+            return
         arg0_expr = self.parent.args[0].expr
         if self.l != 0:
             l = self.l
@@ -2950,9 +2957,9 @@ class bs_s08(bs_rel_off):
         v = int(self.expr)
         mask = ((1 << self.l) - 1)
         if self.l > l:
-            raise StopIteration
+            return
         if v != sign_ext(v & mask, self.l, l):
-            raise StopIteration
+            return
         self.value = swap_uint(self.l, v & ((1 << self.l) - 1))
         yield True
 
@@ -2983,12 +2990,12 @@ class bs_moff(bsi):
 
     def encode(self):
         if not hasattr(self.parent, "mseg"):
-            raise StopIteration
+            return
         m = self.parent.mseg.expr
         if not (isinstance(m, ExprOp) and m.op == 'segm'):
-            raise StopIteration
+            return
         if not isinstance(m.args[1], ExprInt):
-            raise StopIteration
+            return
         l = self.parent.v_opmode()
         if l == 16:
             self.l = 16
@@ -2997,7 +3004,7 @@ class bs_moff(bsi):
         v = int(m.args[1])
         mask = ((1 << self.l) - 1)
         if v != sign_ext(v & mask, self.l, l):
-            raise StopIteration
+            return
         self.value = swap_uint(self.l, v & ((1 << self.l) - 1))
         yield True
 
@@ -3027,7 +3034,7 @@ class bs_movoff(x86_arg):
                 return None, None
             return start, stop
         try:
-            v, start, stop = self.parser.scanString(text).next()
+            v, start, stop = next(self.parser.scanString(text))
         except StopIteration:
             return None, None
         if not isinstance(e, ExprMem):
@@ -3051,12 +3058,12 @@ class bs_movoff(x86_arg):
     def encode(self):
         p = self.parent
         if not isinstance(self.expr, ExprMem) or not isinstance(self.expr.ptr, ExprInt):
-            raise StopIteration
+            return
         self.l = p.v_admode()
         v = int(self.expr.ptr)
         mask = ((1 << self.l) - 1)
         if v != mask & v:
-            raise StopIteration
+            return
         self.value = swap_uint(self.l, v & ((1 << self.l) - 1))
         yield True
 
@@ -3092,7 +3099,7 @@ class bs_msegoff(x86_arg):
                 return None, None
             return start, stop
         try:
-            v, start, stop = self.parser.scanString(text).next()
+            v, start, stop = next(self.parser.scanString(text))
         except StopIteration:
             return None, None
         self.expr = v[0]
@@ -3103,16 +3110,16 @@ class bs_msegoff(x86_arg):
 
     def encode(self):
         if not (isinstance(self.expr, ExprOp) and self.expr.op == 'segm'):
-            raise StopIteration
+            return
         if not isinstance(self.expr.args[0], ExprInt):
-            raise StopIteration
+            return
         if not isinstance(self.expr.args[1], ExprInt):
-            raise StopIteration
+            return
         l = self.parent.v_opmode()
         v = int(self.expr.args[0])
         mask = ((1 << self.l) - 1)
         if v != sign_ext(v & mask, self.l, l):
-            raise StopIteration
+            return
         self.value = swap_uint(self.l, v & ((1 << self.l) - 1))
         yield True
 
@@ -3148,9 +3155,9 @@ sxd = bs(l=0, fname="sx")
 xmmreg = bs(l=0, fname="xmmreg")
 mmreg = bs(l=0, fname="mmreg")
 
-pref_f2 = bs(l=0, fname="prefixed", default="\xf2")
-pref_f3 = bs(l=0, fname="prefixed", default="\xf3")
-pref_66 = bs(l=0, fname="prefixed", default="\x66")
+pref_f2 = bs(l=0, fname="prefixed", default=b"\xf2")
+pref_f3 = bs(l=0, fname="prefixed", default=b"\xf3")
+pref_66 = bs(l=0, fname="prefixed", default=b"\x66")
 no_xmm_pref = bs(l=0, fname="no_xmm_pref")
 
 no_rex = bs(l=0, fname="no_rex")
@@ -3186,7 +3193,7 @@ wd = bs(l=1, fname="wd")
 stk = bs(l=0, fname="stk")
 
 
-class field_size:
+class field_size(object):
     prio = default_prio
 
     def __init__(self, d=None):
@@ -3287,7 +3294,7 @@ rm_arg_bnd_m128 = bs(l=0, cls=(x86_rm_bnd_m128,), fname='rmarg')
 rm_arg_bnd_reg = bs(l=0, cls=(x86_rm_bnd_reg,), fname='rmarg')
 
 
-swapargs = bs_swapargs(l=1, fname="swap", mn_mod=range(1 << 1))
+swapargs = bs_swapargs(l=1, fname="swap", mn_mod=list(range(1 << 1)))
 
 
 class bs_op_mode(bsi):
@@ -4626,5 +4633,5 @@ mod reg r/m
 
 
 def print_size(e):
-    print e, e.size
+    print(e, e.size)
     return e
diff --git a/miasm2/arch/x86/jit.py b/miasm2/arch/x86/jit.py
index f0a9875e..14418902 100644
--- a/miasm2/arch/x86/jit.py
+++ b/miasm2/arch/x86/jit.py
@@ -1,3 +1,4 @@
+from builtins import range
 import logging
 
 from miasm2.jitter.jitload import Jitter, named_arguments
@@ -53,12 +54,12 @@ class jitter_x86_16(Jitter):
         return self.orig_irbloc_fix_regs_for_mode(irblock, 64)
 
     def push_uint16_t(self, value):
-        self.cpu.SP -= self.ir_arch.sp.size / 8
+        self.cpu.SP -= self.ir_arch.sp.size // 8
         self.vm.set_u16(self.cpu.SP, value)
 
     def pop_uint16_t(self):
         value = self.vm.get_u16(self.cpu.SP)
-        self.cpu.SP += self.ir_arch.sp.size / 8
+        self.cpu.SP += self.ir_arch.sp.size // 8
         return value
 
     def get_stack_arg(self, index):
@@ -86,21 +87,21 @@ class jitter_x86_32(Jitter):
         return self.orig_irbloc_fix_regs_for_mode(irblock, 64)
 
     def push_uint16_t(self, value):
-        self.cpu.ESP -= self.ir_arch.sp.size / 8
+        self.cpu.ESP -= self.ir_arch.sp.size // 8
         self.vm.set_u16(self.cpu.ESP, value)
 
     def pop_uint16_t(self):
         value = self.vm.get_u16(self.cpu.ESP)
-        self.cpu.ESP += self.ir_arch.sp.size / 8
+        self.cpu.ESP += self.ir_arch.sp.size // 8
         return value
 
     def push_uint32_t(self, value):
-        self.cpu.ESP -= self.ir_arch.sp.size / 8
+        self.cpu.ESP -= self.ir_arch.sp.size // 8
         self.vm.set_u32(self.cpu.ESP, value)
 
     def pop_uint32_t(self):
         value = self.vm.get_u32(self.cpu.ESP)
-        self.cpu.ESP += self.ir_arch.sp.size / 8
+        self.cpu.ESP += self.ir_arch.sp.size // 8
         return value
 
     def get_stack_arg(self, index):
@@ -116,7 +117,7 @@ class jitter_x86_32(Jitter):
     @named_arguments
     def func_args_stdcall(self, n_args):
         ret_ad = self.pop_uint32_t()
-        args = [self.pop_uint32_t() for _ in xrange(n_args)]
+        args = [self.pop_uint32_t() for _ in range(n_args)]
         return ret_ad, args
 
     def func_ret_stdcall(self, ret_addr, ret_value1=None, ret_value2=None):
@@ -137,7 +138,7 @@ class jitter_x86_32(Jitter):
     @named_arguments
     def func_args_cdecl(self, n_args):
         ret_ad = self.pop_uint32_t()
-        args = [self.get_stack_arg(i) for i in xrange(n_args)]
+        args = [self.get_stack_arg(i) for i in range(n_args)]
         return ret_ad, args
 
     def func_ret_cdecl(self, ret_addr, ret_value1=None, ret_value2=None):
@@ -162,13 +163,13 @@ class jitter_x86_32(Jitter):
         args_regs = ['ECX', 'EDX']
         ret_ad = self.pop_uint32_t()
         args = []
-        for i in xrange(n_args):
+        for i in range(n_args):
             args.append(self.get_arg_n_fastcall(i))
         return ret_ad, args
 
     def func_prepare_fastcall(self, ret_addr, *args):
         args_regs = ['ECX', 'EDX']
-        for i in xrange(min(len(args), len(args_regs))):
+        for i in range(min(len(args), len(args_regs))):
             setattr(self.cpu, args_regs[i], args[i])
         remaining_args = args[len(args_regs):]
         for arg in reversed(remaining_args):
@@ -202,12 +203,12 @@ class jitter_x86_64(Jitter):
         return self.orig_irbloc_fix_regs_for_mode(irblock, 64)
 
     def push_uint64_t(self, value):
-        self.cpu.RSP -= self.ir_arch.sp.size / 8
+        self.cpu.RSP -= self.ir_arch.sp.size // 8
         self.vm.set_u64(self.cpu.RSP, value)
 
     def pop_uint64_t(self):
         value = self.vm.get_u64(self.cpu.RSP)
-        self.cpu.RSP += self.ir_arch.sp.size / 8
+        self.cpu.RSP += self.ir_arch.sp.size // 8
         return value
 
     def get_stack_arg(self, index):
@@ -225,15 +226,15 @@ class jitter_x86_64(Jitter):
         args_regs = self.args_regs_stdcall
         ret_ad = self.pop_uint64_t()
         args = []
-        for i in xrange(min(n_args, 4)):
+        for i in range(min(n_args, 4)):
             args.append(self.cpu.get_gpreg()[args_regs[i]])
-        for i in xrange(max(0, n_args - 4)):
+        for i in range(max(0, n_args - 4)):
             args.append(self.get_stack_arg(i))
         return ret_ad, args
 
     def func_prepare_stdcall(self, ret_addr, *args):
         args_regs = self.args_regs_stdcall
-        for i in xrange(min(len(args), len(args_regs))):
+        for i in range(min(len(args), len(args_regs))):
             setattr(self.cpu, args_regs[i], args[i])
         remaining_args = args[len(args_regs):]
         for arg in reversed(remaining_args):
@@ -262,7 +263,7 @@ class jitter_x86_64(Jitter):
     @named_arguments
     def func_args_systemv(self, n_args):
         ret_ad = self.pop_uint64_t()
-        args = [self.get_arg_n_systemv(index) for index in xrange(n_args)]
+        args = [self.get_arg_n_systemv(index) for index in range(n_args)]
         return ret_ad, args
 
     func_ret_systemv = func_ret_cdecl
@@ -270,7 +271,7 @@ class jitter_x86_64(Jitter):
     def func_prepare_systemv(self, ret_addr, *args):
         args_regs = self.args_regs_systemv
         self.push_uint64_t(ret_addr)
-        for i in xrange(min(len(args), len(args_regs))):
+        for i in range(min(len(args), len(args_regs))):
             setattr(self.cpu, args_regs[i], args[i])
         remaining_args = args[len(args_regs):]
         for arg in reversed(remaining_args):
diff --git a/miasm2/arch/x86/regs.py b/miasm2/arch/x86/regs.py
index ef1095e2..b3f6534b 100644
--- a/miasm2/arch/x86/regs.py
+++ b/miasm2/arch/x86/regs.py
@@ -1,3 +1,4 @@
+from builtins import range
 from miasm2.expression.expression import ExprId
 from miasm2.core.cpu import reg_info
 
@@ -12,20 +13,20 @@ interrupt_num = ExprId('interrupt_num', 8)
 
 
 regs08_str = ["AL", "CL", "DL", "BL", "AH", "CH", "DH", "BH"] + \
-    ["R%dB" % (i + 8) for i in xrange(8)]
+    ["R%dB" % (i + 8) for i in range(8)]
 regs08_expr = [ExprId(x, 8) for x in regs08_str]
 
 regs08_64_str = ["AL", "CL", "DL", "BL", "SPL", "BPL", "SIL", "DIL"] + \
-    ["R%dB" % (i + 8) for i in xrange(8)]
+    ["R%dB" % (i + 8) for i in range(8)]
 regs08_64_expr = [ExprId(x, 8) for x in regs08_64_str]
 
 
 regs16_str = ["AX", "CX", "DX", "BX", "SP", "BP", "SI", "DI"] + \
-    ["R%dW" % (i + 8) for i in xrange(8)]
+    ["R%dW" % (i + 8) for i in range(8)]
 regs16_expr = [ExprId(x, 16) for x in regs16_str]
 
 regs32_str = ["EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI"] + \
-    ["R%dD" % (i + 8) for i in xrange(8)]
+    ["R%dD" % (i + 8) for i in range(8)]
 regs32_expr = [ExprId(x, 32) for x in regs32_str]
 
 regs64_str = ["RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI",
@@ -34,13 +35,13 @@ regs64_str = ["RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI",
 regs64_expr = [ExprId(x, 64) for x in regs64_str]
 
 
-regs_xmm_str = ["XMM%d" % i for i in xrange(16)]
+regs_xmm_str = ["XMM%d" % i for i in range(16)]
 regs_xmm_expr = [ExprId(x, 128) for x in regs_xmm_str]
 
-regs_mm_str = ["MM%d" % i for i in xrange(16)]
+regs_mm_str = ["MM%d" % i for i in range(16)]
 regs_mm_expr = [ExprId(x, 64) for x in regs_mm_str]
 
-regs_bnd_str = ["BND%d" % i for i in xrange(4)]
+regs_bnd_str = ["BND%d" % i for i in range(4)]
 regs_bnd_expr = [ExprId(x, 128) for x in regs_bnd_str]
 
 gpregs08 = reg_info(regs08_str, regs08_expr)
@@ -74,17 +75,17 @@ selectr_str = ["ES", "CS", "SS", "DS", "FS", "GS"]
 selectr_expr = [ExprId(x, 16) for x in selectr_str]
 segmreg = reg_info(selectr_str, selectr_expr)
 
-crregs32_str = ["CR%d" % i for i in xrange(8)]
+crregs32_str = ["CR%d" % i for i in range(8)]
 crregs32_expr = [ExprId(x, 32) for x in crregs32_str]
 crregs = reg_info(crregs32_str, crregs32_expr)
 
 
-drregs32_str = ["DR%d" % i for i in xrange(8)]
+drregs32_str = ["DR%d" % i for i in range(8)]
 drregs32_expr = [ExprId(x, 32) for x in drregs32_str]
 drregs = reg_info(drregs32_str, drregs32_expr)
 
 
-fltregs32_str = ["ST(%d)" % i for i in xrange(8)]
+fltregs32_str = ["ST(%d)" % i for i in range(8)]
 fltregs32_expr = [ExprId(x, 64) for x in fltregs32_str]
 fltregs = reg_info(fltregs32_str, fltregs32_expr)
 
@@ -345,7 +346,7 @@ float_st7 = ExprId("float_st7", 64)
 float_list = [float_st0, float_st1, float_st2, float_st3,
               float_st4, float_st5, float_st6, float_st7]
 
-float_replace = {fltregs32_expr[i]: float_list[i] for i in xrange(8)}
+float_replace = {fltregs32_expr[i]: float_list[i] for i in range(8)}
 float_replace[r_st_all.expr[0]] = float_st0
 
 
diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py
index d03a7cd4..bec09249 100644
--- a/miasm2/arch/x86/sem.py
+++ b/miasm2/arch/x86/sem.py
@@ -16,6 +16,10 @@
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 #
 
+from builtins import range
+
+from future.utils import viewitems
+
 import logging
 import miasm2.expression.expression as m2_expr
 from miasm2.expression.simplifications import expr_simp
@@ -882,7 +886,7 @@ def push_gen(ir, instr, src, size):
     off_size = src.size
 
     sp = mRSP[instr.mode]
-    new_sp = sp - m2_expr.ExprInt(off_size / 8, sp.size)
+    new_sp = sp - m2_expr.ExprInt(off_size // 8, sp.size)
     e.append(m2_expr.ExprAssign(sp, new_sp))
     if ir.do_stk_segm:
         new_sp = ir.gen_segm_expr(SS, new_sp)
@@ -905,7 +909,7 @@ def pop_gen(ir, instr, src, size):
         raise ValueError('bad size stacker!')
 
     sp = mRSP[instr.mode]
-    new_sp = sp + m2_expr.ExprInt(src.size / 8, sp.size)
+    new_sp = sp + m2_expr.ExprInt(src.size // 8, sp.size)
     # don't generate ESP incrementation on POP ESP
     if src != ir.sp:
         e.append(m2_expr.ExprAssign(sp, new_sp))
@@ -1187,7 +1191,7 @@ def cmps(ir, instr, size):
         src1_sgm = src1
         src2_sgm = src2
 
-    offset = m2_expr.ExprInt(size / 8, src1.size)
+    offset = m2_expr.ExprInt(size // 8, src1.size)
 
     e, _ = l_cmp(ir, instr,
                  ir.ExprMem(src1_sgm, size),
@@ -1226,7 +1230,7 @@ def scas(ir, instr, size):
     else:
         src_sgm = src
 
-    offset = m2_expr.ExprInt(size / 8, src.size)
+    offset = m2_expr.ExprInt(size // 8, src.size)
     e, extra = l_cmp(ir, instr,
                      mRAX[instr.mode][:size],
                      ir.ExprMem(src_sgm, size))
@@ -1298,7 +1302,7 @@ def popfd(ir, instr):
     e.append(m2_expr.ExprAssign(vip, m2_expr.ExprSlice(tmp, 20, 21)))
     e.append(m2_expr.ExprAssign(i_d, m2_expr.ExprSlice(tmp, 21, 22)))
     e.append(m2_expr.ExprAssign(mRSP[instr.mode],
-                             mRSP[instr.mode] + m2_expr.ExprInt(instr.mode / 8, mRSP[instr.mode].size)))
+                             mRSP[instr.mode] + m2_expr.ExprInt(instr.mode // 8, mRSP[instr.mode].size)))
     e.append(m2_expr.ExprAssign(exception_flags,
                              m2_expr.ExprCond(m2_expr.ExprSlice(tmp, 8, 9),
                                               m2_expr.ExprInt(
@@ -1339,7 +1343,7 @@ def pusha_gen(ir, instr, size):
     e = []
     cur_sp = mRSP[instr.mode]
     for i, reg in enumerate(pa_regs):
-        stk_ptr = cur_sp + m2_expr.ExprInt(-(size / 8) * (i + 1), instr.mode)
+        stk_ptr = cur_sp + m2_expr.ExprInt(-(size // 8) * (i + 1), instr.mode)
         e.append(m2_expr.ExprAssign(ir.ExprMem(stk_ptr, size), reg[size]))
     e.append(m2_expr.ExprAssign(cur_sp, stk_ptr))
     return e, []
@@ -1359,10 +1363,10 @@ def popa_gen(ir, instr, size):
     for i, reg in enumerate(reversed(pa_regs)):
         if reg == mRSP:
             continue
-        stk_ptr = cur_sp + m2_expr.ExprInt((size / 8) * i, instr.mode)
+        stk_ptr = cur_sp + m2_expr.ExprInt((size // 8) * i, instr.mode)
         e.append(m2_expr.ExprAssign(reg[size], ir.ExprMem(stk_ptr, size)))
 
-    stk_ptr = cur_sp + m2_expr.ExprInt((size / 8) * (i + 1), instr.mode)
+    stk_ptr = cur_sp + m2_expr.ExprInt((size // 8) * (i + 1), instr.mode)
     e.append(m2_expr.ExprAssign(cur_sp, stk_ptr))
 
     return e, []
@@ -1407,19 +1411,19 @@ def call(ir, instr, dst):
 
         e.append(m2_expr.ExprAssign(ir.IRDst, m2))
 
-        c = myesp + m2_expr.ExprInt(-s / 8, s)
+        c = myesp + m2_expr.ExprInt(-s // 8, s)
         e.append(m2_expr.ExprAssign(ir.ExprMem(c, size=s).zeroExtend(s),
                                  CS.zeroExtend(s)))
 
-        c = myesp + m2_expr.ExprInt(-2 * s / 8, s)
+        c = myesp + m2_expr.ExprInt((-2 * s) // 8, s)
         e.append(m2_expr.ExprAssign(ir.ExprMem(c, size=s).zeroExtend(s),
                                  meip.zeroExtend(s)))
 
-        c = myesp + m2_expr.ExprInt((-2 * s) / 8, s)
+        c = myesp + m2_expr.ExprInt((-2 * s) // 8, s)
         e.append(m2_expr.ExprAssign(myesp, c))
         return e, []
 
-    c = myesp + m2_expr.ExprInt((-s / 8), s)
+    c = myesp + m2_expr.ExprInt(-s // 8, s)
     e.append(m2_expr.ExprAssign(myesp, c))
     if ir.do_stk_segm:
         c = ir.gen_segm_expr(SS, c)
@@ -1437,10 +1441,10 @@ def ret(ir, instr, src=None):
     myesp = mRSP[instr.mode][:size]
 
     if src is None:
-        value = (myesp + (m2_expr.ExprInt((size / 8), size)))
+        value = (myesp + (m2_expr.ExprInt(size // 8, size)))
     else:
         src = m2_expr.ExprInt(int(src), size)
-        value = (myesp + (m2_expr.ExprInt((size / 8), size) + src))
+        value = (myesp + (m2_expr.ExprInt(size // 8, size) + src))
 
     e.append(m2_expr.ExprAssign(myesp, value))
     result = myesp
@@ -1473,13 +1477,13 @@ def retf(ir, instr, src=None):
     e.append(m2_expr.ExprAssign(ir.IRDst,
                              ir.ExprMem(result, size=size).zeroExtend(size)))
     # e.append(m2_expr.ExprAssign(meip, ir.ExprMem(c, size = s)))
-    result = myesp + m2_expr.ExprInt(size / 8, size)
+    result = myesp + m2_expr.ExprInt(size // 8, size)
     if ir.do_stk_segm:
         result = ir.gen_segm_expr(SS, result)
 
     e.append(m2_expr.ExprAssign(CS, ir.ExprMem(result, size=16)))
 
-    value = myesp + (m2_expr.ExprInt((2 * size) / 8, size) + src)
+    value = myesp + (m2_expr.ExprInt((2 * size) // 8, size) + src)
     e.append(m2_expr.ExprAssign(myesp, value))
     return e, []
 
@@ -1490,7 +1494,7 @@ def leave(ir, instr):
     e = []
     e.append(m2_expr.ExprAssign(mRBP[size], ir.ExprMem(mRBP[size], size=size)))
     e.append(m2_expr.ExprAssign(myesp,
-                             m2_expr.ExprInt(size / 8, size) + mRBP[size]))
+                             m2_expr.ExprInt(size // 8, size) + mRBP[size]))
     return e, []
 
 
@@ -1502,12 +1506,12 @@ def enter(ir, instr, src1, src2):
     src1 = src1.zeroExtend(size)
 
     e = []
-    esp_tmp = myesp - m2_expr.ExprInt(size / 8, size)
+    esp_tmp = myesp - m2_expr.ExprInt(size // 8, size)
     e.append(m2_expr.ExprAssign(ir.ExprMem(esp_tmp, size=size),
                              myebp))
     e.append(m2_expr.ExprAssign(myebp, esp_tmp))
     e.append(m2_expr.ExprAssign(myesp,
-                             myesp - (src1 + m2_expr.ExprInt(size / 8, size))))
+                             myesp - (src1 + m2_expr.ExprInt(size // 8, size))))
     return e, []
 
 
@@ -1930,8 +1934,8 @@ def stos(ir, instr, size):
 
     addr_o = mRDI[instr.mode][:instr.v_admode()]
     addr = addr_o
-    addr_p = addr + m2_expr.ExprInt(size / 8, addr.size)
-    addr_m = addr - m2_expr.ExprInt(size / 8, addr.size)
+    addr_p = addr + m2_expr.ExprInt(size // 8, addr.size)
+    addr_m = addr - m2_expr.ExprInt(size // 8, addr.size)
     if ir.do_str_segm:
         mss = ES
         if instr.additional_info.g2.value:
@@ -1966,8 +1970,8 @@ def lods(ir, instr, size):
 
     addr_o = mRSI[instr.mode][:instr.v_admode()]
     addr = addr_o
-    addr_p = addr + m2_expr.ExprInt(size / 8, addr.size)
-    addr_m = addr - m2_expr.ExprInt(size / 8, addr.size)
+    addr_p = addr + m2_expr.ExprInt(size // 8, addr.size)
+    addr_m = addr - m2_expr.ExprInt(size // 8, addr.size)
     if ir.do_str_segm:
         mss = DS
         if instr.additional_info.g2.value:
@@ -2018,7 +2022,7 @@ def movs(ir, instr, size):
         src_sgm = src
         dst_sgm = dst
 
-    offset = m2_expr.ExprInt(size / 8, src.size)
+    offset = m2_expr.ExprInt(size // 8, src.size)
 
     e.append(m2_expr.ExprAssign(ir.ExprMem(dst_sgm, size),
                              ir.ExprMem(src_sgm, size)))
@@ -2081,12 +2085,12 @@ def float_pop(avoid_flt=None, popcount=1):
     """
     avoid_flt = float_prev(avoid_flt, popcount)
     e = []
-    for i in xrange(8 - popcount):
+    for i in range(8 - popcount):
         if avoid_flt != float_list[i]:
             e.append(m2_expr.ExprAssign(float_list[i],
                                      float_list[i + popcount]))
     fill_value = m2_expr.ExprOp("sint_to_fp", m2_expr.ExprInt(0, 64))
-    for i in xrange(8 - popcount, 8):
+    for i in range(8 - popcount, 8):
         e.append(m2_expr.ExprAssign(float_list[i],
                                  fill_value))
     e.append(
@@ -2619,20 +2623,45 @@ def fnstenv(ir, instr, dst):
     size = min(32, s)
     ad = ir.ExprMem(dst.ptr, size=16)
     e.append(m2_expr.ExprAssign(ad, float_control))
-    ad = ir.ExprMem(dst.ptr + m2_expr.ExprInt(size /
-                                              8 * 1, dst.ptr.size), size=16)
+    ad = ir.ExprMem(
+        dst.ptr + m2_expr.ExprInt(
+            size // (8 * 1),
+            dst.ptr.size
+        ),
+        size=16
+    )
     e.append(m2_expr.ExprAssign(ad, status_word))
-    ad = ir.ExprMem(dst.ptr + m2_expr.ExprInt(size /
-                                              8 * 3, dst.ptr.size), size=size)
+    ad = ir.ExprMem(
+        dst.ptr + m2_expr.ExprInt(
+            size // (8 * 3),
+            dst.ptr.size
+        ),
+        size=size
+    )
     e.append(m2_expr.ExprAssign(ad, float_eip[:size]))
-    ad = ir.ExprMem(dst.ptr + m2_expr.ExprInt(size /
-                                              8 * 4, dst.ptr.size), size=16)
+    ad = ir.ExprMem(
+        dst.ptr + m2_expr.ExprInt(
+            size // (8 * 4),
+            dst.ptr.size
+        ),
+        size=16
+    )
     e.append(m2_expr.ExprAssign(ad, float_cs))
-    ad = ir.ExprMem(dst.ptr + m2_expr.ExprInt(size /
-                                              8 * 5, dst.ptr.size), size=size)
+    ad = ir.ExprMem(
+        dst.ptr + m2_expr.ExprInt(
+            size // (8 * 5),
+            dst.ptr.size
+        ),
+        size=size
+    )
     e.append(m2_expr.ExprAssign(ad, float_address[:size]))
-    ad = ir.ExprMem(dst.ptr + m2_expr.ExprInt(size /
-                                              8 * 6, dst.ptr.size), size=16)
+    ad = ir.ExprMem(
+        dst.ptr + m2_expr.ExprInt(
+            size // (8 * 6),
+            dst.ptr.size
+        ),
+        size=16
+    )
     e.append(m2_expr.ExprAssign(ad, float_ds))
     return e, []
 
@@ -2651,23 +2680,35 @@ def fldenv(ir, instr, src):
     e.append(m2_expr.ExprAssign(float_control, ad))
 
     # Status word
-    ad = ir.ExprMem(src.ptr + m2_expr.ExprInt(size / 8 * 1, size=src.ptr.size),
-                    size=16)
-    e += [m2_expr.ExprAssign(x, y) for x, y in ((float_c0, ad[8:9]),
-                                             (float_c1, ad[9:10]),
-                                             (float_c2, ad[10:11]),
-                                             (float_stack_ptr, ad[11:14]),
-                                             (float_c3, ad[14:15]))
-          ]
+    ad = ir.ExprMem(
+        src.ptr + m2_expr.ExprInt(
+            size // (8 * 1),
+            size=src.ptr.size
+        ),
+        size=16
+    )
+    e += [
+        m2_expr.ExprAssign(x, y) for x, y in ((float_c0, ad[8:9]),
+                                              (float_c1, ad[9:10]),
+                                              (float_c2, ad[10:11]),
+                                              (float_stack_ptr, ad[11:14]),
+                                              (float_c3, ad[14:15]))
+    ]
 
     # EIP, CS, Address, DS
-    for offset, target in ((3, float_eip[:size]),
-                           (4, float_cs),
-                           (5, float_address[:size]),
-                           (6, float_ds)):
-        ad = ir.ExprMem(src.ptr + m2_expr.ExprInt(size / 8 * offset,
-                                                  size=src.ptr.size),
-                        size=target.size)
+    for offset, target in (
+            (3, float_eip[:size]),
+            (4, float_cs),
+            (5, float_address[:size]),
+            (6, float_ds)
+    ):
+        ad = ir.ExprMem(
+            src.ptr + m2_expr.ExprInt(
+                size // ( 8 * offset),
+                size=src.ptr.size
+            ),
+            size=target.size
+        )
         e.append(m2_expr.ExprAssign(target, ad))
 
     return e, []
@@ -3243,7 +3284,7 @@ def sidt(ir, instr, dst):
     if not isinstance(dst, m2_expr.ExprMem) or dst.size != 32:
         raise ValueError('not exprmem 32bit instance!!')
     ptr = dst.ptr
-    LOG_X86_SEM.warning("DEFAULT SIDT ADDRESS %s!!", str(dst))
+    LOG_X86_SEM.warning("DEFAULT SIDT ADDRESS %s!!", dst)
     e.append(m2_expr.ExprAssign(ir.ExprMem(ptr, 32),
                              m2_expr.ExprInt(0xe40007ff, 32)))
     e.append(
@@ -3253,7 +3294,7 @@ def sidt(ir, instr, dst):
 
 
 def sldt(_, instr, dst):
-    LOG_X86_SEM.warning("DEFAULT SLDT ADDRESS %s!!", str(dst))
+    LOG_X86_SEM.warning("DEFAULT SLDT ADDRESS %s!!", dst)
     e = [m2_expr.ExprAssign(dst, m2_expr.ExprInt(0, dst.size))]
     return e, []
 
@@ -3531,7 +3572,7 @@ def cmpxchg16b(arg1):
 def lds(ir, instr, dst, src):
     e = []
     e.append(m2_expr.ExprAssign(dst, ir.ExprMem(src.ptr, size=dst.size)))
-    DS_value = ir.ExprMem(src.ptr + m2_expr.ExprInt(dst.size / 8, src.ptr.size),
+    DS_value = ir.ExprMem(src.ptr + m2_expr.ExprInt(dst.size // 8, src.ptr.size),
                           size=16)
     e.append(m2_expr.ExprAssign(DS, DS_value))
     return e, []
@@ -3540,7 +3581,7 @@ def lds(ir, instr, dst, src):
 def les(ir, instr, dst, src):
     e = []
     e.append(m2_expr.ExprAssign(dst, ir.ExprMem(src.ptr, size=dst.size)))
-    ES_value = ir.ExprMem(src.ptr + m2_expr.ExprInt(dst.size / 8, src.ptr.size),
+    ES_value = ir.ExprMem(src.ptr + m2_expr.ExprInt(dst.size // 8, src.ptr.size),
                           size=16)
     e.append(m2_expr.ExprAssign(ES, ES_value))
     return e, []
@@ -3549,7 +3590,7 @@ def les(ir, instr, dst, src):
 def lss(ir, instr, dst, src):
     e = []
     e.append(m2_expr.ExprAssign(dst, ir.ExprMem(src.ptr, size=dst.size)))
-    SS_value = ir.ExprMem(src.ptr + m2_expr.ExprInt(dst.size / 8, src.ptr.size),
+    SS_value = ir.ExprMem(src.ptr + m2_expr.ExprInt(dst.size // 8, src.ptr.size),
                           size=16)
     e.append(m2_expr.ExprAssign(SS, SS_value))
     return e, []
@@ -3558,7 +3599,7 @@ def lss(ir, instr, dst, src):
 def lfs(ir, instr, dst, src):
     e = []
     e.append(m2_expr.ExprAssign(dst, ir.ExprMem(src.ptr, size=dst.size)))
-    FS_value = ir.ExprMem(src.ptr + m2_expr.ExprInt(dst.size / 8, src.ptr.size),
+    FS_value = ir.ExprMem(src.ptr + m2_expr.ExprInt(dst.size // 8, src.ptr.size),
                           size=16)
     e.append(m2_expr.ExprAssign(FS, FS_value))
     return e, []
@@ -3567,7 +3608,7 @@ def lfs(ir, instr, dst, src):
 def lgs(ir, instr, dst, src):
     e = []
     e.append(m2_expr.ExprAssign(dst, ir.ExprMem(src.ptr, size=dst.size)))
-    GS_value = ir.ExprMem(src.ptr + m2_expr.ExprInt(dst.size / 8, src.ptr.size),
+    GS_value = ir.ExprMem(src.ptr + m2_expr.ExprInt(dst.size // 8, src.ptr.size),
                           size=16)
     e.append(m2_expr.ExprAssign(GS, GS_value))
     return e, []
@@ -3704,18 +3745,18 @@ def vec_op_clip(op, size, callback=None):
 
 def vec_vertical_sem(op, elt_size, reg_size, dst, src, apply_on_output):
     assert reg_size % elt_size == 0
-    n = reg_size / elt_size
+    n = reg_size // elt_size
     if op == '-':
         ops = [
             apply_on_output((dst[i * elt_size:(i + 1) * elt_size]
                              - src[i * elt_size:(i + 1) * elt_size]))
-            for i in xrange(0, n)
+            for i in range(0, n)
         ]
     else:
         ops = [
             apply_on_output(m2_expr.ExprOp(op, dst[i * elt_size:(i + 1) * elt_size],
                                            src[i * elt_size:(i + 1) * elt_size]))
-            for i in xrange(0, n)
+            for i in range(0, n)
         ]
 
     return m2_expr.ExprCompose(*ops)
@@ -3857,7 +3898,7 @@ def pmaddwd(ir, instr, dst, src):
     sizedst = 32
     sizesrc = 16
     out = []
-    for start in xrange(0, dst.size, sizedst):
+    for start in range(0, dst.size, sizedst):
         base = start
         mul1 = src[base: base + sizesrc].signExtend(sizedst) * dst[base: base + sizesrc].signExtend(sizedst)
         base += sizesrc
@@ -3877,9 +3918,9 @@ def psadbw(ir, instr, dst, src):
     sizedst = 16
     sizesrc = 8
     out_dst = []
-    for start in xrange(0, dst.size, 64):
+    for start in range(0, dst.size, 64):
         out = []
-        for src_start in xrange(0, 64, sizesrc):
+        for src_start in range(0, 64, sizesrc):
             beg = start + src_start
             end = beg + sizesrc
             # Not clear in the doc equations, but in the text, src and dst are:
@@ -4311,7 +4352,7 @@ def pshufb(_, instr, dst, src):
         bit_l = 4
     else:
         raise NotImplementedError("bad size")
-    for i in xrange(0, src.size, 8):
+    for i in range(0, src.size, 8):
         index = src[
             i:i + bit_l].zeroExtend(dst.size) << m2_expr.ExprInt(3, dst.size)
         value = (dst >> index)[:8]
@@ -4325,7 +4366,7 @@ def pshufb(_, instr, dst, src):
 def pshufd(_, instr, dst, src, imm):
     control = int(imm)
     out = []
-    for i in xrange(4):
+    for i in range(4):
         shift = ((control >> (i * 2)) & 3) * 32
         # shift is 2 bits long, expr.size is 128
         # => shift + 32 <= src.size
@@ -4336,7 +4377,7 @@ def pshufd(_, instr, dst, src, imm):
 def pshuflw(_, instr, dst, src, imm):
     control = int(imm)
     out = []
-    for i in xrange(4):
+    for i in range(4):
         shift = ((control >> (i * 2)) & 3) * 16
         out.append(src[shift: shift + 16])
     out.append(src[64:])
@@ -4346,7 +4387,7 @@ def pshuflw(_, instr, dst, src, imm):
 def pshufhw(_, instr, dst, src, imm):
     control = int(imm)
     out = [src[:64]]
-    for i in xrange(4):
+    for i in range(4):
         shift = ((control >> (i * 2)) & 3) * 16
         out.append(src[shift + 64: shift + 16 + 64])
     return [m2_expr.ExprAssign(dst, m2_expr.ExprCompose(*out))], []
@@ -4369,7 +4410,7 @@ def ps_rl_ll(ir, instr, dst, src, op, size):
         count = expr_simp(count)
 
     out = []
-    for i in xrange(0, dst.size, size):
+    for i in range(0, dst.size, size):
         out.append(m2_expr.ExprOp(op, dst[i:i + size], count))
     return [m2_expr.ExprAssign(dst, m2_expr.ExprCompose(*out))], []
 
@@ -4430,15 +4471,15 @@ def iret(ir, instr):
     XXX: only support "no-privilege change"
     """
     size = instr.v_opmode()
-    exprs, _ = retf(ir, instr, m2_expr.ExprInt(size / 8, size=size))
-    tmp = mRSP[instr.mode][:size] + m2_expr.ExprInt((2 * size) / 8, size=size)
+    exprs, _ = retf(ir, instr, m2_expr.ExprInt(size // 8, size=size))
+    tmp = mRSP[instr.mode][:size] + m2_expr.ExprInt((2 * size) // 8, size=size)
     exprs += _tpl_eflags(tmp)
     return exprs, []
 
 
 def pcmpeq(_, instr, dst, src, size):
     e = []
-    for i in xrange(0, dst.size, size):
+    for i in range(0, dst.size, size):
         test = m2_expr.expr_is_equal(dst[i:i + size], src[i:i + size])
         e.append(m2_expr.ExprAssign(dst[i:i + size],
                                  m2_expr.ExprCond(test,
@@ -4449,7 +4490,7 @@ def pcmpeq(_, instr, dst, src, size):
 
 def pcmpgt(_, instr, dst, src, size):
     e = []
-    for i in xrange(0, dst.size, size):
+    for i in range(0, dst.size, size):
         test = m2_expr.expr_is_signed_greater(dst[i:i + size], src[i:i + size])
         e.append(m2_expr.ExprAssign(dst[i:i + size],
                                  m2_expr.ExprCond(test,
@@ -4490,7 +4531,7 @@ def pcmpgtq(ir, instr, dst, src):
 def punpck(_, instr, dst, src, size, off):
     e = []
     slices = []
-    for i in xrange(dst.size / (2 * size)):
+    for i in range(dst.size // (2 * size)):
         slices.append(dst[size * i + off: size * i + off + size])
         slices.append(src[size * i + off: size * i + off + size])
     e.append(m2_expr.ExprAssign(dst, m2_expr.ExprCompose(*slices)))
@@ -4498,19 +4539,19 @@ def punpck(_, instr, dst, src, size, off):
 
 
 def punpckhbw(ir, instr, dst, src):
-    return punpck(ir, instr, dst, src, 8, dst.size / 2)
+    return punpck(ir, instr, dst, src, 8, dst.size // 2)
 
 
 def punpckhwd(ir, instr, dst, src):
-    return punpck(ir, instr, dst, src, 16, dst.size / 2)
+    return punpck(ir, instr, dst, src, 16, dst.size // 2)
 
 
 def punpckhdq(ir, instr, dst, src):
-    return punpck(ir, instr, dst, src, 32, dst.size / 2)
+    return punpck(ir, instr, dst, src, 32, dst.size // 2)
 
 
 def punpckhqdq(ir, instr, dst, src):
-    return punpck(ir, instr, dst, src, 64, dst.size / 2)
+    return punpck(ir, instr, dst, src, 64, dst.size // 2)
 
 
 def punpcklbw(ir, instr, dst, src):
@@ -4667,7 +4708,7 @@ def movq2dq(_, instr, dst, src):
 def sqrt_gen(_, instr, dst, src, size):
     e = []
     out = []
-    for i in xrange(src.size / size):
+    for i in range(src.size // size):
         out.append(m2_expr.ExprOp('fsqrt',
                                   src[i * size: (i + 1) * size]))
     src = m2_expr.ExprCompose(*out)
@@ -4702,7 +4743,7 @@ def sqrtss(_, instr, dst, src):
 def pmovmskb(_, instr, dst, src):
     e = []
     out = []
-    for i in xrange(src.size / 8):
+    for i in range(src.size // 8):
         out.append(src[8 * i + 7:8 * (i + 1)])
     src = m2_expr.ExprCompose(*out)
     e.append(m2_expr.ExprAssign(dst, src.zeroExtend(dst.size)))
@@ -4807,7 +4848,7 @@ def _unsigned_saturation(expr, dst_size):
 def packsswb(ir, instr, dst, src):
     out = []
     for source in [dst, src]:
-        for start in xrange(0, dst.size, 16):
+        for start in range(0, dst.size, 16):
             out.append(_signed_saturation(source[start:start + 16], 8))
     return [m2_expr.ExprAssign(dst, m2_expr.ExprCompose(*out))], []
 
@@ -4815,7 +4856,7 @@ def packsswb(ir, instr, dst, src):
 def packssdw(ir, instr, dst, src):
     out = []
     for source in [dst, src]:
-        for start in xrange(0, dst.size, 32):
+        for start in range(0, dst.size, 32):
             out.append(_signed_saturation(source[start:start + 32], 16))
     return [m2_expr.ExprAssign(dst, m2_expr.ExprCompose(*out))], []
 
@@ -4823,7 +4864,7 @@ def packssdw(ir, instr, dst, src):
 def packuswb(ir, instr, dst, src):
     out = []
     for source in [dst, src]:
-        for start in xrange(0, dst.size, 16):
+        for start in range(0, dst.size, 16):
             out.append(_unsigned_saturation(source[start:start + 16], 8))
     return [m2_expr.ExprAssign(dst, m2_expr.ExprCompose(*out))], []
 
@@ -4894,13 +4935,13 @@ def maskmovq(ir, instr, src, mask):
 
     # For each possibility, check if a write is necessary
     check_labels = [m2_expr.ExprLoc(ir.loc_db.add_location(), ir.IRDst.size)
-                    for _ in xrange(0, mask.size, 8)]
+                    for _ in range(0, mask.size, 8)]
     # If the write has to be done, do it (otherwise, nothing happen)
     write_labels = [m2_expr.ExprLoc(ir.loc_db.add_location(), ir.IRDst.size)
-                    for _ in xrange(0, mask.size, 8)]
+                    for _ in range(0, mask.size, 8)]
 
     # Build check blocks
-    for i, start in enumerate(xrange(0, mask.size, 8)):
+    for i, start in enumerate(range(0, mask.size, 8)):
         bit = mask[start + 7: start + 8]
         cur_label = check_labels[i]
         next_check_label = check_labels[i + 1] if (i + 1) < len(check_labels) else loc_next_expr
@@ -4913,7 +4954,7 @@ def maskmovq(ir, instr, src, mask):
 
     # Build write blocks
     dst_addr = mRDI[instr.mode]
-    for i, start in enumerate(xrange(0, mask.size, 8)):
+    for i, start in enumerate(range(0, mask.size, 8)):
         cur_label = write_labels[i]
         next_check_label = check_labels[i + 1] if (i + 1) < len(check_labels) else loc_next_expr
         write_addr = dst_addr + m2_expr.ExprInt(i, dst_addr.size)
@@ -4972,7 +5013,7 @@ def _select4(src, control):
 def shufps(ir, instr, dst, src, imm8):
     out = []
     control = int(imm8)
-    for i in xrange(4):
+    for i in range(4):
         if i < 2:
             source = dst
         else:
@@ -4990,13 +5031,13 @@ def shufpd(ir, instr, dst, src, imm8):
 
 def movmskps(ir, instr, dst, src):
     out = []
-    for i in xrange(4):
+    for i in range(4):
         out.append(src[(32 * i) + 31:(32 * i) + 32])
     return [m2_expr.ExprAssign(dst, m2_expr.ExprCompose(*out).zeroExtend(dst.size))], []
 
 def movmskpd(ir, instr, dst, src):
     out = []
-    for i in xrange(2):
+    for i in range(2):
         out.append(src[(64 * i) + 63:(64 * i) + 64])
     return [m2_expr.ExprAssign(dst, m2_expr.ExprCompose(*out).zeroExtend(dst.size))], []
 
@@ -5720,7 +5761,7 @@ class ir_x86_16(IntermediateRepresentation):
         irs = []
         for assignblk in irblock:
             new_assignblk = dict(assignblk)
-            for dst, src in assignblk.iteritems():
+            for dst, src in viewitems(assignblk):
                 del new_assignblk[dst]
                 # Special case for 64 bits:
                 # If destination is a 32 bit reg, zero extend the 64 bit reg
diff --git a/miasm2/core/asm_ast.py b/miasm2/core/asm_ast.py
index 3b06ce62..69ff1f9c 100644
--- a/miasm2/core/asm_ast.py
+++ b/miasm2/core/asm_ast.py
@@ -1,3 +1,5 @@
+from builtins import int as int_types
+
 class AstNode(object):
     """
     Ast node object
@@ -68,7 +70,7 @@ class AstMem(AstNode):
     """
     def __init__(self, ptr, size):
         assert isinstance(ptr, AstNode)
-        assert isinstance(size, (int, long))
+        assert isinstance(size, int_types)
         self.ptr = ptr
         self.size = size
 
diff --git a/miasm2/core/asmblock.py b/miasm2/core/asmblock.py
index f6e68a0e..811cc824 100644
--- a/miasm2/core/asmblock.py
+++ b/miasm2/core/asmblock.py
@@ -1,8 +1,13 @@
 #-*- coding:utf-8 -*-
 
+from builtins import map
+from builtins import range
 import logging
 import warnings
 from collections import namedtuple
+from builtins import int as int_types
+
+from future.utils import viewitems, viewvalues
 
 from miasm2.expression.expression import ExprId, ExprInt, get_expr_locs
 from miasm2.expression.expression import LocKey
@@ -22,14 +27,12 @@ log_asmblock.setLevel(logging.WARNING)
 
 
 def is_int(a):
-    return isinstance(a, int) or isinstance(a, long) or \
-        isinstance(a, moduint) or isinstance(a, modint)
-
+    return isinstance(a, (modint, moduint, int_types))
 
 
 class AsmRaw(object):
 
-    def __init__(self, raw=""):
+    def __init__(self, raw=b""):
         self.raw = raw
 
     def __str__(self):
@@ -41,7 +44,7 @@ class AsmRaw(object):
 
 class asm_raw(AsmRaw):
 
-    def __init__(self, raw=""):
+    def __init__(self, raw=b""):
         warnings.warn('DEPRECATION WARNING: use "AsmRaw" instead of "asm_raw"')
         super(asm_label, self).__init__(raw)
 
@@ -190,7 +193,8 @@ class AsmBlock(object):
             for xx in self.bto:
                 log_asmblock.debug('lbl %s', xx)
             c_next = set(
-                [x for x in self.bto if x.c_t == AsmConstraint.c_next])
+                x for x in self.bto if x.c_t == AsmConstraint.c_next
+            )
             c_to = [x for x in self.bto if x.c_t != AsmConstraint.c_next]
             self.bto = set([c] + c_to)
             new_bloc.bto = c_next
@@ -223,7 +227,7 @@ class AsmBlock(object):
     def get_flow_instr(self):
         if not self.lines:
             return None
-        for i in xrange(-1, -1 - self.lines[0].delayslot - 1, -1):
+        for i in range(-1, -1 - self.lines[0].delayslot - 1, -1):
             if not 0 <= i < len(self.lines):
                 return None
             l = self.lines[i]
@@ -236,7 +240,7 @@ class AsmBlock(object):
         delayslot = self.lines[0].delayslot
         end_index = len(self.lines) - 1
         ds_max_index = max(end_index - delayslot, 0)
-        for i in xrange(end_index, ds_max_index - 1, -1):
+        for i in range(end_index, ds_max_index - 1, -1):
             l = self.lines[i]
             if l.is_subcall():
                 return l
@@ -280,8 +284,10 @@ class AsmBlock(object):
         for constraint in self.bto:
             dests.setdefault(constraint.loc_key, set()).add(constraint)
 
-        self.bto = set(self._filter_constraint(constraints)
-                       for constraints in dests.itervalues())
+        self.bto = set(
+            self._filter_constraint(constraints)
+            for constraints in viewvalues(dests)
+        )
 
 
 class asm_bloc(object):
@@ -324,8 +330,10 @@ class AsmBlockBad(AsmBlock):
 
     def __str__(self):
         error_txt = self.ERROR_TYPES.get(self._errno, self._errno)
-        return "\n".join([str(self.loc_key),
-                          "\tBad block: %s" % error_txt])
+        return "%s\n\tBad block: %s" % (
+            self.loc_key,
+            error_txt
+        )
 
     def addline(self, *args, **kwargs):
         raise RuntimeError("An AsmBlockBad cannot have line")
@@ -421,7 +429,9 @@ class AsmCFG(DiGraph):
         """Return the number of blocks in AsmCFG"""
         return len(self._nodes)
 
-    blocks = property(lambda x:x._loc_key_to_block.itervalues())
+    @property
+    def blocks(self):
+        return viewvalues(self._loc_key_to_block)
 
     # Manage graph with associated constraints
     def add_edge(self, src, dst, constraint):
@@ -536,7 +546,7 @@ class AsmCFG(DiGraph):
 
     def node2lines(self, node):
         if self.loc_db is None:
-            loc_key_name = str(node)
+            loc_key_name = node
         else:
             loc_key_name = self.loc_db.pretty_str(node)
         yield self.DotCellDescription(text=loc_key_name,
@@ -545,7 +555,7 @@ class AsmCFG(DiGraph):
                                             'bgcolor': 'grey'})
         block = self._loc_key_to_block.get(node, None)
         if block is None:
-            raise StopIteration
+            return
         if isinstance(block, AsmBlockBad):
             yield [
                 self.DotCellDescription(
@@ -554,7 +564,7 @@ class AsmCFG(DiGraph):
                     ),
                     attr={})
             ]
-            raise StopIteration
+            return
         for line in block.lines:
             if self._dot_offset:
                 yield [self.DotCellDescription(text="%.8X" % line.offset,
@@ -700,14 +710,20 @@ class AsmCFG(DiGraph):
         """
 
         if len(self._pendings) != 0:
-            raise RuntimeError("Some blocks are missing: %s" % map(
-                str,
-                self._pendings.keys()
-            ))
+            raise RuntimeError(
+                "Some blocks are missing: %s" % list(
+                    map(
+                        str,
+                        self._pendings
+                    )
+                )
+            )
 
-        next_edges = {edge: constraint
-                      for edge, constraint in self.edges2constraint.iteritems()
-                      if constraint == AsmConstraint.c_next}
+        next_edges = {
+            edge: constraint
+            for edge, constraint in viewitems(self.edges2constraint)
+            if constraint == AsmConstraint.c_next
+        }
 
         for loc_key in self._nodes:
             if loc_key not in self._loc_key_to_block:
@@ -740,8 +756,11 @@ class AsmCFG(DiGraph):
                         if len(instr.raw) == 0:
                             l = 0
                         else:
-                            l = instr.raw[0].size / 8 * len(instr.raw)
+                            l = (instr.raw[0].size // 8) * len(instr.raw)
                     elif isinstance(instr.raw, str):
+                        data = instr.raw.encode()
+                        l = len(data)
+                    elif isinstance(instr.raw, bytes):
                         data = instr.raw
                         l = len(data)
                     else:
@@ -1148,7 +1167,7 @@ def resolve_symbol(blockChains, loc_db, dst_interval=None):
         if chain.pinned:
             continue
         fixed = False
-        for i in xrange(1, len(fixed_chains)):
+        for i in range(1, len(fixed_chains)):
             prev_chain = fixed_chains[i - 1]
             next_chain = fixed_chains[i]
 
@@ -1187,7 +1206,7 @@ def assemble_block(mnemo, block, loc_db, conservative=False):
         if isinstance(instr, AsmRaw):
             if isinstance(instr.raw, list):
                 # Fix special AsmRaw
-                data = ""
+                data = b""
                 for expr in instr.raw:
                     expr_int = fix_expr_val(expr, loc_db)
                     data += pck[expr_int.size](expr_int.arg)
@@ -1471,7 +1490,7 @@ class disasmEngine(object):
             # XXX TODO nul start block option
             if (self.dont_dis_nulstart_bloc and
                 not cur_block.lines and
-                instr.b.count('\x00') == instr.l):
+                instr.b.count(b'\x00') == instr.l):
                 log_asmblock.warning("reach nul instr at %X", int(off_i))
                 # Block is empty -> bad block
                 cur_block = AsmBlockBad(loc_key, errno=AsmBlockBad.ERROR_NULL_STARTING_BLOCK)
diff --git a/miasm2/core/bin_stream.py b/miasm2/core/bin_stream.py
index af31a52c..4977e2ae 100644
--- a/miasm2/core/bin_stream.py
+++ b/miasm2/core/bin_stream.py
@@ -16,6 +16,9 @@
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 #
 
+from builtins import str
+from future.utils import PY3
+
 from miasm2.core.utils import BIG_ENDIAN, LITTLE_ENDIAN
 from miasm2.core.utils import upck8le, upck16le, upck32le, upck64le
 from miasm2.core.utils import upck8be, upck16be, upck32be, upck64be
@@ -35,6 +38,11 @@ class bin_stream(object):
     def __repr__(self):
         return "<%s !!>" % self.__class__.__name__
 
+    def __str__(self):
+        if PY3:
+            return repr(self)
+        return self.__bytes__()
+
     def hexdump(self, offset, l):
         return
 
@@ -81,8 +89,8 @@ class bin_stream(object):
         # Get initial bytes
         if n > self.getlen() * 8:
             raise IOError('not enough bits %r %r' % (n, len(self.bin) * 8))
-        byte_start = start / 8
-        byte_stop = (start + n + 7) / 8
+        byte_start = start // 8
+        byte_stop = (start + n + 7) // 8
         temp = self.getbytes(byte_start, byte_stop - byte_start)
         if not temp:
             raise IOError('cannot get bytes')
@@ -92,8 +100,8 @@ class bin_stream(object):
         out = 0
         while n:
             # Get needed bits, working on maximum 8 bits at a time
-            cur_byte_idx = start / 8
-            new_bits = ord(temp[cur_byte_idx])
+            cur_byte_idx = start // 8
+            new_bits = ord(temp[cur_byte_idx:cur_byte_idx + 1])
             to_keep = 8 - start % 8
             new_bits &= (1 << to_keep) - 1
             cur_len = min(to_keep, n)
@@ -160,7 +168,7 @@ class bin_stream(object):
 
 class bin_stream_str(bin_stream):
 
-    def __init__(self, input_str="", offset=0L, base_address=0, shift=None):
+    def __init__(self, input_str=b"", offset=0, base_address=0, shift=None):
         bin_stream.__init__(self)
         if shift is not None:
             raise DeprecationWarning("use base_address instead of shift")
@@ -185,9 +193,8 @@ class bin_stream_str(bin_stream):
         self.offset += l
         return self.bin[self.offset - l - self.base_address:self.offset - self.base_address]
 
-    def __str__(self):
-        out = self.bin[self.offset - self.base_address:]
-        return out
+    def __bytes__(self):
+        return self.bin[self.offset - self.base_address:]
 
     def setoffset(self, val):
         self.offset = val
@@ -198,7 +205,7 @@ class bin_stream_str(bin_stream):
 
 class bin_stream_file(bin_stream):
 
-    def __init__(self, binary, offset=0L, base_address=0, shift=None):
+    def __init__(self, binary, offset=0, base_address=0, shift=None):
         bin_stream.__init__(self)
         if shift is not None:
             raise DeprecationWarning("use base_address instead of shift")
@@ -222,8 +229,8 @@ class bin_stream_file(bin_stream):
             raise IOError("Negative offset")
         return self.bin.read(l)
 
-    def __str__(self):
-        return str(self.bin)
+    def __bytes__(self):
+        return self.bin.read()
 
     def getlen(self):
         return self.l - (self.offset - self.base_address)
@@ -231,7 +238,7 @@ class bin_stream_file(bin_stream):
 
 class bin_stream_container(bin_stream):
 
-    def __init__(self, binary, offset=0L):
+    def __init__(self, binary, offset=0):
         bin_stream.__init__(self)
         self.bin = binary
         self.l = binary.virt.max_addr()
@@ -257,9 +264,8 @@ class bin_stream_container(bin_stream):
         except ValueError:
             raise IOError("cannot get bytes")
 
-    def __str__(self):
-        out = self.bin.virt.get(self.offset, self.offset + self.l)
-        return out
+    def __bytes__(self):
+        return self.bin.virt.get(self.offset, self.offset + self.l)
 
     def setoffset(self, val):
         self.offset = val
@@ -279,7 +285,7 @@ class bin_stream_elf(bin_stream_container):
 
 class bin_stream_vm(bin_stream):
 
-    def __init__(self, vm, offset=0L, base_offset=0L):
+    def __init__(self, vm, offset=0, base_offset=0):
         self.offset = offset
         self.base_offset = base_offset
         self.vm = vm
diff --git a/miasm2/core/bin_stream_ida.py b/miasm2/core/bin_stream_ida.py
index fcd89f9f..44cf9367 100644
--- a/miasm2/core/bin_stream_ida.py
+++ b/miasm2/core/bin_stream_ida.py
@@ -1,7 +1,9 @@
+from builtins import range
 from idc import Byte, SegEnd
 from idautils import Segments
 from idaapi import is_mapped
 
+from miasm2.core.utils import int_to_byte
 from miasm2.core.bin_stream import bin_stream_str
 
 
@@ -13,13 +15,13 @@ class bin_stream_ida(bin_stream_str):
     It can raise error on overflow 7FFFFFFF with 32 bit python
     """
     def _getbytes(self, start, l=1):
-        o = ""
-        for ad in xrange(l):
+        out = []
+        for ad in range(l):
             offset = ad + start + self.base_address
             if not is_mapped(offset):
                 raise IOError("not enough bytes")
-            o += chr(Byte(offset))
-        return o
+            out.append(int_to_byte(Byte(offset)))
+        return b''.join(out)
 
     def readbs(self, l=1):
         if self.offset + l > self.l:
diff --git a/miasm2/core/cpu.py b/miasm2/core/cpu.py
index c2fbd3cd..c24b693d 100644
--- a/miasm2/core/cpu.py
+++ b/miasm2/core/cpu.py
@@ -1,12 +1,17 @@
 #-*- coding:utf-8 -*-
 
+from builtins import range
 import re
 import struct
 import logging
 from collections import defaultdict
 
+
+from future.utils import viewitems, viewvalues
+
 import pyparsing
 
+from miasm2.core.utils import decode_hex
 import miasm2.expression.expression as m2_expr
 from miasm2.core.bin_stream import bin_stream, bin_stream_str
 from miasm2.core.utils import Disasm_Exception
@@ -15,6 +20,7 @@ from miasm2.core.locationdb import LocationDB
 
 
 from miasm2.core.asm_ast import AstNode, AstInt, AstId, AstOp
+from future.utils import with_metaclass
 
 log = logging.getLogger("cpuhelper")
 console_handler = logging.StreamHandler()
@@ -23,17 +29,15 @@ log.addHandler(console_handler)
 log.setLevel(logging.WARN)
 
 
-class bitobj:
+class bitobj(object):
 
-    def __init__(self, s=""):
+    def __init__(self, s=b""):
         if not s:
             bits = []
         else:
-            bits = list(bin(int(str(s).encode('hex'), 16))[2:])
-            bits = [int(x) for x in bits]
+            bits = [int(x) for x in bin(int(encode_hex(s), 16))[2:]]
             if len(bits) % 8:
-                bits = [0 for x in xrange(8 - (len(bits) % 8))] + bits
-            bits = ['0' for x in xrange(len(s) * 8 - len(bits))] + bits
+                bits = [0 for x in range(8 - (len(bits) % 8))] + bits
         self.bits = bits
         self.offset = 0
 
@@ -46,7 +50,7 @@ class bitobj:
         if n > len(self.bits) - self.offset:
             raise ValueError('not enough bits %r %r' % (n, len(self.bits)))
         b = self.bits[self.offset:self.offset + n]
-        b = int("".join([str(x) for x in b]), 2)
+        b = int("".join(str(x) for x in b), 2)
         self.offset += n
         return b
 
@@ -55,17 +59,18 @@ class bitobj:
             return
         bits = list(bin(b)[2:])
         bits = [int(x) for x in bits]
-        bits = [0 for x in xrange(n - len(bits))] + bits
+        bits = [0 for x in range(n - len(bits))] + bits
         self.bits += bits
 
     def tostring(self):
         if len(self.bits) % 8:
             raise ValueError(
-                'num bits must be 8 bit aligned: %d' % len(self.bits))
-        b = int("".join([str(x) for x in self.bits]), 2)
+                'num bits must be 8 bit aligned: %d' % len(self.bits)
+            )
+        b = int("".join(str(x) for x in self.bits), 2)
         b = "%X" % b
-        b = '0' * (len(self.bits) / 4 - len(b)) + b
-        b = b.decode('hex')
+        b = '0' * (len(self.bits) // 4 - len(b)) + b
+        b = decode_hex(b.encode())
         return b
 
     def reset(self):
@@ -113,10 +118,10 @@ class reg_info(object):
 class reg_info_dct(object):
 
     def __init__(self, reg_expr):
-        self.dct_str_inv = dict((v.name, k) for k, v in reg_expr.iteritems())
+        self.dct_str_inv = dict((v.name, k) for k, v in viewitems(reg_expr))
         self.dct_expr = reg_expr
-        self.dct_expr_inv = dict((v, k) for k, v in reg_expr.iteritems())
-        reg_str = [v.name for v in reg_expr.itervalues()]
+        self.dct_expr_inv = dict((v, k) for k, v in viewitems(reg_expr))
+        reg_str = [v.name for v in viewvalues(reg_expr)]
         self.parser = literal_list(reg_str).setParseAction(self.cb_parse)
 
     def cb_parse(self, tokens):
@@ -412,11 +417,11 @@ def int2bin(i, l):
 
 
 def myror32(v, r):
-    return ((v & 0xFFFFFFFFL) >> r) | ((v << (32 - r)) & 0xFFFFFFFFL)
+    return ((v & 0xFFFFFFFF) >> r) | ((v << (32 - r)) & 0xFFFFFFFF)
 
 
 def myrol32(v, r):
-    return ((v & 0xFFFFFFFFL) >> (32 - r)) | ((v << r) & 0xFFFFFFFFL)
+    return ((v & 0xFFFFFFFF) >> (32 - r)) | ((v << r) & 0xFFFFFFFF)
 
 
 class bs(object):
@@ -563,7 +568,7 @@ class bsi(object):
 
     def __hash__(self):
         kargs = []
-        for k, v in self.kargs.items():
+        for k, v in list(viewitems(self.kargs)):
             if isinstance(v, list):
                 v = tuple(v)
             kargs.append((k, v))
@@ -595,7 +600,7 @@ class bs_name(bs_divert):
     def divert(self, i, candidates):
         out = []
         for cls, _, bases, dct, fields in candidates:
-            for new_name, value in self.args['name'].iteritems():
+            for new_name, value in viewitems(self.args['name']):
                 nfields = fields[:]
                 s = int2bin(value, self.args['l'])
                 args = dict(self.args)
@@ -620,7 +625,7 @@ class bs_mod_name(bs_divert):
                 for j, v in enumerate(tab):
                     tmp[j] = v
                 tab = tmp
-            for value, new_name in tab.iteritems():
+            for value, new_name in viewitems(tab):
                 nfields = fields[:]
                 s = int2bin(value, self.args['l'])
                 args = dict(self.args)
@@ -676,7 +681,7 @@ class m_arg(object):
             self.expr = e
             return start, stop
         try:
-            v, start, stop = self.parser.scanString(text).next()
+            v, start, stop = next(self.parser.scanString(text))
         except StopIteration:
             return None, None
         arg = v[0]
@@ -713,7 +718,7 @@ class reg_noarg(object):
             self.expr = e
             return start, stop
         try:
-            v, start, stop = self.parser.scanString(text).next()
+            v, start, stop = next(self.parser.scanString(text))
         except StopIteration:
             return None, None
         arg = v[0]
@@ -743,7 +748,7 @@ class reg_noarg(object):
         return v & self.fmask == self.fbits
 
 
-class mn_prefix:
+class mn_prefix(object):
     pass
 
 
@@ -756,7 +761,7 @@ def swap32(v):
 
 
 def perm_inv(p):
-    o = [None for x in xrange(len(p))]
+    o = [None for x in range(len(p))]
     for i, x in enumerate(p):
         o[x] = i
     return o
@@ -775,10 +780,10 @@ total_scans = 0
 def branch2nodes(branch, nodes=None):
     if nodes is None:
         nodes = []
-    for k, v in branch.items():
+    for k, v in viewitems(branch):
         if not isinstance(v, dict):
             continue
-        for k2 in v.keys():
+        for k2 in v:
             nodes.append((k, k2))
         branch2nodes(v, nodes)
 
@@ -789,7 +794,7 @@ def factor_one_bit(tree):
     new_keys = defaultdict(lambda: defaultdict(dict))
     if len(tree) == 1:
         return tree
-    for k, v in tree.items():
+    for k, v in viewitems(tree):
         if k == "mn":
             new_keys[k] = v
             continue
@@ -806,15 +811,15 @@ def factor_one_bit(tree):
         if nk in new_keys[ck]:
             raise NotImplementedError('not fully functional')
         new_keys[ck][nk] = v
-    for k, v in new_keys.items():
+    for k, v in list(viewitems(new_keys)):
         new_keys[k] = factor_one_bit(v)
     # try factor sons
     if len(new_keys) != 1:
         return new_keys
-    subtree = new_keys.values()[0]
+    subtree = next(iter(viewvalues(new_keys)))
     if len(subtree) != 1:
         return new_keys
-    if subtree.keys()[0] == 'mn':
+    if next(iter(subtree)) == 'mn':
         return new_keys
 
     return new_keys
@@ -826,7 +831,7 @@ def factor_fields(tree):
     if len(tree) != 1:
         return tree
     # merge
-    k1, v1 = tree.items()[0]
+    k1, v1 = next(iter(viewitems(tree)))
     if k1 == "mn":
         return tree
     l1, fmask1, fbits1, fname1, flen1 = k1
@@ -839,7 +844,7 @@ def factor_fields(tree):
         return tree
     if len(v1) != 1:
         return tree
-    k2, v2 = v1.items()[0]
+    k2, v2 = next(iter(viewitems(v1)))
     if k2 == "mn":
         return tree
     l2, fmask2, fbits2, fname2, flen2 = k2
@@ -861,7 +866,7 @@ def factor_fields_all(tree):
     if not isinstance(tree, dict):
         return tree
     new_keys = {}
-    for k, v in tree.items():
+    for k, v in viewitems(tree):
         v = factor_fields(v)
         new_keys[k] = factor_fields_all(v)
     return new_keys
@@ -902,7 +907,7 @@ def add_candidate(bases, c):
 
 
 def getfieldby_name(fields, fname):
-    f = filter(lambda x: hasattr(x, 'fname') and x.fname == fname, fields)
+    f = [x for x in fields if hasattr(x, 'fname') and x.fname == fname]
     if len(f) != 1:
         raise ValueError('more than one field with name: %s' % fname)
     return f[0]
@@ -1023,10 +1028,10 @@ class instruction(object):
                 loc_key = exprloc.loc_key
                 names = symbols.get_location_names(loc_key)
                 # special symbols
-                if '$' in names:
+                if b'$' in names:
                     fixed_expr[exprloc] = self.get_asm_offset(exprloc)
                     continue
-                if '_' in names:
+                if b'_' in names:
                     fixed_expr[exprloc] = self.get_asm_next_offset(exprloc)
                     continue
                 arg_int = symbols.get_location_offset(loc_key)
@@ -1059,8 +1064,7 @@ class instruction(object):
         return
 
 
-class cls_mn(object):
-    __metaclass__ = metamn
+class cls_mn(with_metaclass(metamn, object)):
     args_symb = []
     instruction = instruction
     # Block's offset alignment
@@ -1073,8 +1077,10 @@ class cls_mn(object):
         candidates = set()
 
         fname_values = pre_dis_info
-        todo = [(dict(fname_values), branch, offset * 8)
-                for branch in cls.bintree.items()]
+        todo = [
+            (dict(fname_values), branch, offset * 8)
+            for branch in list(viewitems(cls.bintree))
+        ]
         for fname_values, branch, offset_b in todo:
             (l, fmask, fbits, fname, flen), vals = branch
 
@@ -1091,7 +1097,7 @@ class cls_mn(object):
                     continue
                 if fname is not None and not fname in fname_values:
                     fname_values[fname] = v
-            for nb, v in vals.items():
+            for nb, v in viewitems(vals):
                 if 'mn' in nb:
                     candidates.update(v)
                 else:
@@ -1128,7 +1134,7 @@ class cls_mn(object):
                 setattr(self, f.fname, f)
         if hasattr(self, 'args_permut'):
             args = [args[self.args_permut[i]]
-                    for i in xrange(len(self.args_permut))]
+                    for i in range(len(self.args_permut))]
         to_decode.sort(key=lambda x: (x[1].order, x[0]))
         to_decode = [fields_order.index(f[1]) for f in to_decode]
         self.args = args
@@ -1236,7 +1242,7 @@ class cls_mn(object):
             if not getok:
                 continue
 
-            c.l = prefix_len + total_l / 8
+            c.l = prefix_len + total_l // 8
             for i in c.to_decode:
                 f = c.fields_order[i]
                 if f.is_present:
@@ -1258,7 +1264,7 @@ class cls_mn(object):
             c_args = [a.expr for a in c.args]
             instr = cls.instruction(c.name, mode, c_args,
                                     additional_info=c.additional_info())
-            instr.l = prefix_len + total_l / 8
+            instr.l = prefix_len + total_l // 8
             instr.b = cls.getbytes(bs, offset_o, instr.l)
             instr.offset = offset_o
             instr.get_info(c)
@@ -1278,8 +1284,10 @@ class cls_mn(object):
             for i, o in enumerate(out_c):
                 if o.alias:
                     return out[i]
-            raise NotImplementedError('Multiple disas: \n' +
-                                      "\n".join([str(x) for x in out]))
+            raise NotImplementedError(
+                'Multiple disas: \n' +
+                "\n".join(str(x) for x in out)
+            )
         return out[0]
 
     @classmethod
@@ -1317,7 +1325,7 @@ class cls_mn(object):
                             continue
                         try:
                             total_scans += 1
-                            v, start, stop = p.scanString(args_str).next()
+                            v, start, stop = next(p.scanString(args_str))
                         except StopIteration:
                             v, start, stop = [None], None, None
                         if start != 0:
@@ -1396,7 +1404,7 @@ class cls_mn(object):
                     continue
 
                 # only fix args expr
-                for i in xrange(len(c.args)):
+                for i in range(len(c.args)):
                     c.args[i].expr = args[i]
 
                 v = c.value(instr.mode)
@@ -1408,8 +1416,10 @@ class cls_mn(object):
                 vals += v
                 candidates.append((c, v))
         if len(vals) == 0:
-            raise ValueError('cannot asm %r %r' %
-                             (instr.name, [str(x) for x in instr.args]))
+            raise ValueError(
+                'cannot asm %r %r' %
+                (instr.name, [str(x) for x in instr.args])
+            )
         if len(vals) != 1:
             log.debug('asm multiple args ret default')
 
@@ -1571,7 +1581,7 @@ class imm_noarg(object):
             e, start, stop = parser_result[self.parser]
         else:
             try:
-                e, start, stop = self.parser.scanString(text).next()
+                e, start, stop = next(self.parser.scanString(text))
             except StopIteration:
                 return None, None
         if e == [None]:
diff --git a/miasm2/core/ctypesmngr.py b/miasm2/core/ctypesmngr.py
index 7dafd7e1..94c96f7e 100644
--- a/miasm2/core/ctypesmngr.py
+++ b/miasm2/core/ctypesmngr.py
@@ -522,15 +522,15 @@ class CAstTypes(object):
         if isinstance(ast, c_ast.BinaryOp):
             left = self.ast_eval_int(ast.left)
             right = self.ast_eval_int(ast.right)
-            is_pure_int = (isinstance(left, (int, long)) and
-                           isinstance(right, (int, long)))
+            is_pure_int = (isinstance(left, int) and
+                           isinstance(right, int))
 
             if is_pure_int:
                 if ast.op == '*':
                     result = left * right
                 elif ast.op == '/':
                     assert left % right == 0
-                    result = left / right
+                    result = left // right
                 elif ast.op == '+':
                     result = left + right
                 elif ast.op == '-':
diff --git a/miasm2/core/graph.py b/miasm2/core/graph.py
index e385b044..f585379b 100644
--- a/miasm2/core/graph.py
+++ b/miasm2/core/graph.py
@@ -1,4 +1,6 @@
 from collections import defaultdict, namedtuple
+
+from future.utils import viewitems, viewvalues
 import re
 
 
@@ -54,8 +56,9 @@ class DiGraph(object):
     def __eq__(self, graph):
         if not isinstance(graph, self.__class__):
             return False
-        return all((self._nodes == graph.nodes(),
-                    sorted(self._edges) == sorted(graph.edges())))
+        if self._nodes != graph.nodes():
+            return False
+        return sorted(self._edges) == sorted(graph.edges())
 
     def __ne__(self, other):
         return not self.__eq__(other)
@@ -110,7 +113,7 @@ class DiGraph(object):
 
     def predecessors_iter(self, node):
         if not node in self._nodes_pred:
-            raise StopIteration
+            return
         for n_pred in self._nodes_pred[node]:
             yield n_pred
 
@@ -119,7 +122,7 @@ class DiGraph(object):
 
     def successors_iter(self, node):
         if not node in self._nodes_succ:
-            raise StopIteration
+            return
         for n_suc in self._nodes_succ[node]:
             yield n_suc
 
@@ -165,7 +168,7 @@ class DiGraph(object):
                 if path and path[0] == src:
                     out.append(path + [dst])
         return out
-    
+
     def find_path_from_src(self, src, dst, cycles_count=0, done=None):
         """
         This function does the same as function find_path.
@@ -177,7 +180,7 @@ class DiGraph(object):
         @done: dictionary of already processed loc_keys, it's value is number of times it was processed
         @out: list of paths from @src to @dst
         """
-        
+
         if done is None:
             done = {}
         if src == dst:
@@ -229,10 +232,12 @@ class DiGraph(object):
 
     @staticmethod
     def _attr2str(default_attr, attr):
-        return ' '.join('%s="%s"' % (name, value)
-                        for name, value in
-                        dict(default_attr,
-                             **attr).iteritems())
+        return ' '.join(
+            '%s="%s"' % (name, value)
+            for name, value in
+            viewitems(dict(default_attr,
+                           **attr))
+        )
 
     def dot(self):
         """Render dot graph with HTML"""
@@ -277,8 +282,10 @@ class DiGraph(object):
         for src, dst in self.edges():
             attrs = self.edge_attr(src, dst)
 
-            attrs = ' '.join('%s="%s"' % (name, value)
-                             for name, value in attrs.iteritems())
+            attrs = ' '.join(
+                '%s="%s"' % (name, value)
+                for name, value in viewitems(attrs)
+            )
 
             out.append('%s -> %s' % (self.nodeid(src), self.nodeid(dst)) +
                        '[' + attrs + '];')
@@ -304,7 +311,7 @@ class DiGraph(object):
 
     def predecessors_stop_node_iter(self, node, head):
         if node == head:
-            raise StopIteration
+            return
         for next_node in self.predecessors_iter(node):
             yield next_node
 
@@ -515,7 +522,7 @@ class DiGraph(object):
         frontier = {}
 
         for node in idoms:
-            if self._nodes_pred[node] >= 2:
+            if len(self._nodes_pred[node]) >= 2:
                 for predecessor in self.predecessors_iter(node):
                     runner = predecessor
                     if runner not in idoms:
@@ -894,7 +901,7 @@ class MatchGraph(DiGraph):
         standing for a partial solution
         """
         # Avoid having 2 different joker for the same node
-        if partial_sol and candidate in partial_sol.values():
+        if partial_sol and candidate in viewvalues(partial_sol):
             return False
 
         # Check lambda filtering
@@ -1008,5 +1015,3 @@ class MatchGraph(DiGraph):
                                     MatchGraph._propagate_successors)
                 self._propagate_sol(node, partial_sol, graph, todo,
                                     MatchGraph._propagate_predecessors)
-
-        raise StopIteration
diff --git a/miasm2/core/interval.py b/miasm2/core/interval.py
index 3fde83ad..06dc546f 100644
--- a/miasm2/core/interval.py
+++ b/miasm2/core/interval.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 INT_EQ = 0      # Equivalent
 INT_B_IN_A = 1  # B in A
 INT_A_IN_B = -1 # A in B
@@ -232,16 +234,16 @@ class interval(object):
             import Image
             import ImageDraw
         except ImportError:
-            print 'cannot import python PIL imaging'
+            print('cannot import python PIL imaging')
             return
 
         img = Image.new('RGB', (img_x, img_y), (100, 100, 100))
         draw = ImageDraw.Draw(img)
         i_min, i_max = self.hull()
 
-        print hex(i_min), hex(i_max)
+        print(hex(i_min), hex(i_max))
 
-        addr2x = lambda addr: (addr - i_min) * img_x / (i_max - i_min)
+        addr2x = lambda addr: ((addr - i_min) * img_x) // (i_max - i_min)
         for a, b in self.intervals:
             draw.rectangle((addr2x(a), 0, addr2x(b), img_y), (200, 0, 0))
 
diff --git a/miasm2/core/locationdb.py b/miasm2/core/locationdb.py
index 4c5da29e..906a247a 100644
--- a/miasm2/core/locationdb.py
+++ b/miasm2/core/locationdb.py
@@ -1,11 +1,16 @@
 import warnings
+from builtins import int as int_types
 
+from functools import reduce
+from future.utils import viewitems, viewvalues
+
+from miasm2.core.utils import printable, force_bytes
 from miasm2.expression.expression import LocKey, ExprLoc
 from miasm2.expression.modint import moduint, modint
 
 
 def is_int(a):
-    return isinstance(a, (int, long, moduint, modint))
+    return isinstance(a, (int_types, moduint, modint))
 
 
 class LocationDB(object):
@@ -85,6 +90,7 @@ class LocationDB(object):
         Return the LocKey of @name if any, None otherwise.
         @name: target name
         """
+        name = force_bytes(name)
         return self._name_to_loc_key.get(name)
 
     def get_or_create_name_location(self, name):
@@ -92,6 +98,7 @@ class LocationDB(object):
         Return the LocKey of @name if any, create one otherwise.
         @name: target name
         """
+        name = force_bytes(name)
         loc_key = self._name_to_loc_key.get(name)
         if loc_key is not None:
             return loc_key
@@ -100,7 +107,7 @@ class LocationDB(object):
     def get_offset_location(self, offset):
         """
         Return the LocKey of @offset if any, None otherwise.
-        @name: target offset
+        @offset: target offset
         """
         return self._offset_to_loc_key.get(offset)
 
@@ -119,6 +126,7 @@ class LocationDB(object):
         Return the offset of @name if any, None otherwise.
         @name: target name
         """
+        name = force_bytes(name)
         loc_key = self.get_name_location(name)
         if loc_key is None:
             return None
@@ -129,6 +137,7 @@ class LocationDB(object):
         @name: str instance
         @loc_key: LocKey instance
         """
+        name = force_bytes(name)
         assert loc_key in self._loc_keys
         already_existing_loc = self._name_to_loc_key.get(name)
         if already_existing_loc is not None and already_existing_loc != loc_key:
@@ -144,6 +153,7 @@ class LocationDB(object):
         @loc_key: LocKey instance
         """
         assert loc_key in self._loc_keys
+        name = force_bytes(name)
         already_existing_loc = self._name_to_loc_key.get(name)
         if already_existing_loc is None:
             raise KeyError("%r is not already associated" % name)
@@ -195,13 +205,13 @@ class LocationDB(object):
         """Ensure internal structures are consistent with each others"""
         assert set(self._loc_key_to_names).issubset(self._loc_keys)
         assert set(self._loc_key_to_offset).issubset(self._loc_keys)
-        assert self._loc_key_to_offset == {v: k for k, v in self._offset_to_loc_key.iteritems()}
+        assert self._loc_key_to_offset == {v: k for k, v in viewitems(self._offset_to_loc_key)}
         assert reduce(
             lambda x, y:x.union(y),
-            self._loc_key_to_names.itervalues(),
+            viewvalues(self._loc_key_to_names),
             set(),
         ) == set(self._name_to_loc_key)
-        for name, loc_key in self._name_to_loc_key.iteritems():
+        for name, loc_key in viewitems(self._name_to_loc_key):
             assert name in self._loc_key_to_names[loc_key]
 
     def find_free_name(self, name):
@@ -211,6 +221,7 @@ class LocationDB(object):
 
         @name: string
         """
+        name = force_bytes(name)
         if self.get_name_location(name) is None:
             return name
         i = 0
@@ -233,6 +244,7 @@ class LocationDB(object):
         LocKey may be updated and will be returned.
         """
 
+        name = force_bytes(name)
         # Deprecation handling
         if is_int(name):
             assert offset is None or offset == name
@@ -321,6 +333,14 @@ class LocationDB(object):
         """Return a human readable version of @loc_key, according to information
         available in this LocationDB instance"""
         names = self.get_location_names(loc_key)
+        new_names = set()
+        for name in names:
+            try:
+                name = name.decode()
+            except AttributeError:
+                pass
+            new_names.add(name)
+        names = new_names
         if names:
             return ",".join(names)
         offset = self.get_location_offset(loc_key)
@@ -336,23 +356,25 @@ class LocationDB(object):
     @property
     def names(self):
         """Return all known names"""
-        return self._name_to_loc_key.keys()
+        return list(self._name_to_loc_key)
 
     @property
     def offsets(self):
         """Return all known offsets"""
-        return self._offset_to_loc_key.keys()
+        return list(self._offset_to_loc_key)
 
     def __str__(self):
         out = []
         for loc_key in self._loc_keys:
             names = self.get_location_names(loc_key)
             offset = self.get_location_offset(loc_key)
-            out.append("%s: %s - %s" % (
-                loc_key,
-                "0x%x" % offset if offset is not None else None,
-                ",".join(names)
-            ))
+            out.append(
+                "%s: %s - %s" % (
+                    loc_key,
+                    "0x%x" % offset if offset is not None else None,
+                    ",".join(printable(name) for name in names)
+                )
+            )
         return "\n".join(out)
 
     def merge(self, location_db):
diff --git a/miasm2/core/objc.py b/miasm2/core/objc.py
index 14352c7b..30b00682 100644
--- a/miasm2/core/objc.py
+++ b/miasm2/core/objc.py
@@ -5,10 +5,14 @@ C helper for Miasm:
 * Miasm expression to C type
 """
 
+from builtins import zip
+from builtins import int as int_types
 
 import warnings
 from pycparser import c_parser, c_ast
+from functools import total_ordering
 
+from miasm2.core.utils import cmp_elts
 from miasm2.expression.expression_reduce import ExprReducer
 from miasm2.expression.expression import ExprInt, ExprId, ExprOp, ExprMem
 
@@ -65,6 +69,7 @@ def objc_to_str(objc, result=None):
     return result
 
 
+@total_ordering
 class ObjC(object):
     """Generic ObjC"""
 
@@ -87,10 +92,13 @@ class ObjC(object):
         assert other.__class__ in OBJC_PRIO
 
         if OBJC_PRIO[self.__class__] != OBJC_PRIO[other.__class__]:
-            return cmp(OBJC_PRIO[self.__class__], OBJC_PRIO[other.__class__])
+            return cmp_elts(
+                OBJC_PRIO[self.__class__],
+                OBJC_PRIO[other.__class__]
+            )
         if self.align != other.align:
-            return cmp(self.align, other.align)
-        return cmp(self.size, other.size)
+            return cmp_elts(self.align, other.align)
+        return cmp_elts(self.size, other.size)
 
     def __hash__(self):
         return hash((self.__class__, self._align, self._size))
@@ -98,7 +106,18 @@ class ObjC(object):
     def __str__(self):
         return objc_to_str(self)
 
+    def __eq__(self, other):
+        return self.cmp_base(other) == 0
+
+    def __ne__(self, other):
+        # required Python 2.7.14
+        return not self == other
+
+    def __lt__(self, other):
+        return self.cmp_base(other) < 0
+
 
+@total_ordering
 class ObjCDecl(ObjC):
     """C Declaration identified"""
 
@@ -117,11 +136,19 @@ class ObjCDecl(ObjC):
     def __str__(self):
         return str(self.name)
 
-    def __cmp__(self, other):
+    def __eq__(self, other):
+        ret = self.cmp_base(other)
+        if ret:
+            return False
+        return self.name == other.name
+
+    def __lt__(self, other):
         ret = self.cmp_base(other)
         if ret:
-            return ret
-        return cmp(self.name, other.name)
+            if ret < 0:
+                return True
+            return False
+        return self.name < other.name
 
 
 class ObjCInt(ObjC):
@@ -133,10 +160,8 @@ class ObjCInt(ObjC):
     def __str__(self):
         return 'int'
 
-    def __cmp__(self, other):
-        return self.cmp_base(other)
-
 
+@total_ordering
 class ObjCPtr(ObjC):
     """C Pointer"""
 
@@ -172,16 +197,27 @@ class ObjCPtr(ObjC):
         return hash((super(ObjCPtr, self).__hash__(), hash(self._objtype)))
 
     def __repr__(self):
-        return '<%s %r>' % (self.__class__.__name__,
-                            self.objtype.__class__)
+        return '<%s %r>' % (
+            self.__class__.__name__,
+            self.objtype.__class__
+        )
+
+    def __eq__(self, other):
+        ret = self.cmp_base(other)
+        if ret:
+            return False
+        return self.objtype == other.objtype
 
-    def __cmp__(self, other):
+    def __lt__(self, other):
         ret = self.cmp_base(other)
         if ret:
-            return ret
-        return cmp(self.objtype, other.objtype)
+            if ret < 0:
+                return True
+            return False
+        return self.objtype < other.objtype
 
 
+@total_ordering
 class ObjCArray(ObjC):
     """C array (test[XX])"""
 
@@ -205,16 +241,23 @@ class ObjCArray(ObjC):
     def __repr__(self):
         return '<%r[%d]>' % (self.objtype, self.elems)
 
-    def __cmp__(self, other):
+    def __eq__(self, other):
         ret = self.cmp_base(other)
         if ret:
-            return ret
-        ret = cmp(self.elems, other.elems)
-        if ret:
-            return ret
-        return cmp(self.objtype, other.objtype)
+            return False
+        if self.objtype != other.objtype:
+            return False
+        return self.elems == other.elems
 
+    def __lt__(self, other):
+        ret = self.cmp_base(other)
+        if ret > 0:
+            return False
+        if self.objtype > other.objtype:
+            return False
+        return self.elems < other.elems
 
+@total_ordering
 class ObjCStruct(ObjC):
     """C object for structures"""
 
@@ -241,12 +284,22 @@ class ObjCStruct(ObjC):
     def __str__(self):
         return 'struct %s' % (self.name)
 
-    def __cmp__(self, other):
+    def __eq__(self, other):
         ret = self.cmp_base(other)
         if ret:
-            return ret
-        return cmp(self.name, other.name)
+            return False
+        return self.name == other.name
+
+    def __lt__(self, other):
+        ret = self.cmp_base(other)
+        if ret:
+            if ret < 0:
+                return True
+            return False
+        return self.name < other.name
+
 
+@total_ordering
 class ObjCUnion(ObjC):
     """C object for unions"""
 
@@ -273,11 +326,19 @@ class ObjCUnion(ObjC):
     def __str__(self):
         return 'union %s' % (self.name)
 
-    def __cmp__(self, other):
+    def __eq__(self, other):
+        ret = self.cmp_base(other)
+        if ret:
+            return False
+        return self.name == other.name
+
+    def __lt__(self, other):
         ret = self.cmp_base(other)
         if ret:
-            return ret
-        return cmp(self.name, other.name)
+            if ret < 0:
+                return True
+            return False
+        return self.name < other.name
 
 class ObjCEllipsis(ObjC):
     """C integer"""
@@ -288,10 +349,7 @@ class ObjCEllipsis(ObjC):
     align = property(lambda self: self._align)
     size = property(lambda self: self._size)
 
-    def __cmp__(self, other):
-        return self.cmp_base(other)
-
-
+@total_ordering
 class ObjCFunc(ObjC):
     """C object for Functions"""
 
@@ -311,8 +369,10 @@ class ObjCFunc(ObjC):
         return hash((super(ObjCFunc, self).__hash__(), hash(self._args), self._name))
 
     def __repr__(self):
-        return "<%s %s>" % (self.__class__.__name__,
-                            self.name)
+        return "<%s %s>" % (
+            self.__class__.__name__,
+            self.name
+        )
 
     def __str__(self):
         out = []
@@ -323,11 +383,19 @@ class ObjCFunc(ObjC):
             out.append("  %s %s" % (name, arg))
         return '\n'.join(out)
 
-    def __cmp__(self, other):
+    def __eq__(self, other):
+        ret = self.cmp_base(other)
+        if ret:
+            return False
+        return self.name == other.name
+
+    def __lt__(self, other):
         ret = self.cmp_base(other)
         if ret:
-            return ret
-        return cmp(self.name, other.name)
+            if ret < 0:
+                return True
+            return False
+        return self.name < other.name
 
 OBJC_PRIO = {
     ObjC: 0,
@@ -448,7 +516,7 @@ class CGenInt(CGen):
     """Int C object"""
 
     def __init__(self, integer):
-        assert isinstance(integer, (int, long))
+        assert isinstance(integer, int_types)
         self._integer = integer
         super(CGenInt, self).__init__(ObjCInt())
 
@@ -898,7 +966,7 @@ class ExprToAccessC(ExprReducer):
             if base_type.objtype.size == 0:
                 missing_definition(base_type.objtype)
                 return set()
-            element_num = offset / (base_type.objtype.size)
+            element_num = offset // (base_type.objtype.size)
             field_offset = offset % base_type.objtype.size
             if element_num >= base_type.elems:
                 return set()
@@ -919,7 +987,7 @@ class ExprToAccessC(ExprReducer):
         elif isinstance(base_type, ObjCDecl):
             if self.enforce_strict_access and offset % base_type.size != 0:
                 return set()
-            elem_num = offset / base_type.size
+            elem_num = offset // base_type.size
 
             nobj = CGenArray(cgenobj, elem_num,
                              void_type.align, void_type.size)
@@ -942,7 +1010,7 @@ class ExprToAccessC(ExprReducer):
             new_type = out
 
         elif isinstance(base_type, ObjCPtr):
-            elem_num = offset / base_type.size
+            elem_num = offset // base_type.size
             if self.enforce_strict_access and offset % base_type.size != 0:
                 return set()
             nobj = CGenArray(cgenobj, elem_num,
@@ -1025,7 +1093,7 @@ class ExprToAccessC(ExprReducer):
                 target = nobj.ctype.objtype
                 for finalcgenobj in self.cgen_access(nobj, target, 0, True, lvl):
                     assert isinstance(finalcgenobj.ctype, ObjCPtr)
-                    if self.enforce_strict_access and finalcgenobj.ctype.objtype.size != node.expr.size / 8:
+                    if self.enforce_strict_access and finalcgenobj.ctype.objtype.size != node.expr.size // 8:
                         continue
                     found.add(CGenDeref(finalcgenobj))
 
@@ -1035,16 +1103,16 @@ class ExprToAccessC(ExprReducer):
                 if isinstance(target, (ObjCStruct, ObjCUnion)):
                     for finalcgenobj in self.cgen_access(subcgenobj, target, 0, True, lvl):
                         target = finalcgenobj.ctype.objtype
-                        if self.enforce_strict_access and target.size != node.expr.size / 8:
+                        if self.enforce_strict_access and target.size != node.expr.size // 8:
                             continue
                         found.add(CGenDeref(finalcgenobj))
                 elif isinstance(target, ObjCArray):
-                    if self.enforce_strict_access and subcgenobj.ctype.size != node.expr.size / 8:
+                    if self.enforce_strict_access and subcgenobj.ctype.size != node.expr.size // 8:
                         continue
                     found.update(self.cgen_access(CGenDeref(subcgenobj), target,
                                                   0, False, lvl))
                 else:
-                    if self.enforce_strict_access and target.size != node.expr.size / 8:
+                    if self.enforce_strict_access and target.size != node.expr.size // 8:
                         continue
                     found.add(CGenDeref(subcgenobj))
         if not found:
@@ -1504,14 +1572,14 @@ class CTypesManager(object):
             elif size.operator == "*":
                 return arg0 * arg1
             elif size.operator == "/":
-                return arg0 / arg1
+                return arg0 // arg1
             elif size.operator == "<<":
                 return arg0 << arg1
             elif size.operator == ">>":
                 return arg0 >> arg1
             else:
                 raise ValueError("Unknown operator %s" % size.operator)
-        elif isinstance(size, (int, long)):
+        elif isinstance(size, int_types):
             return size
         elif isinstance(size, CTypeSizeof):
             obj = self._get_objc(size.target)
diff --git a/miasm2/core/parse_asm.py b/miasm2/core/parse_asm.py
index 7ddf838c..e9982503 100644
--- a/miasm2/core/parse_asm.py
+++ b/miasm2/core/parse_asm.py
@@ -1,5 +1,7 @@
 #-*- coding:utf-8 -*-
 import re
+import codecs
+from builtins import range
 
 from miasm2.expression.expression import ExprId, ExprInt, ExprOp, LocKey
 import miasm2.core.asmblock as asmblock
@@ -63,7 +65,7 @@ def guess_next_new_label(loc_db):
     """Generate a new label
     @loc_db: the LocationDB instance"""
     i = 0
-    gen_name = "loc_%.8X"
+    gen_name = b"loc_%.8X"
     while True:
         name = gen_name % i
         label = loc_db.get_name_location(name)
@@ -78,7 +80,7 @@ STATE_IN_BLOC = 1
 
 def asm_ast_to_expr_with_size(arg, loc_db, size):
     if isinstance(arg, AstId):
-        return ExprId(arg.name, size)
+        return ExprId(arg.name.encode(), size)
     if isinstance(arg, AstOp):
         args = [asm_ast_to_expr_with_size(tmp, loc_db, size) for tmp in arg.args]
         return ExprOp(arg.op, *args)
@@ -119,7 +121,7 @@ def parse_txt(mnemo, attrib, txt, loc_db=None):
         # label beginning with .L
         match_re = LABEL_RE.match(line)
         if match_re:
-            label_name = match_re.group(1)
+            label_name = match_re.group(1).encode()
             label = loc_db.get_or_create_name_location(label_name)
             lines.append(label)
             continue
@@ -133,18 +135,20 @@ def parse_txt(mnemo, attrib, txt, loc_db=None):
                 # XXX HACK
                 line = line.replace(r'\n', '\n').replace(r'\r', '\r')
                 raw = line[line.find(r'"') + 1:line.rfind(r'"')]
-                raw = raw.decode('string_escape')
+                raw = codecs.escape_decode(raw)[0]
                 if directive == 'string':
-                    raw += "\x00"
+                    raw += b"\x00"
                 lines.append(asmblock.AsmRaw(raw))
                 continue
             if directive == 'ustring':
                 # XXX HACK
                 line = line.replace(r'\n', '\n').replace(r'\r', '\r')
                 raw = line[line.find(r'"') + 1:line.rfind(r'"')] + "\x00"
-                raw = raw.decode('string_escape')
-                raw = "".join([string + '\x00' for string in raw])
-                lines.append(asmblock.AsmRaw(raw))
+                raw = codecs.escape_decode(raw)[0]
+                out = b''
+                for i in range(len(raw)):
+                    out += raw[i:i+1] + b'\x00'
+                lines.append(asmblock.AsmRaw(out))
                 continue
             if directive in declarator:
                 data_raw = line[match_re.end():].split(' ', 1)[1]
@@ -183,12 +187,12 @@ def parse_txt(mnemo, attrib, txt, loc_db=None):
             if directive[0:4] == 'cfi_':
                 continue
 
-            raise ValueError("unknown directive %s" % str(directive))
+            raise ValueError("unknown directive %s" % directive)
 
         # label
         match_re = LABEL_RE.match(line)
         if match_re:
-            label_name = match_re.group(1)
+            label_name = match_re.group(1).encode()
             label = loc_db.get_or_create_name_location(label_name)
             lines.append(label)
             continue
diff --git a/miasm2/core/sembuilder.py b/miasm2/core/sembuilder.py
index 5694ffa3..8ea4c4ac 100644
--- a/miasm2/core/sembuilder.py
+++ b/miasm2/core/sembuilder.py
@@ -4,6 +4,8 @@ import inspect
 import ast
 import re
 
+from future.utils import PY3
+
 import miasm2.expression.expression as m2_expr
 from miasm2.ir.ir import IRBlock, AssignBlock
 
@@ -30,7 +32,6 @@ class MiasmTransformer(ast.NodeTransformer):
 
         # Recursive visit
         node = self.generic_visit(node)
-
         if isinstance(node.func, ast.Name):
             # iX(Y) -> ExprInt(Y, X)
             fc_name = node.func.id
@@ -110,6 +111,17 @@ class MiasmTransformer(ast.NodeTransformer):
                                starargs=None,
                                kwargs=None)
 
+if PY3:
+    def get_arg_name(name):
+        return name.arg
+    def gen_arg(name, ctx):
+        return ast.arg(arg=name, ctx=ctx)
+else:
+    def get_arg_name(name):
+        return name.id
+    def gen_arg(name, ctx):
+        return ast.Name(id=name, ctx=ctx)
+
 
 class SemBuilder(object):
     """Helper for building instruction's semantic side effects method
@@ -300,7 +312,7 @@ class SemBuilder(object):
         # Get the function AST
         parsed = ast.parse(inspect.getsource(func))
         fc_ast = parsed.body[0]
-        argument_names = [name.id for name in fc_ast.args.args]
+        argument_names = [get_arg_name(name) for name in fc_ast.args.args]
 
         # Init local cache
         self._local_ctx = {}
@@ -309,8 +321,10 @@ class SemBuilder(object):
         blocks, body = self._parse_body(fc_ast.body, argument_names)
 
         # Build the new function
-        fc_ast.args.args[0:0] = [ast.Name(id='ir', ctx=ast.Param()),
-                                 ast.Name(id='instr', ctx=ast.Param())]
+        fc_ast.args.args[0:0] = [
+            gen_arg('ir', ast.Param()),
+            gen_arg('instr', ast.Param())
+        ]
         cur_instr = blocks[0][0]
         if len(blocks[-1][0]) == 0:
             ## Last block can be empty
diff --git a/miasm2/core/types.py b/miasm2/core/types.py
index 051c4cca..b915c27f 100644
--- a/miasm2/core/types.py
+++ b/miasm2/core/types.py
@@ -102,9 +102,13 @@ Note that some structures (e.g. MemStr or MemArray) do not have a static
 size and cannot be allocated automatically.
 """
 
+from builtins import range, zip
+from builtins import int as int_types
 import itertools
 import logging
 import struct
+from future.utils import PY3
+from future.utils import viewitems, with_metaclass
 
 log = logging.getLogger(__name__)
 console_handler = logging.StreamHandler()
@@ -155,7 +159,7 @@ def indent(s, size=4):
 # String generic getter/setter/len-er
 # TODO: make miasm2.os_dep.common and jitter ones use these ones
 
-def get_str(vm, addr, enc, max_char=None, end='\x00'):
+def get_str(vm, addr, enc, max_char=None, end=u'\x00'):
     """Get a @end (by default '\\x00') terminated @enc encoded string from a
     VmMngr.
 
@@ -186,7 +190,7 @@ def get_str(vm, addr, enc, max_char=None, end='\x00'):
             break
         s.append(c)
         i += step
-    return ''.join(s).decode(enc)
+    return b''.join(s).decode(enc)
 
 def raw_str(s, enc, end=u'\x00'):
     """Returns a string representing @s as an @end (by default \\x00)
@@ -225,7 +229,7 @@ def raw_len(py_unic_str, enc, end=u'\x00'):
     """
     return len(raw_str(py_unic_str, enc))
 
-def enc_triplet(enc, max_char=None, end='\x00'):
+def enc_triplet(enc, max_char=None, end=u'\x00'):
     """Returns a triplet of functions (get_str_enc, set_str_enc, raw_len_enc)
     for a given encoding (as needed by Str to add an encoding). The prototypes
     are:
@@ -310,8 +314,11 @@ class Type(object):
         Called by self.lval when it is not in cache.
         """
         pinned_base_class = self._get_pinned_base_class()
-        pinned_type = type("Mem%r" % self, (pinned_base_class,),
-                           {'_type': self})
+        pinned_type = type(
+            "Mem%r" % self,
+            (pinned_base_class,),
+            {'_type': self}
+        )
         return pinned_type
 
     def _get_pinned_base_class(self):
@@ -344,7 +351,7 @@ class Type(object):
         raise NotImplementedError("Abstract method")
 
     def __ne__(self, other):
-        return not self.__eq__(other)
+        return not self == other
 
 
 class RawStruct(Type):
@@ -373,7 +380,7 @@ class RawStruct(Type):
         return self.__class__ == other.__class__ and self._fmt == other._fmt
 
     def __ne__(self, other):
-        return not self.__eq__(other)
+        return not self == other
 
     def __hash__(self):
         return hash((self.__class__, self._fmt))
@@ -495,7 +502,7 @@ class Ptr(Num):
 
         # Actual job
         dst_addr = self.get_val(vm, addr)
-        vm.set_mem(dst_addr, str(val))
+        vm.set_mem(dst_addr, bytes(val))
 
     def _get_pinned_base_class(self):
         return MemPtr
@@ -510,7 +517,7 @@ class Ptr(Num):
                 self._type_kwargs == other._type_kwargs
 
     def __ne__(self, other):
-        return not self.__eq__(other)
+        return not self == other
 
     def __hash__(self):
         return hash((super(Ptr, self).__hash__(), self.dst_type,
@@ -587,7 +594,7 @@ class Struct(Type):
                         # But the current offset is added
                         'offset': fd['offset'] + offset,
                     }
-                    for name, fd in field._fields_desc.iteritems()
+                    for name, fd in viewitems(field._fields_desc)
                 }
 
                 # Add the newly generated fields from the anon field
@@ -629,7 +636,7 @@ class Struct(Type):
         return self._fields
 
     def set(self, vm, addr, val):
-        raw = str(val)
+        raw = bytes(val)
         vm.set_mem(addr, raw)
 
     def get(self, vm, addr):
@@ -683,7 +690,7 @@ class Struct(Type):
                 self.name == other.name
 
     def __ne__(self, other):
-        return not self.__eq__(other)
+        return not self == other
 
     def __hash__(self):
         # Only hash name, not fields, because if a field is a Ptr to this
@@ -771,7 +778,7 @@ class Array(Type):
         if isinstance(val, MemSizedArray):
             if val.array_len != self.array_len or len(val) != self.size:
                 raise ValueError("Size mismatch in MemSizedArray assignment")
-            raw = str(val)
+            raw = bytes(val)
             vm.set_mem(addr, raw)
 
         # list assignment
@@ -810,7 +817,7 @@ class Array(Type):
         if isinstance(idx, slice):
             res = []
             idx = self._normalize_slice(idx)
-            for i in xrange(idx.start, idx.stop, idx.step):
+            for i in range(idx.start, idx.stop, idx.step):
                 res.append(self.field_type.get(vm, addr + self.get_offset(i)))
             return res
         else:
@@ -823,9 +830,9 @@ class Array(Type):
         """
         if isinstance(idx, slice):
             idx = self._normalize_slice(idx)
-            if len(item) != len(xrange(idx.start, idx.stop, idx.step)):
+            if len(item) != len(range(idx.start, idx.stop, idx.step)):
                 raise ValueError("Mismatched lengths in slice assignment")
-            for i, val in itertools.izip(xrange(idx.start, idx.stop, idx.step),
+            for i, val in zip(range(idx.start, idx.stop, idx.step),
                                          item):
                 self.field_type.set(vm, addr + self.get_offset(i), val)
         else:
@@ -855,7 +862,7 @@ class Array(Type):
         return slice(start, stop, step)
 
     def _check_bounds(self, idx):
-        if not isinstance(idx, (int, long)):
+        if not isinstance(idx, int_types):
             raise ValueError("index must be an int or a long")
         if idx < 0 or (self.is_sized() and idx >= self.size):
             raise IndexError("Index %s out of bounds" % idx)
@@ -875,7 +882,7 @@ class Array(Type):
                 self.array_len == other.array_len
 
     def __ne__(self, other):
-        return not self.__eq__(other)
+        return not self == other
 
     def __hash__(self):
         return hash((self.__class__, self.field_type, self.array_len))
@@ -942,7 +949,7 @@ class Bits(Type):
                 self._bit_offset == other._bit_offset
 
     def __ne__(self, other):
-        return not self.__eq__(other)
+        return not self == other
 
     def __hash__(self):
         return hash((self.__class__, self._num, self._bits, self._bit_offset))
@@ -1002,7 +1009,7 @@ class BitField(Union):
                 self._num == other._num and super(BitField, self).__eq__(other)
 
     def __ne__(self, other):
-        return not self.__eq__(other)
+        return not self == other
 
     def __hash__(self):
         return hash((super(BitField, self).__hash__(), self._num))
@@ -1117,7 +1124,7 @@ class Str(Type):
         return self.__class__ == other.__class__ and self._enc == other._enc
 
     def __ne__(self, other):
-        return not self.__eq__(other)
+        return not self == other
 
     def __hash__(self):
         return hash((self.__class__, self._enc))
@@ -1136,7 +1143,7 @@ class Void(Type):
         return self.__class__ == other.__class__
 
     def __ne__(self, other):
-        return not self.__eq__(other)
+        return not self == other
 
     def __hash__(self):
         return hash(self.__class__)
@@ -1191,7 +1198,7 @@ class _MetaMemStruct(_MetaMemType):
             cls.gen_fields()
 
 
-class MemType(object):
+class MemType(with_metaclass(_MetaMemType, object)):
     """Base class for classes that allow to map python objects to C types in
     virtual memory. Represents an lvalue of a given type.
 
@@ -1200,7 +1207,6 @@ class MemType(object):
     The main exception is MemStruct, which you may want to subclass yourself
     for syntactic ease.
     """
-    __metaclass__ = _MetaMemType
 
     # allocator is a function(vm, size) -> allocated_address
     allocator = None
@@ -1278,12 +1284,12 @@ class MemType(object):
         """
         return self.sizeof()
 
-    def memset(self, byte='\x00'):
+    def memset(self, byte=b'\x00'):
         """Fill the memory space of this MemType with @byte ('\x00' by
         default). The size is retrieved with self.get_size() (dynamic size).
         """
         # TODO: multibyte patterns
-        if not isinstance(byte, str) or not len(byte) == 1:
+        if not isinstance(byte, bytes) or len(byte) != 1:
             raise ValueError("byte must be a 1-lengthed str")
         self._vm.set_mem(self.get_addr(), byte * self.get_size())
 
@@ -1319,6 +1325,11 @@ class MemType(object):
         return self.get_size()
 
     def __str__(self):
+        if PY3:
+            return repr(self)
+        return self.__bytes__()
+
+    def __bytes__(self):
         return self.raw()
 
     def __repr__(self):
@@ -1327,7 +1338,7 @@ class MemType(object):
     def __eq__(self, other):
         return self.__class__ == other.__class__ and \
                 self.get_type() == other.get_type() and \
-                str(self) == str(other)
+                bytes(self) == bytes(other)
 
     def __ne__(self, other):
         return not self == other
@@ -1350,7 +1361,7 @@ class MemValue(MemType):
         return "%r: %r" % (self.__class__, self.val)
 
 
-class MemStruct(MemType):
+class MemStruct(with_metaclass(_MetaMemStruct, MemType)):
     """Base class to easily implement VmMngr backed C-like structures in miasm.
     Represents a structure in virtual memory.
 
@@ -1403,7 +1414,6 @@ class MemStruct(MemType):
     doc for more information on how to handle recursive types and cyclic
     dependencies.
     """
-    __metaclass__ = _MetaMemStruct
     fields = None
 
     def get_addr(self, field_name=None):
@@ -1667,7 +1677,7 @@ class MemSizedArray(MemArray):
         return self.get_type().size
 
     def __iter__(self):
-        for i in xrange(self.get_type().array_len):
+        for i in range(self.get_type().array_len):
             yield self[i]
 
     def raw(self):
diff --git a/miasm2/core/utils.py b/miasm2/core/utils.py
index c1f48418..9856d4f2 100644
--- a/miasm2/core/utils.py
+++ b/miasm2/core/utils.py
@@ -1,7 +1,15 @@
+from __future__ import print_function
+from builtins import range
 import struct
 import inspect
-import UserDict
+from collections import MutableMapping as DictMixin
+
 from operator import itemgetter
+import codecs
+
+from future.utils import viewitems
+
+import collections
 
 upck8 = lambda x: struct.unpack('B', x)[0]
 upck16 = lambda x: struct.unpack('H', x)[0]
@@ -62,23 +70,57 @@ class Disasm_Exception(Exception):
     pass
 
 
+def printable(string):
+    if isinstance(string, bytes):
+        return "".join(
+            c.decode() if b" " <= c < b"~" else "."
+            for c in (string[i:i+1] for i in range(len(string)))
+        )
+    return string
+
+
+def force_bytes(value):
+    try:
+        return value.encode()
+    except AttributeError:
+        return value
+
+
+def iterbytes(string):
+    for i in range(len(string)):
+        yield string[i:i+1]
+
+
+def int_to_byte(value):
+    return struct.pack('B', value)
+
+def cmp_elts(elt1, elt2):
+    return (elt1 > elt2) - (elt1 < elt2)
+
+
+_DECODE_HEX = codecs.getdecoder("hex_codec")
+_ENCODE_HEX = codecs.getencoder("hex_codec")
+
+def decode_hex(value):
+    return _DECODE_HEX(value)[0]
+
+def encode_hex(value):
+    return _ENCODE_HEX(value)[0]
+
+
 def hexdump(src, length=16):
-    FILTER = ''.join(
-        [(len(repr(chr(x))) == 3) and chr(x) or '.' for x in range(256)])
     lines = []
-    for c in xrange(0, len(src), length):
+    for c in range(0, len(src), length):
         chars = src[c:c + length]
-        hexa = ' '.join(["%02x" % ord(x) for x in chars])
+        hexa = ' '.join("%02x" % ord(x) for x in iterbytes(chars))
         printable = ''.join(
-            ["%s" % ((ord(x) <= 127 and FILTER[ord(x)]) or '.') for x in chars])
+            x.decode() if 32 <= ord(x) <= 126 else '.' for x in iterbytes(chars)
+        )
         lines.append("%04x  %-*s  %s\n" % (c, length * 3, hexa, printable))
-    print ''.join(lines)
-
-# stackoverflow.com/questions/2912231
-
-import collections
+    print(''.join(lines))
 
 
+# stackoverflow.com/questions/2912231
 class keydefaultdict(collections.defaultdict):
 
     def __missing__(self, key):
@@ -88,7 +130,7 @@ class keydefaultdict(collections.defaultdict):
         return value
 
 
-class BoundedDict(UserDict.DictMixin):
+class BoundedDict(DictMixin):
 
     """Limited in size dictionary.
 
@@ -108,7 +150,7 @@ class BoundedDict(UserDict.DictMixin):
         @delete_cb: (optional) callback called when an element is removed
         """
         self._data = initialdata.copy() if initialdata else {}
-        self._min_size = min_size if min_size else max_size / 3
+        self._min_size = min_size if min_size else max_size // 3
         self._max_size = max_size
         self._size = len(self._data)
         # Do not use collections.Counter as it is quite slow
@@ -122,8 +164,11 @@ class BoundedDict(UserDict.DictMixin):
 
             # Bound can only be reached on a new element
             if (self._size >= self._max_size):
-                most_common = sorted(self._counter.iteritems(),
-                                     key=itemgetter(1), reverse=True)
+                most_common = sorted(
+                    viewitems(self._counter),
+                    key=itemgetter(1),
+                    reverse=True
+                )
 
                 # Handle callback
                 if self._delete_cb is not None:
@@ -154,7 +199,7 @@ class BoundedDict(UserDict.DictMixin):
 
     def keys(self):
         "Return the list of dict's keys"
-        return self._data.keys()
+        return list(self._data)
 
     @property
     def data(self):
@@ -180,3 +225,10 @@ class BoundedDict(UserDict.DictMixin):
         if self._delete_cb:
             for key in self._data:
                 self._delete_cb(key)
+
+
+    def __len__(self):
+        return len(self._data)
+
+    def __iter__(self):
+        return iter(self._data)
diff --git a/miasm2/expression/expression.py b/miasm2/expression/expression.py
index 925190ca..03febbfd 100644
--- a/miasm2/expression/expression.py
+++ b/miasm2/expression/expression.py
@@ -29,11 +29,19 @@
 #
 
 
+from builtins import zip
+from builtins import range
 import warnings
 import itertools
+from builtins import int as int_types
+from functools import cmp_to_key, total_ordering
+from future.utils import viewitems
+
+from miasm2.core.utils import force_bytes, cmp_elts
 from miasm2.expression.modint import mod_size2uint, is_modint, size2mask, \
     define_uint
 from miasm2.core.graph import DiGraph
+from functools import reduce
 
 # Define tokens
 TOK_INF = "<"
@@ -145,7 +153,7 @@ class DiGraphExpr(DiGraph):
         return ""
 
 
-
+@total_ordering
 class LocKey(object):
     def __init__(self, key):
         self._key = key
@@ -163,7 +171,11 @@ class LocKey(object):
         return self.key == other.key
 
     def __ne__(self, other):
-        return not self.__eq__(other)
+        # required Python 2.7.14
+        return not self == other
+
+    def __lt__(self, other):
+        return self.key < other.key
 
     def __repr__(self):
         return "<%s %d>" % (self.__class__.__name__, self._key)
@@ -202,11 +214,11 @@ class Expr(object):
     @staticmethod
     def get_object(expr_cls, args):
         if not expr_cls.use_singleton:
-            return object.__new__(expr_cls, args)
+            return object.__new__(expr_cls)
 
         expr = Expr.args2expr.get((expr_cls, args))
         if expr is None:
-            expr = object.__new__(expr_cls, args)
+            expr = object.__new__(expr_cls)
             Expr.args2expr[(expr_cls, args)] = expr
         return expr
 
@@ -276,6 +288,9 @@ class Expr(object):
     def __div__(self, other):
         return ExprOp('/', self, other)
 
+    def __floordiv__(self, other):
+        return self.__div__(other)
+
     def __mod__(self, other):
         return ExprOp('%', self, other)
 
@@ -524,7 +539,7 @@ class ExprInt(Expr):
         return int(self.arg)
 
     def __long__(self):
-        return long(self.arg)
+        return int(self.arg)
 
     def is_int(self, value=None):
         if value is not None and self._arg != value:
@@ -552,7 +567,7 @@ class ExprId(Expr):
         if size is None:
             warnings.warn('DEPRECATION WARNING: size is a mandatory argument: use ExprId(name, SIZE)')
             size = 32
-        assert isinstance(name, str)
+        assert isinstance(name, (str, bytes))
         super(ExprId, self).__init__(size)
         self._name = name
 
@@ -896,7 +911,7 @@ class ExprMem(Expr):
 
         # ptr must be Expr
         assert isinstance(ptr, Expr)
-        assert isinstance(size, (int, long))
+        assert isinstance(size, int_types)
 
         if not isinstance(ptr, Expr):
             raise ValueError(
@@ -1169,8 +1184,8 @@ class ExprSlice(Expr):
 
         # arg must be Expr
         assert isinstance(arg, Expr)
-        assert isinstance(start, (int, long))
-        assert isinstance(stop, (int, long))
+        assert isinstance(start, int_types)
+        assert isinstance(stop, int_types)
         assert start < stop
 
         self._arg, self._start, self._stop = arg, start, stop
@@ -1344,45 +1359,46 @@ class ExprCompose(Expr):
         return True
 
 # Expression order for comparison
-EXPR_ORDER_DICT = {ExprId: 1,
-                   ExprLoc: 2,
-                   ExprCond: 3,
-                   ExprMem: 4,
-                   ExprOp: 5,
-                   ExprSlice: 6,
-                   ExprCompose: 7,
-                   ExprInt: 8,
-                  }
+EXPR_ORDER_DICT = {
+    ExprId: 1,
+    ExprLoc: 2,
+    ExprCond: 3,
+    ExprMem: 4,
+    ExprOp: 5,
+    ExprSlice: 6,
+    ExprCompose: 7,
+    ExprInt: 8,
+}
 
 
 def compare_exprs_compose(expr1, expr2):
-    # Sort by start bit address, then expr, then stop but address
-    ret = cmp(expr1[1], expr2[1])
+    # Sort by start bit address, then expr, then stop bit address
+    ret = cmp_elts(expr1[1], expr2[1])
     if ret:
         return ret
     ret = compare_exprs(expr1[0], expr2[0])
     if ret:
         return ret
-    ret = cmp(expr1[2], expr2[2])
+    ret = cmp_elts(expr1[2], expr2[2])
     return ret
 
 
 def compare_expr_list_compose(l1_e, l2_e):
     # Sort by list elements in incremental order, then by list size
-    for i in xrange(min(len(l1_e), len(l2_e))):
+    for i in range(min(len(l1_e), len(l2_e))):
         ret = compare_exprs(l1_e[i], l2_e[i])
         if ret:
             return ret
-    return cmp(len(l1_e), len(l2_e))
+    return cmp_elts(len(l1_e), len(l2_e))
 
 
 def compare_expr_list(l1_e, l2_e):
     # Sort by list elements in incremental order, then by list size
-    for i in xrange(min(len(l1_e), len(l2_e))):
+    for i in range(min(len(l1_e), len(l2_e))):
         ret = compare_exprs(l1_e[i], l2_e[i])
         if ret:
             return ret
-    return cmp(len(l1_e), len(l2_e))
+    return cmp_elts(len(l1_e), len(l2_e))
 
 
 def compare_exprs(expr1, expr2):
@@ -1396,27 +1412,30 @@ def compare_exprs(expr1, expr2):
     cls1 = expr1.__class__
     cls2 = expr2.__class__
     if cls1 != cls2:
-        return cmp(EXPR_ORDER_DICT[cls1], EXPR_ORDER_DICT[cls2])
+        return cmp_elts(EXPR_ORDER_DICT[cls1], EXPR_ORDER_DICT[cls2])
     if expr1 == expr2:
         return 0
     if cls1 == ExprInt:
-        ret = cmp(expr1.size, expr2.size)
+        ret = cmp_elts(expr1.size, expr2.size)
         if ret != 0:
             return ret
-        return cmp(expr1.arg, expr2.arg)
+        return cmp_elts(expr1.arg, expr2.arg)
     elif cls1 == ExprId:
-        ret = cmp(expr1.name, expr2.name)
+        name1 = force_bytes(expr1.name)
+        name2 = force_bytes(expr2.name)
+        ret = cmp_elts(name1, name2)
         if ret:
             return ret
-        return cmp(expr1.size, expr2.size)
+        return cmp_elts(expr1.size, expr2.size)
     elif cls1 == ExprLoc:
-        ret = cmp(expr1.loc_key, expr2.loc_key)
+        ret = cmp_elts(expr1.loc_key, expr2.loc_key)
         if ret:
             return ret
-        return cmp(expr1.size, expr2.size)
+        return cmp_elts(expr1.size, expr2.size)
     elif cls1 == ExprAssign:
         raise NotImplementedError(
-            "Comparison from an ExprAssign not yet implemented")
+            "Comparison from an ExprAssign not yet implemented"
+        )
     elif cls2 == ExprCond:
         ret = compare_exprs(expr1.cond, expr2.cond)
         if ret:
@@ -1430,36 +1449,33 @@ def compare_exprs(expr1, expr2):
         ret = compare_exprs(expr1.ptr, expr2.ptr)
         if ret:
             return ret
-        return cmp(expr1.size, expr2.size)
+        return cmp_elts(expr1.size, expr2.size)
     elif cls1 == ExprOp:
         if expr1.op != expr2.op:
-            return cmp(expr1.op, expr2.op)
+            return cmp_elts(expr1.op, expr2.op)
         return compare_expr_list(expr1.args, expr2.args)
     elif cls1 == ExprSlice:
         ret = compare_exprs(expr1.arg, expr2.arg)
         if ret:
             return ret
-        ret = cmp(expr1.start, expr2.start)
+        ret = cmp_elts(expr1.start, expr2.start)
         if ret:
             return ret
-        ret = cmp(expr1.stop, expr2.stop)
+        ret = cmp_elts(expr1.stop, expr2.stop)
         return ret
     elif cls1 == ExprCompose:
         return compare_expr_list_compose(expr1.args, expr2.args)
     raise NotImplementedError(
-        "Comparison between %r %r not implemented" % (expr1, expr2))
+        "Comparison between %r %r not implemented" % (expr1, expr2)
+    )
 
 
 def canonize_expr_list(expr_list):
-    expr_list = list(expr_list)
-    expr_list.sort(cmp=compare_exprs)
-    return expr_list
+    return sorted(expr_list, key=cmp_to_key(compare_exprs))
 
 
 def canonize_expr_list_compose(expr_list):
-    expr_list = list(expr_list)
-    expr_list.sort(cmp=compare_exprs_compose)
-    return expr_list
+    return sorted(expr_list, key=cmp_to_key(compare_exprs_compose))
 
 # Generate ExprInt with common size
 
@@ -1604,7 +1620,7 @@ def match_expr(expr, pattern, tks, result=None):
                     break
             if good is True:
                 # We found a possibility
-                for joker, value in myresult.items():
+                for joker, value in viewitems(myresult):
                     # Updating result in place (to keep pointer in recursion)
                     result[joker] = value
                 return result
diff --git a/miasm2/expression/expression_helper.py b/miasm2/expression/expression_helper.py
index 8065df9b..a50e0d5b 100644
--- a/miasm2/expression/expression_helper.py
+++ b/miasm2/expression/expression_helper.py
@@ -17,17 +17,20 @@
 #
 
 # Expressions manipulation functions
+from builtins import range
 import itertools
 import collections
 import random
 import string
 import warnings
 
+from future.utils import viewitems, viewvalues
+
 import miasm2.expression.expression as m2_expr
 
 
 def parity(a):
-    tmp = (a) & 0xFFL
+    tmp = (a) & 0xFF
     cpt = 1
     while tmp != 0:
         cpt ^= tmp & 1
@@ -174,13 +177,15 @@ class Variables_Identifier(object):
         has_change = True
         while has_change:
             has_change = False
-            for var_id, var_value in self._vars.iteritems():
+            for var_id, var_value in list(viewitems(self._vars)):
                 cur = var_value
 
                 # Do not replace with itself
-                to_replace = {v_val:v_id
-                              for v_id, v_val in self._vars.iteritems()
-                              if v_id != var_id}
+                to_replace = {
+                    v_val:v_id
+                    for v_id, v_val in viewitems(self._vars)
+                    if v_id != var_id
+                }
                 var_value = var_value.replace_expr(to_replace)
 
                 if cur != var_value:
@@ -190,23 +195,29 @@ class Variables_Identifier(object):
                     break
 
         # Replace in the original equation
-        self._equation = expr.replace_expr({v_val: v_id for v_id, v_val
-                                            in self._vars.iteritems()})
+        self._equation = expr.replace_expr(
+            {
+                v_val: v_id for v_id, v_val
+                in viewitems(self._vars)
+            }
+        )
 
         # Compute variables dependencies
         self._vars_ordered = collections.OrderedDict()
-        todo = set(self._vars.iterkeys())
+        todo = set(self._vars)
         needs = {}
 
         ## Build initial needs
-        for var_id, var_expr in self._vars.iteritems():
+        for var_id, var_expr in viewitems(self._vars):
             ### Handle corner cases while using Variable Identifier on an
             ### already computed equation
-            needs[var_id] = [var_name
-                             for var_name in var_expr.get_r(mem_read=True)
-                             if self.is_var_identifier(var_name) and \
-                                 var_name in todo and \
-                                 var_name != var_id]
+            needs[var_id] = [
+                var_name
+                for var_name in var_expr.get_r(mem_read=True)
+                if self.is_var_identifier(var_name) and \
+                var_name in todo and \
+                var_name != var_id
+            ]
 
         ## Build order list
         while todo:
@@ -244,12 +255,15 @@ class Variables_Identifier(object):
 
         if (expr in self.var_asked):
             # Expr has already been asked
-
-            if (expr not in self._vars.values()):
+            if expr not in viewvalues(self._vars):
                 # Create var
-                identifier = m2_expr.ExprId("%s%s" % (self.var_prefix,
-                                                      self.var_indice.next()),
-                                            size = expr.size)
+                identifier = m2_expr.ExprId(
+                    "%s%s" % (
+                        self.var_prefix,
+                        next(self.var_indice)
+                    ),
+                    size = expr.size
+                )
                 self._vars[identifier] = expr
 
             # Recursion stop case
@@ -300,7 +314,7 @@ class Variables_Identifier(object):
     def __str__(self):
         "Display variables and final equation"
         out = ""
-        for var_id, var_expr in self.vars.iteritems():
+        for var_id, var_expr in viewitems(self.vars):
             out += "%s = %s\n" % (var_id, var_expr)
         out += "Final: %s" % self.equation
         return out
@@ -312,7 +326,7 @@ class ExprRandom(object):
     # Identifiers length
     identifier_len = 5
     # Identifiers' name charset
-    identifier_charset = string.letters
+    identifier_charset = string.ascii_letters
     # Number max value
     number_max = 0xFFFFFFFF
     # Available operations
@@ -340,7 +354,7 @@ class ExprRandom(object):
         @size: (optional) identifier size
         """
         return m2_expr.ExprId("".join([random.choice(cls.identifier_charset)
-                                       for _ in xrange(cls.identifier_len)]),
+                                       for _ in range(cls.identifier_len)]),
                               size=size)
 
     @classmethod
@@ -365,15 +379,17 @@ class ExprRandom(object):
         @size: (optional) Operation size
         @depth: (optional) Expression depth
         """
-        operand_type = random.choice(cls.operations_by_args_number.keys())
+        operand_type = random.choice(list(cls.operations_by_args_number))
         if isinstance(operand_type, str) and "+" in operand_type:
-            number_args = random.randint(int(operand_type[:-1]),
-                                         cls.operations_max_args_number)
+            number_args = random.randint(
+                int(operand_type[:-1]),
+                cls.operations_max_args_number
+            )
         else:
             number_args = operand_type
 
         args = [cls._gen(size=size, depth=depth - 1)
-                for _ in xrange(number_args)]
+                for _ in range(number_args)]
         operand = random.choice(cls.operations_by_args_number[operand_type])
         return m2_expr.ExprOp(operand,
                               *args)
@@ -593,8 +609,10 @@ def possible_values(expr):
     elif isinstance(expr, m2_expr.ExprCompose):
         # Generate each possibility for sub-argument, associated with the start
         # and stop bit
-        consvals_args = [map(lambda x: x, possible_values(arg))
-                         for arg in expr.args]
+        consvals_args = [
+            list(possible_values(arg))
+            for arg in expr.args
+        ]
         for consvals_possibility in itertools.product(*consvals_args):
             # Merge constraint of each sub-element
             args_constraint = itertools.chain(*[consval.constraints
diff --git a/miasm2/expression/modint.py b/miasm2/expression/modint.py
index 51a2620e..22d17b9b 100644
--- a/miasm2/expression/modint.py
+++ b/miasm2/expression/modint.py
@@ -1,9 +1,13 @@
 #-*- coding:utf-8 -*-
 
+from builtins import range
+from functools import total_ordering
+
+@total_ordering
 class moduint(object):
 
     def __init__(self, arg):
-        self.arg = long(arg) % self.__class__.limit
+        self.arg = int(arg) % self.__class__.limit
         assert(self.arg >= 0 and self.arg < self.__class__.limit)
 
     def __repr__(self):
@@ -20,11 +24,19 @@ class moduint(object):
         else:
             return c2
 
-    def __cmp__(self, y):
+    def __eq__(self, y):
         if isinstance(y, moduint):
-            return cmp(self.arg, y.arg)
-        else:
-            return cmp(self.arg, y)
+            return self.arg == y.arg
+        return self.arg == y
+
+    def __ne__(self, y):
+        # required Python 2.7.14
+        return not self == y
+
+    def __lt__(self, y):
+        if isinstance(y, moduint):
+            return self.arg < y.arg
+        return self.arg < y
 
     def __add__(self, y):
         if isinstance(y, moduint):
@@ -49,13 +61,19 @@ class moduint(object):
         cls = self.__class__
         if isinstance(y, moduint):
             cls = self.maxcast(y)
-        return ((abs(num) / abs(den)) * result_sign)
+        return (abs(num) // abs(den)) * result_sign
+
+    def __floordiv__(self, y):
+        return self.__div__(y)
 
     def __int__(self):
         return int(self.arg)
 
     def __long__(self):
-        return long(self.arg)
+        return int(self.arg)
+
+    def __index__(self):
+        return int(self.arg)
 
     def __invert__(self):
         return self.__class__(~self.arg)
@@ -72,7 +90,7 @@ class moduint(object):
         cls = self.__class__
         if isinstance(y, moduint):
             cls = self.maxcast(y)
-        return cls(self.arg - (y * (self / y)))
+        return cls(self.arg - y * (self // y))
 
     def __mul__(self, y):
         if isinstance(y, moduint):
@@ -100,9 +118,12 @@ class moduint(object):
     def __rdiv__(self, y):
         if isinstance(y, moduint):
             cls = self.maxcast(y)
-            return cls(y.arg / self.arg)
+            return cls(y.arg // self.arg)
         else:
-            return self.__class__(y / self.arg)
+            return self.__class__(y // self.arg)
+
+    def __rfloordiv__(self, y):
+        return self.__rdiv__(y)
 
     def __rlshift__(self, y):
         if isinstance(y, moduint):
@@ -181,11 +202,13 @@ class modint(moduint):
         if isinstance(arg, moduint):
             arg = arg.arg
         a = arg % self.__class__.limit
-        if a >= self.__class__.limit / 2:
+        if a >= self.__class__.limit // 2:
             a -= self.__class__.limit
         self.arg = a
-        assert(self.arg >= -self.__class__.limit /
-               2 and self.arg < self.__class__.limit)
+        assert(
+            self.arg >= -self.__class__.limit // 2 and
+            self.arg < self.__class__.limit
+        )
 
 
 def is_modint(a):
@@ -225,7 +248,7 @@ def define_uint(size):
 
 def define_common_int():
     "Define common int"
-    common_int = xrange(1, 257)
+    common_int = range(1, 257)
 
     for i in common_int:
         define_int(i)
diff --git a/miasm2/expression/simplifications.py b/miasm2/expression/simplifications.py
index 483331a6..331018ae 100644
--- a/miasm2/expression/simplifications.py
+++ b/miasm2/expression/simplifications.py
@@ -4,6 +4,8 @@
 
 import logging
 
+from future.utils import viewitems
+
 from miasm2.expression import simplifications_common
 from miasm2.expression import simplifications_cond
 from miasm2.expression import simplifications_explicit
@@ -126,7 +128,7 @@ class ExpressionSimplifier(object):
         # Clear cache of simplifiied expressions when adding a new pass
         self.simplified_exprs.clear()
 
-        for k, v in passes.items():
+        for k, v in viewitems(passes):
             self.expr_simp_cb[k] = fast_unify(self.expr_simp_cb.get(k, []) + v)
 
     def apply_simp(self, expression):
diff --git a/miasm2/expression/simplifications_common.py b/miasm2/expression/simplifications_common.py
index a4b7c61e..ddcfc668 100644
--- a/miasm2/expression/simplifications_common.py
+++ b/miasm2/expression/simplifications_common.py
@@ -2,6 +2,7 @@
 # Common simplifications passes #
 # ----------------------------- #
 
+from future.utils import viewitems
 
 from miasm2.expression.modint import mod_size2int, mod_size2uint
 from miasm2.expression.expression import ExprInt, ExprSlice, ExprMem, \
@@ -70,14 +71,14 @@ def simp_cst_propagation(e_s, expr):
                 shifter = int2.arg % int2.size
                 out = (int1.arg << shifter) | (int1.arg >> (int2.size - shifter))
             elif op_name == '/':
-                out = int1.arg / int2.arg
+                out = int1.arg // int2.arg
             elif op_name == '%':
                 out = int1.arg % int2.arg
             elif op_name == 'sdiv':
                 assert int2.arg.arg
                 tmp1 = mod_size2int[int1.arg.size](int1.arg)
                 tmp2 = mod_size2int[int2.arg.size](int2.arg)
-                out = mod_size2uint[int1.arg.size](tmp1 / tmp2)
+                out = mod_size2uint[int1.arg.size](tmp1 // tmp2)
             elif op_name == 'smod':
                 assert int2.arg.arg
                 tmp1 = mod_size2int[int1.arg.size](int1.arg)
@@ -92,7 +93,7 @@ def simp_cst_propagation(e_s, expr):
                 assert int2.arg.arg
                 tmp1 = mod_size2uint[int1.arg.size](int1.arg)
                 tmp2 = mod_size2uint[int2.arg.size](int2.arg)
-                out = mod_size2uint[int1.arg.size](tmp1 / tmp2)
+                out = mod_size2uint[int1.arg.size](tmp1 // tmp2)
 
 
 
@@ -151,7 +152,8 @@ def simp_cst_propagation(e_s, expr):
         if len(args) > 2:
             raise ValueError(
                 'sanity check fail on expr -: should have one or 2 args ' +
-                '%r %s' % (expr, expr))
+                '%r %s' % (expr, expr)
+            )
         return ExprOp('+', args[0], -args[1])
 
     # A op 0 => 0
@@ -445,7 +447,7 @@ def simp_cond_factor(e_s, expr):
 
     # Rebuild the new expression
     c_out = not_conds
-    for cond, vals in conds.items():
+    for cond, vals in viewitems(conds):
         new_src1 = [x.src1 for x in vals]
         new_src2 = [x.src2 for x in vals]
         src1 = e_s.expr_simp_wrapper(ExprOp(expr.op, *new_src1))
@@ -583,7 +585,7 @@ def simp_compose(e_s, expr):
         nxt = args[i + 1]
         if arg.is_mem() and nxt.is_mem():
             gap = e_s(nxt.ptr - arg.ptr)
-            if gap.is_int() and arg.size % 8 == 0 and int(gap) == arg.size / 8:
+            if gap.is_int() and arg.size % 8 == 0 and int(gap) == arg.size // 8:
                 args = args[:i] + [ExprMem(arg.ptr,
                                           arg.size + nxt.size)] + args[i + 2:]
                 return ExprCompose(*args)
@@ -1520,7 +1522,7 @@ def simp_add_multiple(_, expr):
     modified = True
     while modified:
         modified = False
-        for arg, count in operands.iteritems():
+        for arg, count in list(viewitems(operands)):
             if not arg.is_op('+'):
                 continue
             components = arg.args
@@ -1536,7 +1538,7 @@ def simp_add_multiple(_, expr):
             modified = True
             break
 
-    for arg, count in operands.iteritems():
+    for arg, count in viewitems(operands):
         if count == 0:
             continue
         if count == 1:
diff --git a/miasm2/ir/ir.py b/miasm2/ir/ir.py
index dc1d203b..82b12dcd 100644
--- a/miasm2/ir/ir.py
+++ b/miasm2/ir/ir.py
@@ -17,14 +17,17 @@
 # with this program; if not, write to the Free Software Foundation, Inc.,
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 #
+from builtins import zip
 import warnings
 
 from itertools import chain
+from future.utils import viewvalues, viewitems
 
 import miasm2.expression.expression as m2_expr
 from miasm2.expression.expression_helper import get_missing_interval
 from miasm2.core.asmblock import AsmBlock, AsmConstraint
 from miasm2.core.graph import DiGraph
+from functools import reduce
 
 
 def _expr_loc_to_symb(expr, loc_db):
@@ -69,8 +72,8 @@ class AssignBlock(object):
         self._assigns = {} # ExprAssign.dst -> ExprAssign.src
 
         # Concurrent assignments are handled in _set
-        if hasattr(irs, "iteritems"):
-            for dst, src in irs.iteritems():
+        if hasattr(irs, "items"):
+            for dst, src in viewitems(irs):
                 self._set(dst, src)
         else:
             for expraff in irs:
@@ -159,21 +162,21 @@ class AssignBlock(object):
         return key in self._assigns
 
     def iteritems(self):
-        for dst, src in self._assigns.iteritems():
+        for dst, src in viewitems(self._assigns):
             yield dst, src
 
     def items(self):
-        return [(dst, src) for dst, src in self.iteritems()]
+        return [(dst, src) for dst, src in viewitems(self._assigns)]
 
     def itervalues(self):
-        for src in self._assigns.itervalues():
+        for src in viewvalues(self._assigns):
             yield src
 
     def keys(self):
-        return self._assigns.keys()
+        return list(self._assigns)
 
     def values(self):
-        return self._assigns.values()
+        return list(viewvalues(self._assigns))
 
     def __iter__(self):
         for dst in self._assigns:
@@ -188,10 +191,10 @@ class AssignBlock(object):
     def __eq__(self, other):
         if set(self.keys()) != set(other.keys()):
             return False
-        return all(other[dst] == src for dst, src in self.iteritems())
+        return all(other[dst] == src for dst, src in viewitems(self))
 
     def __ne__(self, other):
-        return not self.__eq__(other)
+        return not self == other
 
     def __len__(self):
         return len(self._assigns)
@@ -226,7 +229,7 @@ class AssignBlock(object):
         @cst_read: (optional) cst_read argument of `get_r`
         """
         out = {}
-        for dst, src in self.iteritems():
+        for dst, src in viewitems(self):
             src_read = src.get_r(mem_read=mem_read, cst_read=cst_read)
             if isinstance(dst, m2_expr.ExprMem) and mem_read:
                 # Read on destination happens only with ExprMem
@@ -241,12 +244,19 @@ class AssignBlock(object):
         @cst_read: (optional) cst_read argument of `get_r`
         """
         return set(
-            chain.from_iterable(self.get_rw(mem_read=mem_read,
-                                            cst_read=cst_read).itervalues()))
+            chain.from_iterable(
+                viewvalues(
+                    self.get_rw(
+                        mem_read=mem_read,
+                        cst_read=cst_read
+                    )
+                )
+            )
+        )
 
     def __str__(self):
         out = []
-        for dst, src in sorted(self._assigns.iteritems()):
+        for dst, src in sorted(viewitems(self._assigns)):
             out.append("%s = %s" % (dst, src))
         return "\n".join(out)
 
@@ -262,7 +272,7 @@ class AssignBlock(object):
         @simplifier: ExpressionSimplifier instance
         """
         new_assignblk = {}
-        for dst, src in self.iteritems():
+        for dst, src in viewitems(self):
             if dst == src:
                 continue
             new_src = simplifier(src)
@@ -272,7 +282,7 @@ class AssignBlock(object):
 
     def to_string(self, loc_db=None):
         out = []
-        for dst, src in self.iteritems():
+        for dst, src in viewitems(self):
             new_src = src.visit(lambda expr:_expr_loc_to_symb(expr, loc_db))
             new_dst = dst.visit(lambda expr:_expr_loc_to_symb(expr, loc_db))
             line = "%s = %s" % (new_dst, new_src)
@@ -315,7 +325,7 @@ class IRBlock(object):
         return True
 
     def __ne__(self, other):
-        return not self.__eq__(other)
+        return not self == other
 
     def get_label(self):
         warnings.warn('DEPRECATION WARNING: use ".loc_key" instead of ".label"')
@@ -352,7 +362,7 @@ class IRBlock(object):
         final_dst = None
         final_linenb = None
         for linenb, assignblk in enumerate(self):
-            for dst, src in assignblk.iteritems():
+            for dst, src in viewitems(assignblk):
                 if dst.is_id("IRDst"):
                     if final_dst is not None:
                         raise ValueError('Multiple destinations!')
@@ -375,7 +385,7 @@ class IRBlock(object):
         dst_found = False
         for assignblk in self:
             new_assignblk = {}
-            for dst, src in assignblk.iteritems():
+            for dst, src in viewitems(assignblk):
                 if dst.is_id("IRDst"):
                     assert dst_found is False
                     dst_found = True
@@ -396,7 +406,7 @@ class IRBlock(object):
         out = []
         out.append(str(self.loc_key))
         for assignblk in self:
-            for dst, src in assignblk.iteritems():
+            for dst, src in viewitems(assignblk):
                 out.append('\t%s = %s' % (dst, src))
             out.append("")
         return "\n".join(out)
@@ -418,7 +428,7 @@ class IRBlock(object):
         assignblks = []
         for assignblk in self:
             new_assignblk = {}
-            for dst, src in assignblk.iteritems():
+            for dst, src in viewitems(assignblk):
                 new_assignblk[mod_dst(dst)] = mod_src(src)
             assignblks.append(AssignBlock(new_assignblk, assignblk.instr))
         return IRBlock(self.loc_key, assignblks)
@@ -509,11 +519,7 @@ class IRCFG(DiGraph):
         if self.loc_db is None:
             node_name = str(node)
         else:
-            names = self.loc_db.get_location_names(node)
-            if not names:
-                node_name = self.loc_db.pretty_str(node)
-            else:
-                node_name = "".join("%s:\n" % name for name in names)
+            node_name = self.loc_db.pretty_str(node)
         yield self.DotCellDescription(
             text="%s" % node_name,
             attr={
@@ -524,9 +530,9 @@ class IRCFG(DiGraph):
         )
         if node not in self._blocks:
             yield [self.DotCellDescription(text="NOT PRESENT", attr={})]
-            raise StopIteration
+            return
         for i, assignblk in enumerate(self._blocks[node]):
-            for dst, src in assignblk.iteritems():
+            for dst, src in viewitems(assignblk):
 
                 new_src = src.visit(lambda expr:_expr_loc_to_symb(expr, self.loc_db))
                 new_dst = dst.visit(lambda expr:_expr_loc_to_symb(expr, self.loc_db))
@@ -602,14 +608,18 @@ class IRCFG(DiGraph):
         return self.blocks.get(loc_key, None)
 
     def getby_offset(self, offset):
+        """
+        Return the set of loc_keys of irblocks containing @offset
+        @offset: address
+        """
         out = set()
-        for irb in self.blocks.values():
+        for irb in viewvalues(self.blocks):
             for assignblk in irb:
                 instr = assignblk.instr
                 if instr is None:
                     continue
                 if instr.offset <= offset < instr.offset + instr.l:
-                    out.add(irb)
+                    out.add(irb.loc_key)
         return out
 
 
@@ -619,7 +629,7 @@ class IRCFG(DiGraph):
         @simplifier: ExpressionSimplifier instance
         """
         modified = False
-        for loc_key, block in self.blocks.iteritems():
+        for loc_key, block in list(viewitems(self.blocks)):
             assignblks = []
             for assignblk in block:
                 new_assignblk = assignblk.simplify(simplifier)
@@ -629,12 +639,6 @@ class IRCFG(DiGraph):
             self.blocks[loc_key] = IRBlock(loc_key, assignblks)
         return modified
 
-    def replace_expr_in_ir(self, block, replaced):
-        for assignblk in block:
-            for dst, src in assignblk.items():
-                del assignblk[dst]
-                assignblk[dst.replace_expr(replaced)] = src.replace_expr(replaced)
-
     def get_rw(self, regs_ids=None):
         """
         Calls get_rw(irb) for each bloc
@@ -642,7 +646,7 @@ class IRCFG(DiGraph):
         """
         if regs_ids is None:
             regs_ids = []
-        for irblock in self.blocks.values():
+        for irblock in viewvalues(self.blocks):
             irblock.get_rw(regs_ids)
 
     def _extract_dst(self, todo, done):
@@ -873,7 +877,7 @@ class IntermediateRepresentation(object):
     def is_pc_written(self, block):
         """Return the first Assignblk of the @blockin which PC is written
         @block: IRBlock instance"""
-        all_pc = self.arch.pc.values()
+        all_pc = viewvalues(self.arch.pc)
         for assignblk in block:
             if assignblk.dst in all_pc:
                 return assignblk
diff --git a/miasm2/ir/symbexec.py b/miasm2/ir/symbexec.py
index f54ee2a5..b945e85c 100644
--- a/miasm2/ir/symbexec.py
+++ b/miasm2/ir/symbexec.py
@@ -1,6 +1,10 @@
+from __future__ import print_function
+from builtins import range
 import logging
 from collections import MutableMapping
 
+from future.utils import viewitems
+
 from miasm2.expression.expression import ExprOp, ExprId, ExprLoc, ExprInt, \
     ExprMem, ExprCompose, ExprSlice, ExprCond
 from miasm2.expression.simplifications import expr_simp_explicit
@@ -40,7 +44,7 @@ class SymbolicState(StateEngine):
     """Stores a SymbolicExecutionEngine state"""
 
     def __init__(self, dct):
-        self._symbols = frozenset(dct.items())
+        self._symbols = frozenset(viewitems(dct))
 
     def __hash__(self):
         return hash((self.__class__, self._symbols))
@@ -53,7 +57,7 @@ class SymbolicState(StateEngine):
         return self.symbols == other.symbols
 
     def __ne__(self, other):
-        return not self.__eq__(other)
+        return not self == other
 
     def __iter__(self):
         for dst, src in self._symbols:
@@ -71,7 +75,7 @@ class SymbolicState(StateEngine):
 
         symb_a = self.symbols
         symb_b = other.symbols
-        intersection = set(symb_a.keys()).intersection(symb_b.keys())
+        intersection = set(symb_a).intersection(set(symb_b))
         out = {}
         for dst in intersection:
             if symb_a[dst] == symb_b[dst]:
@@ -168,7 +172,7 @@ class MemArray(MutableMapping):
         return self._offset_to_expr.__delitem__(offset)
 
     def __iter__(self):
-        for offset, _ in self._offset_to_expr.iteritems():
+        for offset, _ in viewitems(self._offset_to_expr):
             yield offset
 
     def __len__(self):
@@ -177,7 +181,7 @@ class MemArray(MutableMapping):
     def __repr__(self):
         out = []
         out.append("Base: %s" % self.base)
-        for offset, (index, value) in sorted(self._offset_to_expr.iteritems()):
+        for offset, (index, value) in sorted(viewitems(self._offset_to_expr)):
             out.append("%16X %d %s" % (offset, index, value))
         return '\n'.join(out)
 
@@ -220,7 +224,7 @@ class MemArray(MutableMapping):
         assert size % 8 == 0
         # Parts is (Expr's offset, size, Expr)
         parts = []
-        for index in xrange(size / 8):
+        for index in range(size // 8):
             # Wrap read:
             # @32[EAX+0xFFFFFFFF] is ok and will read at 0xFFFFFFFF, 0, 1, 2
             request_offset = (offset + index) & self._mask
@@ -264,8 +268,8 @@ class MemArray(MutableMapping):
                     index += 1
                     continue
                 if (ptr_offset_a + off_a + size_a) & self._mask == (ptr_offset_b + off_b) & self._mask:
-                    assert size_a <= data_a.size / 8 - off_a
-                    assert size_b <= data_b.size / 8 - off_b
+                    assert size_a <= data_a.size // 8 - off_a
+                    assert size_b <= data_b.size // 8 - off_b
                     # Successive comparable symbolic pointers
                     # [(0, 8, @8[ptr]), (0, 8, @8[ptr+1])] => (0, 16, @16[ptr])
                     ptr = self.offset_to_ptr(ptr_base_a, (ptr_offset_a + off_a) & self._mask)
@@ -280,7 +284,7 @@ class MemArray(MutableMapping):
         # Slice datas
         read_mem = []
         for off, bytesize, data in parts:
-            if data.size / 8 != bytesize:
+            if data.size // 8 != bytesize:
                 data = data[off * 8: (off + bytesize) * 8]
             read_mem.append(data)
 
@@ -294,7 +298,7 @@ class MemArray(MutableMapping):
         """
         assert expr.size % 8 == 0
         assert offset <= self._mask
-        for index in xrange(expr.size / 8):
+        for index in range(expr.size // 8):
             # Wrap write:
             # @32[EAX+0xFFFFFFFF] is ok and will write at 0xFFFFFFFF, 0, 1, 2
             request_offset = (offset + index) & self._mask
@@ -305,7 +309,9 @@ class MemArray(MutableMapping):
             # Special case: Simplify slice of pointer (simplification is ok
             # here, as we won't store the simplified expression)
             if tmp.is_slice() and tmp.arg.is_mem() and tmp.start % 8 == 0:
-                new_ptr = self.expr_simp(tmp.arg.ptr + ExprInt(tmp.start / 8, tmp.arg.ptr.size))
+                new_ptr = self.expr_simp(
+                    tmp.arg.ptr + ExprInt(tmp.start // 8, tmp.arg.ptr.size)
+                )
                 tmp = ExprMem(new_ptr, tmp.stop - tmp.start)
             # Test if write to original value
             if tmp.is_mem():
@@ -332,12 +338,12 @@ class MemArray(MutableMapping):
         assert value.size % 8 == 0
 
         if forward:
-            start, end, step = value_byte_index + 1, value.size / 8, 1
+            start, end, step = value_byte_index + 1, value.size // 8, 1
         else:
             start, end, step = value_byte_index - 1, -1, -1
 
         partnum = 1
-        for value_offset in xrange(start, end, step):
+        for value_offset in range(start, end, step):
             offset += step
             # Check if next part is in known_offsets
             next_index = index + step * partnum
@@ -398,9 +404,8 @@ class MemArray(MutableMapping):
         """
 
         if not self._offset_to_expr:
-            raise StopIteration
-        known_offsets = self._offset_to_expr.keys()
-        known_offsets.sort()
+            return
+        known_offsets = sorted(self._offset_to_expr)
         index = 0
         # Test if the first element is the continuation of the last byte. If
         # yes, merge and output it first.
@@ -444,7 +449,7 @@ class MemArray(MutableMapping):
     def dump(self):
         """Display MemArray content"""
         for mem, value in self.memory():
-            print "%s = %s" % (mem, value)
+            print("%s = %s" % (mem, value))
 
 
 class MemSparse(object):
@@ -484,7 +489,7 @@ class MemSparse(object):
         memarray = self.base_to_memarray.get(base, None)
         if memarray is None:
             return False
-        for i in xrange(expr.size / 8):
+        for i in range(expr.size // 8):
             if offset + i not in memarray:
                 return False
         return True
@@ -500,7 +505,7 @@ class MemSparse(object):
         memarray = self.base_to_memarray.get(base, None)
         if memarray is None:
             return False
-        for i in xrange(expr.size / 8):
+        for i in range(expr.size // 8):
             if offset + i in memarray:
                 return True
         return False
@@ -512,7 +517,7 @@ class MemSparse(object):
     def copy(self):
         """Copy the current object instance"""
         base_to_memarray = {}
-        for base, memarray in self.base_to_memarray.iteritems():
+        for base, memarray in viewitems(self.base_to_memarray):
             base_to_memarray[base] = memarray.copy()
         obj = MemSparse(self.addrsize, self.expr_simp)
         obj.base_to_memarray = base_to_memarray
@@ -529,10 +534,10 @@ class MemSparse(object):
         if memarray is None:
             raise KeyError
         # Check if whole entity is in the MemArray before deleting it
-        for i in xrange(expr.size / 8):
+        for i in range(expr.size // 8):
             if (offset + i) & memarray.mask not in memarray:
                 raise KeyError
-        for i in xrange(expr.size / 8):
+        for i in range(expr.size // 8):
             del memarray[(offset + i) & memarray.mask]
 
     def delete_partial(self, expr):
@@ -546,7 +551,7 @@ class MemSparse(object):
         if memarray is None:
             raise KeyError
         # Check if whole entity is in the MemArray before deleting it
-        for i in xrange(expr.size / 8):
+        for i in range(expr.size // 8):
             real_offset = (offset + i) & memarray.mask
             if real_offset in memarray:
                 del memarray[real_offset]
@@ -583,7 +588,7 @@ class MemSparse(object):
 
     def iteritems(self):
         """Iterate on stored memory variables and their values."""
-        for _, memarray in sorted(self.base_to_memarray.iteritems()):
+        for _, memarray in viewitems(self.base_to_memarray):
             for mem, value in memarray.memory():
                 yield mem, value
 
@@ -593,12 +598,12 @@ class MemSparse(object):
 
     def dump(self):
         """Display MemSparse content"""
-        for mem, value in self.iteritems():
-            print "%s = %s" % (mem, value)
+        for mem, value in viewitems(self):
+            print("%s = %s" % (mem, value))
 
     def __repr__(self):
         out = []
-        for _, memarray in sorted(self.base_to_memarray.iteritems()):
+        for _, memarray in sorted(viewitems(self.base_to_memarray)):
             out.append(repr(memarray))
         return '\n'.join(out)
 
@@ -615,7 +620,7 @@ class SymbolMngr(object):
         self.symbols_id = {}
         self.symbols_mem = MemSparse(addrsize, expr_simp)
         self.mask = (1 << addrsize) - 1
-        for expr, value in init.iteritems():
+        for expr, value in viewitems(init):
             self.write(expr, value)
 
     def __contains__(self, expr):
@@ -687,14 +692,14 @@ class SymbolMngr(object):
         """Display memory content"""
         if ids:
             for variable, value in self.ids():
-                print '%s = %s' % (variable, value)
+                print('%s = %s' % (variable, value))
         if mems:
             for mem, value in self.memory():
-                print '%s = %s' % (mem, value)
+                print('%s = %s' % (mem, value))
 
     def __repr__(self):
         out = []
-        for variable, value in self.iteritems():
+        for variable, value in viewitems(self):
             out.append('%s = %s' % (variable, value))
         return "\n".join(out)
 
@@ -715,12 +720,12 @@ class SymbolMngr(object):
 
     def ids(self):
         """Iterate on variables and their values."""
-        for expr, value in self.symbols_id.iteritems():
+        for expr, value in viewitems(self.symbols_id):
             yield expr, value
 
     def memory(self):
         """Iterate on memory variables and their values."""
-        for mem, value in self.symbols_mem.iteritems():
+        for mem, value in viewitems(self.symbols_mem):
             yield mem, value
 
     def keys(self):
@@ -817,7 +822,7 @@ class SymbolicExecutionEngine(object):
 
         self.symbols = SymbolMngr(addrsize=ir_arch.addrsize, expr_simp=sb_expr_simp)
 
-        for dst, src in state.iteritems():
+        for dst, src in viewitems(state):
             self.symbols.write(dst, src)
 
         self.ir_arch = ir_arch
@@ -833,7 +838,7 @@ class SymbolicExecutionEngine(object):
         @state: StateEngine instance
         """
         self.symbols = SymbolMngr(addrsize=self.ir_arch.addrsize, expr_simp=self.expr_simp)
-        for dst, src in dict(state).iteritems():
+        for dst, src in viewitems(dict(state)):
             self.symbols[dst] = src
 
     state = property(get_state, set_state)
@@ -950,7 +955,7 @@ class SymbolicExecutionEngine(object):
         if init_state is None:
             init_state = {}
         if ids:
-            for variable, value in self.symbols.symbols_id.iteritems():
+            for variable, value in viewitems(self.symbols.symbols_id):
                 if variable in init_state and init_state[variable] == value:
                     continue
                 yield variable, value
@@ -968,7 +973,7 @@ class SymbolicExecutionEngine(object):
         """
 
         for variable, value in self.modified(None, ids, mems):
-            print "%-18s" % variable, "=", "%s" % value
+            print("%-18s" % variable, "=", "%s" % value)
 
     def eval_assignblk(self, assignblk):
         """
@@ -980,7 +985,7 @@ class SymbolicExecutionEngine(object):
         """
         pool_out = {}
         eval_cache = {}
-        for dst, src in assignblk.iteritems():
+        for dst, src in viewitems(assignblk):
             src = self.eval_expr(src, eval_cache)
             if dst.is_mem():
                 ptr = self.eval_expr(dst.ptr, eval_cache)
@@ -1012,7 +1017,7 @@ class SymbolicExecutionEngine(object):
         """
         mem_dst = []
         dst_src = self.eval_assignblk(assignblk)
-        for dst, src in dst_src.iteritems():
+        for dst, src in viewitems(dst_src):
             self.apply_change(dst, src)
             if dst.is_mem():
                 mem_dst.append(dst)
@@ -1026,15 +1031,15 @@ class SymbolicExecutionEngine(object):
         """
         for assignblk in irb:
             if step:
-                print 'Instr', assignblk.instr
-                print 'Assignblk:'
-                print assignblk
-                print '_' * 80
+                print('Instr', assignblk.instr)
+                print('Assignblk:')
+                print(assignblk)
+                print('_' * 80)
             self.eval_updt_assignblk(assignblk)
             if step:
                 self.dump(mems=False)
                 self.dump(ids=False)
-                print '_' * 80
+                print('_' * 80)
         dst = self.eval_expr(self.ir_arch.IRDst)
 
         return dst
diff --git a/miasm2/ir/symbexec_top.py b/miasm2/ir/symbexec_top.py
index be48c065..a1a255f8 100644
--- a/miasm2/ir/symbexec_top.py
+++ b/miasm2/ir/symbexec_top.py
@@ -1,3 +1,5 @@
+from future.utils import viewitems
+
 from miasm2.ir.symbexec import SymbolicExecutionEngine, StateEngine
 from miasm2.expression.simplifications import expr_simp
 from miasm2.expression.expression import ExprId, ExprInt, ExprSlice,\
@@ -16,7 +18,7 @@ def exprid_top(expr):
 class SymbolicStateTop(StateEngine):
 
     def __init__(self, dct, regstop):
-        self._symbols = frozenset(dct.items())
+        self._symbols = frozenset(viewitems(dct))
         self._regstop = frozenset(regstop)
 
     def __hash__(self):
@@ -52,8 +54,8 @@ class SymbolicStateTop(StateEngine):
         """
         symb_a = self.symbols
         symb_b = other.symbols
-        intersection = set(symb_a.keys()).intersection(symb_b.keys())
-        diff = set(symb_a.keys()).union(symb_b.keys()).difference(intersection)
+        intersection = set(symb_a).intersection(symb_b)
+        diff = set(symb_a).union(symb_b).difference(intersection)
         symbols = {}
         regstop = set()
         for dst in diff:
diff --git a/miasm2/ir/symbexec_types.py b/miasm2/ir/symbexec_types.py
index e4f37e3f..57b7580a 100644
--- a/miasm2/ir/symbexec_types.py
+++ b/miasm2/ir/symbexec_types.py
@@ -1,3 +1,7 @@
+from __future__ import print_function
+
+from future.utils import viewitems
+
 from miasm2.ir.symbexec import SymbolicExecutionEngine, StateEngine
 from miasm2.expression.simplifications import expr_simp
 from miasm2.expression.expression import ExprId, ExprMem
@@ -8,9 +12,9 @@ class SymbolicStateCTypes(StateEngine):
 
     def __init__(self, symbols):
         tmp = {}
-        for expr, types in symbols.iteritems():
+        for expr, types in viewitems(symbols):
             tmp[expr] = frozenset(types)
-        self._symbols = frozenset(tmp.iteritems())
+        self._symbols = frozenset(viewitems(tmp))
 
     def __hash__(self):
         return hash((self.__class__, self._symbols))
@@ -84,7 +88,7 @@ class SymbExecCType(SymbolicExecutionEngine):
         @assignblk: AssignBlock instance
         """
         pool_out = {}
-        for dst, src in assignblk.iteritems():
+        for dst, src in viewitems(assignblk):
             objcs = self.chandler.expr_to_types(src, self.symbols)
             if isinstance(dst, ExprMem):
                 continue
@@ -112,16 +116,16 @@ class SymbExecCType(SymbolicExecutionEngine):
         """
         Dump modififed registers symbols only
         """
-        for expr, expr_types in sorted(self.symbols.iteritems()):
+        for expr, expr_types in sorted(viewitems(self.symbols)):
             if not expr.is_mem():
-                print expr
+                print(expr)
                 for expr_type in expr_types:
-                    print '\t', expr_type
+                    print('\t', expr_type)
 
     def dump_mem(self):
         """
         Dump modififed memory symbols
         """
-        for expr, value in sorted(self.symbols.iteritems()):
+        for expr, value in sorted(viewitems(self.symbols)):
             if expr.is_mem():
-                print expr, value
+                print(expr, value)
diff --git a/miasm2/ir/translators/C.py b/miasm2/ir/translators/C.py
index 5a55237f..e44e859f 100644
--- a/miasm2/ir/translators/C.py
+++ b/miasm2/ir/translators/C.py
@@ -11,8 +11,8 @@ def int_size_to_bn(value, size):
         size_nibble = 8
     else:
         # size must be multiple of 4
-        size = ((size + 31) / 32) * 32
-        size_nibble = size / 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
diff --git a/miasm2/ir/translators/miasm.py b/miasm2/ir/translators/miasm.py
index 356ec3fd..e93e9499 100644
--- a/miasm2/ir/translators/miasm.py
+++ b/miasm2/ir/translators/miasm.py
@@ -1,3 +1,4 @@
+from builtins import map
 from miasm2.ir.translators.translator import Translator
 
 
@@ -23,8 +24,10 @@ class TranslatorMiasm(Translator):
                                           expr.stop)
 
     def from_ExprOp(self, expr):
-        return "ExprOp(%s, %s)" % (repr(expr.op),
-                                   ", ".join(map(self.from_expr, expr.args)))
+        return "ExprOp(%s, %s)" % (
+            repr(expr.op),
+            ", ".join(map(self.from_expr, expr.args))
+        )
 
     def from_ExprCompose(self, expr):
         args = ["%s" % self.from_expr(arg) for arg in expr.args]
diff --git a/miasm2/ir/translators/python.py b/miasm2/ir/translators/python.py
index f32e4585..4b1b4b52 100644
--- a/miasm2/ir/translators/python.py
+++ b/miasm2/ir/translators/python.py
@@ -1,3 +1,4 @@
+from builtins import map
 from miasm2.expression.expression import ExprInt
 from miasm2.ir.translators.translator import Translator
 
@@ -24,8 +25,10 @@ class TranslatorPython(Translator):
         return str(expr)
 
     def from_ExprMem(self, expr):
-        return "memory(%s, 0x%x)" % (self.from_expr(expr.ptr),
-                                     expr.size / 8)
+        return "memory(%s, 0x%x)" % (
+            self.from_expr(expr.ptr),
+            expr.size // 8
+        )
 
     def from_ExprSlice(self, expr):
         out = self.from_expr(expr.arg)
@@ -36,26 +39,36 @@ class TranslatorPython(Translator):
     def from_ExprCompose(self, expr):
         out = []
         for index, arg in expr.iter_args():
-            out.append("((%s & 0x%x) << %d)" % (self.from_expr(arg),
-                                                 (1 << arg.size) - 1,
-                                                 index))
+            out.append(
+                "((%s & 0x%x) << %d)" % (
+                    self.from_expr(arg),
+                    (1 << arg.size) - 1,
+                    index
+                )
+            )
         return "(%s)" % ' | '.join(out)
 
     def from_ExprCond(self, expr):
-        return "(%s if (%s) else %s)" % (self.from_expr(expr.src1),
-                                         self.from_expr(expr.cond),
-                                         self.from_expr(expr.src2))
+        return "(%s if (%s) else %s)" % (
+            self.from_expr(expr.src1),
+            self.from_expr(expr.cond),
+            self.from_expr(expr.src2)
+        )
 
     def from_ExprOp(self, expr):
         if expr.op in self.op_no_translate:
-            args = map(self.from_expr, expr.args)
+            args = list(map(self.from_expr, expr.args))
             if len(expr.args) == 1:
-                return "((%s %s) & 0x%x)" % (expr.op,
-                                             args[0],
-                                             (1 << expr.size) - 1)
+                return "((%s %s) & 0x%x)" % (
+                    expr.op,
+                    args[0],
+                    (1 << expr.size) - 1
+                )
             else:
-                return "((%s) & 0x%x)" % ((" %s " % expr.op).join(args),
-                                        (1 << expr.size) - 1)
+                return "((%s) & 0x%x)" % (
+                    (" %s " % expr.op).join(args),
+                    (1 << expr.size) - 1
+                )
         elif expr.op == "parity":
             return "(%s & 0x1)" % self.from_expr(expr.args[0])
 
@@ -75,7 +88,10 @@ class TranslatorPython(Translator):
         raise NotImplementedError("Unknown operator: %s" % expr.op)
 
     def from_ExprAssign(self, expr):
-        return "%s = %s" % tuple(map(self.from_expr, (expr.dst, expr.src)))
+        return "%s = %s" % (
+            self.from_expr(expr.dst),
+            self.from_expr(expr.src)
+        )
 
 
 # Register the class
diff --git a/miasm2/ir/translators/smt2.py b/miasm2/ir/translators/smt2.py
index 81d86798..7b619457 100644
--- a/miasm2/ir/translators/smt2.py
+++ b/miasm2/ir/translators/smt2.py
@@ -1,3 +1,5 @@
+from builtins import map
+from builtins import range
 import logging
 
 from miasm2.ir.translators.translator import Translator
@@ -76,14 +78,14 @@ class SMT2Mem(object):
         original_size = size
         if original_size % 8 != 0:
             # Size not aligned on 8bits -> read more than size and extract after
-            size = ((original_size / 8) + 1) * 8
+            size = ((original_size // 8) + 1) * 8
         res = self[addr]
         if self.is_little_endian():
-            for i in xrange(1, size/8):
+            for i in range(1, size // 8):
                 index = bvadd(addr, bit_vec_val(i, addr_size))
                 res = bv_concat(self[index], res)
         else:
-            for i in xrange(1, size/8):
+            for i in range(1, size // 8):
                 res = bv_concat(res, self[index])
         if size == original_size:
             return res
@@ -185,7 +187,7 @@ class TranslatorSMT2(Translator):
         return smt2_ite(distinct_and, src1, src2)
 
     def from_ExprOp(self, expr):
-        args = map(self.from_expr, expr.args)
+        args = list(map(self.from_expr, expr.args))
         res = args[0]
 
         if len(args) > 1:
@@ -229,7 +231,7 @@ class TranslatorSMT2(Translator):
         elif expr.op == 'parity':
             arg = bv_extract(7, 0, res)
             res = bit_vec_val(1, 1)
-            for i in xrange(8):
+            for i in range(8):
                 res = bvxor(res, bv_extract(i, i, arg))
         elif expr.op == '-':
             res = bvneg(res)
@@ -245,7 +247,7 @@ class TranslatorSMT2(Translator):
             cond = smt2_distinct(op, zero_smt2)
             # ite(cond, size - 1, src)
             res = smt2_ite(cond, bvsub(size_smt2, one_smt2), src)
-            for i in xrange(size - 2, -1, -1):
+            for i in range(size - 2, -1, -1):
                 # smt2 expression of i
                 i_smt2 = bit_vec_val(i, size)
                 # src & (1 << i)
@@ -263,7 +265,7 @@ class TranslatorSMT2(Translator):
             cond = smt2_distinct(bvand(src, one_smt2), zero_smt2)
             # ite(cond, 0, src)
             res= smt2_ite(cond, zero_smt2, src)
-            for i in xrange(size - 1, 0, -1):
+            for i in range(size - 1, 0, -1):
                 index = - i % size
                 index_smt2 = bit_vec_val(index, size)
                 # src & (1 << index)
diff --git a/miasm2/ir/translators/translator.py b/miasm2/ir/translators/translator.py
index a56c6a62..65875072 100644
--- a/miasm2/ir/translators/translator.py
+++ b/miasm2/ir/translators/translator.py
@@ -1,3 +1,5 @@
+from future.utils import viewitems
+
 import miasm2.expression.expression as m2_expr
 from miasm2.core.utils import BoundedDict
 
@@ -104,17 +106,18 @@ class Translator(object):
             return self._cache[expr]
 
         # Handle Expr type
-        handlers = {m2_expr.ExprInt: self.from_ExprInt,
-                    m2_expr.ExprId: self.from_ExprId,
-                    m2_expr.ExprLoc: self.from_ExprLoc,
-                    m2_expr.ExprCompose: self.from_ExprCompose,
-                    m2_expr.ExprSlice: self.from_ExprSlice,
-                    m2_expr.ExprOp: self.from_ExprOp,
-                    m2_expr.ExprMem: self.from_ExprMem,
-                    m2_expr.ExprAssign: self.from_ExprAssign,
-                    m2_expr.ExprCond: self.from_ExprCond
-                    }
-        for target, handler in handlers.iteritems():
+        handlers = {
+            m2_expr.ExprInt: self.from_ExprInt,
+            m2_expr.ExprId: self.from_ExprId,
+            m2_expr.ExprLoc: self.from_ExprLoc,
+            m2_expr.ExprCompose: self.from_ExprCompose,
+            m2_expr.ExprSlice: self.from_ExprSlice,
+            m2_expr.ExprOp: self.from_ExprOp,
+            m2_expr.ExprMem: self.from_ExprMem,
+            m2_expr.ExprAssign: self.from_ExprAssign,
+            m2_expr.ExprCond: self.from_ExprCond
+        }
+        for target, handler in viewitems(handlers):
             if isinstance(expr, target):
                 ## Compute value and update the internal cache
                 ret = handler(expr)
diff --git a/miasm2/ir/translators/z3_ir.py b/miasm2/ir/translators/z3_ir.py
index 204ee976..902e72bd 100644
--- a/miasm2/ir/translators/z3_ir.py
+++ b/miasm2/ir/translators/z3_ir.py
@@ -1,3 +1,5 @@
+from builtins import map
+from builtins import range
 import imp
 import logging
 
@@ -76,13 +78,13 @@ class Z3Mem(object):
         original_size = size
         if original_size % 8 != 0:
             # Size not aligned on 8bits -> read more than size and extract after
-            size = ((original_size / 8) + 1) * 8
+            size = ((original_size // 8) + 1) * 8
         res = self[addr]
         if self.is_little_endian():
-            for i in xrange(1, size/8):
+            for i in range(1, size // 8):
                 res = z3.Concat(self[addr+i], res)
         else:
-            for i in xrange(1, size/8):
+            for i in range(1, size //8):
                 res = z3.Concat(res, self[addr+i])
         if size == original_size:
             return res
@@ -182,7 +184,7 @@ class TranslatorZ3(Translator):
         return z3.UDiv(self._abs(num), self._abs(den)) * result_sign
 
     def from_ExprOp(self, expr):
-        args = map(self.from_expr, expr.args)
+        args = list(map(self.from_expr, expr.args))
         res = args[0]
 
         if len(args) > 1:
@@ -240,7 +242,7 @@ class TranslatorZ3(Translator):
         elif expr.op == 'parity':
             arg = z3.Extract(7, 0, res)
             res = z3.BitVecVal(1, 1)
-            for i in xrange(8):
+            for i in range(8):
                 res = res ^ z3.Extract(i, i, arg)
         elif expr.op == '-':
             res = -res
@@ -248,13 +250,13 @@ class TranslatorZ3(Translator):
             size = expr.size
             src = res
             res = z3.If(src == 0, size, src)
-            for i in xrange(size - 1, -1, -1):
+            for i in range(size - 1, -1, -1):
                 res = z3.If((src & (1 << i)) != 0, i, res)
         elif expr.op == "cntleadzeros":
             size = expr.size
             src = res
             res = z3.If(src == 0, size, src)
-            for i in xrange(size, 0, -1):
+            for i in range(size, 0, -1):
                 index = - i % size
                 out = size - (index + 1)
                 res = z3.If((src & (1 << index)) != 0, out, res)
diff --git a/miasm2/jitter/JitCore.c b/miasm2/jitter/JitCore.c
index a2873d03..ae5af293 100644
--- a/miasm2/jitter/JitCore.c
+++ b/miasm2/jitter/JitCore.c
@@ -2,6 +2,7 @@
 #include "structmember.h"
 #include <stdint.h>
 #include <inttypes.h>
+#include "compat_py23.h"
 #include "queue.h"
 #include "vm_mngr.h"
 #include "vm_mngr_py.h"
@@ -11,7 +12,7 @@
 
 void JitCpu_dealloc(JitCpu* self)
 {
-    self->ob_type->tp_free((PyObject*)self);
+    Py_TYPE(self)->tp_free((PyObject*)self);
 }
 
 
@@ -250,7 +251,7 @@ PyObject* vm_get_mem(JitCpu *self, PyObject* args)
 	       return NULL;
        }
 
-       obj_out = PyString_FromStringAndSize(buf_out, size);
+       obj_out = PyBytes_FromStringAndSize(buf_out, size);
        free(buf_out);
        return obj_out;
 }
diff --git a/miasm2/jitter/JitCore.h b/miasm2/jitter/JitCore.h
index d85b71d9..15efc7d2 100644
--- a/miasm2/jitter/JitCore.h
+++ b/miasm2/jitter/JitCore.h
@@ -11,31 +11,73 @@
 #define RAISE_ret0(errtype, msg) {PyObject* p; p = PyErr_Format( errtype, msg ); return 0;}
 
 
-#define PyGetInt(item, value)						\
-	if (PyInt_Check(item)){						\
-		value = (uint64_t)PyInt_AsLong(item);			\
-	}								\
-	else if (PyLong_Check(item)){					\
-		value = (uint64_t)PyLong_AsUnsignedLongLong(item);	\
-	}								\
-	else{								\
-		RAISE(PyExc_TypeError,"arg must be int");		\
-	}								\
-
-
-#define PyGetInt_retneg(item, value)					\
-	if (PyInt_Check(item)){						\
-		value = (uint64_t)PyInt_AsLong(item);			\
-	}								\
-	else if (PyLong_Check(item)){					\
-		value = (uint64_t)PyLong_AsUnsignedLongLong(item);	\
-	}								\
-	else{								\
-		PyErr_SetString(PyExc_TypeError, "Arg must be int");	\
-		return -1;						\
+#if PY_MAJOR_VERSION >= 3
+#define getset_reg_bn(regname, size)					\
+	static PyObject *JitCpu_get_ ## regname  (JitCpu *self, void *closure) \
+	{								\
+		bn_t bn;						\
+		int j;							\
+		PyObject* py_long;					\
+		PyObject* py_long_new;					\
+		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;		\
+		bn = bignum_mask(bn, (size));				\
+		for (j = BN_BYTE_SIZE - 4; j >= 0 ; j -= 4) {		\
+			tmp = bignum_to_uint64(bignum_mask(bignum_rshift(bn, 8 * j), 32)); \
+			py_tmp = PyLong_FromUnsignedLong(tmp);		\
+			py_long_new = PyObject_CallMethod(py_long, "__lshift__", "O", cst_32); \
+			Py_DECREF(py_long);				\
+			py_long = PyObject_CallMethod(py_long_new, "__add__", "O", py_tmp); \
+			Py_DECREF(py_long_new);				\
+			Py_DECREF(py_tmp);				\
+		}							\
+		Py_DECREF(cst_32);					\
+		return py_long;						\
 	}								\
+									\
+	static int JitCpu_set_ ## regname  (JitCpu *self, PyObject *value, void *closure) \
+	{								\
+		bn_t bn;						\
+		int j;							\
+		PyObject* py_long = value;				\
+		PyObject* py_long_new;					\
+		PyObject* py_tmp;					\
+		PyObject* cst_32;					\
+		PyObject* cst_ffffffff;					\
+		uint64_t tmp;						\
+		if (PyLong_Check(py_long)){				\
+				Py_INCREF(py_long);			\
+			} 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); \
+			py_long_new = PyObject_CallMethod(py_long, "__rshift__", "O", cst_32); \
+			Py_DECREF(py_long);				\
+			py_long = py_long_new;				\
+			tmp = PyLong_AsUnsignedLongMask(py_tmp);	\
+			Py_DECREF(py_tmp);				\
+			bn = bignum_or(bn, bignum_lshift(bignum_from_uint64(tmp), 8 * j)); \
+		}							\
+									\
+		((vm_cpu_t*)(self->cpu))->  regname   = bignum_mask(bn, (size)); \
+		Py_DECREF(py_long);					\
+		Py_DECREF(cst_32);					\
+		Py_DECREF(cst_ffffffff);				\
+		return 0;						\
+	}
 
 
+#else
 #define getset_reg_bn(regname, size)					\
 	static PyObject *JitCpu_get_ ## regname  (JitCpu *self, void *closure) \
 	{								\
@@ -74,18 +116,14 @@
 		PyObject* cst_ffffffff;					\
 		uint64_t tmp;						\
 									\
-		/* Ensure py_long is a PyLong */			\
-		if (PyInt_Check(py_long)) {				\
+		if (PyInt_Check(py_long)){				\
 			tmp = (uint64_t)PyInt_AsLong(py_long);		\
-			py_long = PyLong_FromLong(tmp);			\
+			py_long = PyLong_FromLong((long)tmp);		\
 		} else if (PyLong_Check(py_long)){			\
-			/* Already PyLong */				\
-			/* Increment ref as we will decement it next */	\
 			Py_INCREF(py_long);				\
 		}							\
-		else {							\
-			PyErr_SetString(PyExc_TypeError, "Arg must be int"); \
-			return -1;					\
+		else{							\
+			RAISE(PyExc_TypeError,"arg must be int");	\
 		}							\
 									\
 		cst_ffffffff = PyLong_FromLong(0xffffffff);		\
@@ -108,6 +146,17 @@
 		Py_DECREF(cst_ffffffff);				\
 		return 0;						\
 	}
+#endif
+
+
+
+
+
+
+
+
+
+
 
 #define getset_reg_u64(regname)						\
 	static PyObject *JitCpu_get_ ## regname  (JitCpu *self, void *closure) \
diff --git a/miasm2/jitter/Jitgcc.c b/miasm2/jitter/Jitgcc.c
index 329b7db4..0a39c998 100644
--- a/miasm2/jitter/Jitgcc.c
+++ b/miasm2/jitter/Jitgcc.c
@@ -1,6 +1,7 @@
 #include <Python.h>
 #include <inttypes.h>
 #include <stdint.h>
+#include "compat_py23.h"
 
 typedef struct {
 	uint8_t is_local;
@@ -90,17 +91,16 @@ static PyMethodDef GccMethods[] = {
     {NULL, NULL, 0, NULL}        /* Sentinel */
 };
 
-PyMODINIT_FUNC
-initJitgcc(void)
+
+
+MOD_INIT(Jitgcc)
 {
-    PyObject *m;
+	PyObject *module;
 
-    m = Py_InitModule("Jitgcc", GccMethods);
-    if (m == NULL)
-	    return;
+	MOD_DEF(module, "Jitgcc", "gcc module", GccMethods);
 
-    GccError = PyErr_NewException("gcc.error", NULL, NULL);
-    Py_INCREF(GccError);
-    PyModule_AddObject(m, "error", GccError);
-}
+	if (module == NULL)
+		return NULL;
 
+	return module;
+}
diff --git a/miasm2/jitter/Jitllvm.c b/miasm2/jitter/Jitllvm.c
index bb500d2e..efe5250f 100644
--- a/miasm2/jitter/Jitllvm.c
+++ b/miasm2/jitter/Jitllvm.c
@@ -3,6 +3,7 @@
 #include <inttypes.h>
 
 #include <stdint.h>
+#include "compat_py23.h"
 #include "queue.h"
 #include "vm_mngr.h"
 #include "vm_mngr_py.h"
@@ -82,13 +83,17 @@ static PyMethodDef LLVMMethods[] = {
     {NULL, NULL, 0, NULL}        /* Sentinel */
 };
 
-PyMODINIT_FUNC
-initJitllvm(void)
+
+
+
+MOD_INIT(Jitllvm)
 {
-    PyObject *m;
+	PyObject *module;
 
-    m = Py_InitModule("Jitllvm", LLVMMethods);
-    if (m == NULL)
-	    return;
+	MOD_DEF(module, "Jitllvm", "llvm module", LLVMMethods);
+
+	if (module == NULL)
+		return NULL;
 
+	return module;
 }
diff --git a/miasm2/jitter/arch/JitCore_aarch64.c b/miasm2/jitter/arch/JitCore_aarch64.c
index d8b6d0f9..9e1a870e 100644
--- a/miasm2/jitter/arch/JitCore_aarch64.c
+++ b/miasm2/jitter/arch/JitCore_aarch64.c
@@ -2,6 +2,7 @@
 #include "structmember.h"
 #include <stdint.h>
 #include <inttypes.h>
+#include "../compat_py23.h"
 #include "../queue.h"
 #include "../vm_mngr.h"
 #include "../vm_mngr_py.h"
@@ -117,6 +118,7 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args)
     PyObject* dict;
     PyObject *d_key, *d_value = NULL;
     Py_ssize_t pos = 0;
+    char* d_key_name;
     uint64_t val;
     unsigned int i, found;
 
@@ -125,14 +127,12 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args)
     if(!PyDict_Check(dict))
 	    RAISE(PyExc_TypeError, "arg must be dict");
     while(PyDict_Next(dict, &pos, &d_key, &d_value)){
-	    if(!PyString_Check(d_key))
-		    RAISE(PyExc_TypeError, "key must be str");
-
+	    PyGetStr(d_key_name, d_key);
 	    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))
+		    if (strcmp(d_key_name, gpreg_dict[i].name))
 			    continue;
 		    *((uint32_t*)(((char*)(self->cpu)) + gpreg_dict[i].offset)) = val;
 		    found = 1;
@@ -141,7 +141,7 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args)
 
 	    if (found)
 		    continue;
-	    fprintf(stderr, "unknown key: %s\n", PyString_AsString(d_key));
+	    fprintf(stderr, "unknown key: %s\n", d_key_name);
 	    RAISE(PyExc_ValueError, "unknown reg");
     }
     Py_INCREF(Py_None);
@@ -276,11 +276,11 @@ PyObject* vm_set_mem(JitCpu *self, PyObject* args)
 
        PyGetInt(py_addr, addr);
 
-       if(!PyString_Check(py_buffer))
-	       RAISE(PyExc_TypeError,"arg must be str");
+       if(!PyBytes_Check(py_buffer))
+	       RAISE(PyExc_TypeError,"arg must be bytes");
 
-       size = PyString_Size(py_buffer);
-       PyString_AsStringAndSize(py_buffer, &buffer, &py_length);
+       size = PyBytes_Size(py_buffer);
+       PyBytes_AsStringAndSize(py_buffer, &buffer, &py_length);
 
        ret = vm_write_mem(&(((VmMngr*)self->pyvm)->vm_mngr), addr, buffer, size);
        if (ret < 0)
@@ -491,9 +491,8 @@ static PyGetSetDef JitCpu_getseters[] = {
 
 
 static PyTypeObject JitCpuType = {
-    PyObject_HEAD_INIT(NULL)
-    0,                         /*ob_size*/
-    "JitCore_aarch64.JitCpu",      /*tp_name*/
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "JitCore_aarch64.JitCpu",  /*tp_name*/
     sizeof(JitCpu),            /*tp_basicsize*/
     0,                         /*tp_itemsize*/
     (destructor)JitCpu_dealloc,/*tp_dealloc*/
@@ -540,26 +539,24 @@ static PyMethodDef JitCore_aarch64_Methods[] = {
 
 };
 
-static PyObject *JitCore_aarch64_Error;
 
-PyMODINIT_FUNC
-initJitCore_aarch64(void)
+
+MOD_INIT(JitCore_aarch64)
 {
-    PyObject *m;
+	PyObject *module;
 
-    if (PyType_Ready(&JitCpuType) < 0)
-	return;
+	MOD_DEF(module, "JitCore_aarch64", "JitCore_aarch64 module", JitCore_aarch64_Methods);
 
-    m = Py_InitModule("JitCore_aarch64", JitCore_aarch64_Methods);
-    if (m == NULL)
-	    return;
+	if (module == NULL)
+		return NULL;
 
-    JitCore_aarch64_Error = PyErr_NewException("JitCore_aarch64.error", NULL, NULL);
-    Py_INCREF(JitCore_aarch64_Error);
-    PyModule_AddObject(m, "error", JitCore_aarch64_Error);
+	if (PyType_Ready(&JitCpuType) < 0)
+		return NULL;
 
-    Py_INCREF(&JitCpuType);
-    PyModule_AddObject(m, "JitCpu", (PyObject *)&JitCpuType);
+	Py_INCREF(&JitCpuType);
+	if (PyModule_AddObject(module, "JitCpu", (PyObject *)&JitCpuType) < 0)
+		return NULL;
 
+	return module;
 }
 
diff --git a/miasm2/jitter/arch/JitCore_arm.c b/miasm2/jitter/arch/JitCore_arm.c
index dca341d3..64f30cf4 100644
--- a/miasm2/jitter/arch/JitCore_arm.c
+++ b/miasm2/jitter/arch/JitCore_arm.c
@@ -2,6 +2,7 @@
 #include "structmember.h"
 #include <stdint.h>
 #include <inttypes.h>
+#include "../compat_py23.h"
 #include "../queue.h"
 #include "../vm_mngr.h"
 #include "../vm_mngr_py.h"
@@ -91,6 +92,7 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args)
     PyObject* dict;
     PyObject *d_key, *d_value = NULL;
     Py_ssize_t pos = 0;
+    char* d_key_name;
     uint64_t val;
     unsigned int i, found;
 
@@ -99,14 +101,12 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args)
     if(!PyDict_Check(dict))
 	    RAISE(PyExc_TypeError, "arg must be dict");
     while(PyDict_Next(dict, &pos, &d_key, &d_value)){
-	    if(!PyString_Check(d_key))
-		    RAISE(PyExc_TypeError, "key must be str");
-
+	    PyGetStr(d_key_name, d_key);
 	    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))
+		    if (strcmp(d_key_name, gpreg_dict[i].name))
 			    continue;
 		    *((uint32_t*)(((char*)(self->cpu)) + gpreg_dict[i].offset)) = val;
 		    found = 1;
@@ -115,7 +115,7 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args)
 
 	    if (found)
 		    continue;
-	    fprintf(stderr, "unknown key: %s\n", PyString_AsString(d_key));
+	    fprintf(stderr, "unknown key: %s\n", d_key);
 	    RAISE(PyExc_ValueError, "unknown reg");
     }
     Py_INCREF(Py_None);
@@ -239,11 +239,11 @@ PyObject* vm_set_mem(JitCpu *self, PyObject* args)
 
        PyGetInt(py_addr, addr);
 
-       if(!PyString_Check(py_buffer))
-	       RAISE(PyExc_TypeError,"arg must be str");
+       if(!PyBytes_Check(py_buffer))
+	       RAISE(PyExc_TypeError,"arg must be bytes");
 
-       size = PyString_Size(py_buffer);
-       PyString_AsStringAndSize(py_buffer, &buffer, &py_length);
+       size = PyBytes_Size(py_buffer);
+       PyBytes_AsStringAndSize(py_buffer, &buffer, &py_length);
 
        ret = vm_write_mem(&(((VmMngr*)self->pyvm)->vm_mngr), addr, buffer, size);
        if (ret < 0)
@@ -432,8 +432,7 @@ static PyGetSetDef JitCpu_getseters[] = {
 
 
 static PyTypeObject JitCpuType = {
-    PyObject_HEAD_INIT(NULL)
-    0,                         /*ob_size*/
+    PyVarObject_HEAD_INIT(NULL, 0)
     "JitCore_arm.JitCpu",      /*tp_name*/
     sizeof(JitCpu),            /*tp_basicsize*/
     0,                         /*tp_itemsize*/
@@ -485,26 +484,24 @@ static PyMethodDef JitCore_arm_Methods[] = {
 
 };
 
-static PyObject *JitCore_arm_Error;
 
-PyMODINIT_FUNC
-initJitCore_arm(void)
+
+MOD_INIT(JitCore_arm)
 {
-    PyObject *m;
+	PyObject *module;
 
-    if (PyType_Ready(&JitCpuType) < 0)
-	return;
+	MOD_DEF(module, "JitCore_arm", "JitCore_arm module", JitCore_arm_Methods);
 
-    m = Py_InitModule("JitCore_arm", JitCore_arm_Methods);
-    if (m == NULL)
-	    return;
+	if (module == NULL)
+		return NULL;
 
-    JitCore_arm_Error = PyErr_NewException("JitCore_arm.error", NULL, NULL);
-    Py_INCREF(JitCore_arm_Error);
-    PyModule_AddObject(m, "error", JitCore_arm_Error);
+	if (PyType_Ready(&JitCpuType) < 0)
+		return NULL;
 
-    Py_INCREF(&JitCpuType);
-    PyModule_AddObject(m, "JitCpu", (PyObject *)&JitCpuType);
+	Py_INCREF(&JitCpuType);
+	if (PyModule_AddObject(module, "JitCpu", (PyObject *)&JitCpuType) < 0)
+		return NULL;
 
+	return module;
 }
 
diff --git a/miasm2/jitter/arch/JitCore_mep.c b/miasm2/jitter/arch/JitCore_mep.c
index a089e84f..6e7f1767 100644
--- a/miasm2/jitter/arch/JitCore_mep.c
+++ b/miasm2/jitter/arch/JitCore_mep.c
@@ -5,6 +5,7 @@
 #include <stdint.h>
 
 #include <inttypes.h>
+#include "../compat_py23.h"
 #include "../queue.h"
 #include "../vm_mngr.h"
 #include "../vm_mngr_py.h"
@@ -148,32 +149,31 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args)
     PyObject* dict;
     PyObject *d_key, *d_value = NULL;
     Py_ssize_t pos = 0;
+    char* d_key_name;
     uint64_t val;
     unsigned int i, found;
 
     if (!PyArg_ParseTuple(args, "O", &dict))
-        return NULL;
+	return NULL;
     if(!PyDict_Check(dict))
-        RAISE(PyExc_TypeError, "arg must be dict");
+	RAISE(PyExc_TypeError, "arg must be dict");
     while(PyDict_Next(dict, &pos, &d_key, &d_value)){
-        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;
-            *((uint32_t*)(((char*)(self->cpu)) + gpreg_dict[i].offset)) = val;
-            found = 1;
-            break;
-        }
-
-        if (found)
-            continue;
-        fprintf(stderr, "unknown key: %s\n", PyString_AsString(d_key));
-        RAISE(PyExc_ValueError, "unknown reg");
+	PyGetStr(d_key_name, d_key);
+	PyGetInt(d_value, val);
+
+	found = 0;
+	for (i=0; i < sizeof(gpreg_dict)/sizeof(reg_dict); i++){
+	    if (strcmp(d_key_name, gpreg_dict[i].name))
+		continue;
+	    *((uint32_t*)(((char*)(self->cpu)) + gpreg_dict[i].offset)) = val;
+	    found = 1;
+	    break;
+	}
+
+	if (found)
+	    continue;
+	fprintf(stderr, "unknown key: %s\n", d_key_name);
+	RAISE(PyExc_ValueError, "unknown reg");
     }
     Py_INCREF(Py_None);
     return Py_None;
@@ -193,23 +193,23 @@ PyObject * cpu_init_regs(JitCpu* self)
 
 void dump_gpregs(vm_cpu_t* vmcpu)
 {
-        printf("R0  %.4"PRIX32" ", vmcpu->R0);
-        printf("R1  %.4"PRIX32" ", vmcpu->R1);
-        printf("R2  %.4"PRIX32" ", vmcpu->R2);
-        printf("R3  %.4"PRIX32" ", vmcpu->R3);
-        printf("R4  %.4"PRIX32" ", vmcpu->R4);
-        printf("R5  %.4"PRIX32" ", vmcpu->R5);
-        printf("R6  %.4"PRIX32" ", vmcpu->R6);
-        printf("R7  %.4"PRIX32" ", vmcpu->R7);
-        printf("R8  %.4"PRIX32" ", vmcpu->R8);
-        printf("R9  %.4"PRIX32" ", vmcpu->R9);
-        printf("R10  %.4"PRIX32" ", vmcpu->R10);
-        printf("R11  %.4"PRIX32" ", vmcpu->R11);
-        printf("R12  %.4"PRIX32" ", vmcpu->R12);
-        printf("TP  %.4"PRIX32" ", vmcpu->TP);
-        printf("GP  %.4"PRIX32" ", vmcpu->GP);
-        printf("SP  %.4"PRIX32" ", vmcpu->SP);
-        printf("\n");
+	printf("R0  %.4"PRIX32" ", vmcpu->R0);
+	printf("R1  %.4"PRIX32" ", vmcpu->R1);
+	printf("R2  %.4"PRIX32" ", vmcpu->R2);
+	printf("R3  %.4"PRIX32" ", vmcpu->R3);
+	printf("R4  %.4"PRIX32" ", vmcpu->R4);
+	printf("R5  %.4"PRIX32" ", vmcpu->R5);
+	printf("R6  %.4"PRIX32" ", vmcpu->R6);
+	printf("R7  %.4"PRIX32" ", vmcpu->R7);
+	printf("R8  %.4"PRIX32" ", vmcpu->R8);
+	printf("R9  %.4"PRIX32" ", vmcpu->R9);
+	printf("R10  %.4"PRIX32" ", vmcpu->R10);
+	printf("R11  %.4"PRIX32" ", vmcpu->R11);
+	printf("R12  %.4"PRIX32" ", vmcpu->R12);
+	printf("TP  %.4"PRIX32" ", vmcpu->TP);
+	printf("GP  %.4"PRIX32" ", vmcpu->GP);
+	printf("SP  %.4"PRIX32" ", vmcpu->SP);
+	printf("\n");
 }
 
 
@@ -234,7 +234,7 @@ PyObject* cpu_set_exception(JitCpu* self, PyObject* args)
     uint64_t i;
 
     if (!PyArg_ParseTuple(args, "O", &item1))
-        return NULL;
+	return NULL;
 
     PyGetInt(item1, i);
 
@@ -253,7 +253,7 @@ void check_automod(JitCpu* jitcpu, uint64_t addr, uint64_t size)
     PyObject *result;
 
     if (!(((VmMngr*)jitcpu->pyvm)->vm_mngr.exception_flags & EXCEPT_CODE_AUTOMOD))
-        return;
+	return;
     result = PyObject_CallMethod(jitcpu->jitter, "automod_cb", "LL", addr, size);
     Py_DECREF(result);
 
@@ -296,19 +296,19 @@ PyObject* vm_set_mem(JitCpu *self, PyObject* args)
        int ret = 0x1337;
 
        if (!PyArg_ParseTuple(args, "OO", &py_addr, &py_buffer))
-           return NULL;
+	   return NULL;
 
        PyGetInt(py_addr, addr);
 
-       if(!PyString_Check(py_buffer))
-           RAISE(PyExc_TypeError,"arg must be str");
+       if(!PyBytes_Check(py_buffer))
+	   RAISE(PyExc_TypeError,"arg must be bytes");
 
-       size = PyString_Size(py_buffer);
-       PyString_AsStringAndSize(py_buffer, &buffer, &py_length);
+       size = PyBytes_Size(py_buffer);
+       PyBytes_AsStringAndSize(py_buffer, &buffer, &py_length);
 
        ret = vm_write_mem(&(((VmMngr*)self->pyvm)->vm_mngr), addr, buffer, size);
        if (ret < 0)
-           RAISE(PyExc_TypeError,"arg must be str");
+	   RAISE(PyExc_TypeError,"arg must be str");
        check_automod(self, addr, size*8);
 
        Py_INCREF(Py_None);
@@ -337,8 +337,8 @@ JitCpu_init(JitCpu *self, PyObject *args, PyObject *kwds)
 {
     self->cpu = malloc(sizeof(vm_cpu_t));
     if (self->cpu == NULL) {
-        fprintf(stderr, "cannot alloc vm_cpu_t\n");
-        exit(0);
+	fprintf(stderr, "cannot alloc vm_cpu_t\n");
+	exit(0);
     }
     return 0;
 }
@@ -543,8 +543,7 @@ static PyGetSetDef JitCpu_getseters[] = {
 
 
 static PyTypeObject JitCpuType = {
-    PyObject_HEAD_INIT(NULL)
-    0,                         /*ob_size*/
+    PyVarObject_HEAD_INIT(NULL, 0)
     "JitCore_mep.JitCpu",   /*tp_name*/
     sizeof(JitCpu),            /*tp_basicsize*/
     0,                         /*tp_itemsize*/
@@ -596,25 +595,23 @@ static PyMethodDef JitCore_mep_Methods[] = {
 
 };
 
-static PyObject *JitCore_mep_Error;
 
-PyMODINIT_FUNC
-initJitCore_mep(void)
+
+MOD_INIT(JitCore_mep)
 {
-    PyObject *m;
+	PyObject *module;
 
-    if (PyType_Ready(&JitCpuType) < 0)
-    return;
+	MOD_DEF(module, "JitCore_mep", "JitCore_mep module", JitCore_mep_Methods);
 
-    m = Py_InitModule("JitCore_mep", JitCore_mep_Methods);
-    if (m == NULL)
-        return;
+	if (module == NULL)
+		return NULL;
 
-    JitCore_mep_Error = PyErr_NewException("JitCore_mep.error", NULL, NULL);
-    Py_INCREF(JitCore_mep_Error);
-    PyModule_AddObject(m, "error", JitCore_mep_Error);
+	if (PyType_Ready(&JitCpuType) < 0)
+		return NULL;
 
-    Py_INCREF(&JitCpuType);
-    PyModule_AddObject(m, "JitCpu", (PyObject *)&JitCpuType);
+	Py_INCREF(&JitCpuType);
+	if (PyModule_AddObject(module, "JitCpu", (PyObject *)&JitCpuType) < 0)
+		return NULL;
 
+	return module;
 }
diff --git a/miasm2/jitter/arch/JitCore_mips32.c b/miasm2/jitter/arch/JitCore_mips32.c
index 1c2854aa..1455fec9 100644
--- a/miasm2/jitter/arch/JitCore_mips32.c
+++ b/miasm2/jitter/arch/JitCore_mips32.c
@@ -2,6 +2,7 @@
 #include "structmember.h"
 #include <stdint.h>
 #include <inttypes.h>
+#include "../compat_py23.h"
 #include "../queue.h"
 #include "../vm_mngr.h"
 #include "../vm_mngr_py.h"
@@ -107,6 +108,7 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args)
     PyObject* dict;
     PyObject *d_key, *d_value = NULL;
     Py_ssize_t pos = 0;
+    char* d_key_name;
     uint64_t val;
     unsigned int i, found;
 
@@ -115,14 +117,12 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args)
     if(!PyDict_Check(dict))
 	    RAISE(PyExc_TypeError, "arg must be dict");
     while(PyDict_Next(dict, &pos, &d_key, &d_value)){
-	    if(!PyString_Check(d_key))
-		    RAISE(PyExc_TypeError, "key must be str");
-
+	    PyGetStr(d_key_name, d_key);
 	    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))
+		    if (strcmp(d_key_name, gpreg_dict[i].name))
 			    continue;
 		    *((uint32_t*)(((char*)(self->cpu)) + gpreg_dict[i].offset)) = val;
 		    found = 1;
@@ -131,7 +131,7 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args)
 
 	    if (found)
 		    continue;
-	    fprintf(stderr, "unknown key: %s\n", PyString_AsString(d_key));
+	    fprintf(stderr, "unknown key: %s\n", d_key_name);
 	    RAISE(PyExc_ValueError, "unknown reg");
     }
     Py_INCREF(Py_None);
@@ -264,11 +264,11 @@ PyObject* vm_set_mem(JitCpu *self, PyObject* args)
 
        PyGetInt(py_addr, addr);
 
-       if(!PyString_Check(py_buffer))
-	       RAISE(PyExc_TypeError,"arg must be str");
+       if(!PyBytes_Check(py_buffer))
+	       RAISE(PyExc_TypeError,"arg must be bytes");
 
-       size = PyString_Size(py_buffer);
-       PyString_AsStringAndSize(py_buffer, &buffer, &py_length);
+       size = PyBytes_Size(py_buffer);
+       PyBytes_AsStringAndSize(py_buffer, &buffer, &py_length);
 
        ret = vm_write_mem(&(((VmMngr*)self->pyvm)->vm_mngr), addr, buffer, size);
        if (ret < 0)
@@ -455,8 +455,7 @@ static PyGetSetDef JitCpu_getseters[] = {
 
 
 static PyTypeObject JitCpuType = {
-    PyObject_HEAD_INIT(NULL)
-    0,                         /*ob_size*/
+    PyVarObject_HEAD_INIT(NULL, 0)
     "JitCore_mips32.JitCpu",   /*tp_name*/
     sizeof(JitCpu),            /*tp_basicsize*/
     0,                         /*tp_itemsize*/
@@ -508,26 +507,25 @@ static PyMethodDef JitCore_mips32_Methods[] = {
 
 };
 
-static PyObject *JitCore_mips32_Error;
 
-PyMODINIT_FUNC
-initJitCore_mips32(void)
+
+
+
+MOD_INIT(JitCore_mips32)
 {
-    PyObject *m;
+	PyObject *module;
 
-    if (PyType_Ready(&JitCpuType) < 0)
-	return;
+	MOD_DEF(module, "JitCore_mips32", "JitCore_mips32 module", JitCore_mips32_Methods);
 
-    m = Py_InitModule("JitCore_mips32", JitCore_mips32_Methods);
-    if (m == NULL)
-	    return;
+	if (module == NULL)
+		return NULL;
 
-    JitCore_mips32_Error = PyErr_NewException("JitCore_mips32.error", NULL, NULL);
-    Py_INCREF(JitCore_mips32_Error);
-    PyModule_AddObject(m, "error", JitCore_mips32_Error);
+	if (PyType_Ready(&JitCpuType) < 0)
+		return NULL;
 
-    Py_INCREF(&JitCpuType);
-    PyModule_AddObject(m, "JitCpu", (PyObject *)&JitCpuType);
+	Py_INCREF(&JitCpuType);
+	if (PyModule_AddObject(module, "JitCpu", (PyObject *)&JitCpuType) < 0)
+		return NULL;
 
+	return module;
 }
-
diff --git a/miasm2/jitter/arch/JitCore_msp430.c b/miasm2/jitter/arch/JitCore_msp430.c
index 69f179a4..c21296c7 100644
--- a/miasm2/jitter/arch/JitCore_msp430.c
+++ b/miasm2/jitter/arch/JitCore_msp430.c
@@ -2,6 +2,7 @@
 #include "structmember.h"
 #include <stdint.h>
 #include <inttypes.h>
+#include "../compat_py23.h"
 #include "../queue.h"
 #include "../vm_mngr.h"
 #include "../vm_mngr_py.h"
@@ -89,6 +90,7 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args)
     PyObject* dict;
     PyObject *d_key, *d_value = NULL;
     Py_ssize_t pos = 0;
+    char* d_key_name;
     uint64_t val;
     unsigned int i, found;
 
@@ -97,14 +99,11 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args)
     if(!PyDict_Check(dict))
 	    RAISE(PyExc_TypeError, "arg must be dict");
     while(PyDict_Next(dict, &pos, &d_key, &d_value)){
-	    if(!PyString_Check(d_key))
-		    RAISE(PyExc_TypeError, "key must be str");
-
+	    PyGetStr(d_key_name, d_key);
 	    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))
+		    if (strcmp(d_key_name, gpreg_dict[i].name))
 			    continue;
 		    *((uint32_t*)(((char*)(self->cpu)) + gpreg_dict[i].offset)) = val;
 		    found = 1;
@@ -113,7 +112,7 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args)
 
 	    if (found)
 		    continue;
-	    fprintf(stderr, "unknown key: %s\n", PyString_AsString(d_key));
+	    fprintf(stderr, "unknown key: %s\n", d_key_name);
 	    RAISE(PyExc_ValueError, "unknown reg");
     }
     Py_INCREF(Py_None);
@@ -240,11 +239,11 @@ PyObject* vm_set_mem(JitCpu *self, PyObject* args)
 
        PyGetInt(py_addr, addr);
 
-       if(!PyString_Check(py_buffer))
-	       RAISE(PyExc_TypeError,"arg must be str");
+       if(!PyBytes_Check(py_buffer))
+	       RAISE(PyExc_TypeError,"arg must be bytes");
 
-       size = PyString_Size(py_buffer);
-       PyString_AsStringAndSize(py_buffer, &buffer, &py_length);
+       size = PyBytes_Size(py_buffer);
+       PyBytes_AsStringAndSize(py_buffer, &buffer, &py_length);
 
        ret = vm_write_mem(&(((VmMngr*)self->pyvm)->vm_mngr), addr, buffer, size);
        if (ret < 0)
@@ -403,8 +402,7 @@ static PyGetSetDef JitCpu_getseters[] = {
 
 
 static PyTypeObject JitCpuType = {
-    PyObject_HEAD_INIT(NULL)
-    0,                         /*ob_size*/
+    PyVarObject_HEAD_INIT(NULL, 0)
     "JitCore_msp430.JitCpu",   /*tp_name*/
     sizeof(JitCpu),            /*tp_basicsize*/
     0,                         /*tp_itemsize*/
@@ -456,26 +454,24 @@ static PyMethodDef JitCore_msp430_Methods[] = {
 
 };
 
-static PyObject *JitCore_msp430_Error;
 
-PyMODINIT_FUNC
-initJitCore_msp430(void)
+
+
+MOD_INIT(JitCore_msp430)
 {
-    PyObject *m;
+	PyObject *module;
 
-    if (PyType_Ready(&JitCpuType) < 0)
-	return;
+	MOD_DEF(module, "JitCore_msp430", "JitCore_msp430 module", JitCore_msp430_Methods);
 
-    m = Py_InitModule("JitCore_msp430", JitCore_msp430_Methods);
-    if (m == NULL)
-	    return;
+	if (module == NULL)
+		return NULL;
 
-    JitCore_msp430_Error = PyErr_NewException("JitCore_msp430.error", NULL, NULL);
-    Py_INCREF(JitCore_msp430_Error);
-    PyModule_AddObject(m, "error", JitCore_msp430_Error);
+	if (PyType_Ready(&JitCpuType) < 0)
+		return NULL;
 
-    Py_INCREF(&JitCpuType);
-    PyModule_AddObject(m, "JitCpu", (PyObject *)&JitCpuType);
+	Py_INCREF(&JitCpuType);
+	if (PyModule_AddObject(module, "JitCpu", (PyObject *)&JitCpuType) < 0)
+		return NULL;
 
+	return module;
 }
-
diff --git a/miasm2/jitter/arch/JitCore_ppc32.c b/miasm2/jitter/arch/JitCore_ppc32.c
index e1a3fcd5..8a1bb79e 100644
--- a/miasm2/jitter/arch/JitCore_ppc32.c
+++ b/miasm2/jitter/arch/JitCore_ppc32.c
@@ -2,6 +2,7 @@
 #include "structmember.h"
 #include <stdint.h>
 #include <inttypes.h>
+#include "../compat_py23.h"
 #include "../queue.h"
 #include "../vm_mngr.h"
 #include "../vm_mngr_py.h"
@@ -36,6 +37,7 @@ cpu_set_gpreg(JitCpu *self, PyObject *args) {
     PyObject *dict;
     PyObject *d_key, *d_value = NULL;
     Py_ssize_t pos = 0;
+    char* d_key_name;
     uint64_t val;
     unsigned int i;
 
@@ -46,14 +48,11 @@ cpu_set_gpreg(JitCpu *self, PyObject *args) {
 
     while(PyDict_Next(dict, &pos, &d_key, &d_value)) {
 	int found = 0;
-
-	if(!PyString_Check(d_key))
-	    RAISE(PyExc_TypeError, "key must be str");
-
+	PyGetStr(d_key_name, d_key);
 	PyGetInt(d_value, val);
 
 	for (i=0; i < sizeof(gpreg_dict)/sizeof(reg_dict); i++){
-	    if (strcmp(PyString_AsString(d_key), gpreg_dict[i].name))
+	    if (strcmp(d_key_name, gpreg_dict[i].name))
 		continue;
 	    *((uint32_t*)(((char*)(self->cpu)) + gpreg_dict[i].offset)) = val;
 	    found = 1;
@@ -62,7 +61,7 @@ cpu_set_gpreg(JitCpu *self, PyObject *args) {
 
 	if (found)
 	    continue;
-	fprintf(stderr, "unknown key: %s\n", PyString_AsString(d_key));
+	fprintf(stderr, "unknown key: %s\n", d_key_name);
 	RAISE(PyExc_ValueError, "unknown reg");
     }
 
@@ -192,11 +191,11 @@ vm_set_mem(JitCpu *self, PyObject *args) {
 
    PyGetInt(py_addr, addr);
 
-   if(!PyString_Check(py_buffer))
-       RAISE(PyExc_TypeError,"arg must be str");
+   if(!PyBytes_Check(py_buffer))
+       RAISE(PyExc_TypeError,"arg must be bytes");
 
-   size = PyString_Size(py_buffer);
-   PyString_AsStringAndSize(py_buffer, &buffer, &py_length);
+   size = PyBytes_Size(py_buffer);
+   PyBytes_AsStringAndSize(py_buffer, &buffer, &py_length);
 
    ret = vm_write_mem(&(((VmMngr*)self->pyvm)->vm_mngr), addr, buffer, size);
    if (ret < 0)
@@ -276,8 +275,7 @@ static PyGetSetDef JitCpu_getseters[] = {
 
 
 static PyTypeObject JitCpuType = {
-    PyObject_HEAD_INIT(NULL)
-    0,                         /*ob_size*/
+    PyVarObject_HEAD_INIT(NULL, 0)
     "JitCore_ppc.JitCpu",      /*tp_name*/
     sizeof(JitCpu),            /*tp_basicsize*/
     0,                         /*tp_itemsize*/
@@ -319,31 +317,28 @@ static PyTypeObject JitCpuType = {
 
 
 
-static PyMethodDef JitCore_ppc_Methods[] = {
+static PyMethodDef JitCore_ppc32_Methods[] = {
     {"get_gpreg_offset_all", (PyCFunction)get_gpreg_offset_all, METH_NOARGS},
     {NULL, NULL, 0, NULL}        /* Sentinel */
 };
 
-static PyObject *JitCore_ppc32_Error;
 
-PyMODINIT_FUNC
-initJitCore_ppc32(void)
+
+MOD_INIT(JitCore_ppc32)
 {
-    PyObject *m;
+	PyObject *module;
 
-    if (PyType_Ready(&JitCpuType) < 0)
-	return;
+	MOD_DEF(module, "JitCore_ppc32", "JitCore_ppc32 module", JitCore_ppc32_Methods);
 
-    m = Py_InitModule("JitCore_ppc32", JitCore_ppc_Methods);
-    if (m == NULL)
-	return;
+	if (module == NULL)
+		return NULL;
 
-    JitCore_ppc32_Error = PyErr_NewException("JitCore_ppc32.error", NULL, NULL);
-    Py_INCREF(JitCore_ppc32_Error);
-    PyModule_AddObject(m, "error", JitCore_ppc32_Error);
+	if (PyType_Ready(&JitCpuType) < 0)
+		return NULL;
 
-    Py_INCREF(&JitCpuType);
-    PyModule_AddObject(m, "JitCpu", (PyObject *)&JitCpuType);
+	Py_INCREF(&JitCpuType);
+	if (PyModule_AddObject(module, "JitCpu", (PyObject *)&JitCpuType) < 0)
+		return NULL;
 
+	return module;
 }
-
diff --git a/miasm2/jitter/arch/JitCore_x86.c b/miasm2/jitter/arch/JitCore_x86.c
index a13b6881..50ce6bd5 100644
--- a/miasm2/jitter/arch/JitCore_x86.c
+++ b/miasm2/jitter/arch/JitCore_x86.c
@@ -2,6 +2,7 @@
 #include "structmember.h"
 #include <stdint.h>
 #include <inttypes.h>
+#include "../compat_py23.h"
 #include "../queue.h"
 #include "../vm_mngr.h"
 #include "../vm_mngr_py.h"
@@ -10,6 +11,7 @@
 #include "../op_semantics.h"
 #include "JitCore_x86.h"
 
+
 vm_cpu_t ref_arch_regs;
 
 reg_dict gpreg_dict[] = {
@@ -161,13 +163,11 @@ PyObject* cpu_get_gpreg(JitCpu* self)
 }
 
 
-
-
-
 PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args)
 {
     PyObject* dict;
     PyObject *d_key, *d_value = NULL;
+    char* d_key_name;
     Py_ssize_t pos = 0;
     uint64_t val;
     unsigned int i, found;
@@ -177,12 +177,10 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args)
     if(!PyDict_Check(dict))
 	    RAISE(PyExc_TypeError, "arg must be dict");
     while(PyDict_Next(dict, &pos, &d_key, &d_value)){
-	    if(!PyString_Check(d_key))
-		    RAISE(PyExc_TypeError, "key must be str");
-
+	    PyGetStr(d_key_name, d_key);
 	    found = 0;
 	    for (i=0; i < sizeof(gpreg_dict)/sizeof(reg_dict); i++){
-		    if (strcmp(PyString_AsString(d_key), gpreg_dict[i].name))
+		    if (strcmp(d_key_name, gpreg_dict[i].name))
 			    continue;
 		    found = 1;
 		    switch (gpreg_dict[i].size) {
@@ -213,7 +211,16 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args)
 					    PyObject* cst_ffffffff;
 					    uint64_t tmp;
 
-					    /* Ensure py_long is a PyLong */
+
+#if PY_MAJOR_VERSION >= 3
+					    if (PyLong_Check(py_long)){
+						    /* Already PyLong */
+						    /* Increment ref as we will decement it next */
+						    Py_INCREF(py_long);
+					    } else {
+						    RAISE(PyExc_TypeError,"arg must be int");
+					    }
+#else
 					    if (PyInt_Check(py_long)){
 						    tmp = (uint64_t)PyInt_AsLong(py_long);
 						    py_long = PyLong_FromLong((long)tmp);
@@ -225,6 +232,7 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args)
 					    else{
 						    RAISE(PyExc_TypeError,"arg must be int");
 					    }
+#endif
 
 
 					    cst_ffffffff = PyLong_FromLong(0xffffffff);
@@ -254,7 +262,7 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args)
 
 	    if (found)
 		    continue;
-	    fprintf(stderr, "unknown key: %s\n", PyString_AsString(d_key));
+	    fprintf(stderr, "unknown key: %s\n", d_key_name);
 	    RAISE(PyExc_ValueError, "unknown reg");
     }
     Py_INCREF(Py_None);
@@ -437,7 +445,7 @@ PyObject* cpu_get_segm_base(JitCpu* self, PyObject* args)
 	if (!PyArg_ParseTuple(args, "O", &item1))
 		RAISE(PyExc_TypeError,"Cannot parse arguments");
 	PyGetInt(item1, segm_num);
-	v = PyInt_FromLong((long)(((vm_cpu_t*)self->cpu)->segm_base[segm_num]));
+	v = PyLong_FromLong((long)(((vm_cpu_t*)self->cpu)->segm_base[segm_num]));
 	return v;
 }
 
@@ -484,11 +492,11 @@ PyObject* vm_set_mem(JitCpu *self, PyObject* args)
 
        PyGetInt(py_addr, addr);
 
-       if(!PyString_Check(py_buffer))
-	       RAISE(PyExc_TypeError,"arg must be str");
+       if(!PyBytes_Check(py_buffer))
+	       RAISE(PyExc_TypeError,"arg must be bytes");
 
-       size = PyString_Size(py_buffer);
-       PyString_AsStringAndSize(py_buffer, &buffer, &py_length);
+       size = PyBytes_Size(py_buffer);
+       PyBytes_AsStringAndSize(py_buffer, &buffer, &py_length);
 
        ret = vm_write_mem(&(((VmMngr*)self->pyvm)->vm_mngr), addr, buffer, size);
        if (ret < 0)
@@ -865,9 +873,8 @@ static PyGetSetDef JitCpu_getseters[] = {
 
 
 static PyTypeObject JitCpuType = {
-    PyObject_HEAD_INIT(NULL)
-    0,                         /*ob_size*/
-    "JitCore_x86.JitCpu",   /*tp_name*/
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "JitCore_x86.JitCpu",      /*tp_name*/
     sizeof(JitCpu),            /*tp_basicsize*/
     0,                         /*tp_itemsize*/
     (destructor)JitCpu_dealloc,/*tp_dealloc*/
@@ -918,47 +925,22 @@ static PyMethodDef JitCore_x86_Methods[] = {
 
 };
 
-static PyObject *JitCore_x86_Error;
 
-PyMODINIT_FUNC
-initJitCore_x86(void)
+MOD_INIT(JitCore_x86)
 {
-    PyObject *m;
+	PyObject *module;
 
-    if (PyType_Ready(&JitCpuType) < 0)
-	return;
+	MOD_DEF(module, "JitCore_x86", "JitCore_x86 module", JitCore_x86_Methods);
 
-    m = Py_InitModule("JitCore_x86", JitCore_x86_Methods);
-    if (m == NULL)
-	    return;
+	if (module == NULL)
+		return NULL;
 
-    JitCore_x86_Error = PyErr_NewException("JitCore_x86.error", NULL, NULL);
-    Py_INCREF(JitCore_x86_Error);
-    PyModule_AddObject(m, "error", JitCore_x86_Error);
+	if (PyType_Ready(&JitCpuType) < 0)
+		return NULL;
 
-    Py_INCREF(&JitCpuType);
-    PyModule_AddObject(m, "JitCpu", (PyObject *)&JitCpuType);
+	Py_INCREF(&JitCpuType);
+	if (PyModule_AddObject(module, "JitCpu", (PyObject *)&JitCpuType) < 0)
+		return NULL;
 
+	return module;
 }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/miasm2/jitter/codegen.py b/miasm2/jitter/codegen.py
index 65df0c03..bdd9e570 100644
--- a/miasm2/jitter/codegen.py
+++ b/miasm2/jitter/codegen.py
@@ -2,6 +2,10 @@
 Module to generate C code for a given native @block
 """
 
+from builtins import zip
+
+from future.utils import viewitems, viewvalues
+
 from miasm2.expression.expression import Expr, ExprId, ExprLoc, ExprInt, \
     ExprMem, ExprCond, LocKey
 from miasm2.ir.ir import IRBlock, AssignBlock
@@ -238,18 +242,18 @@ class CGen(object):
 
         prefetchers = self.get_mem_prefetch(assignblk)
 
-        for expr, prefetcher in sorted(prefetchers.iteritems()):
+        for expr, prefetcher in viewitems(prefetchers):
             str_src = self.id_to_c(expr)
             str_dst = self.id_to_c(prefetcher)
             c_prefetch.append('%s = %s;' % (str_dst, str_src))
 
-        for var in prefetchers.itervalues():
+        for var in viewvalues(prefetchers):
             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()):
+        for dst, src in viewitems(assignblk):
             src = src.replace_expr(prefetchers)
             if dst == self.ir_arch.IRDst:
                 pass
@@ -294,7 +298,7 @@ class CGen(object):
             else:
                 raise ValueError("Unknown dst")
 
-        for dst, new_dst in dst_var.iteritems():
+        for dst, new_dst in viewitems(dst_var):
             if dst == self.ir_arch.IRDst:
                 continue
 
@@ -450,7 +454,7 @@ class CGen(object):
         out.append('switch(DST_case) {')
 
         stopcase = False
-        for dst, index in sorted(dst2index.iteritems(), key=lambda lblindex: lblindex[1]):
+        for dst, index in sorted(viewitems(dst2index), key=lambda lblindex: lblindex[1]):
             if index == -1:
                 # Handle '-1' case only once
                 if not stopcase:
diff --git a/miasm2/jitter/compat_py23.h b/miasm2/jitter/compat_py23.h
new file mode 100644
index 00000000..bc66d80b
--- /dev/null
+++ b/miasm2/jitter/compat_py23.h
@@ -0,0 +1,87 @@
+#ifndef __COMPAT_PY23_H__
+#define __COMPAT_PY23_H__
+
+
+
+#if PY_MAJOR_VERSION >= 3
+#define PyGetInt(item, value)						\
+	if (PyLong_Check(item)){					\
+		value = (uint64_t)PyLong_AsUnsignedLongLong(item);	\
+	}								\
+	else{								\
+		RAISE(PyExc_TypeError,"arg must be int");		\
+	}
+
+
+#define PyGetInt_retneg(item, value)					\
+	if (PyLong_Check(item)){					\
+		value = (uint64_t)PyLong_AsUnsignedLongLong(item);	\
+	}								\
+	else{								\
+		PyErr_SetString(PyExc_TypeError, "Arg must be int");	\
+		return -1;						\
+	}
+
+#define PyGetStr(dest, name)						\
+	if (!PyUnicode_Check((name)))					\
+		RAISE(PyExc_TypeError,"Page name must be bytes");	\
+	(dest) = PyUnicode_AsUTF8((name))
+
+
+
+#else
+#define PyGetInt(item, value)						\
+	if (PyInt_Check(item)){						\
+		value = (uint64_t)PyInt_AsLong(item);			\
+	}								\
+	else if (PyLong_Check(item)){					\
+		value = (uint64_t)PyLong_AsUnsignedLongLong(item);	\
+	}								\
+	else{								\
+		RAISE(PyExc_TypeError,"arg must be int");		\
+	}
+
+
+#define PyGetInt_retneg(item, value)					\
+	if (PyInt_Check(item)){						\
+		value = (uint64_t)PyLong_AsLong(item);			\
+	}								\
+	else if (PyLong_Check(item)){					\
+		value = (uint64_t)PyLong_AsUnsignedLongLong(item);	\
+	}								\
+	else{								\
+		PyErr_SetString(PyExc_TypeError, "Arg must be int");	\
+		return -1;						\
+	}								\
+
+
+#define PyGetStr(dest, name)						\
+	if (!PyString_Check((name)))					\
+		RAISE(PyExc_TypeError,"Page name must be bytes");	\
+	(dest) = PyString_AsString((name))
+
+#endif
+
+
+
+#if PY_MAJOR_VERSION >= 3
+
+#define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
+
+#define MOD_DEF(ob, name, doc, methods)		  \
+	static struct PyModuleDef moduledef = {				\
+					       PyModuleDef_HEAD_INIT, name, doc, -1, methods, }; \
+	ob = PyModule_Create(&moduledef);
+#else
+
+#define MOD_INIT(name) PyMODINIT_FUNC init##name(void)
+
+#define MOD_DEF(ob, name, doc, methods)			\
+	ob = Py_InitModule3(name, methods, doc);
+#endif
+
+
+
+
+
+#endif
diff --git a/miasm2/jitter/emulatedsymbexec.py b/miasm2/jitter/emulatedsymbexec.py
index 78c02fb1..3ccce522 100644
--- a/miasm2/jitter/emulatedsymbexec.py
+++ b/miasm2/jitter/emulatedsymbexec.py
@@ -1,3 +1,4 @@
+from miasm2.core.utils import decode_hex, encode_hex
 import miasm2.expression.expression as m2_expr
 from miasm2.ir.symbexec import SymbolicExecutionEngine
 
@@ -43,14 +44,16 @@ class EmulatedSymbExec(SymbolicExecutionEngine):
         if not addr.is_int():
             return super(EmulatedSymbExec, self).mem_read(expr_mem)
         addr = int(addr)
-        size = expr_mem.size / 8
+        size = expr_mem.size // 8
         value = self.cpu.get_mem(addr, size)
         if self.vm.is_little_endian():
             value = value[::-1]
         self.vm.add_mem_read(addr, size)
 
-        return m2_expr.ExprInt(int(value.encode("hex"), 16),
-                               expr_mem.size)
+        return m2_expr.ExprInt(
+            int(encode_hex(value), 16),
+            expr_mem.size
+        )
 
     def mem_write(self, dest, data):
         """Memory read wrapper for symbolic execution
@@ -65,10 +68,10 @@ class EmulatedSymbExec(SymbolicExecutionEngine):
 
         # Format information
         addr = dest.ptr.arg.arg
-        size = data.size / 8
+        size = data.size // 8
         content = hex(to_write).replace("0x", "").replace("L", "")
         content = "0" * (size * 2 - len(content)) + content
-        content = content.decode("hex")
+        content = decode_hex(content)
 
         if self.vm.is_little_endian():
             content = content[::-1]
diff --git a/miasm2/jitter/jitcore.py b/miasm2/jitter/jitcore.py
index 78e27244..33efdfd9 100644
--- a/miasm2/jitter/jitcore.py
+++ b/miasm2/jitter/jitcore.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 #
 # Copyright (C) 2011 EADS France, Fabrice Desclaux <fabrice.desclaux@eads.net>
 #
@@ -18,6 +19,8 @@
 from hashlib import md5
 import warnings
 
+from future.utils import viewvalues
+
 from miasm2.core.asmblock import disasmEngine, AsmBlockBad
 from miasm2.core.interval import interval
 from miasm2.core.utils import BoundedDict
@@ -141,7 +144,7 @@ class JitCore(object):
             return cur_block
         # Logging
         if self.log_newbloc:
-            print cur_block.to_string(self.mdis.loc_db)
+            print(cur_block.to_string(self.mdis.loc_db))
 
         # Update label -> block
         self.loc_key_to_block[cur_block.loc_key] = cur_block
@@ -222,7 +225,7 @@ class JitCore(object):
 
         # Find concerned blocks
         modified_blocks = set()
-        for block in self.loc_key_to_block.values():
+        for block in viewvalues(self.loc_key_to_block):
             if not block.lines:
                 continue
             if block.ad_max <= ad1 or block.ad_min >= ad2:
@@ -282,13 +285,17 @@ class JitCore(object):
         Build a hash of the block @block
         @block: asmblock
         """
-        block_raw = "".join(line.b for line in block.lines)
+        block_raw = b"".join(line.b for line in block.lines)
         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()
+        block_hash = md5(
+            b"%X_%s_%s_%s_%s" % (
+                offset,
+                self.arch_name.encode(),
+                b'\x01' if self.log_mn else b'\x00',
+                b'\x01' if self.log_regs else b'\x00',
+                block_raw
+            )
+        ).hexdigest()
         return block_hash
 
     @property
diff --git a/miasm2/jitter/jitcore_cc_base.py b/miasm2/jitter/jitcore_cc_base.py
index 7853816a..997d6330 100644
--- a/miasm2/jitter/jitcore_cc_base.py
+++ b/miasm2/jitter/jitcore_cc_base.py
@@ -3,6 +3,7 @@
 import os
 import tempfile
 import platform
+import sysconfig
 from distutils.sysconfig import get_python_inc
 
 from miasm2.jitter.jitcore import JitCore
@@ -28,7 +29,7 @@ def gen_core(arch, attrib):
     return txt
 
 
-class myresolver:
+class myresolver(object):
 
     def __init__(self, offset):
         self.offset = offset
@@ -37,7 +38,7 @@ class myresolver:
         return "return PyLong_FromUnsignedLongLong(0x%X);" % self.offset
 
 
-class resolver:
+class resolver(object):
 
     def __init__(self):
         self.resolvers = keydefaultdict(myresolver)
@@ -57,7 +58,7 @@ class JitCore_Cc_Base(JitCore):
         self.states = {}
         self.tempdir = os.path.join(tempfile.gettempdir(), "miasm_cache")
         try:
-            os.mkdir(self.tempdir, 0755)
+            os.mkdir(self.tempdir, 0o755)
         except OSError:
             pass
         if not os.access(self.tempdir, os.R_OK | os.W_OK):
@@ -72,12 +73,23 @@ class JitCore_Cc_Base(JitCore):
 
     def load(self):
         lib_dir = os.path.dirname(os.path.realpath(__file__))
-        ext = ".so" if not is_win else ".lib"
-        libs = [os.path.join(lib_dir, "VmMngr" + ext),
-                os.path.join(lib_dir, "arch", "JitCore_%s%s" % (self.ir_arch.arch.name, ext))]
-
-        include_files = [os.path.dirname(__file__),
-                         get_python_inc()]
+        ext = sysconfig.get_config_var('EXT_SUFFIX')
+        if ext is None:
+            ext = ".so" if not is_win else ".lib"
+
+        libs = [
+            os.path.join(lib_dir, "VmMngr" + ext),
+            os.path.join(
+                lib_dir,
+                "arch",
+                "JitCore_%s%s" % (self.ir_arch.arch.name, ext)
+            )
+        ]
+
+        include_files = [
+            os.path.dirname(__file__),
+            get_python_inc()
+        ]
         self.include_files = include_files
         self.libs = libs
 
@@ -94,7 +106,11 @@ class JitCore_Cc_Base(JitCore):
         @irblocks: list of irblocks
         """
         f_declaration = '_MIASM_EXPORT 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 = 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 238f2239..5fd54c3d 100644
--- a/miasm2/jitter/jitcore_gcc.py
+++ b/miasm2/jitter/jitcore_gcc.py
@@ -5,9 +5,9 @@ import tempfile
 import ctypes
 import _ctypes
 import platform
+import sysconfig
 from subprocess import check_call
 from distutils.sysconfig import get_python_inc
-
 from miasm2.jitter import Jitgcc
 from miasm2.jitter.jitcore_cc_base import JitCore_Cc_Base, gen_core
 
@@ -45,7 +45,9 @@ class JitCore_Gcc(JitCore_Cc_Base):
         @block: block to jit
         """
         block_hash = self.hash_block(block)
-        ext = ".so" if not is_win else ".pyd"
+        ext = sysconfig.get_config_var('EXT_SUFFIX')
+        if ext is None:
+            ext = ".so" if not is_win else ".pyd"
         fname_out = os.path.join(self.tempdir, "%s%s" % (block_hash, ext))
 
         if not os.access(fname_out, os.R_OK | os.X_OK):
@@ -53,7 +55,7 @@ class JitCore_Gcc(JitCore_Cc_Base):
 
             # Create unique C file
             fdesc, fname_in = tempfile.mkstemp(suffix=".c")
-            os.write(fdesc, func_code)
+            os.write(fdesc, func_code.encode())
             os.close(fdesc)
 
             # Create unique SO file
@@ -63,7 +65,14 @@ class JitCore_Gcc(JitCore_Cc_Base):
             inc_dir = ["-I%s" % inc for inc in self.include_files]
             libs = ["%s" % lib for lib in self.libs]
             if is_win:
-                libs.append(os.path.join(get_python_inc(), "..", "libs", "python27.lib"))
+                libs.append(
+                    os.path.join(
+                        get_python_inc(),
+                        "..",
+                        "libs",
+                        "python27.lib"
+                    )
+                )
                 cl = [
                     "cl", "/nologo", "/W3", "/MP",
                     "/Od", "/DNDEBUG", "/D_WINDOWS", "/Gm-", "/EHsc",
@@ -76,26 +85,44 @@ class JitCore_Gcc(JitCore_Cc_Base):
                 basename_out, _ = os.path.splitext(fname_tmp)
                 basename_in, _ = os.path.splitext(os.path.basename(fname_in))
                 for ext in ('.obj', '.exp', '.lib'):
-                    artifact_out_path = os.path.join(out_dir, basename_out + ext)
+                    artifact_out_path = os.path.join(
+                        out_dir,
+                        basename_out + ext
+                    )
                     if os.path.isfile(artifact_out_path):
                         os.remove(artifact_out_path)
-                    artifact_in_path = os.path.join(out_dir, basename_in + ext)
+                    artifact_in_path = os.path.join(
+                        out_dir,
+                        basename_in + ext
+                    )
                     if os.path.isfile(artifact_in_path):
                         os.remove(artifact_in_path)
             else:
-                args = ["cc", "-O3", "-shared", "-fPIC", fname_in, "-o", fname_tmp] + inc_dir + libs
+                args = [
+                    "cc",
+                    "-O3",
+                    "-shared",
+                    "-fPIC",
+                    fname_in,
+                    "-o",
+                    fname_tmp
+                ] + inc_dir + libs
                 check_call(args)
 
             # Move temporary file to final file
             try:
                 os.rename(fname_tmp, fname_out)
-            except WindowsError, e:
-                # On Windows, os.rename works slightly differently than on Linux; quoting the documentation:
-                # "On Unix, if dst exists and is a file, it will be replaced silently if the user has permission.
-                # The operation may fail on some Unix flavors if src and dst are on different filesystems.
-                # If successful, the renaming will be an atomic operation (this is a POSIX requirement).
-                # On Windows, if dst already exists, OSError will be raised even if it is a file; there may be no way
-                # to implement an atomic rename when dst names an existing file."
+            except WindowsError as e:
+                # On Windows, os.rename works slightly differently than on
+                # Linux; quoting the documentation:
+                # "On Unix, if dst exists and is a file, it will be replaced
+                # silently if the user has permission.  The operation may fail
+                # on some Unix flavors if src and dst are on different
+                # filesystems.  If successful, the renaming will be an atomic
+                # operation (this is a POSIX requirement).  On Windows, if dst
+                # already exists, OSError will be raised even if it is a file;
+                # there may be no way to implement an atomic rename when dst
+                # names an existing file."
                 # [Error 183] Cannot create a file when that file already exists
                 if e.winerror != 183:
                     raise
diff --git a/miasm2/jitter/jitcore_llvm.py b/miasm2/jitter/jitcore_llvm.py
index 463e476a..d017e122 100644
--- a/miasm2/jitter/jitcore_llvm.py
+++ b/miasm2/jitter/jitcore_llvm.py
@@ -1,32 +1,40 @@
+from __future__ import print_function
 import os
 import importlib
 import tempfile
+import sysconfig
 
 from miasm2.jitter.llvmconvert import *
 import miasm2.jitter.jitcore as jitcore
-import Jitllvm
+from miasm2.jitter import Jitllvm
 import platform
 
+is_win = platform.system() == "Windows"
+
 class JitCore_LLVM(jitcore.JitCore):
     "JiT management, using LLVM as backend"
 
     # Architecture dependent libraries
-    arch_dependent_libs = {"x86": "JitCore_x86",
-                           "arm": "JitCore_arm",
-                           "msp430": "JitCore_msp430",
-                           "mips32": "JitCore_mips32",
-                           "aarch64": "JitCore_aarch64",
-                           "ppc32": "JitCore_ppc32",
+    arch_dependent_libs = {
+        "x86": "JitCore_x86",
+        "arm": "JitCore_arm",
+        "msp430": "JitCore_msp430",
+        "mips32": "JitCore_mips32",
+        "aarch64": "JitCore_aarch64",
+        "ppc32": "JitCore_ppc32",
     }
 
     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
-                             "log_func": False,    # Print LLVM functions
-                             "log_assembly": False,  # Print assembly executed
-                             })
+        self.options.update(
+            {
+                "safe_mode": True,   # Verify each function
+                "optimise": True,     # Optimise functions
+                "log_func": False,    # Print LLVM functions
+                "log_assembly": False,  # Print assembly executed
+            }
+        )
 
         self.exec_wrapper = Jitllvm.llvm_exec_block
         self.ir_arch = ir_arch
@@ -34,7 +42,7 @@ class JitCore_LLVM(jitcore.JitCore):
         # Cache temporary dir
         self.tempdir = os.path.join(tempfile.gettempdir(), "miasm_cache")
         try:
-            os.mkdir(self.tempdir, 0755)
+            os.mkdir(self.tempdir, 0o755)
         except OSError:
             pass
         if not os.access(self.tempdir, os.R_OK | os.W_OK):
@@ -49,10 +57,13 @@ class JitCore_LLVM(jitcore.JitCore):
         # Get architecture dependent Jitcore library (if any)
         lib_dir = os.path.dirname(os.path.realpath(__file__))
         lib_dir = os.path.join(lib_dir, 'arch')
-        ext = '.so' if platform.system() != 'Windows' else '.pyd'
+        ext = sysconfig.get_config_var('EXT_SUFFIX')
+        if ext is None:
+            ext = ".so" if not is_win else ".pyd"
         try:
             jit_lib = os.path.join(
-                lib_dir, self.arch_dependent_libs[self.ir_arch.arch.name] + ext)
+                lib_dir, self.arch_dependent_libs[self.ir_arch.arch.name] + ext
+            )
             libs_to_load.append(jit_lib)
         except KeyError:
             pass
@@ -103,9 +114,9 @@ class JitCore_LLVM(jitcore.JitCore):
 
             # Log
             if self.options["log_func"] is True:
-                print func
+                print(func)
             if self.options["log_assembly"] is True:
-                print func.get_assembly()
+                print(func.get_assembly())
 
             # Use propagate the cache filename
             self.context.set_cache_filename(func, fname_out)
diff --git a/miasm2/jitter/jitcore_python.py b/miasm2/jitter/jitcore_python.py
index fdd5c2ae..4262c334 100644
--- a/miasm2/jitter/jitcore_python.py
+++ b/miasm2/jitter/jitcore_python.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+from builtins import zip
 import miasm2.jitter.jitcore as jitcore
 from miasm2.expression.expression import ExprInt, ExprLoc
 import miasm2.jitter.csts as csts
@@ -111,10 +113,10 @@ class JitCore_Python(jitcore.JitCore):
                 if index == 0:
                     # Pre code
                     if instr_attrib.log_mn:
-                        print "%.8X %s" % (
+                        print("%.8X %s" % (
                             instr_attrib.instr.offset,
                             instr_attrib.instr.to_string(loc_db)
-                        )
+                        ))
 
                 # Exec IRBlock
                 instr = instr_attrib.instr
diff --git a/miasm2/jitter/jitload.py b/miasm2/jitter/jitload.py
index 59c7ac97..3f3cf10f 100644
--- a/miasm2/jitter/jitload.py
+++ b/miasm2/jitter/jitload.py
@@ -1,9 +1,10 @@
-
 import logging
 import warnings
 from functools import wraps
 from collections import Sequence, namedtuple
 
+from future.utils import viewitems
+
 from miasm2.jitter.csts import *
 from miasm2.core.utils import *
 from miasm2.core.bin_stream import bin_stream_vm
@@ -42,12 +43,15 @@ def named_arguments(func):
             ret_ad, arg_vals = func(self, len(args))
             arg_vals = namedtuple("args", args)(*arg_vals)
             # func_name(arguments) return address
-            log_func.info('%s(%s) ret addr: %s',
-                          get_caller_name(1),
-                          ', '.join("%s=0x%x" % (field, value)
-                                    for field, value in arg_vals._asdict(
-                                    ).iteritems()),
-                         hex(ret_ad))
+            log_func.info(
+                '%s(%s) ret addr: %s',
+                get_caller_name(1),
+                ', '.join(
+                    "%s=0x%x" % (field, value)
+                    for field, value in viewitems(arg_vals._asdict())
+                ),
+                hex(ret_ad)
+            )
             return ret_ad, namedtuple("args", args)(*arg_vals)
         else:
             ret_ad, arg_vals = func(self, args)
@@ -86,7 +90,7 @@ class CallbackHandler(object):
         Return the list of empty keys (removed)"""
 
         to_check = set()
-        for key, cb_list in self.callbacks.items():
+        for key, cb_list in viewitems(self.callbacks):
             try:
                 cb_list.remove(callback)
                 to_check.add(key)
@@ -145,7 +149,7 @@ class CallbackHandlerBitflag(CallbackHandler):
                         yield res
 
 
-class ExceptionHandle():
+class ExceptionHandle(object):
 
     "Return type for exception handler"
 
@@ -326,7 +330,7 @@ class Jitter(object):
 
         return self.jit.run_at(
             self.cpu, pc,
-            set(self.breakpoints_handler.callbacks.keys())
+            set(self.breakpoints_handler.callbacks)
         )
 
     def runiter_once(self, pc):
@@ -398,7 +402,7 @@ class Jitter(object):
 
         while self.run:
             try:
-                return self.run_iterator.next()
+                return next(self.run_iterator)
             except StopIteration:
                 pass
 
@@ -411,7 +415,9 @@ class Jitter(object):
 
     def init_stack(self):
         self.vm.add_memory_page(
-            self.stack_base, PAGE_READ | PAGE_WRITE, "\x00" * self.stack_size,
+            self.stack_base,
+            PAGE_READ | PAGE_WRITE,
+            b"\x00" * self.stack_size,
             "Stack")
         sp = self.arch.getsp(self.attrib)
         setattr(self.cpu, sp.name, self.stack_base + self.stack_size)
@@ -430,7 +436,7 @@ class Jitter(object):
         l = 0
         tmp = addr
         while ((max_char is None or l < max_char) and
-               self.vm.get_mem(tmp, 1) != "\x00"):
+               self.vm.get_mem(tmp, 1) != b"\x00"):
             tmp += 1
             l += 1
         return self.vm.get_mem(addr, l)
@@ -442,21 +448,21 @@ class Jitter(object):
         l = 0
         tmp = addr
         while ((max_char is None or l < max_char) and
-               self.vm.get_mem(tmp, 2) != "\x00\x00"):
+               self.vm.get_mem(tmp, 2) != b"\x00\x00"):
             tmp += 2
             l += 2
         s = self.vm.get_mem(addr, l)
-        s = s[::2]  # TODO: real unicode decoding
+        s = s.decode("utf-16le")
         return s
 
     def set_str_ansi(self, addr, s):
         """Set an ansi string in memory"""
-        s = s + "\x00"
+        s = s + b"\x00"
         self.vm.set_mem(addr, s)
 
     def set_str_unic(self, addr, s):
         """Set an unicode string in memory"""
-        s = "\x00".join(list(s)) + '\x00' * 3
+        s = b"\x00".join(list(s)) + b'\x00' * 3
         self.vm.set_mem(addr, s)
 
     @staticmethod
@@ -492,7 +498,11 @@ class Jitter(object):
             user_globals = {}
 
         self.libs = libs
-        self.user_globals = user_globals
+        out = {}
+        for name, func in viewitems(user_globals):
+            name = force_bytes(name)
+            out[name] = func
+        self.user_globals = out
 
         for f_addr in libs.fad2cname:
             self.handle_function(f_addr)
diff --git a/miasm2/jitter/llvmconvert.py b/miasm2/jitter/llvmconvert.py
index fd32001c..bea8cd36 100644
--- a/miasm2/jitter/llvmconvert.py
+++ b/miasm2/jitter/llvmconvert.py
@@ -11,9 +11,15 @@
 #
 #
 
+from builtins import zip
+from builtins import range
 import os
 from llvmlite import binding as llvm
 from llvmlite import ir as llvm_ir
+from builtins import int as int_types
+
+from future.utils import viewitems, viewvalues
+
 from miasm2.expression.expression import ExprId, ExprInt, ExprMem, ExprSlice, \
     ExprCond, ExprLoc, ExprOp, ExprCompose, LocKey, Expr, \
     TOK_EQUAL, \
@@ -67,7 +73,7 @@ class LLVMType(llvm_ir.Type):
         return precision
 
 
-class LLVMContext():
+class LLVMContext(object):
 
     "Context for llvm binding. Stand for a LLVM Module"
 
@@ -139,7 +145,7 @@ class LLVMContext():
     def add_fc(self, fc, readonly=False):
         "Add function into known_fc"
 
-        for name, detail in fc.iteritems():
+        for name, detail in viewitems(fc):
             fnty = llvm_ir.FunctionType(detail["ret"], detail["args"])
             fn = llvm_ir.Function(self.mod, fnty, name=name)
             if readonly:
@@ -444,8 +450,10 @@ class LLVMContext_JIT(LLVMContext):
             self.add_shared_library(lib_fname)
 
         # Activate cache
-        self.exec_engine.set_object_cache(self.cache_notify,
-                                          self.cache_getbuffer)
+        self.exec_engine.set_object_cache(
+            self.cache_notify,
+            self.cache_getbuffer
+        )
 
     def set_cache_filename(self, func, fname_out):
         "Set the filename @fname_out to use for cache for @func"
@@ -473,16 +481,20 @@ class LLVMContext_IRCompilation(LLVMContext):
         """Perform a memory lookup at @addr of size @size (in bit)"""
         builder = func.builder
         int_size = LLVMType.IntType(size)
-        ptr_casted = builder.inttoptr(addr,
-                                      llvm_ir.PointerType(int_size))
+        ptr_casted = builder.inttoptr(
+            addr,
+            llvm_ir.PointerType(int_size)
+        )
         return builder.load(ptr_casted)
 
     def memory_write(self, func, addr, size, value):
         """Perform a memory write at @addr of size @size (in bit) with LLVM IR @value"""
         builder = func.builder
         int_size = LLVMType.IntType(size)
-        ptr_casted = builder.inttoptr(addr,
-                                      llvm_ir.PointerType(int_size))
+        ptr_casted = builder.inttoptr(
+            addr,
+            llvm_ir.PointerType(int_size)
+        )
         return builder.store(value, ptr_casted)
 
 
@@ -504,8 +516,9 @@ class LLVMFunction(object):
     ## Add the size as first argument
     op_translate_with_size = {}
     ## Add the size as suffix
-    op_translate_with_suffix_size = {'bcdadd': 'bcdadd',
-                                     'bcdadd_cf': 'bcdadd_cf',
+    op_translate_with_suffix_size = {
+        'bcdadd': 'bcdadd',
+        'bcdadd_cf': 'bcdadd_cf',
     }
 
     def __init__(self, llvm_context, name="fc", new_module=True):
@@ -582,12 +595,20 @@ class LLVMFunction(object):
         offset = self.llvm_context.vmcpu[name]
 
         # Pointer cast
-        ptr = builder.gep(self.local_vars["vmcpu"],
-                          [llvm_ir.Constant(LLVMType.IntType(),
-                                            offset)])
+        ptr = builder.gep(
+            self.local_vars["vmcpu"],
+            [
+                llvm_ir.Constant(
+                    LLVMType.IntType(),
+                    offset
+                )
+            ]
+        )
         pointee_type = LLVMType.IntType(expr.size)
-        ptr_casted = builder.bitcast(ptr,
-                                     llvm_ir.PointerType(pointee_type))
+        ptr_casted = builder.bitcast(
+            ptr,
+            llvm_ir.PointerType(pointee_type)
+        )
         # Store in cache
         self.local_vars_pointers[name] = ptr_casted
 
@@ -612,7 +633,10 @@ class LLVMFunction(object):
 
     def get_basic_block_by_loc_key(self, loc_key):
         "Return the bbl corresponding to label, None otherwise"
-        return self.name2bbl.get(self.llvm_context.canonize_label_name(loc_key), None)
+        return self.name2bbl.get(
+            self.llvm_context.canonize_label_name(loc_key),
+            None
+        )
 
     def global_constant(self, name, value):
         """
@@ -658,10 +682,15 @@ class LLVMFunction(object):
         count = 0
         while "%s_%d" % (base_name, count) in self.mod.globals:
             count += 1
-        global_fmt = self.global_constant("%s_%d" % (base_name, count),
-                                          fmt_bytes)
-        fnty = llvm_ir.FunctionType(llvm_ir.IntType(32), [cstring],
-                                    var_arg=True)
+        global_fmt = self.global_constant(
+            "%s_%d" % (base_name, count),
+            fmt_bytes
+        )
+        fnty = llvm_ir.FunctionType(
+            llvm_ir.IntType(32),
+            [cstring],
+            var_arg=True
+        )
         # Insert printf()
         fn = mod.globals.get('printf', None)
         if fn is None:
@@ -692,7 +721,10 @@ class LLVMFunction(object):
         "Init the function"
 
         # Build type for fc signature
-        fc_type = llvm_ir.FunctionType(self.ret_type, [k[1] for k in self.my_args])
+        fc_type = llvm_ir.FunctionType(
+            self.ret_type,
+            [k[1] for k in self.my_args]
+        )
 
         # Add fc in module
         try:
@@ -741,7 +773,9 @@ class LLVMFunction(object):
             return ret
 
         if expr.is_loc():
-            offset = self.llvm_context.ir_arch.loc_db.get_location_offset(expr.loc_key)
+            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
@@ -785,7 +819,12 @@ class LLVMFunction(object):
                 casted_args = []
                 for i, arg in enumerate(args):
                     if arg.type.width < fc_ptr.args[i].type.width:
-                        casted_args.append(builder.zext(arg, fc_ptr.args[i].type))
+                        casted_args.append(
+                            builder.zext(
+                                arg,
+                                fc_ptr.args[i].type
+                            )
+                        )
                     else:
                         casted_args.append(arg)
                 ret = builder.call(fc_ptr, casted_args)
@@ -810,8 +849,10 @@ class LLVMFunction(object):
                 assert len(expr.args) == 1
                 arg = self.add_ir(expr.args[0])
                 truncated = builder.trunc(arg, LLVMType.IntType(8))
-                bitcount = builder.call(self.mod.get_global("llvm.ctpop.i8"),
-                                        [truncated])
+                bitcount = builder.call(
+                    self.mod.get_global("llvm.ctpop.i8"),
+                    [truncated]
+                )
                 ret = builder.not_(builder.trunc(bitcount, LLVMType.IntType(1)))
                 self.update_cache(expr, ret)
                 return ret
@@ -824,16 +865,20 @@ class LLVMFunction(object):
                     "cnttrailzeros": "cttz",
                 }[op]
                 func_llvm_name = "llvm.%s.i%d" % (func_name, expr.size)
-                func_sig = {func_llvm_name: {
-                    "ret": LLVMType.IntType(expr.size),
-                    "args": [LLVMType.IntType(expr.args[0].size)]
-                }}
+                func_sig = {
+                    func_llvm_name: {
+                        "ret": LLVMType.IntType(expr.size),
+                        "args": [LLVMType.IntType(expr.args[0].size)]
+                    }
+                }
                 try:
                     self.mod.get_global(func_llvm_name)
                 except KeyError:
                     self.llvm_context.add_fc(func_sig, readonly=True)
-                ret = builder.call(self.mod.get_global(func_llvm_name),
-                                   [arg])
+                ret = builder.call(
+                    self.mod.get_global(func_llvm_name),
+                    [arg]
+                )
                 self.update_cache(expr, ret)
                 return ret
 
@@ -867,12 +912,19 @@ class LLVMFunction(object):
                 casted_args = []
                 for i, arg in enumerate(args, 1):
                     if arg.type.width < fc_ptr.args[i].type.width:
-                        casted_args.append(builder.zext(arg, fc_ptr.args[i].type))
+                        casted_args.append(
+                            builder.zext(
+                                arg,
+                                fc_ptr.args[i].type
+                            )
+                        )
                     else:
                         casted_args.append(arg)
 
-                ret = builder.call(fc_ptr,
-                                   [self.local_vars["jitcpu"]] + casted_args)
+                ret = builder.call(
+                    fc_ptr,
+                    [self.local_vars["jitcpu"]] + casted_args
+                )
                 if ret.type.width > expr.size:
                     ret = builder.trunc(ret, LLVMType.IntType(expr.size))
                 self.update_cache(expr, ret)
@@ -905,11 +957,14 @@ class LLVMFunction(object):
             if op in unsigned_cmps:
                 op = unsigned_cmps[op]
                 args = [self.add_ir(arg) for arg in expr.args]
-                ret = builder.select(builder.icmp_unsigned(op,
-                                                           args[0],
-                                                           args[1]),
-                                     llvm_ir.IntType(expr.size)(1),
-                                     llvm_ir.IntType(expr.size)(0))
+                ret = builder.select(
+                    builder.icmp_unsigned(op,
+                                          args[0],
+                                          args[1]
+                    ),
+                    llvm_ir.IntType(expr.size)(1),
+                    llvm_ir.IntType(expr.size)(0)
+                )
                 self.update_cache(expr, ret)
                 return ret
 
@@ -919,8 +974,11 @@ class LLVMFunction(object):
                 count = self.add_ir(expr.args[1])
                 value = self.add_ir(expr.args[0])
                 itype = LLVMType.IntType(expr.size)
-                cond_ok = self.builder.icmp_unsigned("<", count,
-                                                     itype(expr.size))
+                cond_ok = self.builder.icmp_unsigned(
+                    "<",
+                    count,
+                    itype(expr.size)
+                )
                 zero = itype(0)
                 if op == ">>":
                     callback = builder.lshr
@@ -932,8 +990,11 @@ class LLVMFunction(object):
                     cond_neg = self.builder.icmp_signed("<", value, zero)
                     zero = self.builder.select(cond_neg, itype(-1), zero)
 
-                ret = self.builder.select(cond_ok, callback(value, count),
-                                          zero)
+                ret = self.builder.select(
+                    cond_ok,
+                    callback(value, count),
+                    zero
+                )
                 self.update_cache(expr, ret)
                 return ret
 
@@ -948,8 +1009,10 @@ class LLVMFunction(object):
 
                 # As shift of expr_size is undefined, we urem the shifters
                 shift = builder.urem(count, expr_size)
-                shift_inv = builder.urem(builder.sub(expr_size, shift),
-                                         expr_size)
+                shift_inv = builder.urem(
+                    builder.sub(expr_size, shift),
+                    expr_size
+                )
 
                 if op == '<<<':
                     part_a = builder.shl(value, shift)
@@ -1045,12 +1108,16 @@ class LLVMFunction(object):
                 # Apply the correct func
                 if expr.size == 32:
                     arg = builder.bitcast(arg, llvm_ir.FloatType())
-                    ret = builder.call(self.mod.get_global("llvm.%s.f32" % op),
-                                       [arg])
+                    ret = builder.call(
+                        self.mod.get_global("llvm.%s.f32" % op),
+                        [arg]
+                    )
                 elif expr.size == 64:
                     arg = builder.bitcast(arg, llvm_ir.DoubleType())
-                    ret = builder.call(self.mod.get_global("llvm.%s.f64" % op),
-                                       [arg])
+                    ret = builder.call(
+                        self.mod.get_global("llvm.%s.f64" % op),
+                        [arg]
+                    )
                 else:
                     raise RuntimeError("Unsupported precision: %x", expr.size)
 
@@ -1164,22 +1231,27 @@ class LLVMFunction(object):
 
             # Remove trailing bits
             if expr.start != 0:
-                to_shr = llvm_ir.Constant(LLVMType.IntType(expr.arg.size),
-                                          expr.start)
-                shred = builder.lshr(src,
-                                     to_shr)
+                to_shr = llvm_ir.Constant(
+                    LLVMType.IntType(expr.arg.size),
+                    expr.start
+                )
+                shred = builder.lshr(src, to_shr)
             else:
                 shred = src
 
             # Remove leading bits
-            to_and = llvm_ir.Constant(LLVMType.IntType(expr.arg.size),
-                                      (1 << (expr.stop - expr.start)) - 1)
+            to_and = llvm_ir.Constant(
+                LLVMType.IntType(expr.arg.size),
+                (1 << (expr.stop - expr.start)) - 1
+            )
             anded = builder.and_(shred,
                                  to_and)
 
             # Cast into e.size
-            ret = builder.trunc(anded,
-                                LLVMType.IntType(expr.size))
+            ret = builder.trunc(
+                anded,
+                LLVMType.IntType(expr.size)
+            )
 
             self.update_cache(expr, ret)
             return ret
@@ -1192,17 +1264,23 @@ class LLVMFunction(object):
             for start, src in expr.iter_args():
                 # src & size
                 src = self.add_ir(src)
-                src_casted = builder.zext(src,
-                                          LLVMType.IntType(expr.size))
-                to_and = llvm_ir.Constant(LLVMType.IntType(expr.size),
-                                          (1 << src.type.width) - 1)
+                src_casted = builder.zext(
+                    src,
+                    LLVMType.IntType(expr.size)
+                )
+                to_and = llvm_ir.Constant(
+                    LLVMType.IntType(expr.size),
+                    (1 << src.type.width) - 1
+                )
                 anded = builder.and_(src_casted,
                                      to_and)
 
                 if (start != 0):
                     # result << start
-                    to_shl = llvm_ir.Constant(LLVMType.IntType(expr.size),
-                                              start)
+                    to_shl = llvm_ir.Constant(
+                        LLVMType.IntType(expr.size),
+                        start
+                    )
                     shled = builder.shl(anded, to_shl)
                     final = shled
                 else:
@@ -1213,7 +1291,7 @@ class LLVMFunction(object):
 
             # result = part1 | part2 | ...
             last = args[0]
-            for i in xrange(1, len(expr.args)):
+            for i in range(1, len(expr.args)):
                 last = builder.or_(last, args[i])
 
             self.update_cache(expr, last)
@@ -1246,9 +1324,11 @@ class LLVMFunction(object):
 
         # Compute cond
         zero_casted = llvm_ir.Constant(t_size, 0)
-        condition_bool = builder.icmp_unsigned("!=",
-                                               exceptionflag,
-                                               zero_casted)
+        condition_bool = builder.icmp_unsigned(
+            "!=",
+            exceptionflag,
+            zero_casted
+        )
 
         # Create bbls
         branch_id = self.new_branch_name()
@@ -1264,7 +1344,7 @@ class LLVMFunction(object):
         # Then Bloc
         builder.position_at_end(then_block)
         PC = self.llvm_context.PC
-        if isinstance(offset, (int, long)):
+        if isinstance(offset, int_types):
             offset = self.add_ir(ExprInt(offset, PC.size))
         self.assign(offset, PC)
         self.assign(self.add_ir(ExprInt(1, 8)), ExprId("status", 32))
@@ -1289,13 +1369,18 @@ class LLVMFunction(object):
         # Compute cond
         if restricted_exception is True:
             flag = m2_csts.EXCEPT_NUM_UPDT_EIP
-            condition_bool = builder.icmp_unsigned(">", exceptionflag,
-                                                   llvm_ir.Constant(t_size, flag))
+            condition_bool = builder.icmp_unsigned(
+                ">",
+                exceptionflag,
+                llvm_ir.Constant(t_size, flag)
+            )
         else:
             zero_casted = llvm_ir.Constant(t_size, 0)
-            condition_bool = builder.icmp_unsigned("!=",
-                                                   exceptionflag,
-                                                   zero_casted)
+            condition_bool = builder.icmp_unsigned(
+                "!=",
+                exceptionflag,
+                zero_casted
+            )
 
         # Create bbls
         branch_id = self.new_branch_name()
@@ -1311,7 +1396,7 @@ class LLVMFunction(object):
         # Then Bloc
         builder.position_at_end(then_block)
         PC = self.llvm_context.PC
-        if isinstance(offset, (int, long)):
+        if isinstance(offset, int_types):
             offset = self.add_ir(ExprInt(offset, PC.size))
         self.assign(offset, PC)
         self.assign(self.add_ir(ExprInt(1, 8)), ExprId("status", 32))
@@ -1324,8 +1409,12 @@ class LLVMFunction(object):
     def gen_pre_code(self, instr_attrib):
         if instr_attrib.log_mn:
             loc_db = self.llvm_context.ir_arch.loc_db
-            self.printf("%.8X %s\n" % (instr_attrib.instr.offset,
-                                       instr_attrib.instr.to_string(loc_db)))
+            self.printf(
+                "%.8X %s\n" % (
+                    instr_attrib.instr.offset,
+                    instr_attrib.instr.to_string(loc_db)
+                )
+            )
 
     def gen_post_code(self, attributes, pc_value):
         if attributes.log_regs:
@@ -1464,7 +1553,7 @@ class LLVMFunction(object):
 
             # Evaluate expressions
             values = {}
-            for dst, src in assignblk.iteritems():
+            for dst, src in viewitems(assignblk):
                 if dst == self.llvm_context.ir_arch.IRDst:
                     case2dst, case_value = self.expr2cases(src)
                 else:
@@ -1472,40 +1561,51 @@ class LLVMFunction(object):
 
             # Check memory access exception
             if attributes[index].mem_read:
-                self.check_memory_exception(instr.offset,
-                                            restricted_exception=True)
+                self.check_memory_exception(
+                    instr.offset,
+                    restricted_exception=True
+                )
 
             # Update the memory
-            for dst, src in values.iteritems():
+            for dst, src in viewitems(values):
                 if isinstance(dst, ExprMem):
                     self.assign(src, dst)
 
             # Check memory write exception
             if attributes[index].mem_write:
-                self.check_memory_exception(instr.offset,
-                                            restricted_exception=True)
+                self.check_memory_exception(
+                    instr.offset,
+                    restricted_exception=True
+                )
 
             # Update registers values
-            for dst, src in values.iteritems():
+            for dst, src in viewitems(values):
                 if not isinstance(dst, ExprMem):
                     self.assign(src, dst)
 
             # Check post assignblk exception flags
             if attributes[index].set_exception:
-                self.check_cpu_exception(instr.offset, restricted_exception=True)
+                self.check_cpu_exception(
+                    instr.offset,
+                    restricted_exception=True
+                )
 
         # Destination
         assert case2dst is not None
         if len(case2dst) == 1:
             # Avoid switch in this common case
-            self.gen_jump2dst(instr_attrib, instr_offsets, case2dst.values()[0])
+            self.gen_jump2dst(
+                instr_attrib,
+                instr_offsets,
+                next(iter(viewvalues(case2dst)))
+            )
         else:
             current_bbl = self.builder.basic_block
 
             # Gen the out cases
             branch_id = self.new_branch_name()
             case2bbl = {}
-            for case, dst in case2dst.iteritems():
+            for case, dst in list(viewitems(case2dst)):
                 name = "switch_%s_%d" % (branch_id, case)
                 bbl = self.append_basic_block(name)
                 case2bbl[case] = bbl
@@ -1515,7 +1615,7 @@ class LLVMFunction(object):
             # Jump on the correct output
             self.builder.position_at_end(current_bbl)
             switch = self.builder.switch(case_value, case2bbl[0])
-            for i, bbl in case2bbl.iteritems():
+            for i, bbl in viewitems(case2bbl):
                 if i == 0:
                     # Default case is case 0, arbitrary
                     continue
@@ -1528,17 +1628,23 @@ class LLVMFunction(object):
         builder = self.builder
         m2_exception_flag = self.llvm_context.ir_arch.arch.regs.exception_flags
         t_size = LLVMType.IntType(m2_exception_flag.size)
-        self.assign(self.add_ir(ExprInt(1, 8)),
-                    ExprId("status", 32))
-        self.assign(t_size(m2_csts.EXCEPT_UNK_MNEMO),
-                    m2_exception_flag)
-        offset = self.llvm_context.ir_arch.loc_db.get_location_offset(asmblock.loc_key)
+        self.assign(
+            self.add_ir(ExprInt(1, 8)),
+            ExprId("status", 32)
+        )
+        self.assign(
+            t_size(m2_csts.EXCEPT_UNK_MNEMO),
+            m2_exception_flag
+        )
+        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):
         """
-        In case of delayslot, generate a dummy BBL which return on the computed IRDst
-        or on next_label
+        In case of delayslot, generate a dummy BBL which return on the computed
+        IRDst or on next_label
         """
         if self.llvm_context.has_delayslot:
             next_label = codegen.get_block_post_label(asmblock)
@@ -1552,9 +1658,11 @@ class LLVMFunction(object):
 
             # Check if IRDst has been set
             zero_casted = LLVMType.IntType(codegen.delay_slot_set.size)(0)
-            condition_bool = builder.icmp_unsigned("!=",
-                                                   self.add_ir(codegen.delay_slot_set),
-                                                   zero_casted)
+            condition_bool = builder.icmp_unsigned(
+                "!=",
+                self.add_ir(codegen.delay_slot_set),
+                zero_casted
+            )
 
             # Create bbls
             branch_id = self.new_branch_name()
@@ -1627,8 +1735,10 @@ class LLVMFunction(object):
         if self.llvm_context.has_delayslot:
             for element in (codegen.delay_slot_dst, codegen.delay_slot_set):
                 eltype = LLVMType.IntType(element.size)
-                ptr = self.CreateEntryBlockAlloca(eltype,
-                                                  default_value=eltype(0))
+                ptr = self.CreateEntryBlockAlloca(
+                    eltype,
+                    default_value=eltype(0)
+                )
                 self.local_vars_pointers[element.name] = ptr
             loc_key = codegen.get_block_post_label(asmblock)
             offset = self.llvm_context.ir_arch.loc_db.get_location_offset(loc_key)
@@ -1640,9 +1750,12 @@ class LLVMFunction(object):
 
 
         for instr, irblocks in zip(asmblock.lines, irblocks_list):
-            instr_attrib, irblocks_attributes = codegen.get_attributes(instr, irblocks,
-                                                                       self.log_mn,
-                                                                       self.log_regs)
+            instr_attrib, irblocks_attributes = codegen.get_attributes(
+                instr,
+                irblocks,
+                self.log_mn,
+                self.log_regs
+            )
 
             # Pre-create basic blocks
             for irblock in irblocks:
@@ -1783,7 +1896,7 @@ class LLVMFunction_IRCompilation(LLVMFunction):
 
     def gen_irblock(self, irblock):
         instr_attrib = Attributes()
-        attributes = [Attributes() for _ in xrange(len(irblock.assignblks))]
+        attributes = [Attributes() for _ in range(len(irblock.assignblks))]
         instr_offsets = None
         return super(LLVMFunction_IRCompilation, self).gen_irblock(
             instr_attrib, attributes, instr_offsets, irblock
@@ -1791,11 +1904,11 @@ class LLVMFunction_IRCompilation(LLVMFunction):
 
     def from_ircfg(self, ircfg, append_ret=True):
         # Create basic blocks
-        for loc_key, irblock in ircfg.blocks.iteritems():
+        for loc_key, irblock in viewitems(ircfg.blocks):
             self.append_basic_block(loc_key)
 
         # Add IRBlocks
-        for label, irblock in ircfg.blocks.iteritems():
+        for label, irblock in viewitems(ircfg.blocks):
             self.builder.position_at_end(self.get_basic_block_by_loc_key(label))
             self.gen_irblock(irblock)
 
diff --git a/miasm2/jitter/loader/elf.py b/miasm2/jitter/loader/elf.py
index 17041372..1044fe73 100644
--- a/miasm2/jitter/loader/elf.py
+++ b/miasm2/jitter/loader/elf.py
@@ -1,6 +1,8 @@
 import struct
 from collections import defaultdict
 
+from future.utils import viewitems
+
 from elfesteem import cstruct
 from elfesteem import *
 import elfesteem.elf as elf_csts
@@ -23,7 +25,7 @@ def get_import_address_elf(e):
     for sh in e.sh:
         if not hasattr(sh, 'rel'):
             continue
-        for k, v in sh.rel.items():
+        for k, v in viewitems(sh.rel):
             import2addr[('xxx', k)].add(v.offset)
     return import2addr
 
@@ -32,7 +34,7 @@ def preload_elf(vm, e, runtime_lib, patch_vm_imp=True, loc_db=None):
     # XXX quick hack
     fa = get_import_address_elf(e)
     dyn_funcs = {}
-    for (libname, libfunc), ads in fa.items():
+    for (libname, libfunc), ads in viewitems(fa):
         # Quick hack - if a symbol is already known, do not stub it
         if loc_db and loc_db.get_name_location(libfunc) is not None:
             continue
@@ -66,7 +68,7 @@ def fill_loc_db_with_symbols(elf, loc_db, base_addr=0):
     symbol_sections = []
     for section_header in elf.sh:
         if hasattr(section_header, 'symbols'):
-            for name, sym in section_header.symbols.iteritems():
+            for name, sym in viewitems(section_header.symbols):
                 if not name or sym.value == 0:
                     continue
                 name = loc_db.find_free_name(name)
@@ -275,10 +277,14 @@ def vm_load_elf(vm, fdata, name="", base_addr=0, loc_db=None, apply_reloc=False,
         # -2: Trick to avoid merging 2 consecutive pages
         i += [(a_addr, b_addr - 2)]
     for a, b in i.intervals:
-        vm.add_memory_page(a, PAGE_READ | PAGE_WRITE, "\x00" * (b + 2 - a),
-                           repr(name))
-
-    for r_vaddr, data in all_data.items():
+        vm.add_memory_page(
+            a,
+            PAGE_READ | PAGE_WRITE,
+            b"\x00" * (b + 2 - a),
+            repr(name)
+        )
+
+    for r_vaddr, data in viewitems(all_data):
         vm.set_mem(r_vaddr, data)
 
     if loc_db is not None:
diff --git a/miasm2/jitter/loader/pe.py b/miasm2/jitter/loader/pe.py
index 176e0065..a8e6ec0d 100644
--- a/miasm2/jitter/loader/pe.py
+++ b/miasm2/jitter/loader/pe.py
@@ -1,8 +1,11 @@
+from builtins import map
 import os
 import struct
 import logging
 from collections import defaultdict
 
+from future.utils import viewitems, viewvalues
+
 from elfesteem import pe
 from elfesteem import cstruct
 from elfesteem import *
@@ -45,7 +48,8 @@ def get_import_address_pe(e):
                 funcname = imp
             # l = "    %2d %-16s" % (ii, repr(funcname))
             import2addr[(libname, funcname)].add(
-                e.rva2virt(s.firstthunk + e._wsize * ii / 8))
+                e.rva2virt(s.firstthunk + (e._wsize * ii) // 8)
+            )
     return import2addr
 
 
@@ -53,7 +57,7 @@ def preload_pe(vm, e, runtime_lib, patch_vm_imp=True):
     fa = get_import_address_pe(e)
     dyn_funcs = {}
     # log.debug('imported funcs: %s' % fa)
-    for (libname, libfunc), ads in fa.items():
+    for (libname, libfunc), ads in viewitems(fa):
         for ad in ads:
             ad_base_lib = runtime_lib.lib_get_add_base(libname)
             ad_libfunc = runtime_lib.lib_get_add_func(ad_base_lib, libfunc, ad)
@@ -81,7 +85,7 @@ def is_redirected_export(pe_obj, addr):
     addr_rva = pe_obj.virt2rva(addr)
     if not (export_dir.rva <= addr_rva < export_dir.rva + export_dir.size):
         return False
-    addr_end = pe_obj.virt.find('\x00', addr)
+    addr_end = pe_obj.virt.find(b'\x00', addr)
     data = pe_obj.virt.get(addr, addr_end)
 
     dllname, func_info = data.split('.', 1)
@@ -150,10 +154,16 @@ def vm_load_pe(vm, fdata, align_s=True, load_hdr=True, name="", **kargs):
             min_len = min(pe.SHList[0].addr, 0x1000)
 
             # Get and pad the pe_hdr
-            pe_hdr = pe.content[:hdr_len] + max(
-                0, (min_len - hdr_len)) * "\x00"
-            vm.add_memory_page(pe.NThdr.ImageBase, PAGE_READ | PAGE_WRITE,
-                               pe_hdr, "%r: PE Header" % name)
+            pe_hdr = (
+                pe.content[:hdr_len] +
+                max(0, (min_len - hdr_len)) * b"\x00"
+            )
+            vm.add_memory_page(
+                pe.NThdr.ImageBase,
+                PAGE_READ | PAGE_WRITE,
+                pe_hdr,
+                "%r: PE Header" % name
+            )
 
         # Align sections size
         if align_s:
@@ -173,13 +183,17 @@ def vm_load_pe(vm, fdata, align_s=True, load_hdr=True, name="", **kargs):
 
         # Pad sections with null bytes and map them
         for section in pe.SHList:
-            data = str(section.data)
-            data += "\x00" * (section.size - len(data))
+            data = bytes(section.data)
+            data += b"\x00" * (section.size - len(data))
             attrib = PAGE_READ
             if section.flags & 0x80000000:
                 attrib |= PAGE_WRITE
-            vm.add_memory_page(pe.rva2virt(section.addr), attrib, data,
-                               "%r: %r" % (name, section.name))
+            vm.add_memory_page(
+                pe.rva2virt(section.addr),
+                attrib,
+                data,
+                "%r: %r" % (name, section.name)
+            )
 
         return pe
 
@@ -209,15 +223,17 @@ def vm_load_pe(vm, fdata, align_s=True, load_hdr=True, name="", **kargs):
               (max_addr - min_addr))
 
     # Create only one big section containing the whole PE
-    vm.add_memory_page(min_addr,
-                       PAGE_READ | PAGE_WRITE,
-                       (max_addr - min_addr) * "\x00")
+    vm.add_memory_page(
+        min_addr,
+        PAGE_READ | PAGE_WRITE,
+        (max_addr - min_addr) * b"\x00"
+    )
 
     # Copy each sections content in memory
     for section in pe.SHList:
         log.debug('Map 0x%x bytes to 0x%x', len(section.data),
                   pe.rva2virt(section.addr))
-        vm.set_mem(pe.rva2virt(section.addr), str(section.data))
+        vm.set_mem(pe.rva2virt(section.addr), bytes(section.data))
 
     return pe
 
@@ -256,7 +272,7 @@ def vm_load_pe_libs(vm, libs_name, libs, lib_path_base, **kargs):
 
 def vm_fix_imports_pe_libs(lib_imgs, libs, lib_path_base,
                            patch_vm_imp=True, **kargs):
-    for e in lib_imgs.values():
+    for e in viewvalues(lib_imgs):
         preload_pe(e, libs, patch_vm_imp)
 
 
@@ -281,7 +297,7 @@ def vm2pe(myjit, fname, libs=None, e_orig=None,
 
     mye.NThdr.ImageBase = img_base
     all_mem = myjit.vm.get_all_memory()
-    addrs = all_mem.keys()
+    addrs = list(all_mem)
     addrs.sort()
     mye.Opthdr.AddressOfEntryPoint = mye.virt2rva(myjit.pc)
     first = True
@@ -303,8 +319,6 @@ def vm2pe(myjit, fname, libs=None, e_orig=None,
         first = False
     if libs:
         if added_funcs is not None:
-            # name_inv = dict([(x[1], x[0]) for x in libs.name2off.items()])
-
             for addr, funcaddr in added_funcs:
                 libbase, dllname = libs.fad2info[funcaddr]
                 libs.lib_get_add_func(libbase, dllname, addr)
@@ -323,7 +337,7 @@ def vm2pe(myjit, fname, libs=None, e_orig=None,
     log.debug('%r', mye.SHList)
     if e_orig:
         # resource
-        xx = str(mye)
+        xx = bytes(mye)
         mye.content = xx
         ad = e_orig.NThdr.optentries[pe.DIRECTORY_ENTRY_RESOURCE].rva
         size = e_orig.NThdr.optentries[pe.DIRECTORY_ENTRY_RESOURCE].size
@@ -333,10 +347,13 @@ def vm2pe(myjit, fname, libs=None, e_orig=None,
             mye.NThdr.optentries[pe.DIRECTORY_ENTRY_RESOURCE].size = size
             mye.DirRes = pe.DirRes.unpack(mye.img_rva, ad, mye)
             log.debug('%r', mye.DirRes)
-            s_res = mye.SHList.add_section(name="myres", rawsize=len(mye.DirRes))
+            s_res = mye.SHList.add_section(
+                name="myres",
+                rawsize=len(mye.DirRes)
+            )
             mye.DirRes.set_rva(s_res.addr)
     # generation
-    open(fname, 'wb').write(str(mye))
+    open(fname, 'wb').write(bytes(mye))
     return mye
 
 
@@ -408,7 +425,9 @@ class libimp_pe(libimp):
                     ad = self.lib_imp2ad[libad_tmp][exp_fname]
 
                 self.lib_imp2ad[libad][imp_ord_or_name] = ad
-                name_inv = dict([(x[1], x[0]) for x in self.name2off.items()])
+                name_inv = dict(
+                    (value, key) for key, value in viewitems(self.name2off)
+                )
                 c_name = canon_libname_libfunc(
                     name_inv[libad], imp_ord_or_name)
                 self.fad2cname[ad] = c_name
@@ -423,34 +442,36 @@ class libimp_pe(libimp):
         """
 
         new_lib = []
-        for lib_name, ad in self.name2off.items():
+        for lib_name, ad in viewitems(self.name2off):
             # Build an IMAGE_IMPORT_DESCRIPTOR
 
             # Get fixed addresses
             out_ads = dict()  # addr -> func_name
-            for func_name, dst_addresses in self.lib_imp2dstad[ad].items():
+            for func_name, dst_addresses in viewitems(self.lib_imp2dstad[ad]):
                 out_ads.update({addr: func_name for addr in dst_addresses})
 
             # Filter available addresses according to @filter_import
             all_ads = [
-                addr for addr in out_ads.keys() if filter_import(target_pe, addr)]
+                addr for addr in list(out_ads) if filter_import(target_pe, addr)
+            ]
+
             if not all_ads:
                 continue
 
             # Keep non-NULL elements
-            all_ads.sort()
+            all_ads.sort(key=str)
             for i, x in enumerate(all_ads):
                 if x not in [0,  None]:
                     break
             all_ads = all_ads[i:]
-            log.debug('ads: %s', map(hex, all_ads))
+            log.debug('ads: %s', list(map(hex, all_ads)))
 
             while all_ads:
                 # Find libname's Import Address Table
                 othunk = all_ads[0]
                 i = 0
                 while (i + 1 < len(all_ads) and
-                       all_ads[i] + target_pe._wsize / 8 == all_ads[i + 1]):
+                       all_ads[i] + target_pe._wsize // 8 == all_ads[i + 1]):
                     i += 1
                 # 'i + 1' is IAT's length
 
@@ -515,7 +536,7 @@ def vm_load_pe_and_dependencies(vm, fname, name2module, runtime_lib,
         todo += [(name, os.path.join(lib_path_base, name), weight - 1)
                  for name in new_dependencies]
 
-    ordered_modules = sorted(weight2name.items())
+    ordered_modules = sorted(viewitems(weight2name))
     for _, modules in ordered_modules:
         for name in modules:
             pe_obj = name2module[name]
@@ -525,7 +546,7 @@ def vm_load_pe_and_dependencies(vm, fname, name2module, runtime_lib,
             if pe_obj.DirExport:
                 runtime_lib.add_export_lib(pe_obj, name)
 
-    for pe_obj in name2module.itervalues():
+    for pe_obj in viewvalues(name2module):
         if pe_obj is None:
             continue
         preload_pe(vm, pe_obj, runtime_lib, patch_vm_imp=True)
diff --git a/miasm2/jitter/loader/utils.py b/miasm2/jitter/loader/utils.py
index a3a0ecd1..80e19310 100644
--- a/miasm2/jitter/loader/utils.py
+++ b/miasm2/jitter/loader/utils.py
@@ -1,5 +1,10 @@
+from builtins import int as int_types
 import logging
 
+from future.utils import viewitems, viewvalues
+
+from miasm2.core.utils import force_bytes
+
 log = logging.getLogger('loader_common')
 hnd = logging.StreamHandler()
 hnd.setFormatter(logging.Formatter("[%(levelname)s]: %(message)s"))
@@ -8,11 +13,13 @@ log.setLevel(logging.INFO)
 
 
 def canon_libname_libfunc(libname, libfunc):
-    dn = libname.split('.')[0]
-    if type(libfunc) == str:
-        return "%s_%s" % (dn, libfunc)
-    else:
+    libname = force_bytes(libname)
+    dn = libname.split(b'.')[0]
+    if isinstance(libfunc, int_types):
         return str(dn), libfunc
+    else:
+        libfunc = force_bytes(libfunc)
+        return b"%s_%s" % (dn, libfunc)
 
 
 class libimp(object):
@@ -30,10 +37,11 @@ class libimp(object):
         self.fake_libs = set()
 
     def lib_get_add_base(self, name):
-        name = name.lower().strip(' ')
-        if not "." in name:
+        name = force_bytes(name)
+        name = name.lower().strip(b' ')
+        if not b"." in name:
             log.debug('warning adding .dll to modulename')
-            name += '.dll'
+            name += b'.dll'
             log.debug(name)
 
         if name in self.name2off:
@@ -50,7 +58,7 @@ class libimp(object):
         return ad
 
     def lib_get_add_func(self, libad, imp_ord_or_name, dst_ad=None):
-        if not libad in self.name2off.values():
+        if not libad in viewvalues(self.name2off):
             raise ValueError('unknown lib base!', hex(libad))
 
         # test if not ordinatl
@@ -70,7 +78,9 @@ class libimp(object):
         self.libbase2lastad[libad] += 0x10  # arbitrary
         self.lib_imp2ad[libad][imp_ord_or_name] = ad
 
-        name_inv = dict([(x[1], x[0]) for x in self.name2off.items()])
+        name_inv = dict(
+            (value, key) for key, value in viewitems(self.name2off)
+        )
         c_name = canon_libname_libfunc(name_inv[libad], imp_ord_or_name)
         self.fad2cname[ad] = c_name
         self.cname2addr[c_name] = ad
@@ -79,8 +89,7 @@ class libimp(object):
 
     def check_dst_ad(self):
         for ad in self.lib_imp2dstad:
-            all_ads = self.lib_imp2dstad[ad].values()
-            all_ads.sort()
+            all_ads = sorted(viewvalues(self.lib_imp2dstad[ad]))
             for i, x in enumerate(all_ads[:-1]):
                 if x is None or all_ads[i + 1] is None:
                     return False
diff --git a/miasm2/jitter/vm_mngr_py.c b/miasm2/jitter/vm_mngr_py.c
index 93de9bb4..1173146b 100644
--- a/miasm2/jitter/vm_mngr_py.c
+++ b/miasm2/jitter/vm_mngr_py.c
@@ -20,6 +20,7 @@
 #include <stdint.h>
 #include <inttypes.h>
 #include <signal.h>
+#include "compat_py23.h"
 #include "queue.h"
 #include "vm_mngr.h"
 #include "vm_mngr_py.h"
@@ -54,18 +55,6 @@ PyObject* _vm_get_exception(unsigned int xcpt)
 	return p;
 }
 
-
-#define PyGetInt(item, value)						\
-	if (PyInt_Check(item)){						\
-		value = (uint64_t)PyInt_AsLong(item);			\
-	}								\
-	else if (PyLong_Check(item)){					\
-		value = (uint64_t)PyLong_AsUnsignedLongLong(item);	\
-	}								\
-	else{								\
-		RAISE(PyExc_TypeError,"arg must be int");		\
-	}								\
-
 static void sig_alarm(int signo)
 {
 	global_vmmngr->vm_mngr.exception_flags |= BREAK_SIGALARM;
@@ -104,18 +93,16 @@ PyObject* vm_add_memory_page(VmMngr* self, PyObject* args)
 	PyGetInt(addr, page_addr);
 	PyGetInt(access, page_access);
 
-	if(!PyString_Check(item_str))
-		RAISE(PyExc_TypeError,"arg must be str");
+	if(!PyBytes_Check(item_str))
+		RAISE(PyExc_TypeError,"arg must be bytes");
 
-	buf_size = PyString_Size(item_str);
-	PyString_AsStringAndSize(item_str, &buf_data, &length);
+	buf_size = PyBytes_Size(item_str);
+	PyBytes_AsStringAndSize(item_str, &buf_data, &length);
 
 	if (name == NULL) {
 		name_ptr = (char*)"";
 	} else {
-		if (!PyString_Check(name))
-			RAISE(PyExc_TypeError,"name must be str");
-		name_ptr = PyString_AsString(name);
+		PyGetStr(name_ptr, name);
 	}
 	mpn = create_memory_page_node(page_addr, (unsigned int)buf_size, (unsigned int)page_access, name_ptr);
 	if (mpn == NULL)
@@ -177,11 +164,11 @@ PyObject* vm_set_mem(VmMngr* self, PyObject* args)
 
        PyGetInt(py_addr, addr);
 
-       if (!PyString_Check(py_buffer))
-	       RAISE(PyExc_TypeError,"arg must be str");
+       if (!PyBytes_Check(py_buffer))
+	       RAISE(PyExc_TypeError,"arg must be bytes");
 
-       size = PyString_Size(py_buffer);
-       PyString_AsStringAndSize(py_buffer, &buffer, &py_length);
+       size = PyBytes_Size(py_buffer);
+       PyBytes_AsStringAndSize(py_buffer, &buffer, &py_length);
 
        ret = vm_write_mem(&self->vm_mngr, addr, buffer, size);
        if (ret < 0)
@@ -238,7 +225,7 @@ PyObject* vm_get_mem(VmMngr* self, PyObject* args)
 	       RAISE(PyExc_RuntimeError,"Cannot find address");
        }
 
-       obj_out = PyString_FromStringAndSize(buf_out, size);
+       obj_out = PyBytes_FromStringAndSize(buf_out, size);
        free(buf_out);
        return obj_out;
 }
@@ -648,7 +635,7 @@ PyObject *vm_dump(PyObject* self)
 	PyObject* ret_obj;
 
 	buf_final = dump(&((VmMngr* )self)->vm_mngr);
-	ret_obj = PyString_FromString(buf_final);
+	ret_obj = PyUnicode_FromString(buf_final);
 	free(buf_final);
 	return ret_obj;
 }
@@ -677,15 +664,15 @@ PyObject* vm_get_all_memory(VmMngr* self, PyObject* args)
 
 		dict2 =  PyDict_New();
 
-		o = PyString_FromStringAndSize(mpn->ad_hp, mpn->size);
+		o = PyBytes_FromStringAndSize(mpn->ad_hp, mpn->size);
 		PyDict_SetItemString(dict2, "data", o);
 		Py_DECREF(o);
 
-		o = PyInt_FromLong((long)mpn->size);
+		o = PyLong_FromLong((long)mpn->size);
 		PyDict_SetItemString(dict2, "size", o);
 		Py_DECREF(o);
 
-		o = PyInt_FromLong((long)mpn->access);
+		o = PyLong_FromLong((long)mpn->access);
 		PyDict_SetItemString(dict2, "access", o);
 		Py_DECREF(o);
 
@@ -818,7 +805,7 @@ VmMngr_dealloc(VmMngr* self)
     vm_reset_memory_page_pool(self, NULL);
     vm_reset_code_bloc_pool(self, NULL);
     vm_reset_memory_breakpoint(self, NULL);
-    self->ob_type->tp_free((PyObject*)self);
+    Py_TYPE(self)->tp_free((PyObject*)self);
 }
 
 
@@ -957,8 +944,7 @@ static PyGetSetDef VmMngr_getseters[] = {
 };
 
 static PyTypeObject VmMngrType = {
-    PyObject_HEAD_INIT(NULL)
-    0,                         /*ob_size*/
+    PyVarObject_HEAD_INIT(NULL, 0)
     "VmMngr",                  /*tp_name*/
     sizeof(VmMngr),            /*tp_basicsize*/
     0,                         /*tp_itemsize*/
@@ -998,30 +984,30 @@ static PyTypeObject VmMngrType = {
     VmMngr_new,                /* tp_new */
 };
 
-
 static PyMethodDef VmMngr_Methods[] = {
 	{NULL, NULL, 0, NULL}        /* Sentinel */
 
 };
 
-static PyObject *Vm_Mngr_Error;
+char vm_mngr_mod_docs[] = "vm_mngr module.";
+char vm_mngr_mod_name[] = "VmMngr";
 
-PyMODINIT_FUNC
-initVmMngr(void)
+
+MOD_INIT(VmMngr)
 {
-    PyObject *m;
+	PyObject *module;
 
-    if (PyType_Ready(&VmMngrType) < 0)
-	return;
+	MOD_DEF(module, "VmMngr", "vm_mngr module", VmMngr_Methods);
+
+	if (module == NULL)
+		return NULL;
 
-    m = Py_InitModule("VmMngr", VmMngr_Methods);
-    if (m == NULL)
-	    return;
+	if (PyType_Ready(&VmMngrType) < 0)
+		return NULL;
 
-    Vm_Mngr_Error = PyErr_NewException("VmMngr.error", NULL, NULL);
-    Py_INCREF(Vm_Mngr_Error);
-    PyModule_AddObject(m, "error", Vm_Mngr_Error);
+	Py_INCREF(&VmMngrType);
+	if (PyModule_AddObject(module, "Vm", (PyObject *)&VmMngrType) < 0)
+		return NULL;
 
-    Py_INCREF(&VmMngrType);
-    PyModule_AddObject(m, "Vm", (PyObject *)&VmMngrType);
+	return module;
 }
diff --git a/miasm2/os_dep/common.py b/miasm2/os_dep/common.py
index 7e46b276..ed68185f 100644
--- a/miasm2/os_dep/common.py
+++ b/miasm2/os_dep/common.py
@@ -1,5 +1,8 @@
 import os
 
+from future.utils import viewitems
+
+from miasm2.core.utils import force_bytes
 from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE
 from miasm2.core.utils import get_caller_name
 from miasm2.core.utils import pck64, upck64
@@ -11,7 +14,7 @@ def get_str_ansi(jitter, ad_str, max_char=None):
     l = 0
     tmp = ad_str
     while ((max_char is None or l < max_char) and
-           jitter.vm.get_mem(tmp, 1) != "\x00"):
+           jitter.vm.get_mem(tmp, 1) != b"\x00"):
         tmp += 1
         l += 1
     return jitter.vm.get_mem(ad_str, l)
@@ -21,22 +24,25 @@ def get_str_unic(jitter, ad_str, max_char=None):
     l = 0
     tmp = ad_str
     while ((max_char is None or l < max_char) and
-           jitter.vm.get_mem(tmp, 2) != "\x00\x00"):
+           jitter.vm.get_mem(tmp, 2) != b"\x00\x00"):
         tmp += 2
         l += 2
     s = jitter.vm.get_mem(ad_str, l)
-    # TODO: real unicode decoding
-    s = s[::2]
+    s = s.decode("utf-16le")
     return s
 
 
-def set_str_ansi(s):
-    return s + "\x00"
+def set_str_ansi(value):
+    value = force_bytes(value)
+    return value + b"\x00"
 
 
-def set_str_unic(s):
-    # TODO: real unicode encoding
-    return "\x00".join(list(s)) + '\x00' * 3
+def set_str_unic(value):
+    try:
+        value = value.decode()
+    except AttributeError:
+        pass
+    return value.encode("utf-16le") + b'\x00' * 2
 
 
 class heap(object):
@@ -74,30 +80,34 @@ class heap(object):
             combination of them); default is PAGE_READ|PAGE_WRITE
         """
         addr = self.next_addr(size)
-        vm.add_memory_page(addr, perm, "\x00" * (size),
-                           "Heap alloc by %s" % get_caller_name(2))
+        vm.add_memory_page(
+            addr,
+            perm,
+            b"\x00" * (size),
+            "Heap alloc by %s" % get_caller_name(2)
+        )
         return addr
 
     def get_size(self, vm, ptr):
         """
         @vm: a VmMngr instance
         @size: ptr to get the size of the associated allocation.
-        
+
         `ptr` can be the base address of a previous allocation, or an address
         within the allocated range. The size of the whole allocation is always
         returned, regardless ptr is the base address or not.
         """
-	assert vm.is_mapped(ptr, 1)
-	data = vm.get_all_memory()
-	ptr_page = data.get(ptr, None)
-	if ptr_page is None:
-	    for address, page_info in data.iteritems():
-		if address <= ptr < address + page_info["size"]:
-		    ptr_page = page_info
-		    break
-	    else:
-		raise RuntimeError("Must never happen (unmapped but mark as mapped by API)")
-	return ptr_page["size"]
+        assert vm.is_mapped(ptr, 1)
+        data = vm.get_all_memory()
+        ptr_page = data.get(ptr, None)
+        if ptr_page is None:
+            for address, page_info in viewitems(data):
+                if address <= ptr < address + page_info["size"]:
+                    ptr_page = page_info
+                    break
+            else:
+                raise RuntimeError("Must never happen (unmapped but mark as mapped by API)")
+        return ptr_page["size"]
 
 
 def windows_to_sbpath(path):
@@ -118,26 +128,36 @@ def unix_to_sbpath(path):
     return os.path.join(BASE_SB_PATH, *path)
 
 def get_fmt_args(fmt, cur_arg, get_str, get_arg_n):
-    output = ""
     idx = 0
     fmt = get_str(fmt)
+    if isinstance(fmt, bytes):
+        chars_format = b'%cdfsuxX'
+        char_percent = b'%'
+        char_string = b's'
+        output = b""
+    else:
+        chars_format = u'%cdfsuxX'
+        char_percent = u'%'
+        char_string = u's'
+        output = u""
+
     while True:
         if idx == len(fmt):
             break
-        char = fmt[idx]
+        char = fmt[idx:idx+1]
         idx += 1
-        if char == '%':
-            token = '%'
+        if char == char_percent:
+            token = char_percent
             while True:
-                char = fmt[idx]
+                char = fmt[idx:idx+1]
                 idx += 1
                 token += char
-                if char.lower() in '%cdfsux':
+                if char in chars_format:
                     break
-            if char == '%':
+            if char == char_percent:
                 output += char
                 continue
-            if token.endswith('s'):
+            if token.endswith(char_string):
                 addr = get_arg_n(cur_arg)
                 arg = get_str(addr)
             else:
diff --git a/miasm2/os_dep/linux/environment.py b/miasm2/os_dep/linux/environment.py
index 7cafae43..ae9c3317 100644
--- a/miasm2/os_dep/linux/environment.py
+++ b/miasm2/os_dep/linux/environment.py
@@ -1,9 +1,12 @@
+from __future__ import print_function
 from collections import namedtuple
 import functools
 import os
 import struct
 import termios
 
+from future.utils import viewitems
+
 from miasm2.core.interval import interval
 from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE
 
@@ -99,7 +102,7 @@ class FileDescriptorSTDOUT(FileDescriptorCharDevice):
     inode = 1
 
     def write(self, data):
-        print "[STDOUT] %s" % data.rstrip()
+        print("[STDOUT] %s" % data.rstrip())
 
 
 class FileDescriptorSTDERR(FileDescriptorCharDevice):
@@ -107,7 +110,7 @@ class FileDescriptorSTDERR(FileDescriptorCharDevice):
     inode = 2
 
     def write(self, data):
-        print "[STDERR] %s" % data.rstrip()
+        print("[STDERR] %s" % data.rstrip())
 
 
 class FileDescriptorDirectory(FileDescriptor):
@@ -301,7 +304,7 @@ class FileSystem(object):
         size = os.path.getsize(path)
         fdesc.size = size
         fdesc.blksize = self.blocksize
-        fdesc.blocks = (size + ((512 - (size % 512)) % 512)) / 512
+        fdesc.blocks = (size + ((512 - (size % 512)) % 512)) // 512
         return fd
 
 
@@ -330,17 +333,17 @@ class LinuxEnvironment(object):
     user_euid = 1000
     user_gid = 1000
     user_egid = 1000
-    user_name = "user"
+    user_name = b"user"
 
     # Memory mapping information
     brk_current = 0x74000000
     mmap_current = 0x75000000
 
     # System information
-    sys_sysname = "Linux"
-    sys_nodename = "user-pc"
-    sys_release = "4.13.0-19-generic"
-    sys_version = "#22-Ubuntu"
+    sys_sysname = b"Linux"
+    sys_nodename = b"user-pc"
+    sys_release = b"4.13.0-19-generic"
+    sys_version = b"#22-Ubuntu"
     sys_machine = None
 
     # Filesystem
@@ -525,17 +528,24 @@ class LinuxEnvironment(object):
             self.mmap_current += (len_ + 0x1000) & ~0xfff
 
         all_mem = vmmngr.get_all_memory()
-        mapped = interval([(start, start + info["size"] - 1)
-                           for start, info in all_mem.iteritems()])
+        mapped = interval(
+            [
+                (start, start + info["size"] - 1)
+                for start, info in viewitems(all_mem)
+            ]
+        )
 
         MAP_FIXED = 0x10
         if flags & MAP_FIXED:
             # Alloc missing and override
             missing = interval([(addr, addr + len_ - 1)]) - mapped
             for start, stop in missing:
-                vmmngr.add_memory_page(start, PAGE_READ|PAGE_WRITE,
-                                          "\x00" * (stop - start + 1),
-                                          "mmap allocated")
+                vmmngr.add_memory_page(
+                    start,
+                    PAGE_READ|PAGE_WRITE,
+                    b"\x00" * (stop - start + 1),
+                    "mmap allocated"
+                )
         else:
             # Find first candidate segment nearby addr
             for start, stop in mapped:
@@ -548,14 +558,18 @@ class LinuxEnvironment(object):
             else:
                 assert (interval([(addr, addr + len_)]) & mapped).empty
 
-            vmmngr.add_memory_page(addr, PAGE_READ|PAGE_WRITE, "\x00" * len_,
-                                      "mmap allocated")
+            vmmngr.add_memory_page(
+                addr,
+                PAGE_READ|PAGE_WRITE,
+                b"\x00" * len_,
+                "mmap allocated"
+            )
 
 
         if fd == 0xffffffff:
             if off != 0:
                 raise RuntimeError("Not implemented")
-            data = "\x00" * len_
+            data = b"\x00" * len_
         else:
             fdesc = self.file_descriptors[fd]
             cur_pos = fdesc.tell()
@@ -572,23 +586,30 @@ class LinuxEnvironment(object):
             addr = self.brk_current
         else:
             all_mem = vmmngr.get_all_memory()
-            mapped = interval([(start, start + info["size"] - 1)
-                               for start, info in all_mem.iteritems()])
+            mapped = interval(
+                [
+                    (start, start + info["size"] - 1)
+                    for start, info in viewitems(all_mem)
+                ]
+            )
 
             # Alloc missing and override
             missing = interval([(self.brk_current, addr)]) - mapped
             for start, stop in missing:
-                vmmngr.add_memory_page(start, PAGE_READ|PAGE_WRITE,
-                                       "\x00" * (stop - start + 1),
-                                       "BRK")
+                vmmngr.add_memory_page(
+                    start,
+                    PAGE_READ|PAGE_WRITE,
+                    b"\x00" * (stop - start + 1),
+                    "BRK"
+                )
 
             self.brk_current = addr
         return addr
 
 
 class LinuxEnvironment_x86_64(LinuxEnvironment):
-    platform_arch = "x86_64"
-    sys_machine = "x86_64"
+    platform_arch = b"x86_64"
+    sys_machine = b"x86_64"
 
     O_ACCMODE = 0x3
     O_CLOEXEC = 0x80000
@@ -599,8 +620,8 @@ class LinuxEnvironment_x86_64(LinuxEnvironment):
 
 
 class LinuxEnvironment_arml(LinuxEnvironment):
-    platform_arch = "arml"
-    sys_machine = "arml"
+    platform_arch = b"arml"
+    sys_machine = b"arml"
 
     O_ACCMODE = 0x3
     O_CLOEXEC = 0x80000
@@ -676,7 +697,7 @@ class AuxVec(object):
             self.AT_PLATFORM: linux_env.platform_arch,
             self.AT_HWCAP: 0,
             self.AT_SECURE: 0,
-            self.AT_RANDOM: "\x00" * 0x10,
+            self.AT_RANDOM: b"\x00" * 0x10,
             # vDSO is not mandatory
             self.AT_SYSINFO_EHDR: None,
         }
@@ -693,7 +714,7 @@ class AuxVec(object):
 
     def iteritems(self):
         """Iterator on auxiliary vector id and values"""
-        for AT_number, value in self.info.iteritems():
+        for AT_number, value in viewitems(self.info):
             if AT_number in self.ptrs:
                 value = self.ptrs[AT_number]
             if value is None:
@@ -701,6 +722,7 @@ class AuxVec(object):
                 continue
             yield (AT_number, value)
 
+    items = iteritems
 
 def prepare_loader_x86_64(jitter, argv, envp, auxv, linux_env,
                           hlt_address=0x13371acc):
@@ -735,15 +757,15 @@ def prepare_loader_x86_64(jitter, argv, envp, auxv, linux_env,
     # [argument vector]
 
     for AT_number, data in auxv.data_to_map():
-        data += "\x00"
+        data += b"\x00"
         jitter.cpu.RSP -= len(data)
         ptr = jitter.cpu.RSP
         jitter.vm.set_mem(ptr, data)
         auxv.ptrs[AT_number] = ptr
 
     env_ptrs = []
-    for name, value in envp.iteritems():
-        env = "%s=%s\x00" % (name, value)
+    for name, value in viewitems(envp):
+        env = b"%s=%s\x00" % (name, value)
         jitter.cpu.RSP -= len(env)
         ptr = jitter.cpu.RSP
         jitter.vm.set_mem(ptr, env)
@@ -751,7 +773,7 @@ def prepare_loader_x86_64(jitter, argv, envp, auxv, linux_env,
 
     argv_ptrs = []
     for arg in argv:
-        arg += "\x00"
+        arg += b"\x00"
         jitter.cpu.RSP -= len(arg)
         ptr = jitter.cpu.RSP
         jitter.vm.set_mem(ptr, arg)
@@ -760,7 +782,7 @@ def prepare_loader_x86_64(jitter, argv, envp, auxv, linux_env,
     jitter.push_uint64_t(hlt_address)
     jitter.push_uint64_t(0)
     jitter.push_uint64_t(0)
-    for auxid, auxval in auxv.iteritems():
+    for auxid, auxval in viewitems(auxv):
         jitter.push_uint64_t(auxval)
         jitter.push_uint64_t(auxid)
     jitter.push_uint64_t(0)
@@ -840,15 +862,15 @@ def prepare_loader_arml(jitter, argv, envp, auxv, linux_env,
     # [argument vector]
 
     for AT_number, data in auxv.data_to_map():
-        data += "\x00"
+        data += b"\x00"
         jitter.cpu.SP -= len(data)
         ptr = jitter.cpu.SP
         jitter.vm.set_mem(ptr, data)
         auxv.ptrs[AT_number] = ptr
 
     env_ptrs = []
-    for name, value in envp.iteritems():
-        env = "%s=%s\x00" % (name, value)
+    for name, value in viewitems(envp):
+        env = b"%s=%s\x00" % (name, value)
         jitter.cpu.SP -= len(env)
         ptr = jitter.cpu.SP
         jitter.vm.set_mem(ptr, env)
@@ -856,7 +878,7 @@ def prepare_loader_arml(jitter, argv, envp, auxv, linux_env,
 
     argv_ptrs = []
     for arg in argv:
-        arg += "\x00"
+        arg += b"\x00"
         jitter.cpu.SP -= len(arg)
         ptr = jitter.cpu.SP
         jitter.vm.set_mem(ptr, arg)
@@ -865,7 +887,7 @@ def prepare_loader_arml(jitter, argv, envp, auxv, linux_env,
     jitter.push_uint32_t(hlt_address)
     jitter.push_uint32_t(0)
     jitter.push_uint32_t(0)
-    for auxid, auxval in auxv.iteritems():
+    for auxid, auxval in viewitems(auxv):
         jitter.push_uint32_t(auxval)
         jitter.push_uint32_t(auxid)
     jitter.push_uint32_t(0)
diff --git a/miasm2/os_dep/linux/syscall.py b/miasm2/os_dep/linux/syscall.py
index 5bf7d64c..cd4de49f 100644
--- a/miasm2/os_dep/linux/syscall.py
+++ b/miasm2/os_dep/linux/syscall.py
@@ -1,3 +1,4 @@
+from builtins import range
 import fcntl
 import functools
 import logging
@@ -74,7 +75,7 @@ def sys_x86_64_rt_sigaction(jitter, linux_env):
     # Stub
     if oact != 0:
         # Return an empty old action
-        jitter.vm.set_mem(oact, "\x00" * sigsetsize)
+        jitter.vm.set_mem(oact, b"\x00" * sigsetsize)
     jitter.syscall_ret_systemv(0)
 
 
@@ -110,10 +111,10 @@ def sys_x86_64_newuname(jitter, linux_env):
         linux_env.sys_machine
     ]
     # TODO: Elements start at 0x41 multiples on my tests...
-    output = ""
+    output = b""
     for elem in info:
         output += elem
-        output += "\x00" * (0x41 - len(elem))
+        output += b"\x00" * (0x41 - len(elem))
     jitter.vm.set_mem(nameptr, output)
     jitter.syscall_ret_systemv(0)
 
@@ -141,10 +142,10 @@ def sys_arml_newuname(jitter, linux_env):
         linux_env.sys_machine
     ]
     # TODO: Elements start at 0x41 multiples on my tests...
-    output = ""
+    output = b""
     for elem in info:
         output += elem
-        output += "\x00" * (0x41 - len(elem))
+        output += b"\x00" * (0x41 - len(elem))
     jitter.vm.set_mem(nameptr, output)
     jitter.syscall_ret_systemv(0)
 
@@ -220,7 +221,7 @@ def sys_x86_64_writev(jitter, linux_env):
 
     # Stub
     fdesc = linux_env.file_descriptors[fd]
-    for iovec_num in xrange(vlen):
+    for iovec_num in range(vlen):
         # struct iovec {
         #    void  *iov_base;    /* Starting address */
         #    size_t iov_len;     /* Number of bytes to transfer */
@@ -239,7 +240,7 @@ def sys_arml_writev(jitter, linux_env):
 
     # Stub
     fdesc = linux_env.file_descriptors[fd]
-    for iovec_num in xrange(vlen):
+    for iovec_num in range(vlen):
         # struct iovec {
         #    void  *iov_base;    /* Starting address */
         #    size_t iov_len;     /* Number of bytes to transfer */
@@ -511,7 +512,7 @@ def sys_x86_64_getdents(jitter, linux_env):
         d_reclen = 8 * 2 + 2 + 1 + len(name) + 1
         d_off = cur_len + d_reclen
         entry = struct.pack("QqH", d_ino, d_off, d_reclen) + \
-                name + "\x00" + struct.pack("B", d_type)
+                name + b"\x00" + struct.pack("B", d_type)
         assert len(entry) == d_reclen
         return entry
 
@@ -539,7 +540,7 @@ def sys_arml_getdents64(jitter, linux_env):
         d_reclen = 8 * 2 + 2 + 1 + len(name) + 1
         d_off = cur_len + d_reclen
         entry = struct.pack("QqHB", d_ino, d_off, d_reclen, d_type) + \
-                name + "\x00"
+                name + b"\x00"
         assert len(entry) == d_reclen
         return entry
 
@@ -595,7 +596,7 @@ def sys_x86_64_lgetxattr(jitter, linux_env):
     log.debug("sys_lgetxattr(%r, %r, %x, %x)", rpathname, rname, value, size)
 
     # Stub
-    jitter.vm.set_mem(value, "\x00" * size)
+    jitter.vm.set_mem(value, b"\x00" * size)
     jitter.cpu.RAX = 0
 
 
@@ -610,7 +611,7 @@ def sys_x86_64_getxattr(jitter, linux_env):
     log.debug("sys_getxattr(%r, %r, %x, %x)", rpathname, rname, value, size)
 
     # Stub
-    jitter.vm.set_mem(value, "\x00" * size)
+    jitter.vm.set_mem(value, b"\x00" * size)
     jitter.cpu.RAX = 0
 
 
@@ -690,7 +691,7 @@ def sys_x86_64_readlink(jitter, linux_env):
         # Not a link
         jitter.cpu.RAX = -1
     else:
-        data = link[:bufsize - 1] + "\x00"
+        data = link[:bufsize - 1] + b"\x00"
         jitter.vm.set_mem(buf, data)
         jitter.cpu.RAX = len(data) - 1
 
diff --git a/miasm2/os_dep/linux_stdlib.py b/miasm2/os_dep/linux_stdlib.py
index 9e1cc9db..f12284ee 100644
--- a/miasm2/os_dep/linux_stdlib.py
+++ b/miasm2/os_dep/linux_stdlib.py
@@ -1,9 +1,16 @@
 #-*- coding:utf-8 -*-
 
+from __future__ import print_function
 import struct
 from sys import stdout
-from string import printable
 
+try:
+    # Python3 binary stdout
+    stdout = stdout.buffer
+except AttributeError:
+    pass
+
+from miasm2.core.utils import int_to_byte, cmp_elts
 from miasm2.os_dep.common import heap
 from miasm2.os_dep.common import get_fmt_args as _get_fmt_args
 
@@ -67,7 +74,7 @@ def xxx___libc_start_main(jitter):
 
         main = args.main
         # done by __libc_init_first
-        size = jitter.ir_arch.pc.size / 8
+        size = jitter.ir_arch.pc.size // 8
         argc = args.argc
         argv = args.ubp_av
         envp = argv + (args.argc + 1) * size
@@ -88,7 +95,7 @@ def xxx_isprint(jitter):
     checks for any printable character including space.
     '''
     ret_addr, args = jitter.func_args_systemv(['c'])
-    ret = 1 if chr(args.c & 0xFF) in printable else 0
+    ret = 1 if 0x20 <= args.c & 0xFF < 0x7f else 0
     return jitter.func_ret_systemv(ret_addr, ret)
 
 
@@ -113,7 +120,7 @@ def xxx_memset(jitter):
     byte c.'''
 
     ret_addr, args = jitter.func_args_systemv(['dest', 'c', 'n'])
-    jitter.vm.set_mem(args.dest, chr(args.c & 0xFF) * args.n)
+    jitter.vm.set_mem(args.dest, int_to_byte(args.c & 0xFF) * args.n)
     return jitter.func_ret_systemv(ret_addr, args.dest)
 
 
@@ -127,11 +134,11 @@ def xxx_puts(jitter):
     ret_addr, args = jitter.func_args_systemv(['s'])
     index = args.s
     char = jitter.vm.get_mem(index, 1)
-    while char != '\x00':
+    while char != b'\x00':
         stdout.write(char)
         index += 1
         char = jitter.vm.get_mem(index, 1)
-    stdout.write('\n')
+    stdout.write(b'\n')
     return jitter.func_ret_systemv(ret_addr, 1)
 
 
@@ -146,7 +153,7 @@ def xxx_snprintf(jitter):
     output = get_fmt_args(jitter, fmt, cur_arg)
     output = output[:size - 1]
     ret = len(output)
-    jitter.vm.set_mem(args.string, output + '\x00')
+    jitter.vm.set_mem(args.string, output + b'\x00')
     return jitter.func_ret_systemv(ret_addr, ret)
 
 
@@ -155,7 +162,7 @@ def xxx_sprintf(jitter):
     cur_arg, fmt = 2, args.fmt
     output = get_fmt_args(jitter, fmt, cur_arg)
     ret = len(output)
-    jitter.vm.set_mem(args.string, output + '\x00')
+    jitter.vm.set_mem(args.string, output + b'\x00')
     return jitter.func_ret_systemv(ret_addr, ret)
 
 
@@ -164,13 +171,13 @@ def xxx_printf(jitter):
     cur_arg, fmt = 1, args.fmt
     output = get_fmt_args(jitter, fmt, cur_arg)
     ret = len(output)
-    print output,
+    stdout.write(output)
     return jitter.func_ret_systemv(ret_addr, ret)
 
 
 def xxx_strcpy(jitter):
     ret_ad, args = jitter.func_args_systemv(["dst", "src"])
-    str_src = jitter.get_str_ansi(args.src) + '\x00'
+    str_src = jitter.get_str_ansi(args.src) + b'\x00'
     jitter.vm.set_mem(args.dst, str_src)
     jitter.func_ret_systemv(ret_ad, args.dst)
 
@@ -196,11 +203,11 @@ def xxx_strcmp(jitter):
     ret_ad, args = jitter.func_args_systemv(["ptr_str1", "ptr_str2"])
     s1 = jitter.get_str_ansi(args.ptr_str1)
     s2 = jitter.get_str_ansi(args.ptr_str2)
-    jitter.func_ret_systemv(ret_ad, cmp(s1, s2))
+    jitter.func_ret_systemv(ret_ad, cmp_elts(s1, s2))
 
 
 def xxx_strncmp(jitter):
     ret_ad, args = jitter.func_args_systemv(["ptr_str1", "ptr_str2", "size"])
     s1 = jitter.get_str_ansi(args.ptr_str1, args.size)
     s2 = jitter.get_str_ansi(args.ptr_str2, args.size)
-    jitter.func_ret_systemv(ret_ad, cmp(s1, s2))
+    jitter.func_ret_systemv(ret_ad, cmp_elts(s1, s2))
diff --git a/miasm2/os_dep/win_api_x86_32.py b/miasm2/os_dep/win_api_x86_32.py
index df679074..e6ef3601 100644
--- a/miasm2/os_dep/win_api_x86_32.py
+++ b/miasm2/os_dep/win_api_x86_32.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 #
 # Copyright (C) 2011 EADS France, Fabrice Desclaux <fabrice.desclaux@eads.net>
 #
@@ -15,6 +16,7 @@
 # with this program; if not, write to the Free Software Foundation, Inc.,
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 #
+from past.builtins import cmp
 import struct
 import os
 import stat
@@ -22,14 +24,16 @@ import time
 import string
 import logging
 from zlib import crc32
-from StringIO import StringIO
+from io import StringIO
 import time
 import datetime
 
+from future.utils import PY3, viewitems
+
 try:
     from Crypto.Hash import MD5, SHA
 except ImportError:
-    print "cannot find crypto, skipping"
+    print("cannot find crypto, skipping")
 
 from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE, PAGE_EXEC
 from miasm2.core.utils import pck16, pck32, hexdump, whoami
@@ -77,10 +81,10 @@ ACCESS_DICT = {0x0: 0,
                0x100: 0
                }
 
-ACCESS_DICT_INV = dict((x[1], x[0]) for x in ACCESS_DICT.iteritems())
+ACCESS_DICT_INV = dict((x[1], x[0]) for x in viewitems(ACCESS_DICT))
 
 
-class whandle():
+class whandle(object):
 
     def __init__(self, name, info):
         self.name = name
@@ -90,7 +94,7 @@ class whandle():
         return '<%r %r %r>' % (self.__class__.__name__, self.name, self.info)
 
 
-class handle_generator():
+class handle_generator(object):
 
     def __init__(self):
         self.offset = 600
@@ -106,7 +110,7 @@ class handle_generator():
 
     def __repr__(self):
         out = '<%r\n' % self.__class__.__name__
-        ks = self.all_handles.keys()
+        ks = list(self.all_handles)
         ks.sort()
 
         for k in ks:
@@ -124,7 +128,7 @@ class handle_generator():
         self.all_handles.__delitem__(item)
 
 
-class c_winobjs:
+class c_winobjs(object):
 
     def __init__(self):
         self.alloc_ad = 0x20000000
@@ -140,8 +144,8 @@ class c_winobjs:
         self.dw_pid_dummy2 = 0x333
         self.dw_pid_cur = 0x444
         self.module_fname_nux = None
-        self.module_name = "test.exe"
-        self.module_path = "c:\\mydir\\" + self.module_name
+        self.module_name = b"test.exe"
+        self.module_path = b"c:\\mydir\\" + self.module_name
         self.hcurmodule = None
         self.module_filesize = None
         self.getversion = 0x0A280105
@@ -161,8 +165,11 @@ class c_winobjs:
         self.tls_values = {}
         self.handle_pool = handle_generator()
         self.handle_mapped = {}
-        self.hkey_handles = {0x80000001: "hkey_current_user", 0x80000002: "hkey_local_machine"}
-        self.cur_dir = "c:\\tmp"
+        self.hkey_handles = {
+            0x80000001: b"hkey_current_user",
+            0x80000002: b"hkey_local_machine"
+        }
+        self.cur_dir = b"c:\\tmp"
 
         self.nt_mdl = {}
         self.nt_mdl_ad = None
@@ -176,9 +183,11 @@ class c_winobjs:
         self.events_pool = {}
         self.find_data = None
 
-        self.current_datetime = datetime.datetime(year=2017, month=8, day=21,
-                                                  hour=13, minute=37,
-                                                  second=11, microsecond=123456)
+        self.current_datetime = datetime.datetime(
+            year=2017, month=8, day=21,
+            hour=13, minute=37,
+            second=11, microsecond=123456
+        )
 
 winobjs = c_winobjs()
 
@@ -194,7 +203,7 @@ process_list = [
         winobjs.dw_pid_explorer,  # DWORD     th32ParentProcessID;
         0xbeef,  # LONG      pcPriClassBase;
         0x0,  # DWORD     dwFlags;
-        "dummy1.exe"  # TCHAR     szExeFile[MAX_PATH];
+        b"dummy1.exe"  # TCHAR     szExeFile[MAX_PATH];
     ],
     [
         0x40,  # DWORD     dwSize;
@@ -206,7 +215,7 @@ process_list = [
         4,  # DWORD     th32ParentProcessID;
         0xbeef,  # LONG      pcPriClassBase;
         0x0,  # DWORD     dwFlags;
-        "explorer.exe"  # TCHAR     szExeFile[MAX_PATH];
+        b"explorer.exe"  # TCHAR     szExeFile[MAX_PATH];
     ],
 
     [
@@ -219,7 +228,7 @@ process_list = [
         winobjs.dw_pid_explorer,  # DWORD     th32ParentProcessID;
         0xbeef,  # LONG      pcPriClassBase;
         0x0,  # DWORD     dwFlags;
-        "dummy2.exe"  # TCHAR     szExeFile[MAX_PATH];
+        b"dummy2.exe"  # TCHAR     szExeFile[MAX_PATH];
     ],
 
     [
@@ -239,19 +248,24 @@ process_list = [
 ]
 
 
-class hobj:
+class hobj(object):
     pass
 
 
-class mdl:
+class mdl(object):
 
     def __init__(self, ad, l):
         self.ad = ad
         self.l = l
 
-    def __str__(self):
+    def __bytes__(self):
         return struct.pack('LL', self.ad, self.l)
 
+    def __str__(self):
+        if PY3:
+            return repr(self)
+        return self.__bytes__()
+
 
 def kernel32_HeapAlloc(jitter):
     ret_ad, args = jitter.func_args_stdcall(["heap", "flags", "size"])
@@ -322,7 +336,8 @@ def kernel32_Process32First(jitter):
     ret_ad, args = jitter.func_args_stdcall(["s_handle", "ad_pentry"])
 
     pentry = struct.pack(
-        'IIIIIIIII', *process_list[0][:-1]) + process_list[0][-1]
+        'IIIIIIIII', *process_list[0][:-1]
+    ) + process_list[0][-1]
     jitter.vm.set_mem(args.ad_pentry, pentry)
     winobjs.toolhelpsnapshot_info[args.s_handle] = 0
 
@@ -360,19 +375,20 @@ def kernel32_GetVersionEx(jitter, str_size, set_str):
 
     size = jitter.vm.get_u32(args.ptr_struct)
     if size in [0x14+str_size, 0x1c+str_size]:
-        tmp = struct.pack("IIIII%dsHHHBB" % str_size,
-                          0x114,            # struct size
-                          0x5,              # maj vers
-                          0x2,              # min vers
-                          0xa28,            # build nbr
-                          0x2,              # platform id
-                          set_str("Service pack 4"),
-                          3,                # wServicePackMajor
-                          0,                # wServicePackMinor
-                          0x100,            # wSuiteMask
-                          1,                # wProductType
-                          0                 # wReserved
-                          )
+        tmp = struct.pack(
+            "IIIII%dsHHHBB" % str_size,
+            0x114,            # struct size
+            0x5,              # maj vers
+            0x2,              # min vers
+            0xa28,            # build nbr
+            0x2,              # platform id
+            set_str("Service pack 4"),
+            3,                # wServicePackMajor
+            0,                # wServicePackMinor
+            0x100,            # wSuiteMask
+            1,                # wProductType
+            0                 # wReserved
+        )
         tmp = tmp[:size]
         jitter.vm.set_mem(args.ptr_struct, tmp)
         ret = 1
@@ -691,10 +707,10 @@ def kernel32_GetFileSize(jitter):
     ret_ad, args = jitter.func_args_stdcall(["hwnd", "lpfilesizehight"])
 
     if args.hwnd == winobjs.module_cur_hwnd:
-        ret = len(open(winobjs.module_fname_nux).read())
+        ret = len(open(winobjs.module_fname_nux, "rb").read())
     elif args.hwnd in winobjs.handle_pool:
         wh = winobjs.handle_pool[args.hwnd]
-        ret = len(open(wh.name).read())
+        ret = len(open(wh.name, "rb").read())
     else:
         raise ValueError('unknown hwnd!')
 
@@ -707,10 +723,10 @@ def kernel32_GetFileSizeEx(jitter):
     ret_ad, args = jitter.func_args_stdcall(["hwnd", "lpfilesizehight"])
 
     if args.hwnd == winobjs.module_cur_hwnd:
-        l = len(open(winobjs.module_fname_nux).read())
+        l = len(open(winobjs.module_fname_nux, "rb").read())
     elif args.hwnd in winobjs.handle_pool:
         wh = winobjs.handle_pool[args.hwnd]
-        l = len(open(wh.name).read())
+        l = len(open(wh.name, "rb").read())
     else:
         raise ValueError('unknown hwnd!')
 
@@ -797,9 +813,13 @@ def kernel32_GetModuleFileName(jitter, funcname, set_str):
     if args.hmodule in [0, winobjs.hcurmodule]:
         p = winobjs.module_path[:]
     elif (winobjs.runtime_dll and
-          args.hmodule in winobjs.runtime_dll.name2off.values()):
-        name_inv = dict([(x[1], x[0])
-                        for x in winobjs.runtime_dll.name2off.items()])
+          args.hmodule in viewvalues(winobjs.runtime_dll.name2off)):
+        name_inv = dict(
+            [
+                (x[1], x[0])
+                for x in viewitems(winobjs.runtime_dll.name2off)
+            ]
+        )
         p = name_inv[args.hmodule]
     else:
         log.warning(('Unknown module 0x%x.' +
@@ -987,7 +1007,7 @@ def kernel32_VirtualLock(jitter):
     jitter.func_ret_stdcall(ret_ad, 1)
 
 
-class systeminfo:
+class systeminfo(object):
     oemId = 0
     dwPageSize = 0x1000
     lpMinimumApplicationAddress = 0x10000
@@ -1292,7 +1312,7 @@ def mdl2ad(n):
 
 
 def ad2mdl(ad):
-    return ((ad - winobjs.nt_mdl_ad) & 0xFFFFFFFFL) / 0x10
+    return ((ad - winobjs.nt_mdl_ad) & 0xFFFFFFFF) // 0x10
 
 
 def ntoskrnl_IoAllocateMdl(jitter):
@@ -1300,7 +1320,7 @@ def ntoskrnl_IoAllocateMdl(jitter):
                                              "chargequota", "pirp"])
     m = mdl(args.v_addr, args.l)
     winobjs.nt_mdl[winobjs.nt_mdl_cur] = m
-    jitter.vm.set_mem(mdl2ad(winobjs.nt_mdl_cur), str(m))
+    jitter.vm.set_mem(mdl2ad(winobjs.nt_mdl_cur), bytes(m))
     jitter.func_ret_stdcall(ret_ad, mdl2ad(winobjs.nt_mdl_cur))
     winobjs.nt_mdl_cur += 1
 
@@ -1665,7 +1685,7 @@ def kernel32_WaitForSingleObject(jitter):
         if args.dwms and args.dwms + t_start > time.time() * 1000:
             ret = 0x102
             break
-        for key, value in winobjs.events_pool.iteritems():
+        for key, value in viewitems(winobjs.events_pool):
             if key != args.handle:
                 continue
             found = True
@@ -1835,19 +1855,19 @@ def ntdll_LdrGetProcedureAddress(jitter):
 
 def ntdll_memset(jitter):
     ret_ad, args = jitter.func_args_cdecl(['addr', 'c', 'size'])
-    jitter.vm.set_mem(args.addr, chr(args.c) * args.size)
+    jitter.vm.set_mem(args.addr, int_to_byte(args.c) * args.size)
     jitter.func_ret_cdecl(ret_ad, args.addr)
 
 
 def msvcrt_memset(jitter):
     ret_ad, args = jitter.func_args_cdecl(['addr', 'c', 'size'])
-    jitter.vm.set_mem(args.addr, chr(args.c) * args.size)
+    jitter.vm.set_mem(args.addr, int_to_byte(args.c) * args.size)
     jitter.func_ret_cdecl(ret_ad, args.addr)
 
 def msvcrt_strrchr(jitter):
     ret_ad, args = jitter.func_args_cdecl(['pstr','c'])
     s = jitter.get_str_ansi(args.pstr)
-    c = chr(args.c)
+    c = int_to_byte(args.c)
     ret = args.pstr + s.rfind(c)
     log.info("strrchr(%x '%s','%s') = %x" % (args.pstr,s,c,ret))
     jitter.func_ret_cdecl(ret_ad, ret)
@@ -1855,7 +1875,7 @@ def msvcrt_strrchr(jitter):
 def msvcrt_wcsrchr(jitter):
     ret_ad, args = jitter.func_args_cdecl(['pstr','c'])
     s = jitter.get_str_unic(args.pstr)
-    c = chr(args.c)
+    c = int_to_byte(args.c)
     ret = args.pstr + (s.rfind(c)*2)
     log.info("wcsrchr(%x '%s',%s) = %x" % (args.pstr,s,c,ret))
     jitter.func_ret_cdecl(ret_ad, ret)
@@ -1863,7 +1883,6 @@ def msvcrt_wcsrchr(jitter):
 def msvcrt_memcpy(jitter):
     ret_ad, args = jitter.func_args_cdecl(['dst', 'src', 'size'])
     s = jitter.vm.get_mem(args.src, args.size)
-    #log.info("memcpy buf %s" % s.encode("hex"))
     jitter.vm.set_mem(args.dst, s)
     jitter.func_ret_cdecl(ret_ad, args.dst)
 
@@ -2011,7 +2030,7 @@ def shlwapi_StrToInt64ExW(jitter):
 def user32_IsCharAlpha(jitter, funcname, get_str):
     ret_ad, args = jitter.func_args_stdcall(["c"])
     try:
-        c = chr(args.c)
+        c = int_to_byte(args.c)
     except:
         log.error('bad char %r', args.c)
         c = "\x00"
@@ -2032,7 +2051,7 @@ def user32_IsCharAlphaW(jitter):
 
 def user32_IsCharAlphaNumericA(jitter):
     ret_ad, args = jitter.func_args_stdcall(["c"])
-    c = chr(args.c)
+    c = int_to_byte(args.c)
     if c.isalnum(jitter):
         ret = 1
     else:
@@ -2051,7 +2070,7 @@ def msvcrt_sprintf(jitter):
     ret_ad, args, output = msvcrt_sprintf_str(jitter, jitter.get_str_ansi)
     ret = len(output)
     log.info("sprintf() = '%s'" % (output))
-    jitter.vm.set_mem(args.string, output + '\x00')
+    jitter.vm.set_mem(args.string, output + b'\x00')
     return jitter.func_ret_cdecl(ret_ad, ret)
 
 def msvcrt_swprintf(jitter):
@@ -2060,7 +2079,7 @@ def msvcrt_swprintf(jitter):
     output = get_fmt_args(jitter, fmt, cur_arg, jitter.get_str_unic)
     ret = len(output)
     log.info("swprintf('%s') = '%s'" % (jitter.get_str_unic(args.fmt), output))
-    jitter.vm.set_mem(args.string, output.encode("utf-16le") + '\x00\x00')
+    jitter.vm.set_mem(args.string, output.encode("utf-16le") + b'\x00\x00')
     return jitter.func_ret_cdecl(ret_ad, ret)
 
 def msvcrt_fprintf(jitter):
@@ -2111,7 +2130,7 @@ def kernel32_GetCurrentDirectoryA(jitter):
     ret_ad, args = jitter.func_args_stdcall(["size","buf"])
     dir_ = winobjs.cur_dir
     log.debug("GetCurrentDirectory() = '%s'" % dir_)
-    jitter.vm.set_mem(args.buf, dir_[:args.size-1] + "\x00")
+    jitter.vm.set_mem(args.buf, dir_[:args.size-1] + b"\x00")
     ret = len(dir_)
     if args.size <= len(dir_):
         ret += 1
@@ -2346,7 +2365,7 @@ def filetime_to_unixtime(filetime):
     Convert filetime to unixtime
     # https://msdn.microsoft.com/en-us/library/ms724228
     """
-    return int((filetime - DATE_1601_TO_1970) / 10000000)
+    return int((filetime - DATE_1601_TO_1970) // 10000000)
 
 
 def datetime_to_systemtime(curtime):
@@ -2359,7 +2378,7 @@ def datetime_to_systemtime(curtime):
                     curtime.hour,      # hour
                     curtime.minute ,   # minutes
                     curtime.second,    # seconds
-                    int(curtime.microsecond / 1000),  # millisec
+                    int(curtime.microsecond // 1000),  # millisec
                     )
     return s
 
@@ -2515,7 +2534,7 @@ def kernel32_VirtualQuery(jitter):
 
     all_mem = jitter.vm.get_all_memory()
     found = None
-    for basead, m in all_mem.iteritems():
+    for basead, m in viewitems(all_mem):
         if basead <= args.ad < basead + m['size']:
             found = args.ad, m
             break
@@ -2798,7 +2817,7 @@ def kernel32_GetTempFileNameA(jitter):
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
-class win32_find_data:
+class win32_find_data(object):
     fileattrib = 0
     creationtime = 0
     lastaccesstime = 0
@@ -2811,7 +2830,7 @@ class win32_find_data:
     alternamefilename = ""
 
     def __init__(self, **kargs):
-        for k, v in kargs.items():
+        for k, v in viewitems(kargs):
             setattr(self, k, v)
 
     def toStruct(self):
@@ -2833,7 +2852,7 @@ class win32_find_data:
         return s
 
 
-class find_data_mngr:
+class find_data_mngr(object):
 
     def __init__(self):
         self.patterns = {}
@@ -2904,7 +2923,7 @@ def raw2guid(r):
     return '{%.8X-%.4X-%.4X-%.4X-%.2X%.2X%.2X%.2X%.2X%.2X}' % o
 
 
-digs = string.digits + string.lowercase
+digs = string.digits + string.ascii_lowercase
 
 
 def int2base(x, base):
diff --git a/miasm2/os_dep/win_api_x86_32_seh.py b/miasm2/os_dep/win_api_x86_32_seh.py
index be524895..27808d83 100644
--- a/miasm2/os_dep/win_api_x86_32_seh.py
+++ b/miasm2/os_dep/win_api_x86_32_seh.py
@@ -21,6 +21,8 @@ import logging
 import os
 import struct
 
+from future.utils import viewitems
+
 from elfesteem import pe_init
 
 from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE
@@ -78,7 +80,7 @@ return_from_exception = 0x6eadbeef
 
 name2module = []
 main_pe = None
-main_pe_name = "c:\\xxx\\toto.exe"
+main_pe_name = b"c:\\xxx\\toto.exe"
 
 MAX_SEH = 5
 
@@ -92,18 +94,27 @@ def build_teb(jitter, teb_address):
     """
 
     # Only allocate space for ExceptionList/ProcessEnvironmentBlock/Self
-    jitter.vm.add_memory_page(teb_address, PAGE_READ | PAGE_WRITE,
-                              "\x00" * NT_TIB.get_offset("StackBase"),
-                              "TEB.NtTib.ExceptionList")
-    jitter.vm.add_memory_page(teb_address + NT_TIB.get_offset("Self"),
-                              PAGE_READ | PAGE_WRITE,
-                              "\x00" * (NT_TIB.sizeof() - NT_TIB.get_offset("Self")),
-                              "TEB.NtTib.Self")
-    jitter.vm.add_memory_page(teb_address + TEB.get_offset("ProcessEnvironmentBlock"),
-                              PAGE_READ | PAGE_WRITE,
-                              "\x00" * (TEB.get_offset("LastErrorValue") -
-                                        TEB.get_offset("ProcessEnvironmentBlock")),
-                              "TEB.ProcessEnvironmentBlock")
+    jitter.vm.add_memory_page(
+        teb_address,
+        PAGE_READ | PAGE_WRITE,
+        b"\x00" * NT_TIB.get_offset("StackBase"),
+        "TEB.NtTib.ExceptionList"
+    )
+    jitter.vm.add_memory_page(
+        teb_address + NT_TIB.get_offset("Self"),
+        PAGE_READ | PAGE_WRITE,
+        b"\x00" * (NT_TIB.sizeof() - NT_TIB.get_offset("Self")),
+        "TEB.NtTib.Self"
+    )
+    jitter.vm.add_memory_page(
+        teb_address + TEB.get_offset("ProcessEnvironmentBlock"),
+        PAGE_READ | PAGE_WRITE,
+        b"\x00" * (
+            TEB.get_offset("LastErrorValue") -
+            TEB.get_offset("ProcessEnvironmentBlock")
+        ),
+        "TEB.ProcessEnvironmentBlock"
+    )
     Teb = TEB(jitter.vm, teb_address)
     Teb.NtTib.ExceptionList = DEFAULT_SEH
     Teb.NtTib.Self = teb_address
@@ -123,9 +134,12 @@ def build_peb(jitter, peb_address):
         offset, length = peb_address + 0xC, 0
     length += 4
 
-    jitter.vm.add_memory_page(offset, PAGE_READ | PAGE_WRITE,
-                              "\x00" * length,
-                              "PEB")
+    jitter.vm.add_memory_page(
+        offset,
+        PAGE_READ | PAGE_WRITE,
+        b"\x00" * length,
+        "PEB"
+    )
 
     Peb = PEB(jitter.vm, peb_address)
     if main_pe:
@@ -167,9 +181,12 @@ def build_ldr_data(jitter, modules_info):
         size += ListEntry.sizeof()
         ntdll_addr_entry = modules_info.module2entry[ntdll_pe]
 
-    jitter.vm.add_memory_page(addr + offset, PAGE_READ | PAGE_WRITE,
-                              "\x00" * size,
-                              "Loader struct")  # (ldrdata.get_size() - offset))
+    jitter.vm.add_memory_page(
+        addr + offset,
+        PAGE_READ | PAGE_WRITE,
+        b"\x00" * size,
+        "Loader struct"
+    )  # (ldrdata.get_size() - offset))
 
     if main_pe:
         ldrdata.InLoadOrderModuleList.flink = main_addr_entry
@@ -213,7 +230,7 @@ class LoadedModules(object):
         self.module2name[module] = name
 
     def __repr__(self):
-        return "\n".join([str(x) for x in self.name2module.iteritems()])
+        return "\n".join(str(x) for x in viewitems(self.name2module))
 
 
 def create_modules_chain(jitter, name2module):
@@ -230,7 +247,7 @@ def create_modules_chain(jitter, name2module):
     offset_path = 0x600
 
     out = ""
-    for i, (fname, pe_obj) in enumerate(name2module.items(), 1):
+    for i, (fname, pe_obj) in enumerate(viewitems(name2module), 1):
         if pe_obj is None:
             log.warning("Unknown module: omitted from link list (%r)",
                         fname)
@@ -238,35 +255,45 @@ def create_modules_chain(jitter, name2module):
         addr = base_addr + i * 0x1000
         bpath = fname.replace('/', '\\')
         bname_str = os.path.split(fname)[1].lower()
-        bname = "\x00".join(bname_str) + "\x00"
+        bname_unicode = bname_str.encode("utf-16le")
         log.info("Add module %x %r", pe_obj.NThdr.ImageBase, bname_str)
 
         modules_info.add(bname_str, pe_obj, addr)
 
         # Allocate a partial LdrDataEntry (0-Flags)
-        jitter.vm.add_memory_page(addr, PAGE_READ | PAGE_WRITE,
-                                  "\x00" * LdrDataEntry.get_offset("Flags"),
-                                  "Module info %r" % bname_str)
+        jitter.vm.add_memory_page(
+            addr,
+            PAGE_READ | PAGE_WRITE,
+            b"\x00" * LdrDataEntry.get_offset("Flags"),
+            "Module info %r" % bname_str
+        )
 
         LdrEntry = LdrDataEntry(jitter.vm, addr)
 
         LdrEntry.DllBase = pe_obj.NThdr.ImageBase
         LdrEntry.EntryPoint = pe_obj.Opthdr.AddressOfEntryPoint
         LdrEntry.SizeOfImage = pe_obj.NThdr.sizeofimage
-        LdrEntry.FullDllName.length = len(bname)
-        LdrEntry.FullDllName.maxlength = len(bname) + 2
+        LdrEntry.FullDllName.length = len(bname_unicode)
+        LdrEntry.FullDllName.maxlength = len(bname_unicode) + 2
         LdrEntry.FullDllName.data = addr + offset_path
-        LdrEntry.BaseDllName.length = len(bname)
-        LdrEntry.BaseDllName.maxlength = len(bname) + 2
+        LdrEntry.BaseDllName.length = len(bname_unicode)
+        LdrEntry.BaseDllName.maxlength = len(bname_unicode) + 2
         LdrEntry.BaseDllName.data = addr + offset_name
 
-        jitter.vm.add_memory_page(addr + offset_name, PAGE_READ | PAGE_WRITE,
-                                  bname + "\x00" * 3,
-                                  "Module name %r" % bname_str)
-
-        jitter.vm.add_memory_page(addr + offset_path, PAGE_READ | PAGE_WRITE,
-                                  "\x00".join(bpath) + "\x00" + "\x00" * 3,
-                                  "Module path %r" % bname_str)
+        jitter.vm.add_memory_page(
+            addr + offset_name,
+            PAGE_READ | PAGE_WRITE,
+            bname_unicode + b"\x00" * 2,
+            "Module name %r" % bname_str
+        )
+
+        bpath_unicode = bpath.encode('utf-16le')
+        jitter.vm.add_memory_page(
+            addr + offset_path,
+            PAGE_READ | PAGE_WRITE,
+            bpath_unicode + b"\x00" * 2,
+            "Module path %r" % bname_str
+        )
 
     return modules_info
 
@@ -372,14 +399,15 @@ def add_process_env(jitter):
     @jitter: jitter instance
     """
 
-    env_str = 'ALLUSEESPROFILE=C:\\Documents and Settings\\All Users\x00'
-    env_str = '\x00'.join(env_str)
-    env_str += "\x00" * 0x10
-    jitter.vm.add_memory_page(process_environment_address,
-                              PAGE_READ | PAGE_WRITE,
-                              env_str,
-                              "Process environment")
-    jitter.vm.set_mem(process_environment_address, env_str)
+    env_unicode = 'ALLUSEESPROFILE=C:\\Documents and Settings\\All Users\x00'.encode('utf-16le')
+    env_unicode += b"\x00" * 0x10
+    jitter.vm.add_memory_page(
+        process_environment_address,
+        PAGE_READ | PAGE_WRITE,
+        env_unicode,
+        "Process environment"
+    )
+    jitter.vm.set_mem(process_environment_address, env_unicode)
 
 
 def add_process_parameters(jitter):
@@ -388,13 +416,15 @@ def add_process_parameters(jitter):
     @jitter: jitter instance
     """
 
-    o = ""
+    o = b""
     o += pck32(0x1000)  # size
-    o += "E" * (0x48 - len(o))
+    o += b"E" * (0x48 - len(o))
     o += pck32(process_environment_address)
-    jitter.vm.add_memory_page(process_parameters_address,
-                              PAGE_READ | PAGE_WRITE,
-                              o, "Process parameters")
+    jitter.vm.add_memory_page(
+        process_parameters_address,
+        PAGE_READ | PAGE_WRITE,
+        o, "Process parameters"
+    )
 
 
 # http://blog.fireeye.com/research/2010/08/download_exec_notes.html
@@ -431,7 +461,7 @@ def regs2ctxt(jitter, context_address):
     """
 
     ctxt = ContextException(jitter.vm, context_address)
-    ctxt.memset("\x00")
+    ctxt.memset(b"\x00")
     # ContextFlags
     # XXX
 
@@ -543,12 +573,17 @@ def fake_seh_handler(jitter, except_code, previous_seh=None):
             seh = seh.Next.deref
         seh = seh.Next.deref
 
-    log.info('seh_ptr %x { old_seh %r eh %r} ctx_addr %x',
-             seh.get_addr(), seh.Next, seh.Handler, context_address)
+    log.info(
+        'seh_ptr %x { old_seh %r eh %r} ctx_addr %x',
+        seh.get_addr(),
+        seh.Next,
+        seh.Handler,
+        context_address
+    )
 
     # Write exception_record
     except_record = EXCEPTION_RECORD(jitter.vm, exception_record_address)
-    except_record.memset("\x00")
+    except_record.memset(b"\x00")
     except_record.ExceptionCode = except_code
     except_record.ExceptionAddress = jitter.cpu.EIP
 
diff --git a/requirements.txt b/requirements.txt
index acdef10b..84530589 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,4 @@
 pyparsing
-git+https://github.com/serpilliere/elfesteem@master#egg=elfesteem-0.1
+future
+git+https://github.com/serpilliere/elfesteem@py23_lalet#egg=elfesteem-0.1
 llvmlite==0.26.0
diff --git a/setup.py b/setup.py
index 7b0fb86d..83e4608e 100755
--- a/setup.py
+++ b/setup.py
@@ -1,86 +1,122 @@
 #! /usr/bin/env python2
 
+from __future__ import print_function
 from distutils.core import setup, Extension
 from distutils.util import get_platform
-from shutil import copy2
+import io
+import os
 import platform
-import os, sys
+from shutil import copy2
+import sys
 
 is_win = platform.system() == "Windows"
 
 def buil_all():
-    packages=["miasm2",
-              "miasm2/arch",
-              "miasm2/arch/x86",
-              "miasm2/arch/arm",
-              "miasm2/arch/aarch64",
-              "miasm2/arch/msp430",
-              "miasm2/arch/mep",
-              "miasm2/arch/sh4",
-              "miasm2/arch/mips32",
-              "miasm2/arch/ppc",
-              "miasm2/core",
-              "miasm2/expression",
-              "miasm2/ir",
-              "miasm2/ir/translators",
-              "miasm2/analysis",
-              "miasm2/os_dep",
-              "miasm2/os_dep/linux",
-              "miasm2/jitter",
-              "miasm2/jitter/arch",
-              "miasm2/jitter/loader",
-              ]
+    packages=[
+        "miasm2",
+        "miasm2/arch",
+        "miasm2/arch/x86",
+        "miasm2/arch/arm",
+        "miasm2/arch/aarch64",
+        "miasm2/arch/msp430",
+        "miasm2/arch/mep",
+        "miasm2/arch/sh4",
+        "miasm2/arch/mips32",
+        "miasm2/arch/ppc",
+        "miasm2/core",
+        "miasm2/expression",
+        "miasm2/ir",
+        "miasm2/ir/translators",
+        "miasm2/analysis",
+        "miasm2/os_dep",
+        "miasm2/os_dep/linux",
+        "miasm2/jitter",
+        "miasm2/jitter/arch",
+        "miasm2/jitter/loader",
+    ]
     ext_modules_all = [
-        Extension("miasm2.jitter.VmMngr",
-                  ["miasm2/jitter/vm_mngr.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/bn.h",
-                  ]),
+        Extension(
+            "miasm2.jitter.VmMngr",
+            [
+                "miasm2/jitter/vm_mngr.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/bn.h",
+            ]
+        ),
         Extension("miasm2.jitter.Jitllvm",
                   ["miasm2/jitter/Jitllvm.c",
                    "miasm2/jitter/bn.c",
@@ -96,42 +132,54 @@ def buil_all():
         os.environ['MSSdk'] = '1'
         os.environ['DISTUTILS_USE_SDK'] = '1'
 
-    print "building"
+    print("building")
     build_ok = False
     for name, ext_modules in [("all", ext_modules_all),
     ]:
-        print "build with", repr(name)
+        print("build with", repr(name))
         try:
             s = setup(
                 name = "Miasm",
                 version = "2.0",
                 packages = packages,
-                package_data = {"miasm2":["jitter/*.h",
-                                          "jitter/arch/*.h",]},
+                package_data = {
+                    "miasm2":[
+                        "jitter/*.h",
+                        "jitter/arch/*.h",
+                    ]
+                },
                 ext_modules = ext_modules,
                 # Metadata
                 author = "Fabrice Desclaux",
                 author_email = "serpilliere@droid-corp.org",
                 description = "Machine code manipulation library",
                 license = "GPLv2",
-                # keywords = "",
-                # url = "",
+                long_description=io.open('README.md', encoding='utf-8').read(),
+                keywords = [
+                    "reverse engineering",
+                    "disassembler",
+                    "emulator",
+                    "symbolic execution",
+                    "intermediate representation",
+                    "assembler",
+                ],
+                url = "http://miasm.re",
             )
-        except SystemExit, e:
-            print repr(e)
+        except SystemExit as e:
+            print(repr(e))
             continue
         build_ok = True
         break
     if not build_ok:
         raise ValueError("Unable to build Miasm!")
-    print "build", name
+    print("build", name)
     # we copy libraries from build dir to current miasm directory
     build_base = "build"
     if "build" in s.command_options:
         if "build_base" in s.command_options["build"]:
             build_base = s.command_options["build"]["build_base"]
 
-    print build_base
+    print(build_base)
     if is_win:
         libs = []
         for root, _, files in os.walk(build_base):
@@ -156,7 +204,7 @@ def buil_all():
                 dst = os.path.join(dst, "arch")
             dst = os.path.join(dst, filename)
             if not os.path.isfile(dst):
-                print "Copying", lib, "to", dst
+                print("Copying", lib, "to", dst)
                 copy2(lib, dst)
 
 buil_all()
diff --git a/test/analysis/data_flow.py b/test/analysis/data_flow.py
index 2d4e2275..288f4bd6 100644
--- a/test/analysis/data_flow.py
+++ b/test/analysis/data_flow.py
@@ -1,4 +1,8 @@
 """ Test cases for dead code elimination"""
+from __future__ import print_function
+
+from future.utils import viewitems
+
 from miasm2.expression.expression import ExprId, ExprInt, ExprAssign, ExprMem
 from miasm2.core.locationdb import LocationDB
 from miasm2.analysis.data_flow import *
@@ -683,7 +687,7 @@ for test_nb, test in enumerate([(G1_IRA, G1_EXP_IRA),
     # Extract test elements
     g_ira, g_exp_ira = test
 
-    print "[+] Test", test_nb+1
+    print("[+] Test", test_nb+1)
 
     # Print initial graph, for debug
     open("graph_%02d.dot" % (test_nb+1), "w").write(g_ira.dot())
@@ -700,6 +704,6 @@ for test_nb, test in enumerate([(G1_IRA, G1_EXP_IRA),
     # Same number of blocks
     assert len(g_ira.blocks) == len(g_exp_ira.blocks)
     # Check that each expr in the blocks are the same
-    for lbl, irb in g_ira.blocks.iteritems():
+    for lbl, irb in viewitems(g_ira.blocks):
         exp_irb = g_exp_ira.blocks[lbl]
         assert exp_irb.assignblks == irb.assignblks
diff --git a/test/analysis/depgraph.py b/test/analysis/depgraph.py
index 4d9aa322..c229caf2 100644
--- a/test/analysis/depgraph.py
+++ b/test/analysis/depgraph.py
@@ -1,6 +1,10 @@
 """Regression test module for DependencyGraph"""
-from miasm2.expression.expression import ExprId, ExprInt, ExprAssign, ExprCond, \
-    ExprLoc, LocKey
+from __future__ import print_function
+
+from future.utils import viewitems
+
+from miasm2.expression.expression import ExprId, ExprInt, ExprAssign, \
+    ExprCond, ExprLoc, LocKey
 from miasm2.core.locationdb import LocationDB
 from miasm2.ir.analysis import ira
 from miasm2.ir.ir import IRBlock, AssignBlock
@@ -136,7 +140,7 @@ def bloc2graph(irgraph, label=False, lines=True):
         block_html_lines = []
         if lines and irblock is not None:
             for assignblk in irblock:
-                for dst, src in assignblk.iteritems():
+                for dst, src in viewitems(assignblk):
                     if False:
                         out_render = "%.8X</td><td %s> " % (0, td_attr)
                     else:
@@ -220,7 +224,7 @@ def dg2graph(graph, label=False, lines=True):
     return '\n'.join(out)
 
 
-print "   [+] Test dictionary equality"
+print("   [+] Test dictionary equality")
 DNA = DependencyNode(LBL2, A, 0)
 DNB = DependencyNode(LBL1, B, 1)
 DNC = DependencyNode(LBL1, C, 0)
@@ -747,10 +751,14 @@ def flatNode(node):
             element = int(node.element.arg)
         else:
             RuntimeError("Unsupported type '%s'" % type(enode.element))
-        name = loc_db.pretty_str(node.loc_key)
-        return (name,
-                element,
-                node.line_nb)
+        names = loc_db.get_location_names(node.loc_key)
+        assert len(names) == 1
+        name = next(iter(names))
+        return (
+            name,
+            element,
+            node.line_nb
+        )
     else:
         return str(node)
 
@@ -761,8 +769,10 @@ def flatGraph(graph):
         out_nodes.add(flatNode(node))
     for nodeA, nodeB in graph.edges():
         out_edges.add((flatNode(nodeA), flatNode(nodeB)))
-    out = (tuple(sorted(list(out_nodes))),
-           tuple(sorted(list(out_edges))))
+    out = (
+        tuple(sorted(list(out_nodes), key=str)),
+        tuple(sorted(list(out_edges), key=str))
+    )
     return out
 
 
@@ -819,7 +829,7 @@ def test_result(graphA, graphB, leaves):
         if set(parentsA_noidx.keys()) != set(parentsB_noidx.keys()):
             return False
 
-        for node_noidx, nodeA in parentsA_noidx.iteritems():
+        for node_noidx, nodeA in viewitems(parentsA_noidx):
             nodeB = parentsB_noidx[node_noidx]
             todo.add((nodeA, nodeB))
 
@@ -835,7 +845,8 @@ def match_results(resultsA, resultsB, nodes):
     if len(resultsA) != len(resultsB):
         return False
 
-    for resultA in resultsA:
+    for flatA in resultsA:
+        resultA = unflatGraph(flatA)
         nodes = resultA.leaves()
         for resultB in resultsB:
             if test_result(resultA, resultB, nodes):
@@ -854,253 +865,253 @@ def get_flat_init_depnodes(depnodes):
     return out
 
 # TESTS
-flat_test_results = [[((('lbl0', 1, 0), ('lbl0', 'c', 0), ('lbl1', 'b', 0), ('lbl2', 'a', 0)),
-                       ((('lbl0', 1, 0), ('lbl0', 'c', 0)),
-                        (('lbl0', 'c', 0), ('lbl1', 'b', 0)),
-                        (('lbl1', 'b', 0), ('lbl2', 'a', 0))))],
-                     [((('lbl0', 1, 0),
-                        ('lbl0', 'c', 0),
-                        ('lbl1', 2, 0),
-                        ('lbl1', 'b', 0),
-                        ('lbl2', 'a', 0)),
-                       ((('lbl0', 1, 0), ('lbl0', 'c', 0)),
-                        (('lbl0', 'c', 0), ('lbl2', 'a', 0)),
-                        (('lbl1', 2, 0), ('lbl1', 'b', 0)),
-                        (('lbl1', 'b', 0), ('lbl2', 'a', 0))))],
-                     [((('lbl0', 1, 0),
-                        ('lbl0', 'c', 0),
-                        ('lbl1', 2, 0),
-                        ('lbl1', 'b', 0),
-                        ('lbl3', 'a', 0)),
-                       ((('lbl0', 1, 0), ('lbl0', 'c', 0)),
-                        (('lbl0', 'c', 0), ('lbl3', 'a', 0)),
-                        (('lbl1', 2, 0), ('lbl1', 'b', 0)),
-                        (('lbl1', 'b', 0), ('lbl3', 'a', 0)))),
-                      ((('lbl0', 1, 0),
-                        ('lbl0', 'c', 0),
-                        ('lbl2', 3, 0),
-                        ('lbl2', 'b', 0),
-                        ('lbl3', 'a', 0)),
-                       ((('lbl0', 1, 0), ('lbl0', 'c', 0)),
-                        (('lbl0', 'c', 0), ('lbl3', 'a', 0)),
-                        (('lbl2', 3, 0), ('lbl2', 'b', 0)),
-                        (('lbl2', 'b', 0), ('lbl3', 'a', 0))))],
-                     [(('b', ('lbl2', 'a', 0)), (('b', ('lbl2', 'a', 0)),))],
-                     [((('lbl0', 1, 0),
-                        ('lbl0', 'b', 0),
-                        ('lbl1', 2, 0),
-                        ('lbl1', 'b', 0),
-                        ('lbl2', 'a', 0)),
-                       ((('lbl0', 1, 0), ('lbl0', 'b', 0)),
-                        (('lbl0', 'b', 0), ('lbl1', 'b', 0)),
-                        (('lbl1', 2, 0), ('lbl1', 'b', 0)),
-                        (('lbl1', 'b', 0), ('lbl1', 'b', 0)),
-                        (('lbl1', 'b', 0), ('lbl2', 'a', 0)))),
-                      ((('lbl0', 1, 0),
-                        ('lbl0', 'b', 0),
-                        ('lbl1', 2, 0),
-                        ('lbl1', 'b', 0),
-                        ('lbl2', 'a', 0)),
-                       ((('lbl0', 1, 0), ('lbl0', 'b', 0)),
-                        (('lbl0', 'b', 0), ('lbl1', 'b', 0)),
-                        (('lbl1', 2, 0), ('lbl1', 'b', 0)),
-                        (('lbl1', 'b', 0), ('lbl2', 'a', 0))))],
-                     [((('lbl0', 1, 0), ('lbl0', 'b', 0), ('lbl1', 'a', 0)),
-                       ((('lbl0', 1, 0), ('lbl0', 'b', 0)),
-                        (('lbl0', 'b', 0), ('lbl1', 'a', 0))))],
-                     [((('lbl0', 1, 0),
-                        ('lbl0', 'c', 0),
-                        ('lbl1', 'a', 1),
-                        ('lbl1', 'b', 0),
-                        ('lbl2', 'd', 0)),
-                       ((('lbl0', 1, 0), ('lbl0', 'c', 0)),
-                        (('lbl0', 'c', 0), ('lbl1', 'b', 0)),
-                        (('lbl1', 'a', 1), ('lbl2', 'd', 0)),
-                        (('lbl1', 'b', 0), ('lbl1', 'a', 1))))],
-                     [(('d', ('lbl1', 'b', 0), ('lbl1', 'c', 1), ('lbl2', 'a', 0)),
-                       (('d', ('lbl1', 'c', 1)),
-                        (('lbl1', 'b', 0), ('lbl2', 'a', 0)),
-                        (('lbl1', 'c', 1), ('lbl1', 'b', 0)))),
-                      ((('lbl0', 1, 0), ('lbl0', 'c', 0), ('lbl1', 'b', 0), ('lbl2', 'a', 0)),
-                       ((('lbl0', 1, 0), ('lbl0', 'c', 0)),
-                        (('lbl0', 'c', 0), ('lbl1', 'b', 0)),
-                        (('lbl1', 'b', 0), ('lbl2', 'a', 0))))],
+flat_test_results = [[(((b'lbl0', 1, 0), (b'lbl0', 'c', 0), (b'lbl1', 'b', 0), (b'lbl2', 'a', 0)),
+                       (((b'lbl0', 1, 0), (b'lbl0', 'c', 0)),
+                        ((b'lbl0', 'c', 0), (b'lbl1', 'b', 0)),
+                        ((b'lbl1', 'b', 0), (b'lbl2', 'a', 0))))],
+                     [(((b'lbl0', 1, 0),
+                        (b'lbl0', 'c', 0),
+                        (b'lbl1', 2, 0),
+                        (b'lbl1', 'b', 0),
+                        (b'lbl2', 'a', 0)),
+                       (((b'lbl0', 1, 0), (b'lbl0', 'c', 0)),
+                        ((b'lbl0', 'c', 0), (b'lbl2', 'a', 0)),
+                        ((b'lbl1', 2, 0), (b'lbl1', 'b', 0)),
+                        ((b'lbl1', 'b', 0), (b'lbl2', 'a', 0))))],
+                     [(((b'lbl0', 1, 0),
+                        (b'lbl0', 'c', 0),
+                        (b'lbl1', 2, 0),
+                        (b'lbl1', 'b', 0),
+                        (b'lbl3', 'a', 0)),
+                       (((b'lbl0', 1, 0), (b'lbl0', 'c', 0)),
+                        ((b'lbl0', 'c', 0), (b'lbl3', 'a', 0)),
+                        ((b'lbl1', 2, 0), (b'lbl1', 'b', 0)),
+                        ((b'lbl1', 'b', 0), (b'lbl3', 'a', 0)))),
+                      (((b'lbl0', 1, 0),
+                        (b'lbl0', 'c', 0),
+                        (b'lbl2', 3, 0),
+                        (b'lbl2', 'b', 0),
+                        (b'lbl3', 'a', 0)),
+                       (((b'lbl0', 1, 0), (b'lbl0', 'c', 0)),
+                        ((b'lbl0', 'c', 0), (b'lbl3', 'a', 0)),
+                        ((b'lbl2', 3, 0), (b'lbl2', 'b', 0)),
+                        ((b'lbl2', 'b', 0), (b'lbl3', 'a', 0))))],
+                     [(('b', (b'lbl2', 'a', 0)), (('b', (b'lbl2', 'a', 0)),))],
+                     [(((b'lbl0', 1, 0),
+                        (b'lbl0', 'b', 0),
+                        (b'lbl1', 2, 0),
+                        (b'lbl1', 'b', 0),
+                        (b'lbl2', 'a', 0)),
+                       (((b'lbl0', 1, 0), (b'lbl0', 'b', 0)),
+                        ((b'lbl0', 'b', 0), (b'lbl1', 'b', 0)),
+                        ((b'lbl1', 2, 0), (b'lbl1', 'b', 0)),
+                        ((b'lbl1', 'b', 0), (b'lbl1', 'b', 0)),
+                        ((b'lbl1', 'b', 0), (b'lbl2', 'a', 0)))),
+                      (((b'lbl0', 1, 0),
+                        (b'lbl0', 'b', 0),
+                        (b'lbl1', 2, 0),
+                        (b'lbl1', 'b', 0),
+                        (b'lbl2', 'a', 0)),
+                       (((b'lbl0', 1, 0), (b'lbl0', 'b', 0)),
+                        ((b'lbl0', 'b', 0), (b'lbl1', 'b', 0)),
+                        ((b'lbl1', 2, 0), (b'lbl1', 'b', 0)),
+                        ((b'lbl1', 'b', 0), (b'lbl2', 'a', 0))))],
+                     [(((b'lbl0', 1, 0), (b'lbl0', 'b', 0), (b'lbl1', 'a', 0)),
+                       (((b'lbl0', 1, 0), (b'lbl0', 'b', 0)),
+                        ((b'lbl0', 'b', 0), (b'lbl1', 'a', 0))))],
+                     [(((b'lbl0', 1, 0),
+                        (b'lbl0', 'c', 0),
+                        (b'lbl1', 'a', 1),
+                        (b'lbl1', 'b', 0),
+                        (b'lbl2', 'd', 0)),
+                       (((b'lbl0', 1, 0), (b'lbl0', 'c', 0)),
+                        ((b'lbl0', 'c', 0), (b'lbl1', 'b', 0)),
+                        ((b'lbl1', 'a', 1), (b'lbl2', 'd', 0)),
+                        ((b'lbl1', 'b', 0), (b'lbl1', 'a', 1))))],
+                     [(('d', (b'lbl1', 'b', 0), (b'lbl1', 'c', 1), (b'lbl2', 'a', 0)),
+                       (('d', (b'lbl1', 'c', 1)),
+                        ((b'lbl1', 'b', 0), (b'lbl2', 'a', 0)),
+                        ((b'lbl1', 'c', 1), (b'lbl1', 'b', 0)))),
+                      (((b'lbl0', 1, 0), (b'lbl0', 'c', 0), (b'lbl1', 'b', 0), (b'lbl2', 'a', 0)),
+                       (((b'lbl0', 1, 0), (b'lbl0', 'c', 0)),
+                        ((b'lbl0', 'c', 0), (b'lbl1', 'b', 0)),
+                        ((b'lbl1', 'b', 0), (b'lbl2', 'a', 0))))],
                      [(('d',
-                        ('lbl0', 1, 0),
-                        ('lbl0', 'c', 0),
-                        ('lbl1', 'b', 0),
-                        ('lbl1', 'c', 1),
-                        ('lbl2', 'a', 0)),
-                       (('d', ('lbl1', 'c', 1)),
-                        (('lbl0', 1, 0), ('lbl0', 'c', 0)),
-                        (('lbl0', 'c', 0), ('lbl1', 'b', 0)),
-                        (('lbl1', 'b', 0), ('lbl2', 'a', 0)))),
-                      (('d', ('lbl1', 'b', 0), ('lbl1', 'c', 1), ('lbl2', 'a', 0)),
-                       (('d', ('lbl1', 'c', 1)),
-                        (('lbl1', 'b', 0), ('lbl2', 'a', 0)),
-                        (('lbl1', 'c', 1), ('lbl1', 'b', 0))))],
-                     [(('b', ('lbl1', 2, 0), ('lbl1', 'b', 0), ('lbl2', 'a', 0)),
-                       (('b', ('lbl1', 'b', 0)),
-                        (('lbl1', 2, 0), ('lbl1', 'b', 0)),
-                        (('lbl1', 'b', 0), ('lbl1', 'b', 0)),
-                        (('lbl1', 'b', 0), ('lbl2', 'a', 0)))),
-                      (('b', ('lbl1', 2, 0), ('lbl1', 'b', 0), ('lbl2', 'a', 0)),
-                       (('b', ('lbl1', 'b', 0)),
-                        (('lbl1', 2, 0), ('lbl1', 'b', 0)),
-                        (('lbl1', 'b', 0), ('lbl2', 'a', 0))))],
-                     [((('lbl0', 1, 0),
-                        ('lbl0', 2, 0),
-                        ('lbl0', 'a', 0),
-                        ('lbl0', 'b', 0),
-                        ('lbl1', 'a', 0),
-                        ('lbl1', 'b', 0),
-                        ('lbl2', 'a', 0)),
-                       ((('lbl0', 1, 0), ('lbl0', 'a', 0)),
-                        (('lbl0', 2, 0), ('lbl0', 'b', 0)),
-                        (('lbl0', 'a', 0), ('lbl1', 'b', 0)),
-                        (('lbl0', 'b', 0), ('lbl1', 'a', 0)),
-                        (('lbl1', 'a', 0), ('lbl2', 'a', 0)),
-                        (('lbl1', 'b', 0), ('lbl2', 'a', 0))))],
-                     [((('lbl0', 1, 0),
-                        ('lbl0', 'b', 0),
-                        ('lbl1', 2, 1),
-                        ('lbl1', 'a', 0),
-                        ('lbl1', 'b', 1),
-                        ('lbl2', 'b', 0)),
-                       ((('lbl0', 1, 0), ('lbl0', 'b', 0)),
-                        (('lbl0', 'b', 0), ('lbl1', 'b', 1)),
-                        (('lbl1', 2, 1), ('lbl1', 'b', 1)),
-                        (('lbl1', 'a', 0), ('lbl2', 'b', 0)),
-                        (('lbl1', 'b', 1), ('lbl1', 'a', 0)))),
-                      ((('lbl0', 1, 0),
-                        ('lbl0', 'b', 0),
-                        ('lbl1', 2, 1),
-                        ('lbl1', 'a', 0),
-                        ('lbl1', 'b', 1),
-                        ('lbl2', 'b', 0)),
-                       ((('lbl0', 1, 0), ('lbl0', 'b', 0)),
-                        (('lbl0', 'b', 0), ('lbl1', 'b', 1)),
-                        (('lbl1', 2, 1), ('lbl1', 'b', 1)),
-                        (('lbl1', 'a', 0), ('lbl2', 'b', 0)),
-                        (('lbl1', 'b', 1), ('lbl1', 'a', 0)),
-                        (('lbl1', 'b', 1), ('lbl1', 'b', 1)))),
-                      ((('lbl0', 1, 0), ('lbl0', 'b', 0), ('lbl1', 'a', 0), ('lbl2', 'b', 0)),
-                       ((('lbl0', 1, 0), ('lbl0', 'b', 0)),
-                        (('lbl0', 'b', 0), ('lbl1', 'a', 0)),
-                        (('lbl1', 'a', 0), ('lbl2', 'b', 0))))],
-                     [((('lbl0', 1, 0),
-                        ('lbl0', 'a', 0),
-                        ('lbl1', 'c', 0),
-                        ('lbl2', 3, 0),
-                        ('lbl2', 3, 1),
-                        ('lbl2', 'a', 1),
-                        ('lbl2', 'b', 0),
-                        ('lbl3', 'r', 0)),
-                       ((('lbl0', 1, 0), ('lbl0', 'a', 0)),
-                        (('lbl0', 'a', 0), ('lbl2', 'b', 0)),
-                        (('lbl1', 'c', 0), ('lbl3', 'r', 0)),
-                        (('lbl2', 3, 0), ('lbl2', 'b', 0)),
-                        (('lbl2', 3, 1), ('lbl2', 'a', 1)),
-                        (('lbl2', 'a', 1), ('lbl1', 'c', 0)),
-                        (('lbl2', 'a', 1), ('lbl2', 'b', 0)),
-                        (('lbl2', 'b', 0), ('lbl2', 'a', 1)))),
-                      ((('lbl0', 1, 0),
-                        ('lbl0', 'a', 0),
-                        ('lbl1', 'c', 0),
-                        ('lbl2', 3, 0),
-                        ('lbl2', 3, 1),
-                        ('lbl2', 'a', 1),
-                        ('lbl2', 'b', 0),
-                        ('lbl3', 'r', 0)),
-                       ((('lbl0', 1, 0), ('lbl0', 'a', 0)),
-                        (('lbl0', 'a', 0), ('lbl2', 'b', 0)),
-                        (('lbl1', 'c', 0), ('lbl3', 'r', 0)),
-                        (('lbl2', 3, 0), ('lbl2', 'b', 0)),
-                        (('lbl2', 3, 1), ('lbl2', 'a', 1)),
-                        (('lbl2', 'a', 1), ('lbl1', 'c', 0)),
-                        (('lbl2', 'b', 0), ('lbl2', 'a', 1)))),
-                      ((('lbl0', 1, 0), ('lbl0', 'a', 0), ('lbl1', 'c', 0), ('lbl3', 'r', 0)),
-                       ((('lbl0', 1, 0), ('lbl0', 'a', 0)),
-                        (('lbl0', 'a', 0), ('lbl1', 'c', 0)),
-                        (('lbl1', 'c', 0), ('lbl3', 'r', 0))))],
+                        (b'lbl0', 1, 0),
+                        (b'lbl0', 'c', 0),
+                        (b'lbl1', 'b', 0),
+                        (b'lbl1', 'c', 1),
+                        (b'lbl2', 'a', 0)),
+                       (('d', (b'lbl1', 'c', 1)),
+                        ((b'lbl0', 1, 0), (b'lbl0', 'c', 0)),
+                        ((b'lbl0', 'c', 0), (b'lbl1', 'b', 0)),
+                        ((b'lbl1', 'b', 0), (b'lbl2', 'a', 0)))),
+                      (('d', (b'lbl1', 'b', 0), (b'lbl1', 'c', 1), (b'lbl2', 'a', 0)),
+                       (('d', (b'lbl1', 'c', 1)),
+                        ((b'lbl1', 'b', 0), (b'lbl2', 'a', 0)),
+                        ((b'lbl1', 'c', 1), (b'lbl1', 'b', 0))))],
+                     [(('b', (b'lbl1', 2, 0), (b'lbl1', 'b', 0), (b'lbl2', 'a', 0)),
+                       (('b', (b'lbl1', 'b', 0)),
+                        ((b'lbl1', 2, 0), (b'lbl1', 'b', 0)),
+                        ((b'lbl1', 'b', 0), (b'lbl1', 'b', 0)),
+                        ((b'lbl1', 'b', 0), (b'lbl2', 'a', 0)))),
+                      (('b', (b'lbl1', 2, 0), (b'lbl1', 'b', 0), (b'lbl2', 'a', 0)),
+                       (('b', (b'lbl1', 'b', 0)),
+                        ((b'lbl1', 2, 0), (b'lbl1', 'b', 0)),
+                        ((b'lbl1', 'b', 0), (b'lbl2', 'a', 0))))],
+                     [(((b'lbl0', 1, 0),
+                        (b'lbl0', 2, 0),
+                        (b'lbl0', 'a', 0),
+                        (b'lbl0', 'b', 0),
+                        (b'lbl1', 'a', 0),
+                        (b'lbl1', 'b', 0),
+                        (b'lbl2', 'a', 0)),
+                       (((b'lbl0', 1, 0), (b'lbl0', 'a', 0)),
+                        ((b'lbl0', 2, 0), (b'lbl0', 'b', 0)),
+                        ((b'lbl0', 'a', 0), (b'lbl1', 'b', 0)),
+                        ((b'lbl0', 'b', 0), (b'lbl1', 'a', 0)),
+                        ((b'lbl1', 'a', 0), (b'lbl2', 'a', 0)),
+                        ((b'lbl1', 'b', 0), (b'lbl2', 'a', 0))))],
+                     [(((b'lbl0', 1, 0),
+                        (b'lbl0', 'b', 0),
+                        (b'lbl1', 2, 1),
+                        (b'lbl1', 'a', 0),
+                        (b'lbl1', 'b', 1),
+                        (b'lbl2', 'b', 0)),
+                       (((b'lbl0', 1, 0), (b'lbl0', 'b', 0)),
+                        ((b'lbl0', 'b', 0), (b'lbl1', 'b', 1)),
+                        ((b'lbl1', 2, 1), (b'lbl1', 'b', 1)),
+                        ((b'lbl1', 'a', 0), (b'lbl2', 'b', 0)),
+                        ((b'lbl1', 'b', 1), (b'lbl1', 'a', 0)))),
+                      (((b'lbl0', 1, 0),
+                        (b'lbl0', 'b', 0),
+                        (b'lbl1', 2, 1),
+                        (b'lbl1', 'a', 0),
+                        (b'lbl1', 'b', 1),
+                        (b'lbl2', 'b', 0)),
+                       (((b'lbl0', 1, 0), (b'lbl0', 'b', 0)),
+                        ((b'lbl0', 'b', 0), (b'lbl1', 'b', 1)),
+                        ((b'lbl1', 2, 1), (b'lbl1', 'b', 1)),
+                        ((b'lbl1', 'a', 0), (b'lbl2', 'b', 0)),
+                        ((b'lbl1', 'b', 1), (b'lbl1', 'a', 0)),
+                        ((b'lbl1', 'b', 1), (b'lbl1', 'b', 1)))),
+                      (((b'lbl0', 1, 0), (b'lbl0', 'b', 0), (b'lbl1', 'a', 0), (b'lbl2', 'b', 0)),
+                       (((b'lbl0', 1, 0), (b'lbl0', 'b', 0)),
+                        ((b'lbl0', 'b', 0), (b'lbl1', 'a', 0)),
+                        ((b'lbl1', 'a', 0), (b'lbl2', 'b', 0))))],
+                     [(((b'lbl0', 1, 0),
+                        (b'lbl0', 'a', 0),
+                        (b'lbl1', 'c', 0),
+                        (b'lbl2', 3, 0),
+                        (b'lbl2', 3, 1),
+                        (b'lbl2', 'a', 1),
+                        (b'lbl2', 'b', 0),
+                        (b'lbl3', 'r', 0)),
+                       (((b'lbl0', 1, 0), (b'lbl0', 'a', 0)),
+                        ((b'lbl0', 'a', 0), (b'lbl2', 'b', 0)),
+                        ((b'lbl1', 'c', 0), (b'lbl3', 'r', 0)),
+                        ((b'lbl2', 3, 0), (b'lbl2', 'b', 0)),
+                        ((b'lbl2', 3, 1), (b'lbl2', 'a', 1)),
+                        ((b'lbl2', 'a', 1), (b'lbl1', 'c', 0)),
+                        ((b'lbl2', 'a', 1), (b'lbl2', 'b', 0)),
+                        ((b'lbl2', 'b', 0), (b'lbl2', 'a', 1)))),
+                      (((b'lbl0', 1, 0),
+                        (b'lbl0', 'a', 0),
+                        (b'lbl1', 'c', 0),
+                        (b'lbl2', 3, 0),
+                        (b'lbl2', 3, 1),
+                        (b'lbl2', 'a', 1),
+                        (b'lbl2', 'b', 0),
+                        (b'lbl3', 'r', 0)),
+                       (((b'lbl0', 1, 0), (b'lbl0', 'a', 0)),
+                        ((b'lbl0', 'a', 0), (b'lbl2', 'b', 0)),
+                        ((b'lbl1', 'c', 0), (b'lbl3', 'r', 0)),
+                        ((b'lbl2', 3, 0), (b'lbl2', 'b', 0)),
+                        ((b'lbl2', 3, 1), (b'lbl2', 'a', 1)),
+                        ((b'lbl2', 'a', 1), (b'lbl1', 'c', 0)),
+                        ((b'lbl2', 'b', 0), (b'lbl2', 'a', 1)))),
+                      (((b'lbl0', 1, 0), (b'lbl0', 'a', 0), (b'lbl1', 'c', 0), (b'lbl3', 'r', 0)),
+                       (((b'lbl0', 1, 0), (b'lbl0', 'a', 0)),
+                        ((b'lbl0', 'a', 0), (b'lbl1', 'c', 0)),
+                        ((b'lbl1', 'c', 0), (b'lbl3', 'r', 0))))],
                      [(('d',
-                        ('lbl0', 1, 0),
-                        ('lbl0', 'a', 0),
-                        ('lbl1', 'b', 0),
-                        ('lbl3', 'r', 0)),
-                       (('d', ('lbl3', 'r', 0)),
-                        (('lbl0', 1, 0), ('lbl0', 'a', 0)),
-                        (('lbl0', 'a', 0), ('lbl1', 'b', 0)),
-                        (('lbl1', 'b', 0), ('lbl3', 'r', 0)))),
-                      ((('lbl0', 1, 0),
-                        ('lbl0', 'a', 0),
-                        ('lbl1', 'b', 0),
-                        ('lbl2', 1, 1),
-                        ('lbl2', 'a', 1),
-                        ('lbl2', 'd', 0),
-                        ('lbl3', 'r', 0)),
-                       ((('lbl0', 1, 0), ('lbl0', 'a', 0)),
-                        (('lbl0', 'a', 0), ('lbl2', 'd', 0)),
-                        (('lbl1', 'b', 0), ('lbl3', 'r', 0)),
-                        (('lbl2', 1, 1), ('lbl2', 'a', 1)),
-                        (('lbl2', 'a', 1), ('lbl1', 'b', 0)),
-                        (('lbl2', 'a', 1), ('lbl2', 'd', 0)),
-                        (('lbl2', 'd', 0), ('lbl2', 'a', 1)),
-                        (('lbl2', 'd', 0), ('lbl3', 'r', 0)))),
-                      ((('lbl0', 1, 0),
-                        ('lbl0', 'a', 0),
-                        ('lbl1', 'b', 0),
-                        ('lbl2', 1, 1),
-                        ('lbl2', 'a', 1),
-                        ('lbl2', 'd', 0),
-                        ('lbl3', 'r', 0)),
-                       ((('lbl0', 1, 0), ('lbl0', 'a', 0)),
-                        (('lbl0', 'a', 0), ('lbl2', 'd', 0)),
-                        (('lbl1', 'b', 0), ('lbl3', 'r', 0)),
-                        (('lbl2', 1, 1), ('lbl2', 'a', 1)),
-                        (('lbl2', 'a', 1), ('lbl1', 'b', 0)),
-                        (('lbl2', 'd', 0), ('lbl2', 'a', 1)),
-                        (('lbl2', 'd', 0), ('lbl3', 'r', 0))))],
+                        (b'lbl0', 1, 0),
+                        (b'lbl0', 'a', 0),
+                        (b'lbl1', 'b', 0),
+                        (b'lbl3', 'r', 0)),
+                       (('d', (b'lbl3', 'r', 0)),
+                        ((b'lbl0', 1, 0), (b'lbl0', 'a', 0)),
+                        ((b'lbl0', 'a', 0), (b'lbl1', 'b', 0)),
+                        ((b'lbl1', 'b', 0), (b'lbl3', 'r', 0)))),
+                      (((b'lbl0', 1, 0),
+                        (b'lbl0', 'a', 0),
+                        (b'lbl1', 'b', 0),
+                        (b'lbl2', 1, 1),
+                        (b'lbl2', 'a', 1),
+                        (b'lbl2', 'd', 0),
+                        (b'lbl3', 'r', 0)),
+                       (((b'lbl0', 1, 0), (b'lbl0', 'a', 0)),
+                        ((b'lbl0', 'a', 0), (b'lbl2', 'd', 0)),
+                        ((b'lbl1', 'b', 0), (b'lbl3', 'r', 0)),
+                        ((b'lbl2', 1, 1), (b'lbl2', 'a', 1)),
+                        ((b'lbl2', 'a', 1), (b'lbl1', 'b', 0)),
+                        ((b'lbl2', 'a', 1), (b'lbl2', 'd', 0)),
+                        ((b'lbl2', 'd', 0), (b'lbl2', 'a', 1)),
+                        ((b'lbl2', 'd', 0), (b'lbl3', 'r', 0)))),
+                      (((b'lbl0', 1, 0),
+                        (b'lbl0', 'a', 0),
+                        (b'lbl1', 'b', 0),
+                        (b'lbl2', 1, 1),
+                        (b'lbl2', 'a', 1),
+                        (b'lbl2', 'd', 0),
+                        (b'lbl3', 'r', 0)),
+                       (((b'lbl0', 1, 0), (b'lbl0', 'a', 0)),
+                        ((b'lbl0', 'a', 0), (b'lbl2', 'd', 0)),
+                        ((b'lbl1', 'b', 0), (b'lbl3', 'r', 0)),
+                        ((b'lbl2', 1, 1), (b'lbl2', 'a', 1)),
+                        ((b'lbl2', 'a', 1), (b'lbl1', 'b', 0)),
+                        ((b'lbl2', 'd', 0), (b'lbl2', 'a', 1)),
+                        ((b'lbl2', 'd', 0), (b'lbl3', 'r', 0))))],
                      [(('b',
-                        ('lbl0', 1, 0),
-                        ('lbl0', 'a', 0),
-                        ('lbl1', 'b', 2),
-                        ('lbl1', 'c', 1),
-                        ('lbl1', 'd', 0),
-                        ('lbl2', 'r', 0)),
-                       (('b', ('lbl1', 'd', 0)),
-                        (('lbl0', 1, 0), ('lbl0', 'a', 0)),
-                        (('lbl0', 'a', 0), ('lbl1', 'd', 0)),
-                        (('lbl1', 'b', 2), ('lbl1', 'd', 0)),
-                        (('lbl1', 'b', 2), ('lbl2', 'r', 0)),
-                        (('lbl1', 'c', 1), ('lbl1', 'b', 2)),
-                        (('lbl1', 'd', 0), ('lbl1', 'c', 1)))),
+                        (b'lbl0', 1, 0),
+                        (b'lbl0', 'a', 0),
+                        (b'lbl1', 'b', 2),
+                        (b'lbl1', 'c', 1),
+                        (b'lbl1', 'd', 0),
+                        (b'lbl2', 'r', 0)),
+                       (('b', (b'lbl1', 'd', 0)),
+                        ((b'lbl0', 1, 0), (b'lbl0', 'a', 0)),
+                        ((b'lbl0', 'a', 0), (b'lbl1', 'd', 0)),
+                        ((b'lbl1', 'b', 2), (b'lbl1', 'd', 0)),
+                        ((b'lbl1', 'b', 2), (b'lbl2', 'r', 0)),
+                        ((b'lbl1', 'c', 1), (b'lbl1', 'b', 2)),
+                        ((b'lbl1', 'd', 0), (b'lbl1', 'c', 1)))),
                       (('b',
-                        ('lbl0', 1, 0),
-                        ('lbl0', 'a', 0),
-                        ('lbl1', 'b', 2),
-                        ('lbl1', 'c', 1),
-                        ('lbl1', 'd', 0),
-                        ('lbl2', 'r', 0)),
-                       (('b', ('lbl1', 'd', 0)),
-                        (('lbl0', 1, 0), ('lbl0', 'a', 0)),
-                        (('lbl0', 'a', 0), ('lbl1', 'd', 0)),
-                        (('lbl1', 'b', 2), ('lbl2', 'r', 0)),
-                        (('lbl1', 'c', 1), ('lbl1', 'b', 2)),
-                        (('lbl1', 'd', 0), ('lbl1', 'c', 1))))],
-                     [((('lbl0', 1, 0), ('lbl0', 'a', 0), ('lbl5', 'r', 0)),
-                       ((('lbl0', 1, 0), ('lbl0', 'a', 0)),
-                        (('lbl0', 'a', 0), ('lbl5', 'r', 0))))],
-                     [((('lbl0', 2, 0),
-                        ('lbl0', 'd', 0),
-                        ('lbl1', 'a', 0),
-                        ('lbl1', 'b', 0),
-                        ('lbl2', 'a', 0)),
-                       ((('lbl0', 2, 0), ('lbl0', 'd', 0)),
-                        (('lbl0', 'd', 0), ('lbl1', 'a', 0)),
-                        (('lbl0', 'd', 0), ('lbl1', 'b', 0)),
-                        (('lbl1', 'a', 0), ('lbl2', 'a', 0)),
-                        (('lbl1', 'b', 0), ('lbl2', 'a', 0))))]]
+                        (b'lbl0', 1, 0),
+                        (b'lbl0', 'a', 0),
+                        (b'lbl1', 'b', 2),
+                        (b'lbl1', 'c', 1),
+                        (b'lbl1', 'd', 0),
+                        (b'lbl2', 'r', 0)),
+                       (('b', (b'lbl1', 'd', 0)),
+                        ((b'lbl0', 1, 0), (b'lbl0', 'a', 0)),
+                        ((b'lbl0', 'a', 0), (b'lbl1', 'd', 0)),
+                        ((b'lbl1', 'b', 2), (b'lbl2', 'r', 0)),
+                        ((b'lbl1', 'c', 1), (b'lbl1', 'b', 2)),
+                        ((b'lbl1', 'd', 0), (b'lbl1', 'c', 1))))],
+                     [(((b'lbl0', 1, 0), (b'lbl0', 'a', 0), (b'lbl5', 'r', 0)),
+                       (((b'lbl0', 1, 0), (b'lbl0', 'a', 0)),
+                        ((b'lbl0', 'a', 0), (b'lbl5', 'r', 0))))],
+                     [(((b'lbl0', 2, 0),
+                        (b'lbl0', 'd', 0),
+                        (b'lbl1', 'a', 0),
+                        (b'lbl1', 'b', 0),
+                        (b'lbl2', 'a', 0)),
+                       (((b'lbl0', 2, 0), (b'lbl0', 'd', 0)),
+                        ((b'lbl0', 'd', 0), (b'lbl1', 'a', 0)),
+                        ((b'lbl0', 'd', 0), (b'lbl1', 'b', 0)),
+                        ((b'lbl1', 'a', 0), (b'lbl2', 'a', 0)),
+                        ((b'lbl1', 'b', 0), (b'lbl2', 'a', 0))))]]
 
 test_results = [[unflatGraph(flat_result) for flat_result in flat_results]
                 for flat_results in flat_test_results]
@@ -1127,7 +1138,7 @@ for test_nb, test in enumerate([(G1_IRA, G1_INPUT),
                                 ]):
 
     # Extract test elements
-    print "[+] Test", test_nb + 1
+    print("[+] Test", test_nb + 1)
     ircfg, (depnodes, heads) = test
 
     open("graph_%02d.dot" % (test_nb + 1), "w").write(ircfg.dot())
@@ -1149,25 +1160,25 @@ for test_nb, test in enumerate([(G1_IRA, G1_INPUT),
         # if g_ind == 4:
         # TODO: Implicit specifications
         #    continue
-        print " - Class %s - %s" % (g_dep.__class__.__name__,
-                                    suffix_key_list[g_ind])
+        print(" - Class %s - %s" % (g_dep.__class__.__name__,
+                                    suffix_key_list[g_ind]))
         # Select the correct result key
         mode_suffix = suffix_key_list[g_ind]
         graph_test_key = "graph" + mode_suffix
 
         # Test public APIs
         results = g_dep.get_from_depnodes(depnodes, heads)
-        print "RESULTS"
+        print("RESULTS")
         all_results = set()
         all_flat = set()
         for i, result in enumerate(results):
             all_flat.add(flatGraph(result.graph))
-            all_results.add(unflatGraph(flatGraph(result.graph)))
+            all_results.add(flatGraph(result.graph))
             open("graph_test_%02d_%02d.dot" % (test_nb + 1, i),
                  "w").write(dg2graph(result.graph))
 
         if g_ind == 0:
-            all_flat = sorted(all_flat)
+            all_flat = sorted(all_flat, key=str)
             all_flats.append(all_flat)
         flat_depnodes = get_flat_init_depnodes(depnodes)
         if not match_results(all_results, test_results[test_nb], flat_depnodes):
@@ -1175,11 +1186,11 @@ for test_nb, test in enumerate([(G1_IRA, G1_INPUT),
         continue
 
 if FAILED:
-    print "FAILED :", len(FAILED)
+    print("FAILED :", len(FAILED))
     for test_num in sorted(FAILED):
-        print test_num,
+        print(test_num, end=' ')
 else:
-    print "SUCCESS"
+    print("SUCCESS")
 
 # Return an error status on error
 assert not FAILED
diff --git a/test/analysis/dg_check.py b/test/analysis/dg_check.py
index dd662079..a50855ef 100644
--- a/test/analysis/dg_check.py
+++ b/test/analysis/dg_check.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 from pdb import pm
 import sys
 import subprocess
@@ -12,9 +13,7 @@ expected = json.load(open(expected_file))
 result = json.loads(stdout)
 
 
-expected.sort()
-result.sort()
+assert len(expected) == len(result)
 
-print expected
-print result
-assert expected == result
+assert all(r in result for r in expected)
+assert all(r in expected for r in result)
diff --git a/test/analysis/dse.py b/test/analysis/dse.py
index 344b9108..82668ea8 100644
--- a/test/analysis/dse.py
+++ b/test/analysis/dse.py
@@ -1,6 +1,8 @@
 import sys
 from pdb import pm
 
+from future.utils import viewitems
+
 from elfesteem.strpatchwork import StrPatchwork
 from miasm2.core import parse_asm
 from miasm2.expression.expression import ExprCompose, ExprOp, ExprInt, ExprId
@@ -80,10 +82,10 @@ class DSETest(object):
         loc_db.set_location_offset(loc_db.get_name_location("main"), 0x0)
         output = StrPatchwork()
         patches = asm_resolve_final(mn_x86, blocks, loc_db)
-        for offset, raw in patches.items():
+        for offset, raw in viewitems(patches):
             output[offset] = raw
 
-        self.assembly = str(output)
+        self.assembly = bytes(output)
 
     def check(self):
         regs = self.dse.ir_arch.arch.regs
diff --git a/test/analysis/modularintervals.py b/test/analysis/modularintervals.py
index 45aa82bd..cf286e3a 100644
--- a/test/analysis/modularintervals.py
+++ b/test/analysis/modularintervals.py
@@ -1,3 +1,4 @@
+from builtins import range
 from random import shuffle, seed
 
 from miasm2.core.interval import interval
@@ -11,10 +12,10 @@ def gen_all_intervals(size):
     -> 2**(2**size) (number of partition)
     """
     nb_elements = 1 << size
-    for bvec in xrange(1 << nb_elements):
+    for bvec in range(1 << nb_elements):
         # Bit vector: if bit i is on, i is in the interval
         to_ret = interval()
-        for i in xrange(nb_elements):
+        for i in range(nb_elements):
             if bvec & i == i:
                 to_ret += [(i, i)]
         yield to_ret
@@ -22,12 +23,12 @@ def gen_all_intervals(size):
 def interval_elements(interv):
     """Generator on element of an interval"""
     for sub_range in interv:
-        for i in xrange(sub_range[0], sub_range[1] + 1):
+        for i in range(sub_range[0], sub_range[1] + 1):
             yield i
 
 size = 4
 left, right = list(gen_all_intervals(size)), list(gen_all_intervals(size))
-right_int = range(1 << size)
+right_int = list(range(1 << size))
 mask = (1 << size) - 1
 
 def test(left, right):
diff --git a/test/analysis/range.py b/test/analysis/range.py
index 0e38ec95..946d0116 100644
--- a/test/analysis/range.py
+++ b/test/analysis/range.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 from miasm2.expression.expression import *
 from miasm2.analysis.expression_range import expr_range
 from miasm2.ir.translators import Translator
@@ -81,7 +82,7 @@ for expr in [
 
 ]:
     computed_range = expr_range(expr)
-    print expr, computed_range
+    print(expr, computed_range)
 
     # Trivia checks
     assert all(x[1] < (1 << expr.size) for x in computed_range)
diff --git a/test/analysis/unssa.py b/test/analysis/unssa.py
index a796f3b6..42e56246 100644
--- a/test/analysis/unssa.py
+++ b/test/analysis/unssa.py
@@ -1,4 +1,6 @@
 """ Test cases for dead code elimination"""
+from future.utils import viewvalues
+
 from miasm2.expression.expression import ExprId, ExprInt, ExprAssign, ExprMem, \
     ExprCond, ExprLoc
 from miasm2.core.locationdb import LocationDB
@@ -568,7 +570,7 @@ class IRAOutRegs(IRATest):
                     continue
                 if reg in regs_todo:
                     out[reg] = dst
-        return set(out.values())
+        return set(viewvalues(out))
 
 
 
@@ -623,7 +625,7 @@ for test_nb, ircfg in enumerate(
 
     # Save a copy of ircfg
     ircfg_orig = IRCFG(IRDst, loc_db)
-    for irblock in ircfg.blocks.values():
+    for irblock in viewvalues(ircfg.blocks):
         ircfg_orig.add_irblock(irblock)
 
     # SSA
diff --git a/test/arch/aarch64/arch.py b/test/arch/aarch64/arch.py
index d2f5114e..948ee489 100644
--- a/test/arch/aarch64/arch.py
+++ b/test/arch/aarch64/arch.py
@@ -1,6 +1,8 @@
+from __future__ import print_function
 import sys
 import time
 from pdb import pm
+from miasm2.core.utils import decode_hex
 from miasm2.arch.aarch64.arch import *
 from miasm2.core.locationdb import LocationDB
 
@@ -1824,25 +1826,25 @@ reg_tests_aarch64 = [
 
 
 def h2i(s):
-    return s.replace(' ', '').decode('hex')
+    return decode_hex(s.replace(' ', ''))
 
 
 ts = time.time()
 
 for s, l in reg_tests_aarch64[:]:
-    print "-" * 80
-    print s[:12], l
+    print("-" * 80)
+    print(s[:12], l)
     s = s[12:]
     b = h2i((l))
     mn = mn_aarch64.dis(b, 'l')
-    print [str(x) for x in mn.args]
-    print s
-    print mn
+    print([str(x) for x in mn.args])
+    print(s)
+    print(mn)
     assert(str(mn) == s)
     l = mn_aarch64.fromstring(s, loc_db, 'l')
     assert(str(l) == s)
     a = mn_aarch64.asm(l)
-    print [x for x in a]
-    print repr(b)
+    print([x for x in a])
+    print(repr(b))
     assert(b in a)
 
diff --git a/test/arch/aarch64/unit/asm_test.py b/test/arch/aarch64/unit/asm_test.py
index 677d474f..e49a2a62 100644
--- a/test/arch/aarch64/unit/asm_test.py
+++ b/test/arch/aarch64/unit/asm_test.py
@@ -1,6 +1,8 @@
 import sys
 import os
 
+from future.utils import viewitems
+
 from miasm2.arch.aarch64.arch import mn_aarch64, base_expr, variable
 from miasm2.core import parse_asm
 from miasm2.expression.expression import *
@@ -28,10 +30,10 @@ class Asm_Test(object):
         loc_db.set_location_offset(loc_db.get_name_location("main"), 0x0)
         s = StrPatchwork()
         patches = asmblock.asm_resolve_final(mn_aarch64, blocks, loc_db)
-        for offset, raw in patches.items():
+        for offset, raw in viewitems(patches):
             s[offset] = raw
 
-        self.assembly = str(s)
+        self.assembly = bytes(s)
 
     def run(self):
         run_addr = 0
diff --git a/test/arch/arm/arch.py b/test/arch/arm/arch.py
index f86c3cfb..bf2b1a02 100644
--- a/test/arch/arm/arch.py
+++ b/test/arch/arm/arch.py
@@ -1,4 +1,7 @@
+from __future__ import print_function
 import time
+
+from miasm2.core.utils import decode_hex, encode_hex
 from miasm2.arch.arm.arch import *
 from miasm2.core.locationdb import LocationDB
 from pdb import pm
@@ -7,7 +10,7 @@ from pdb import pm
 loc_db = LocationDB()
 
 def h2i(s):
-    return s.replace(' ', '').decode('hex')
+    return decode_hex(s.replace(' ', ''))
 
 
 def u16swap(i):
@@ -225,19 +228,19 @@ reg_tests_arm = [
 ts = time.time()
 
 for s, l in reg_tests_arm:
-    print "-" * 80
+    print("-" * 80)
     s = s[12:]
     b = h2i((l))
     mn = mn_arm.dis(b, 'l')
-    print [str(x) for x in mn.args]
-    print s
-    print mn
+    print([str(x) for x in mn.args])
+    print(s)
+    print(mn)
     assert(str(mn) == s)
     l = mn_arm.fromstring(s, loc_db, 'l')
     assert(str(l) == s)
     a = mn_arm.asm(l)
-    print [x for x in a]
-    print repr(b)
+    print([x for x in a])
+    print(repr(b))
     assert(b in a)
 
 reg_tests_armt = [
@@ -692,30 +695,30 @@ reg_tests_armt = [
 
 
 ]
-print "#" * 40, 'armthumb', '#' * 40
+print("#" * 40, 'armthumb', '#' * 40)
 
 for s, l in reg_tests_armt:
-    print "-" * 80
+    print("-" * 80)
     s = s[12:]
     b = h2i((l))
-    print b.encode('hex')
+    print(encode_hex(b))
     mn = mn_armt.dis(b, 'l')
-    print [str(x) for x in mn.args]
-    print s
-    print mn
+    print([str(x) for x in mn.args])
+    print(s)
+    print(mn)
     assert(str(mn) == s)
     l = mn_armt.fromstring(s, loc_db, 'l')
     assert(str(l) == s)
-    print 'Asm..', l
+    print('Asm..', l)
     a = mn_armt.asm(l)
-    print [x for x in a]
-    print repr(b)
+    print([x for x in a])
+    print(repr(b))
     assert(b in a)
 
-print 'TEST time', time.time() - ts
+print('TEST time', time.time() - ts)
 
 # speed test arm
-o = ""
+o = b""
 for s, l in reg_tests_arm:
     s = s[12:]
     b = h2i((l))
@@ -731,11 +734,11 @@ while off < bs.getlen():
     mn = mn_arm.dis(bs, 'l', off)
     instr_num += 1
     off += 4
-print 'instr per sec:', instr_num / (time.time() - ts)
+print('instr per sec:', instr_num // (time.time() - ts))
 
 
 # speed test thumb
-o = ""
+o = b""
 for s, l in reg_tests_armt:
     s = s[12:]
     b = h2i((l))
@@ -751,7 +754,7 @@ while off < bs.getlen():
     mn = mn_armt.dis(bs, 'l', off)
     instr_num += 1
     off += mn.l
-print 'instr per sec:', instr_num / (time.time() - ts)
+print('instr per sec:', instr_num // (time.time() - ts))
 
 import cProfile
 cProfile.run(r'mn_arm.dis("\xe1\xa0\xa0\x06", "l")')
diff --git a/test/arch/arm/sem.py b/test/arch/arm/sem.py
index d94b7ded..9c19431b 100755
--- a/test/arch/arm/sem.py
+++ b/test/arch/arm/sem.py
@@ -1,9 +1,12 @@
 #! /usr/bin/env python2
 #-*- coding:utf-8 -*-
 
+from __future__ import print_function
 import unittest
 import logging
 
+from future.utils import viewitems
+
 from miasm2.ir.symbexec import SymbolicExecutionEngine
 from miasm2.arch.arm.arch import mn_arm as mn
 from miasm2.arch.arm.sem import ir_arml as ir_arch
@@ -23,7 +26,7 @@ def M(addr):
 def compute(asm, inputstate={}, debug=False):
     loc_db = LocationDB()
     sympool = dict(regs_init)
-    sympool.update({k: ExprInt(v, k.size) for k, v in inputstate.iteritems()})
+    sympool.update({k: ExprInt(v, k.size) for k, v in viewitems(inputstate)})
     ir_tmp = ir_arch(loc_db)
     ircfg = ir_tmp.new_ircfg()
     symexec = SymbolicExecutionEngine(ir_tmp, sympool)
@@ -34,17 +37,17 @@ def compute(asm, inputstate={}, debug=False):
     lbl = ir_tmp.add_instr_to_ircfg(instr, ircfg)
     symexec.run_at(ircfg, lbl)
     if debug:
-        for k, v in symexec.symbols.items():
+        for k, v in viewitems(symexec.symbols):
             if regs_init.get(k, None) != v:
-                print k, v
+                print(k, v)
     out = {}
-    for k, v in symexec.symbols.items():
+    for k, v in viewitems(symexec.symbols):
         if k in EXCLUDE_REGS:
             continue
         elif regs_init.get(k, None) == v:
             continue
         elif isinstance(v, ExprInt):
-            out[k] = long(v)
+            out[k] = int(v)
         else:
             out[k] = v
     return out
@@ -58,210 +61,210 @@ class TestARMSemantic(unittest.TestCase):
     def test_shift(self):
         # §A8.4:                   Shifts applied to a register
         self.assertEqual(
-            compute('MOV R4, R4       ', {R4: 0xDEADBEEFL, }), {R4: 0xDEADBEEFL, })
+            compute('MOV R4, R4       ', {R4: 0xDEADBEEF, }), {R4: 0xDEADBEEF, })
         self.assertRaises(ValueError, compute, 'MOV R4, R4 LSL  0')
         self.assertEqual(
-            compute('MOV R4, R4 LSL  1', {R4: 0xDEADBEEFL, }), {R4: 0xBD5B7DDEL, })
+            compute('MOV R4, R4 LSL  1', {R4: 0xDEADBEEF, }), {R4: 0xBD5B7DDE, })
         self.assertEqual(
-            compute('MOV R4, R4 LSL 16', {R4: 0xDEADBEEFL, }), {R4: 0xBEEF0000L, })
+            compute('MOV R4, R4 LSL 16', {R4: 0xDEADBEEF, }), {R4: 0xBEEF0000, })
         self.assertEqual(
-            compute('MOV R4, R4 LSL 31', {R4: 0xDEADBEEFL, }), {R4: 0x80000000L, })
+            compute('MOV R4, R4 LSL 31', {R4: 0xDEADBEEF, }), {R4: 0x80000000, })
         self.assertRaises(ValueError, compute, 'MOV R4, R4 LSL 32')
         self.assertEqual(
-            compute('MOV R4, R4 LSL R5', {R4: 0xDEADBEEFL, R5: 0xBADBAD01L, }), {R4: 0xBD5B7DDEL, R5: 0xBADBAD01L, })
+            compute('MOV R4, R4 LSL R5', {R4: 0xDEADBEEF, R5: 0xBADBAD01, }), {R4: 0xBD5B7DDE, R5: 0xBADBAD01, })
         self.assertRaises(ValueError, compute, 'MOV R4, R4 LSR  0')
         self.assertEqual(
-            compute('MOV R4, R4 LSR  1', {R4: 0xDEADBEEFL, }), {R4: 0x6F56DF77L, })
+            compute('MOV R4, R4 LSR  1', {R4: 0xDEADBEEF, }), {R4: 0x6F56DF77, })
         self.assertEqual(
-            compute('MOV R4, R4 LSR 16', {R4: 0xDEADBEEFL, }), {R4: 0x0000DEADL, })
+            compute('MOV R4, R4 LSR 16', {R4: 0xDEADBEEF, }), {R4: 0x0000DEAD, })
         self.assertEqual(
-            compute('MOV R4, R4 LSR 31', {R4: 0xDEADBEEFL, }), {R4: 0x00000001L, })
+            compute('MOV R4, R4 LSR 31', {R4: 0xDEADBEEF, }), {R4: 0x00000001, })
         self.assertEqual(
-            compute('MOV R4, R4 LSR 32', {R4: 0xDEADBEEFL, }), {R4: 0xDEADBEEFL, })
+            compute('MOV R4, R4 LSR 32', {R4: 0xDEADBEEF, }), {R4: 0xDEADBEEF, })
         self.assertRaises(ValueError, compute, 'MOV R4, R4 LSR 33')
         self.assertEqual(
-            compute('MOV R4, R4 LSR R5', {R4: 0xDEADBEEFL, R5: 0xBADBAD01L, }), {R4: 0x6F56DF77L, R5: 0xBADBAD01L, })
+            compute('MOV R4, R4 LSR R5', {R4: 0xDEADBEEF, R5: 0xBADBAD01, }), {R4: 0x6F56DF77, R5: 0xBADBAD01, })
         self.assertRaises(ValueError, compute, 'MOV R4, R4 ASR  0')
         self.assertEqual(
-            compute('MOV R4, R4 ASR  1', {R4: 0xDEADBEEFL, }), {R4: 0xEF56DF77L, })
+            compute('MOV R4, R4 ASR  1', {R4: 0xDEADBEEF, }), {R4: 0xEF56DF77, })
         self.assertEqual(
-            compute('MOV R4, R4 ASR 16', {R4: 0xDEADBEEFL, }), {R4: 0xFFFFDEADL, })
+            compute('MOV R4, R4 ASR 16', {R4: 0xDEADBEEF, }), {R4: 0xFFFFDEAD, })
         self.assertEqual(
-            compute('MOV R4, R4 ASR 31', {R4: 0xDEADBEEFL, }), {R4: 0xFFFFFFFFL, })
+            compute('MOV R4, R4 ASR 31', {R4: 0xDEADBEEF, }), {R4: 0xFFFFFFFF, })
         self.assertEqual(
-            compute('MOV R4, R4 ASR 32', {R4: 0xDEADBEEFL, }), {R4: 0xDEADBEEFL, })
+            compute('MOV R4, R4 ASR 32', {R4: 0xDEADBEEF, }), {R4: 0xDEADBEEF, })
         self.assertRaises(ValueError, compute, 'MOV R4, R4 ASR 33')
         self.assertEqual(
-            compute('MOV R4, R4 ASR R5', {R4: 0xDEADBEEFL, R5: 0xBADBAD01L, }), {R4: 0xEF56DF77L, R5: 0xBADBAD01L, })
+            compute('MOV R4, R4 ASR R5', {R4: 0xDEADBEEF, R5: 0xBADBAD01, }), {R4: 0xEF56DF77, R5: 0xBADBAD01, })
         self.assertRaises(ValueError, compute, 'MOV R4, R4 ROR  0')
         self.assertEqual(
-            compute('MOV R4, R4 ROR  1', {R4: 0xDEADBEEFL, }), {R4: 0xEF56DF77L, })
+            compute('MOV R4, R4 ROR  1', {R4: 0xDEADBEEF, }), {R4: 0xEF56DF77, })
         self.assertEqual(
-            compute('MOV R4, R4 ROR 16', {R4: 0xDEADBEEFL, }), {R4: 0xBEEFDEADL, })
+            compute('MOV R4, R4 ROR 16', {R4: 0xDEADBEEF, }), {R4: 0xBEEFDEAD, })
         self.assertEqual(
-            compute('MOV R4, R4 ROR 31', {R4: 0xDEADBEEFL, }), {R4: 0xBD5B7DDFL, })
+            compute('MOV R4, R4 ROR 31', {R4: 0xDEADBEEF, }), {R4: 0xBD5B7DDF, })
         self.assertRaises(ValueError, compute, 'MOV R4, R4 ROR 32')
         self.assertEqual(
-            compute('MOV R4, R4 ROR R5', {R4: 0xDEADBEEFL, R5: 0xBADBAD01L, }), {R4: 0xEF56DF77L, R5: 0xBADBAD01L, })
-        self.assertEqual(compute('MOV R4, R4 RRX   ', {cf: 0L, R4: 0xDEADBEEFL, }), {
-                         cf: 0L, R4: 0x6F56DF77L, })
-        self.assertEqual(compute('MOV R4, R4 RRX   ', {cf: 1L, R4: 0xDEADBEEFL, }), {
-                         cf: 1L, R4: 0xEF56DF77L, })
+            compute('MOV R4, R4 ROR R5', {R4: 0xDEADBEEF, R5: 0xBADBAD01, }), {R4: 0xEF56DF77, R5: 0xBADBAD01, })
+        self.assertEqual(compute('MOV R4, R4 RRX   ', {cf: 0, R4: 0xDEADBEEF, }), {
+                         cf: 0, R4: 0x6F56DF77, })
+        self.assertEqual(compute('MOV R4, R4 RRX   ', {cf: 1, R4: 0xDEADBEEF, }), {
+                         cf: 1, R4: 0xEF56DF77, })
 
     def test_ADC(self):
         # §A8.8.1:                 ADC{S}{<c>}{<q>} {<Rd>,} <Rn>, #<const>
         self.assertRaises(
             ValueError, compute, 'ADC          R4,   0x00000001 ')
         self.assertEqual(compute('ADC                R4,    R4,   0x00000001 ',   {
-                                 cf: 0L, R4: 0x00000000L, }), {cf: 0L,     R4: 0x00000001L, })
+                                 cf: 0, R4: 0x00000000, }), {cf: 0,     R4: 0x00000001, })
         self.assertEqual(compute('ADC                R4,    R4,   0x00000000 ',   {
-                                 cf: 1L, R4: 0x00000000L, }), {cf: 1L,     R4: 0x00000001L, })
+                                 cf: 1, R4: 0x00000000, }), {cf: 1,     R4: 0x00000001, })
         self.assertEqual(compute('ADC                PC,    R4,   0x00000001 ',   {
-                                 cf: 0L, R4: 0xFFFFFFFFL, PC: 0x55555555L, }), {cf: 0L,     R4: 0xFFFFFFFFL, PC: 0x00000000L, })
+                                 cf: 0, R4: 0xFFFFFFFF, PC: 0x55555555, }), {cf: 0,     R4: 0xFFFFFFFF, PC: 0x00000000, })
         self.assertEqual(compute('ADC                PC,    R4,   0x00000000 ',   {
-                                 cf: 1L, R4: 0xFFFFFFFFL, PC: 0x55555555L, }), {cf: 1L,     R4: 0xFFFFFFFFL, PC: 0x00000000L, })
-        self.assertEqual(compute('ADCS               R4,    R4,   0x80000000 ',   {cf: 0L, R4: 0x80000000L, }), {
-                         nf: 0L, zf: 1L, cf: 1L, of: 1L, R4: 0x00000000L, })
-        self.assertEqual(compute('ADCS               R4,    R4,   0xFF000000 ',   {cf: 1L, R4: 0x00FFFFFEL, }), {
-                         nf: 1L, zf: 0L, cf: 0L, of: 0L, R4: 0xFFFFFFFFL, })
+                                 cf: 1, R4: 0xFFFFFFFF, PC: 0x55555555, }), {cf: 1,     R4: 0xFFFFFFFF, PC: 0x00000000, })
+        self.assertEqual(compute('ADCS               R4,    R4,   0x80000000 ',   {cf: 0, R4: 0x80000000, }), {
+                         nf: 0, zf: 1, cf: 1, of: 1, R4: 0x00000000, })
+        self.assertEqual(compute('ADCS               R4,    R4,   0xFF000000 ',   {cf: 1, R4: 0x00FFFFFE, }), {
+                         nf: 1, zf: 0, cf: 0, of: 0, R4: 0xFFFFFFFF, })
         self.assertEqual(compute('ADCS               PC,    R4,   0x00000000 ',   {
-                                 cf: 0L, R4: 0x00000000L, PC: 0x55555555L, }), {cf: 0L,     R4: 0x00000000L, PC: 0x00000000L, })
+                                 cf: 0, R4: 0x00000000, PC: 0x55555555, }), {cf: 0,     R4: 0x00000000, PC: 0x00000000, })
         self.assertEqual(compute('ADCS               PC,    R4,   0xFF000000 ',   {
-                                 cf: 1L, R4: 0x01000000L, PC: 0x55555555L, }), {cf: 1L,     R4: 0x01000000L, PC: 0x00000001L, })
+                                 cf: 1, R4: 0x01000000, PC: 0x55555555, }), {cf: 1,     R4: 0x01000000, PC: 0x00000001, })
 
         # §A8.8.2:                 ADC{S}{<c>}{<q>} {<Rd>,} <Rn>, <Rm> {,<shift>}
         self.assertRaises(
             ValueError, compute, 'ADC          R4,   R5          ')
         self.assertEqual(compute('ADC                R4,    R4,   R5          ',  {
-                                 cf: 1L, R4: 0xFFFFFFFFL, R5: 0x00000000L, }), {cf: 1L,     R4: 0x00000000L, R5: 0x00000000L, })
+                                 cf: 1, R4: 0xFFFFFFFF, R5: 0x00000000, }), {cf: 1,     R4: 0x00000000, R5: 0x00000000, })
         self.assertEqual(compute('ADC                R4,    R4,   R5    LSL 1 ',  {
-                                 cf: 0L, R4: 0x00000001L, R5: 0x00000008L, }), {cf: 0L,     R4: 0x00000011L, R5: 0x00000008L, })
+                                 cf: 0, R4: 0x00000001, R5: 0x00000008, }), {cf: 0,     R4: 0x00000011, R5: 0x00000008, })
         self.assertEqual(compute('ADC                R4,    R4,   R5    LSR 2 ',  {
-                                 cf: 1L, R4: 0x00000000L, R5: 0x80000041L, }), {cf: 1L,     R4: 0x20000011L, R5: 0x80000041L, })
+                                 cf: 1, R4: 0x00000000, R5: 0x80000041, }), {cf: 1,     R4: 0x20000011, R5: 0x80000041, })
         self.assertEqual(compute('ADC                R4,    R4,   R5    ASR 3 ',  {
-                                 cf: 0L, R4: 0x00000001L, R5: 0x80000081L, }), {cf: 0L,     R4: 0xF0000011L, R5: 0x80000081L, })
+                                 cf: 0, R4: 0x00000001, R5: 0x80000081, }), {cf: 0,     R4: 0xF0000011, R5: 0x80000081, })
         self.assertEqual(compute('ADC                R4,    R4,   R5    ROR 4 ',  {
-                                 cf: 1L, R4: 0xFFFFFFFFL, R5: 0x0000010FL, }), {cf: 1L,     R4: 0xF0000010L, R5: 0x0000010FL, })
+                                 cf: 1, R4: 0xFFFFFFFF, R5: 0x0000010F, }), {cf: 1,     R4: 0xF0000010, R5: 0x0000010F, })
         self.assertEqual(compute('ADC                R4,    R4,   R5    RRX   ',  {
-                                 cf: 1L, R4: 0xFFFFFFFFL, R5: 0x00000101L, }), {cf: 1L,     R4: 0x80000080L, R5: 0x00000101L, })
-        self.assertEqual(compute('ADCS               R4,    R4,   R5          ',  {cf: 1L, R4: 0xFFFFFFFFL, R5: 0x00000000L, }), {
-                         nf: 0L, zf: 1L, cf: 1L, of: 0L, R4: 0x00000000L, R5: 0x00000000L, })
-        self.assertEqual(compute('ADCS               R4,    R4,   R5    LSL 1 ',  {cf: 0L, R4: 0x00000001L, R5: 0x00000008L, }), {
-                         nf: 0L, zf: 0L, cf: 0L, of: 0L, R4: 0x00000011L, R5: 0x00000008L, })
-        self.assertEqual(compute('ADCS               R4,    R4,   R5    LSR 2 ',  {cf: 1L, R4: 0x00000000L, R5: 0x80000041L, }), {
-                         nf: 0L, zf: 0L, cf: 0L, of: 0L, R4: 0x20000011L, R5: 0x80000041L, })
-        self.assertEqual(compute('ADCS               R4,    R4,   R5    ASR 3 ',  {cf: 0L, R4: 0x00000001L, R5: 0x80000081L, }), {
-                         nf: 1L, zf: 0L, cf: 0L, of: 0L, R4: 0xF0000011L, R5: 0x80000081L, })
-        self.assertEqual(compute('ADCS               R4,    R4,   R5    ROR 4 ',  {cf: 1L, R4: 0xFFFFFFFFL, R5: 0x0000010FL, }), {
-                         nf: 1L, zf: 0L, cf: 1L, of: 0L, R4: 0xF0000010L, R5: 0x0000010FL, })
-        self.assertEqual(compute('ADCS               R4,    R4,   R5    RRX   ',  {cf: 1L, R4: 0xFFFFFFFFL, R5: 0x00000101L, }), {
-                         nf: 1L, zf: 0L, cf: 1L, of: 0L, R4: 0x80000080L, R5: 0x00000101L, })
+                                 cf: 1, R4: 0xFFFFFFFF, R5: 0x00000101, }), {cf: 1,     R4: 0x80000080, R5: 0x00000101, })
+        self.assertEqual(compute('ADCS               R4,    R4,   R5          ',  {cf: 1, R4: 0xFFFFFFFF, R5: 0x00000000, }), {
+                         nf: 0, zf: 1, cf: 1, of: 0, R4: 0x00000000, R5: 0x00000000, })
+        self.assertEqual(compute('ADCS               R4,    R4,   R5    LSL 1 ',  {cf: 0, R4: 0x00000001, R5: 0x00000008, }), {
+                         nf: 0, zf: 0, cf: 0, of: 0, R4: 0x00000011, R5: 0x00000008, })
+        self.assertEqual(compute('ADCS               R4,    R4,   R5    LSR 2 ',  {cf: 1, R4: 0x00000000, R5: 0x80000041, }), {
+                         nf: 0, zf: 0, cf: 0, of: 0, R4: 0x20000011, R5: 0x80000041, })
+        self.assertEqual(compute('ADCS               R4,    R4,   R5    ASR 3 ',  {cf: 0, R4: 0x00000001, R5: 0x80000081, }), {
+                         nf: 1, zf: 0, cf: 0, of: 0, R4: 0xF0000011, R5: 0x80000081, })
+        self.assertEqual(compute('ADCS               R4,    R4,   R5    ROR 4 ',  {cf: 1, R4: 0xFFFFFFFF, R5: 0x0000010F, }), {
+                         nf: 1, zf: 0, cf: 1, of: 0, R4: 0xF0000010, R5: 0x0000010F, })
+        self.assertEqual(compute('ADCS               R4,    R4,   R5    RRX   ',  {cf: 1, R4: 0xFFFFFFFF, R5: 0x00000101, }), {
+                         nf: 1, zf: 0, cf: 1, of: 0, R4: 0x80000080, R5: 0x00000101, })
 
         # §A8.8.3:                 ADC{S}{<c>}{<q>} {<Rd>,} <Rn>, <Rm>, <type> <Rs>
         self.assertEqual(compute('ADC                R4,    R6,   R4    LSL R5',  {
-                                 cf: 0L, R4: 0x00000001L, R5: 0x00000004L, R6: 0L, }), {cf: 0L,     R4: 0x00000010L, R5: 0x00000004L, R6: 0L, })
+                                 cf: 0, R4: 0x00000001, R5: 0x00000004, R6: 0, }), {cf: 0,     R4: 0x00000010, R5: 0x00000004, R6: 0, })
         self.assertEqual(compute('ADC                R4,    R6,   R4    LSR R5',  {
-                                 cf: 1L, R4: 0x00000110L, R5: 0x80000004L, R6: 0L, }), {cf: 1L,     R4: 0x00000012L, R5: 0x80000004L, R6: 0L, })
+                                 cf: 1, R4: 0x00000110, R5: 0x80000004, R6: 0, }), {cf: 1,     R4: 0x00000012, R5: 0x80000004, R6: 0, })
         self.assertEqual(compute('ADC                R4,    R6,   R4    ASR R5',  {
-                                 cf: 0L, R4: 0x80000010L, R5: 0xF0000001L, R6: 0L, }), {cf: 0L,     R4: 0xC0000008L, R5: 0xF0000001L, R6: 0L, })
+                                 cf: 0, R4: 0x80000010, R5: 0xF0000001, R6: 0, }), {cf: 0,     R4: 0xC0000008, R5: 0xF0000001, R6: 0, })
         self.assertEqual(compute('ADC                R4,    R6,   R4    ROR R5',  {
-                                 cf: 1L, R4: 0x000000FFL, R5: 0x00000F04L, R6: 0L, }), {cf: 1L,     R4: 0xF0000010L, R5: 0x00000F04L, R6: 0L, })
-        self.assertEqual(compute('ADCS               R4,    R6,   R4    LSL R5',  {cf: 0L, R4: 0x00000001L, R5: 0x00000004L, R6: 0L, }), {
-                         nf: 0L, zf: 0L, cf: 0L, of: 0L, R4: 0x00000010L, R5: 0x00000004L, R6: 0L, })
-        self.assertEqual(compute('ADCS               R4,    R6,   R4    LSR R5',  {cf: 1L, R4: 0x00000110L, R5: 0x80000004L, R6: 0L, }), {
-                         nf: 0L, zf: 0L, cf: 0L, of: 0L, R4: 0x00000012L, R5: 0x80000004L, R6: 0L, })
-        self.assertEqual(compute('ADCS               R4,    R6,   R4    ASR R5',  {cf: 0L, R4: 0x80000010L, R5: 0xF0000001L, R6: 0L, }), {
-                         nf: 1L, zf: 0L, cf: 0L, of: 0L, R4: 0xC0000008L, R5: 0xF0000001L, R6: 0L, })
-        self.assertEqual(compute('ADCS               R4,    R6,   R4    ROR R5',  {cf: 1L, R4: 0x000000FFL, R5: 0x00000F04L, R6: 0L, }), {
-                         nf: 1L, zf: 0L, cf: 0L, of: 0L, R4: 0xF0000010L, R5: 0x00000F04L, R6: 0L, })
+                                 cf: 1, R4: 0x000000FF, R5: 0x00000F04, R6: 0, }), {cf: 1,     R4: 0xF0000010, R5: 0x00000F04, R6: 0, })
+        self.assertEqual(compute('ADCS               R4,    R6,   R4    LSL R5',  {cf: 0, R4: 0x00000001, R5: 0x00000004, R6: 0, }), {
+                         nf: 0, zf: 0, cf: 0, of: 0, R4: 0x00000010, R5: 0x00000004, R6: 0, })
+        self.assertEqual(compute('ADCS               R4,    R6,   R4    LSR R5',  {cf: 1, R4: 0x00000110, R5: 0x80000004, R6: 0, }), {
+                         nf: 0, zf: 0, cf: 0, of: 0, R4: 0x00000012, R5: 0x80000004, R6: 0, })
+        self.assertEqual(compute('ADCS               R4,    R6,   R4    ASR R5',  {cf: 0, R4: 0x80000010, R5: 0xF0000001, R6: 0, }), {
+                         nf: 1, zf: 0, cf: 0, of: 0, R4: 0xC0000008, R5: 0xF0000001, R6: 0, })
+        self.assertEqual(compute('ADCS               R4,    R6,   R4    ROR R5',  {cf: 1, R4: 0x000000FF, R5: 0x00000F04, R6: 0, }), {
+                         nf: 1, zf: 0, cf: 0, of: 0, R4: 0xF0000010, R5: 0x00000F04, R6: 0, })
 
     def test_ADD(self):
         # §A8.8.{5,9}:             ADD{S}{<c>}{<q>} {<Rd>,} <Rn>, #<const>
         self.assertRaises(
             ValueError, compute, 'ADD          R4,   0x00000001L ')
         self.assertEqual(compute('ADD                R4,    R4,   0x00000001 ',   {
-                                 R4: 0x00000000L, }), {R4: 0x00000001L, })
+                                 R4: 0x00000000, }), {R4: 0x00000001, })
         self.assertEqual(compute('ADD                R4,    R4,   0x00000000 ',   {
-                                 R4: 0x00000000L, }), {R4: 0x00000000L, })
+                                 R4: 0x00000000, }), {R4: 0x00000000, })
         self.assertEqual(compute('ADD                PC,    R4,   0x00000001 ',   {
-                                 R4: 0xFFFFFFFFL, PC: 0x55555555L, }), {R4: 0xFFFFFFFFL, PC: 0x00000000L, })
+                                 R4: 0xFFFFFFFF, PC: 0x55555555, }), {R4: 0xFFFFFFFF, PC: 0x00000000, })
         self.assertEqual(compute('ADD                PC,    R4,   0x00000000 ',   {
-                                 R4: 0xFFFFFFFFL, PC: 0x55555555L, }), {R4: 0xFFFFFFFFL, PC: 0xFFFFFFFFL, })
-        self.assertEqual(compute('ADDS               R4,    R4,   0x80000000 ',   {R4: 0x80000000L, }), {
-                         nf: 0L, zf: 1L, cf: 1L, of: 1L, R4: 0x00000000L, })
-        self.assertEqual(compute('ADDS               R4,    R4,   0xFF000000 ',   {R4: 0x00FFFFFEL, }), {
-                         nf: 1L, zf: 0L, cf: 0L, of: 0L, R4: 0xFFFFFFFEL, })
+                                 R4: 0xFFFFFFFF, PC: 0x55555555, }), {R4: 0xFFFFFFFF, PC: 0xFFFFFFFF, })
+        self.assertEqual(compute('ADDS               R4,    R4,   0x80000000 ',   {R4: 0x80000000, }), {
+                         nf: 0, zf: 1, cf: 1, of: 1, R4: 0x00000000, })
+        self.assertEqual(compute('ADDS               R4,    R4,   0xFF000000 ',   {R4: 0x00FFFFFE, }), {
+                         nf: 1, zf: 0, cf: 0, of: 0, R4: 0xFFFFFFFE, })
         self.assertEqual(compute('ADDS               PC,    R4,   0x00000000 ',   {
-                                 R4: 0x00000000L, PC: 0x55555555L, }), {R4: 0x00000000L, PC: 0x00000000L, })
+                                 R4: 0x00000000, PC: 0x55555555, }), {R4: 0x00000000, PC: 0x00000000, })
         self.assertEqual(compute('ADDS               PC,    R4,   0xFF000000 ',   {
-                                 R4: 0x01000000L, PC: 0x55555555L, }), {R4: 0x01000000L, PC: 0x00000000L, })
+                                 R4: 0x01000000, PC: 0x55555555, }), {R4: 0x01000000, PC: 0x00000000, })
         # SP special part
         self.assertEqual(compute('ADD                R4,    SP,   0x00000001 ',   {
-                                 R4: 0x00000000L, SP: 0x00000000L, }), {R4: 0x00000001L, SP: 0x00000000L, })
+                                 R4: 0x00000000, SP: 0x00000000, }), {R4: 0x00000001, SP: 0x00000000, })
 
         # §A8.8.{7,11}:            ADD{S}{<c>}{<q>} {<Rd>,} <Rn>, <Rm> {,<shift>}
         self.assertRaises(
             ValueError, compute, 'ADD          R4,   R5          ')
         self.assertEqual(compute('ADD                R4,    R4,   R5          ',  {
-                                 R4: 0xFFFFFFFFL, R5: 0x00000001L, }), {R4: 0x00000000L, R5: 0x00000001L, })
+                                 R4: 0xFFFFFFFF, R5: 0x00000001, }), {R4: 0x00000000, R5: 0x00000001, })
         self.assertEqual(compute('ADD                R4,    R4,   R5    LSL 1 ',  {
-                                 R4: 0x00000001L, R5: 0x00000008L, }), {R4: 0x00000011L, R5: 0x00000008L, })
+                                 R4: 0x00000001, R5: 0x00000008, }), {R4: 0x00000011, R5: 0x00000008, })
         self.assertEqual(compute('ADD                R4,    R4,   R5    LSR 2 ',  {
-                                 R4: 0x00000000L, R5: 0x80000041L, }), {R4: 0x20000010L, R5: 0x80000041L, })
+                                 R4: 0x00000000, R5: 0x80000041, }), {R4: 0x20000010, R5: 0x80000041, })
         self.assertEqual(compute('ADD                R4,    R4,   R5    ASR 3 ',  {
-                                 R4: 0x00000001L, R5: 0x80000081L, }), {R4: 0xF0000011L, R5: 0x80000081L, })
+                                 R4: 0x00000001, R5: 0x80000081, }), {R4: 0xF0000011, R5: 0x80000081, })
         self.assertEqual(compute('ADD                R4,    R4,   R5    ROR 4 ',  {
-                                 R4: 0xFFFFFFFFL, R5: 0x0000010FL, }), {R4: 0xF000000FL, R5: 0x0000010FL, })
+                                 R4: 0xFFFFFFFF, R5: 0x0000010F, }), {R4: 0xF000000F, R5: 0x0000010F, })
         self.assertEqual(compute('ADD                R4,    R4,   R5    RRX   ',  {
-                                 cf: 1L, R4: 0xFFFFFFFFL, R5: 0x00000101L, }), {cf: 1L,     R4: 0x8000007FL, R5: 0x00000101L, })
-        self.assertEqual(compute('ADDS               R4,    R4,   R5          ',  {R4: 0xFFFFFFFFL, R5: 0x00000001L, }), {
-                         nf: 0L, zf: 1L, cf: 1L, of: 0L, R4: 0x00000000L, R5: 0x00000001L, })
-        self.assertEqual(compute('ADDS               R4,    R4,   R5    LSL 1 ',  {R4: 0x00000001L, R5: 0x00000008L, }), {
-                         nf: 0L, zf: 0L, cf: 0L, of: 0L, R4: 0x00000011L, R5: 0x00000008L, })
-        self.assertEqual(compute('ADDS               R4,    R4,   R5    LSR 2 ',  {R4: 0x00000000L, R5: 0x80000041L, }), {
-                         nf: 0L, zf: 0L, cf: 0L, of: 0L, R4: 0x20000010L, R5: 0x80000041L, })
-        self.assertEqual(compute('ADDS               R4,    R4,   R5    ASR 3 ',  {R4: 0x00000001L, R5: 0x80000081L, }), {
-                         nf: 1L, zf: 0L, cf: 0L, of: 0L, R4: 0xF0000011L, R5: 0x80000081L, })
-        self.assertEqual(compute('ADDS               R4,    R4,   R5    ROR 4 ',  {R4: 0xFFFFFFFFL, R5: 0x0000010FL, }), {
-                         nf: 1L, zf: 0L, cf: 1L, of: 0L, R4: 0xF000000FL, R5: 0x0000010FL, })
-        self.assertEqual(compute('ADDS               R4,    R4,   R5    RRX   ',  {cf: 1L, R4: 0xFFFFFFFFL, R5: 0x00000101L, }), {
-                         nf: 1L, zf: 0L, cf: 1L, of: 0L, R4: 0x8000007FL, R5: 0x00000101L, })
+                                 cf: 1, R4: 0xFFFFFFFF, R5: 0x00000101, }), {cf: 1,     R4: 0x8000007F, R5: 0x00000101, })
+        self.assertEqual(compute('ADDS               R4,    R4,   R5          ',  {R4: 0xFFFFFFFF, R5: 0x00000001, }), {
+                         nf: 0, zf: 1, cf: 1, of: 0, R4: 0x00000000, R5: 0x00000001, })
+        self.assertEqual(compute('ADDS               R4,    R4,   R5    LSL 1 ',  {R4: 0x00000001, R5: 0x00000008, }), {
+                         nf: 0, zf: 0, cf: 0, of: 0, R4: 0x00000011, R5: 0x00000008, })
+        self.assertEqual(compute('ADDS               R4,    R4,   R5    LSR 2 ',  {R4: 0x00000000, R5: 0x80000041, }), {
+                         nf: 0, zf: 0, cf: 0, of: 0, R4: 0x20000010, R5: 0x80000041, })
+        self.assertEqual(compute('ADDS               R4,    R4,   R5    ASR 3 ',  {R4: 0x00000001, R5: 0x80000081, }), {
+                         nf: 1, zf: 0, cf: 0, of: 0, R4: 0xF0000011, R5: 0x80000081, })
+        self.assertEqual(compute('ADDS               R4,    R4,   R5    ROR 4 ',  {R4: 0xFFFFFFFF, R5: 0x0000010F, }), {
+                         nf: 1, zf: 0, cf: 1, of: 0, R4: 0xF000000F, R5: 0x0000010F, })
+        self.assertEqual(compute('ADDS               R4,    R4,   R5    RRX   ',  {cf: 1, R4: 0xFFFFFFFF, R5: 0x00000101, }), {
+                         nf: 1, zf: 0, cf: 1, of: 0, R4: 0x8000007F, R5: 0x00000101, })
         # SP special part
         self.assertEqual(compute('ADD                R4,    SP,   R4    LSR 1 ',  {
-                                 R4: 0x00000002L, SP: 0x00000000L, }), {R4: 0x00000001L, SP: 0x00000000L, })
+                                 R4: 0x00000002, SP: 0x00000000, }), {R4: 0x00000001, SP: 0x00000000, })
 
         # §A8.8.8:                 ADD{S}{<c>}{<q>} {<Rd>,} <Rn>, <Rm>, <type> <Rs>
         self.assertEqual(compute('ADD                R4,    R6,   R4    LSL R5',  {
-                                 R4: 0x00000001L, R5: 0x00000004L, R6: 0L, }), {R4: 0x00000010L, R5: 0x00000004L, R6: 0L, })
+                                 R4: 0x00000001, R5: 0x00000004, R6: 0, }), {R4: 0x00000010, R5: 0x00000004, R6: 0, })
         self.assertEqual(compute('ADD                R4,    R6,   R4    LSR R5',  {
-                                 R4: 0x00000110L, R5: 0x80000004L, R6: 0L, }), {R4: 0x00000011L, R5: 0x80000004L, R6: 0L, })
+                                 R4: 0x00000110, R5: 0x80000004, R6: 0, }), {R4: 0x00000011, R5: 0x80000004, R6: 0, })
         self.assertEqual(compute('ADD                R4,    R6,   R4    ASR R5',  {
-                                 R4: 0x80000010L, R5: 0xF0000001L, R6: 0L, }), {R4: 0xC0000008L, R5: 0xF0000001L, R6: 0L, })
+                                 R4: 0x80000010, R5: 0xF0000001, R6: 0, }), {R4: 0xC0000008, R5: 0xF0000001, R6: 0, })
         self.assertEqual(compute('ADD                R4,    R6,   R4    ROR R5',  {
-                                 R4: 0x000000FFL, R5: 0x00000F04L, R6: 0L, }), {R4: 0xF000000FL, R5: 0x00000F04L, R6: 0L, })
-        self.assertEqual(compute('ADDS               R4,    R6,   R4    LSL R5',  {R4: 0x00000001L, R5: 0x00000004L, R6: 0L, }), {
-                         nf: 0L, zf: 0L, cf: 0L, of: 0L, R4: 0x00000010L, R5: 0x00000004L, R6: 0L, })
-        self.assertEqual(compute('ADDS               R4,    R6,   R4    LSR R5',  {R4: 0x00000110L, R5: 0x80000004L, R6: 0L, }), {
-                         nf: 0L, zf: 0L, cf: 0L, of: 0L, R4: 0x00000011L, R5: 0x80000004L, R6: 0L, })
-        self.assertEqual(compute('ADDS               R4,    R6,   R4    ASR R5',  {R4: 0x80000010L, R5: 0xF0000001L, R6: 0L, }), {
-                         nf: 1L, zf: 0L, cf: 0L, of: 0L, R4: 0xC0000008L, R5: 0xF0000001L, R6: 0L, })
-        self.assertEqual(compute('ADDS               R4,    R6,   R4    ROR R5',  {R4: 0x000000FFL, R5: 0x00000F04L, R6: 0L, }), {
-                         nf: 1L, zf: 0L, cf: 0L, of: 0L, R4: 0xF000000FL, R5: 0x00000F04L, R6: 0L, })
+                                 R4: 0x000000FF, R5: 0x00000F04, R6: 0, }), {R4: 0xF000000F, R5: 0x00000F04, R6: 0, })
+        self.assertEqual(compute('ADDS               R4,    R6,   R4    LSL R5',  {R4: 0x00000001, R5: 0x00000004, R6: 0, }), {
+                         nf: 0, zf: 0, cf: 0, of: 0, R4: 0x00000010, R5: 0x00000004, R6: 0, })
+        self.assertEqual(compute('ADDS               R4,    R6,   R4    LSR R5',  {R4: 0x00000110, R5: 0x80000004, R6: 0, }), {
+                         nf: 0, zf: 0, cf: 0, of: 0, R4: 0x00000011, R5: 0x80000004, R6: 0, })
+        self.assertEqual(compute('ADDS               R4,    R6,   R4    ASR R5',  {R4: 0x80000010, R5: 0xF0000001, R6: 0, }), {
+                         nf: 1, zf: 0, cf: 0, of: 0, R4: 0xC0000008, R5: 0xF0000001, R6: 0, })
+        self.assertEqual(compute('ADDS               R4,    R6,   R4    ROR R5',  {R4: 0x000000FF, R5: 0x00000F04, R6: 0, }), {
+                         nf: 1, zf: 0, cf: 0, of: 0, R4: 0xF000000F, R5: 0x00000F04, R6: 0, })
 
 
         # Test against qemu
-        self.assertEqual(compute('ADDS               R3,    R2,   R3 ', {R2: 0x1L, R3: 0x1L}),
-                         { nf: 0L, zf: 0L, cf: 0L, of: 0L, R2: 0x00000001L, R3: 0x00000002L})
-        self.assertEqual(compute('ADDS               R3,    R2,   R3 ', {R2: 0x1L, R3: 0x7FFFFFFFL}),
-                         { nf: 1L, zf: 0L, cf: 0L, of: 1L, R2: 0x00000001L, R3: 0x80000000L})
-        self.assertEqual(compute('ADDS               R3,    R2,   R3 ', {R2: 0x80000000L, R3: 0x80000000L}),
-                         { nf: 0L, zf: 1L, cf: 1L, of: 1L, R2: 0x80000000L, R3: 0x00000000L})
-        self.assertEqual(compute('ADDS               R3,    R2,   R3 ', {R2: 0x7FFFFFFFL, R3:0x7FFFFFFFL}),
-                         { nf: 1L, zf: 0L, cf: 0L, of: 1L, R2: 0x7FFFFFFFL, R3:0xFFFFFFFEL})
-        self.assertEqual(compute('ADDS               R3,    R2,   R3 ', {R2: 0L, R3:0}),
-                         { nf: 0L, zf: 1L, cf: 0L, of: 0L, R2: 0L, R3:0})
-        self.assertEqual(compute('ADDS               R3,    R2,   R3 ', {R2: 0xFFFFFFFFL, R3:0xFFFFFFFFL}),
-                         { nf: 1L, zf: 0L, cf: 1L, of: 0L, R2: 0xFFFFFFFFL, R3:0xFFFFFFFEL})
+        self.assertEqual(compute('ADDS               R3,    R2,   R3 ', {R2: 0x1, R3: 0x1}),
+                         { nf: 0, zf: 0, cf: 0, of: 0, R2: 0x00000001, R3: 0x00000002})
+        self.assertEqual(compute('ADDS               R3,    R2,   R3 ', {R2: 0x1, R3: 0x7FFFFFFF}),
+                         { nf: 1, zf: 0, cf: 0, of: 1, R2: 0x00000001, R3: 0x80000000})
+        self.assertEqual(compute('ADDS               R3,    R2,   R3 ', {R2: 0x80000000, R3: 0x80000000}),
+                         { nf: 0, zf: 1, cf: 1, of: 1, R2: 0x80000000, R3: 0x00000000})
+        self.assertEqual(compute('ADDS               R3,    R2,   R3 ', {R2: 0x7FFFFFFF, R3:0x7FFFFFFF}),
+                         { nf: 1, zf: 0, cf: 0, of: 1, R2: 0x7FFFFFFF, R3:0xFFFFFFFE})
+        self.assertEqual(compute('ADDS               R3,    R2,   R3 ', {R2: 0, R3:0}),
+                         { nf: 0, zf: 1, cf: 0, of: 0, R2: 0, R3:0})
+        self.assertEqual(compute('ADDS               R3,    R2,   R3 ', {R2: 0xFFFFFFFF, R3:0xFFFFFFFF}),
+                         { nf: 1, zf: 0, cf: 1, of: 0, R2: 0xFFFFFFFF, R3:0xFFFFFFFE})
 
 
 
@@ -275,26 +278,26 @@ class TestARMSemantic(unittest.TestCase):
         # §A8.8.13:                AND{S}{<c>}{<q>} {<Rd>,} <Rn>, #<const>
         self.assertRaises(
             ValueError, compute, 'AND          R4,   0x00000001 ')
-        self.assertEqual(compute('AND                R4,    R4,   0x00000001 ',   {R4: 0xDEADBEEFL, }), {R4: 0x00000001L, })
-        self.assertEqual(compute('AND                R4,    R4,   0x00000000 ',   {R4: 0x00000000L, }), {R4: 0x00000000L, })
-        self.assertEqual(compute('AND                PC,    R4,   0x00000001 ',   {R4: 0xFFFFFFFFL, PC: 0x55555555L, }), {R4: 0xFFFFFFFFL, PC: 0x00000001L, })
-        self.assertEqual(compute('AND                PC,    R4,   0x00000000 ',   {R4: 0xFFFFFFFFL, PC: 0x55555555L, }), {R4: 0xFFFFFFFFL, PC: 0x00000000L, })
+        self.assertEqual(compute('AND                R4,    R4,   0x00000001 ',   {R4: 0xDEADBEEF, }), {R4: 0x00000001, })
+        self.assertEqual(compute('AND                R4,    R4,   0x00000000 ',   {R4: 0x00000000, }), {R4: 0x00000000, })
+        self.assertEqual(compute('AND                PC,    R4,   0x00000001 ',   {R4: 0xFFFFFFFF, PC: 0x55555555, }), {R4: 0xFFFFFFFF, PC: 0x00000001, })
+        self.assertEqual(compute('AND                PC,    R4,   0x00000000 ',   {R4: 0xFFFFFFFF, PC: 0x55555555, }), {R4: 0xFFFFFFFF, PC: 0x00000000, })
 
         # §A8.8.14:                AND{S}{<c>}{<q>} {<Rd>,} <Rn>, <Rm> {,<shift>}
         self.assertRaises(
             ValueError, compute, 'AND          R4,   R5          ')
-        self.assertEqual(compute('AND                R4,    R4,   R5          ',  {R4: 0xFFFFFFFEL, R5: 0x00000001L, }), {R4: 0x00000000L, R5: 0x00000001L, })
-        self.assertEqual(compute('AND                R4,    R4,   R5    LSL 1 ',  {R4: 0x00000011L, R5: 0x00000008L, }), {R4: 0x00000010L, R5: 0x00000008L, })
-        self.assertEqual(compute('AND                R4,    R4,   R5    LSR 2 ',  {R4: 0xFFFFFFFFL, R5: 0x80000041L, }), {R4: 0x20000010L, R5: 0x80000041L, })
-        self.assertEqual(compute('AND                R4,    R4,   R5    ASR 3 ',  {R4: 0xF00000FFL, R5: 0x80000081L, }), {R4: 0xF0000010L, R5: 0x80000081L, })
-        self.assertEqual(compute('AND                R4,    R4,   R5    ROR 4 ',  {R4: 0xFFFFFFFFL, R5: 0x000000FFL, }), {R4: 0xF000000FL, R5: 0x000000FFL, })
-        self.assertEqual(compute('AND                R4,    R4,   R5    RRX   ',  {R4: 0xFFFFFFFFL, R5: 0x00000101L, }), {R4: ExprCompose(ExprInt(0x80L, 31), cf_init), R5: 0x00000101L, })
+        self.assertEqual(compute('AND                R4,    R4,   R5          ',  {R4: 0xFFFFFFFE, R5: 0x00000001, }), {R4: 0x00000000, R5: 0x00000001, })
+        self.assertEqual(compute('AND                R4,    R4,   R5    LSL 1 ',  {R4: 0x00000011, R5: 0x00000008, }), {R4: 0x00000010, R5: 0x00000008, })
+        self.assertEqual(compute('AND                R4,    R4,   R5    LSR 2 ',  {R4: 0xFFFFFFFF, R5: 0x80000041, }), {R4: 0x20000010, R5: 0x80000041, })
+        self.assertEqual(compute('AND                R4,    R4,   R5    ASR 3 ',  {R4: 0xF00000FF, R5: 0x80000081, }), {R4: 0xF0000010, R5: 0x80000081, })
+        self.assertEqual(compute('AND                R4,    R4,   R5    ROR 4 ',  {R4: 0xFFFFFFFF, R5: 0x000000FF, }), {R4: 0xF000000F, R5: 0x000000FF, })
+        self.assertEqual(compute('AND                R4,    R4,   R5    RRX   ',  {R4: 0xFFFFFFFF, R5: 0x00000101, }), {R4: ExprCompose(ExprInt(0x80, 31), cf_init), R5: 0x00000101, })
 
         # §A8.8.15:                AND{S}{<c>}{<q>} {<Rd>,} <Rn>, <Rm>, <type> <Rs>
-        self.assertEqual(compute('AND                R4,    R6,   R4    LSL R5',  {R4: 0x00000001L, R5: 0x00000004L, R6: -1, }), {R4: 0x00000010L, R5: 0x00000004L, R6: 0xFFFFFFFFL, })
-        self.assertEqual(compute('AND                R4,    R6,   R4    LSR R5',  {R4: 0x00000110L, R5: 0x80000004L, R6: -1, }), {R4: 0x00000011L, R5: 0x80000004L, R6: 0xFFFFFFFFL, })
-        self.assertEqual(compute('AND                R4,    R6,   R4    ASR R5',  {R4: 0x80000010L, R5: 0xF0000001L, R6: -1, }), {R4: 0xC0000008L, R5: 0xF0000001L, R6: 0xFFFFFFFFL, })
-        self.assertEqual(compute('AND                R4,    R6,   R4    ROR R5',  {R4: 0x000000FFL, R5: 0x00000F04L, R6: -1, }), {R4: 0xF000000FL, R5: 0x00000F04L, R6: 0xFFFFFFFFL, })
+        self.assertEqual(compute('AND                R4,    R6,   R4    LSL R5',  {R4: 0x00000001, R5: 0x00000004, R6: -1, }), {R4: 0x00000010, R5: 0x00000004, R6: 0xFFFFFFFF, })
+        self.assertEqual(compute('AND                R4,    R6,   R4    LSR R5',  {R4: 0x00000110, R5: 0x80000004, R6: -1, }), {R4: 0x00000011, R5: 0x80000004, R6: 0xFFFFFFFF, })
+        self.assertEqual(compute('AND                R4,    R6,   R4    ASR R5',  {R4: 0x80000010, R5: 0xF0000001, R6: -1, }), {R4: 0xC0000008, R5: 0xF0000001, R6: 0xFFFFFFFF, })
+        self.assertEqual(compute('AND                R4,    R6,   R4    ROR R5',  {R4: 0x000000FF, R5: 0x00000F04, R6: -1, }), {R4: 0xF000000F, R5: 0x00000F04, R6: 0xFFFFFFFF, })
 
     def test_ASR(self):
         # §A8.8.16:                ASR{S}{<c>}{<q>} {<Rd>,} <Rm>, #<imm>    <==>    MOV{S}{<c>}{<q>} {<Rd>,} <Rm>, ASR #<n>
@@ -305,191 +308,191 @@ class TestARMSemantic(unittest.TestCase):
 
     def test_SUBS(self):
         # Test against qemu
-        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x2L, R3: 0x1L}),
-                         { nf: 0L, zf: 0L, cf: 1L, of: 0L, R2: 0x00000002L, R3: 0x1L})
-        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x1L, R3: 0x2L}),
-                         { nf: 1L, zf: 0L, cf: 0L, of: 0L, R2: 0x00000001L, R3: 0xFFFFFFFFL})
-        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x0L, R3: 0xFFFFFFFFL}),
-                         { nf: 0L, zf: 0L, cf: 0L, of: 0L, R2: 0x00000000L, R3: 0x1L})
-        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0xFFFFFFFFL, R3: 0x0L}),
-                         { nf: 1L, zf: 0L, cf: 1L, of: 0L, R2: 0xFFFFFFFFL, R3: 0xFFFFFFFFL})
-        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x1L, R3: 0x7FFFFFFFL}),
-                         { nf: 1L, zf: 0L, cf: 0L, of: 0L, R2: 0x00000001L, R3: 0x80000002L})
-        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x7FFFFFFFL, R3: 0x1L}),
-                         { nf: 0L, zf: 0L, cf: 1L, of: 0L, R2: 0x7FFFFFFFL, R3: 0x7FFFFFFEL})
-        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x80000000L, R3: 0x80000001L}),
-                         { nf: 1L, zf: 0L, cf: 0L, of: 0L, R2: 0x80000000L, R3: 0xFFFFFFFFL})
-        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x80000001L, R3: 0x80000000L}),
-                         { nf: 0L, zf: 0L, cf: 1L, of: 0L, R2: 0x80000001L, R3: 0x1L})
+        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x2, R3: 0x1}),
+                         { nf: 0, zf: 0, cf: 1, of: 0, R2: 0x00000002, R3: 0x1})
+        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x1, R3: 0x2}),
+                         { nf: 1, zf: 0, cf: 0, of: 0, R2: 0x00000001, R3: 0xFFFFFFFF})
+        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x0, R3: 0xFFFFFFFF}),
+                         { nf: 0, zf: 0, cf: 0, of: 0, R2: 0x00000000, R3: 0x1})
+        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0xFFFFFFFF, R3: 0x0}),
+                         { nf: 1, zf: 0, cf: 1, of: 0, R2: 0xFFFFFFFF, R3: 0xFFFFFFFF})
+        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x1, R3: 0x7FFFFFFF}),
+                         { nf: 1, zf: 0, cf: 0, of: 0, R2: 0x00000001, R3: 0x80000002})
+        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x7FFFFFFF, R3: 0x1}),
+                         { nf: 0, zf: 0, cf: 1, of: 0, R2: 0x7FFFFFFF, R3: 0x7FFFFFFE})
+        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x80000000, R3: 0x80000001}),
+                         { nf: 1, zf: 0, cf: 0, of: 0, R2: 0x80000000, R3: 0xFFFFFFFF})
+        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x80000001, R3: 0x80000000}),
+                         { nf: 0, zf: 0, cf: 1, of: 0, R2: 0x80000001, R3: 0x1})
 
     def test_CMP(self):
         # Test against qemu
-        self.assertEqual(compute('CMP                R0,    R1 ', {R0: 0x11223344L, R1: 0x88223344L}),
-                         { nf: 1L, zf: 0L, cf: 0L, of: 1L, R0: 0x11223344L, R1: 0x88223344L})
-
-        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x2L, R3: 0x1L}),
-                         { nf: 0L, zf: 0L, cf: 1L, of: 0L, R2: 0x00000002L, R3: 0x1L})
-        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x1L, R3: 0x2L}),
-                         { nf: 1L, zf: 0L, cf: 0L, of: 0L, R2: 0x00000001L, R3: 0xFFFFFFFFL})
-        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x0L, R3: 0xFFFFFFFFL}),
-                         { nf: 0L, zf: 0L, cf: 0L, of: 0L, R2: 0x00000000L, R3: 0x1L})
-        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0xFFFFFFFFL, R3: 0x0L}),
-                         { nf: 1L, zf: 0L, cf: 1L, of: 0L, R2: 0xFFFFFFFFL, R3: 0xFFFFFFFFL})
-        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x1L, R3: 0x7FFFFFFFL}),
-                         { nf: 1L, zf: 0L, cf: 0L, of: 0L, R2: 0x00000001L, R3: 0x80000002L})
-        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x7FFFFFFFL, R3: 0x1L}),
-                         { nf: 0L, zf: 0L, cf: 1L, of: 0L, R2: 0x7FFFFFFFL, R3: 0x7FFFFFFEL})
-        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x80000000L, R3: 0x80000001L}),
-                         { nf: 1L, zf: 0L, cf: 0L, of: 0L, R2: 0x80000000L, R3: 0xFFFFFFFFL})
-        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x80000001L, R3: 0x80000000L}),
-                         { nf: 0L, zf: 0L, cf: 1L, of: 0L, R2: 0x80000001L, R3: 0x1L})
+        self.assertEqual(compute('CMP                R0,    R1 ', {R0: 0x11223344, R1: 0x88223344}),
+                         { nf: 1, zf: 0, cf: 0, of: 1, R0: 0x11223344, R1: 0x88223344})
+
+        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x2, R3: 0x1}),
+                         { nf: 0, zf: 0, cf: 1, of: 0, R2: 0x00000002, R3: 0x1})
+        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x1, R3: 0x2}),
+                         { nf: 1, zf: 0, cf: 0, of: 0, R2: 0x00000001, R3: 0xFFFFFFFF})
+        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x0, R3: 0xFFFFFFFF}),
+                         { nf: 0, zf: 0, cf: 0, of: 0, R2: 0x00000000, R3: 0x1})
+        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0xFFFFFFFF, R3: 0x0}),
+                         { nf: 1, zf: 0, cf: 1, of: 0, R2: 0xFFFFFFFF, R3: 0xFFFFFFFF})
+        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x1, R3: 0x7FFFFFFF}),
+                         { nf: 1, zf: 0, cf: 0, of: 0, R2: 0x00000001, R3: 0x80000002})
+        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x7FFFFFFF, R3: 0x1}),
+                         { nf: 0, zf: 0, cf: 1, of: 0, R2: 0x7FFFFFFF, R3: 0x7FFFFFFE})
+        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x80000000, R3: 0x80000001}),
+                         { nf: 1, zf: 0, cf: 0, of: 0, R2: 0x80000000, R3: 0xFFFFFFFF})
+        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x80000001, R3: 0x80000000}),
+                         { nf: 0, zf: 0, cf: 1, of: 0, R2: 0x80000001, R3: 0x1})
 
 
 
     def test_ADDS(self):
-        self.assertEqual(compute('ADDS   R2, R2, R3', {R2: 0x2L, R3: 0x1L}), {R2: 0x3L, R3: 0x1L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x0L})
-        self.assertEqual(compute('ADDS   R2, R2, R3', {R2: 0x1L, R3: 0x2L}), {R2: 0x3L, R3: 0x2L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x0L})
-        self.assertEqual(compute('ADDS   R2, R2, R3', {R2: 0x0L, R3: 0xffffffffL}), {R2: 0xffffffffL, R3: 0xffffffffL, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x1L})
-        self.assertEqual(compute('ADDS   R2, R2, R3', {R2: 0xffffffffL, R3: 0x0L}), {R2: 0xffffffffL, R3: 0x0L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x1L})
-        self.assertEqual(compute('ADDS   R2, R2, R3', {R2: 0x1L, R3: 0x7fffffffL}), {R2: 0x80000000L, R3: 0x7fffffffL, of: 0x1L, zf: 0x0L, cf: 0x0L, nf: 0x1L})
-        self.assertEqual(compute('ADDS   R2, R2, R3', {R2: 0x7fffffffL, R3: 0x1L}), {R2: 0x80000000L, R3: 0x1L, of: 0x1L, zf: 0x0L, cf: 0x0L, nf: 0x1L})
-        self.assertEqual(compute('ADDS   R2, R2, R3', {R2: 0x80000000L, R3: 0x80000001L}), {R2: 0x1L, R3: 0x80000001L, of: 0x1L, zf: 0x0L, cf: 0x1L, nf: 0x0L})
-        self.assertEqual(compute('ADDS   R2, R2, R3', {R2: 0x80000001L, R3: 0x80000000L}), {R2: 0x1L, R3: 0x80000000L, of: 0x1L, zf: 0x0L, cf: 0x1L, nf: 0x0L})
+        self.assertEqual(compute('ADDS   R2, R2, R3', {R2: 0x2, R3: 0x1}), {R2: 0x3, R3: 0x1, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x0})
+        self.assertEqual(compute('ADDS   R2, R2, R3', {R2: 0x1, R3: 0x2}), {R2: 0x3, R3: 0x2, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x0})
+        self.assertEqual(compute('ADDS   R2, R2, R3', {R2: 0x0, R3: 0xffffffff}), {R2: 0xffffffff, R3: 0xffffffff, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x1})
+        self.assertEqual(compute('ADDS   R2, R2, R3', {R2: 0xffffffff, R3: 0x0}), {R2: 0xffffffff, R3: 0x0, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x1})
+        self.assertEqual(compute('ADDS   R2, R2, R3', {R2: 0x1, R3: 0x7fffffff}), {R2: 0x80000000, R3: 0x7fffffff, of: 0x1, zf: 0x0, cf: 0x0, nf: 0x1})
+        self.assertEqual(compute('ADDS   R2, R2, R3', {R2: 0x7fffffff, R3: 0x1}), {R2: 0x80000000, R3: 0x1, of: 0x1, zf: 0x0, cf: 0x0, nf: 0x1})
+        self.assertEqual(compute('ADDS   R2, R2, R3', {R2: 0x80000000, R3: 0x80000001}), {R2: 0x1, R3: 0x80000001, of: 0x1, zf: 0x0, cf: 0x1, nf: 0x0})
+        self.assertEqual(compute('ADDS   R2, R2, R3', {R2: 0x80000001, R3: 0x80000000}), {R2: 0x1, R3: 0x80000000, of: 0x1, zf: 0x0, cf: 0x1, nf: 0x0})
 
     def test_ANDS(self):
-        self.assertEqual(compute('ANDS   R2, R2, R3', {R2: 0x2L, R3: 0x1L}), {zf: 0x1L, R2: 0x0L, nf: 0x0L, R3: 0x1L})
-        self.assertEqual(compute('ANDS   R2, R2, R3', {R2: 0x1L, R3: 0x2L}), {zf: 0x1L, R2: 0x0L, nf: 0x0L, R3: 0x2L})
-        self.assertEqual(compute('ANDS   R2, R2, R3', {R2: 0x0L, R3: 0xffffffffL}), {zf: 0x1L, R2: 0x0L, nf: 0x0L, R3: 0xffffffffL})
-        self.assertEqual(compute('ANDS   R2, R2, R3', {R2: 0xffffffffL, R3: 0x0L}), {zf: 0x1L, R2: 0x0L, nf: 0x0L, R3: 0x0L})
-        self.assertEqual(compute('ANDS   R2, R2, R3', {R2: 0x1L, R3: 0x7fffffffL}), {zf: 0x0L, R2: 0x1L, nf: 0x0L, R3: 0x7fffffffL})
-        self.assertEqual(compute('ANDS   R2, R2, R3', {R2: 0x7fffffffL, R3: 0x1L}), {zf: 0x0L, R2: 0x1L, nf: 0x0L, R3: 0x1L})
-        self.assertEqual(compute('ANDS   R2, R2, R3', {R2: 0x80000000L, R3: 0x80000001L}), {zf: 0x0L, R2: 0x80000000L, nf: 0x1L, R3: 0x80000001L})
-        self.assertEqual(compute('ANDS   R2, R2, R3', {R2: 0x80000001L, R3: 0x80000000L}), {zf: 0x0L, R2: 0x80000000L, nf: 0x1L, R3: 0x80000000L})
+        self.assertEqual(compute('ANDS   R2, R2, R3', {R2: 0x2, R3: 0x1}), {zf: 0x1, R2: 0x0, nf: 0x0, R3: 0x1})
+        self.assertEqual(compute('ANDS   R2, R2, R3', {R2: 0x1, R3: 0x2}), {zf: 0x1, R2: 0x0, nf: 0x0, R3: 0x2})
+        self.assertEqual(compute('ANDS   R2, R2, R3', {R2: 0x0, R3: 0xffffffff}), {zf: 0x1, R2: 0x0, nf: 0x0, R3: 0xffffffff})
+        self.assertEqual(compute('ANDS   R2, R2, R3', {R2: 0xffffffff, R3: 0x0}), {zf: 0x1, R2: 0x0, nf: 0x0, R3: 0x0})
+        self.assertEqual(compute('ANDS   R2, R2, R3', {R2: 0x1, R3: 0x7fffffff}), {zf: 0x0, R2: 0x1, nf: 0x0, R3: 0x7fffffff})
+        self.assertEqual(compute('ANDS   R2, R2, R3', {R2: 0x7fffffff, R3: 0x1}), {zf: 0x0, R2: 0x1, nf: 0x0, R3: 0x1})
+        self.assertEqual(compute('ANDS   R2, R2, R3', {R2: 0x80000000, R3: 0x80000001}), {zf: 0x0, R2: 0x80000000, nf: 0x1, R3: 0x80000001})
+        self.assertEqual(compute('ANDS   R2, R2, R3', {R2: 0x80000001, R3: 0x80000000}), {zf: 0x0, R2: 0x80000000, nf: 0x1, R3: 0x80000000})
 
     def test_BICS(self):
-        self.assertEqual(compute('BICS   R2, R2, R3', {R2: 0x2L, R3: 0x1L}), {zf: 0x0L, R2: 0x2L, nf: 0x0L, R3: 0x1L})
-        self.assertEqual(compute('BICS   R2, R2, R3', {R2: 0x1L, R3: 0x2L}), {zf: 0x0L, R2: 0x1L, nf: 0x0L, R3: 0x2L})
-        self.assertEqual(compute('BICS   R2, R2, R3', {R2: 0x0L, R3: 0xffffffffL}), {zf: 0x1L, R2: 0x0L, nf: 0x0L, R3: 0xffffffffL})
-        self.assertEqual(compute('BICS   R2, R2, R3', {R2: 0xffffffffL, R3: 0x0L}), {zf: 0x0L, R2: 0xffffffffL, nf: 0x1L, R3: 0x0L})
-        self.assertEqual(compute('BICS   R2, R2, R3', {R2: 0x1L, R3: 0x7fffffffL}), {zf: 0x1L, R2: 0x0L, nf: 0x0L, R3: 0x7fffffffL})
-        self.assertEqual(compute('BICS   R2, R2, R3', {R2: 0x7fffffffL, R3: 0x1L}), {zf: 0x0L, R2: 0x7ffffffeL, nf: 0x0L, R3: 0x1L})
-        self.assertEqual(compute('BICS   R2, R2, R3', {R2: 0x80000000L, R3: 0x80000001L}), {zf: 0x1L, R2: 0x0L, nf: 0x0L, R3: 0x80000001L})
-        self.assertEqual(compute('BICS   R2, R2, R3', {R2: 0x80000001L, R3: 0x80000000L}), {zf: 0x0L, R2: 0x1L, nf: 0x0L, R3: 0x80000000L})
+        self.assertEqual(compute('BICS   R2, R2, R3', {R2: 0x2, R3: 0x1}), {zf: 0x0, R2: 0x2, nf: 0x0, R3: 0x1})
+        self.assertEqual(compute('BICS   R2, R2, R3', {R2: 0x1, R3: 0x2}), {zf: 0x0, R2: 0x1, nf: 0x0, R3: 0x2})
+        self.assertEqual(compute('BICS   R2, R2, R3', {R2: 0x0, R3: 0xffffffff}), {zf: 0x1, R2: 0x0, nf: 0x0, R3: 0xffffffff})
+        self.assertEqual(compute('BICS   R2, R2, R3', {R2: 0xffffffff, R3: 0x0}), {zf: 0x0, R2: 0xffffffff, nf: 0x1, R3: 0x0})
+        self.assertEqual(compute('BICS   R2, R2, R3', {R2: 0x1, R3: 0x7fffffff}), {zf: 0x1, R2: 0x0, nf: 0x0, R3: 0x7fffffff})
+        self.assertEqual(compute('BICS   R2, R2, R3', {R2: 0x7fffffff, R3: 0x1}), {zf: 0x0, R2: 0x7ffffffe, nf: 0x0, R3: 0x1})
+        self.assertEqual(compute('BICS   R2, R2, R3', {R2: 0x80000000, R3: 0x80000001}), {zf: 0x1, R2: 0x0, nf: 0x0, R3: 0x80000001})
+        self.assertEqual(compute('BICS   R2, R2, R3', {R2: 0x80000001, R3: 0x80000000}), {zf: 0x0, R2: 0x1, nf: 0x0, R3: 0x80000000})
 
     def test_CMN(self):
-        self.assertEqual(compute('CMN   R2, R3', {R2: 0x2L, R3: 0x1L}), {R2: 0x2L, R3: 0x1L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x0L})
-        self.assertEqual(compute('CMN   R2, R3', {R2: 0x1L, R3: 0x2L}), {R2: 0x1L, R3: 0x2L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x0L})
-        self.assertEqual(compute('CMN   R2, R3', {R2: 0x0L, R3: 0xffffffffL}), {R2: 0x0L, R3: 0xffffffffL, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x1L})
-        self.assertEqual(compute('CMN   R2, R3', {R2: 0xffffffffL, R3: 0x0L}), {R2: 0xffffffffL, R3: 0x0L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x1L})
-        self.assertEqual(compute('CMN   R2, R3', {R2: 0x1L, R3: 0x7fffffffL}), {R2: 0x1L, R3: 0x7fffffffL, of: 0x1L, zf: 0x0L, cf: 0x0L, nf: 0x1L})
-        self.assertEqual(compute('CMN   R2, R3', {R2: 0x7fffffffL, R3: 0x1L}), {R2: 0x7fffffffL, R3: 0x1L, of: 0x1L, zf: 0x0L, cf: 0x0L, nf: 0x1L})
-        self.assertEqual(compute('CMN   R2, R3', {R2: 0x80000000L, R3: 0x80000001L}), {R2: 0x80000000L, R3: 0x80000001L, of: 0x1L, zf: 0x0L, cf: 0x1L, nf: 0x0L})
-        self.assertEqual(compute('CMN   R2, R3', {R2: 0x80000001L, R3: 0x80000000L}), {R2: 0x80000001L, R3: 0x80000000L, of: 0x1L, zf: 0x0L, cf: 0x1L, nf: 0x0L})
+        self.assertEqual(compute('CMN   R2, R3', {R2: 0x2, R3: 0x1}), {R2: 0x2, R3: 0x1, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x0})
+        self.assertEqual(compute('CMN   R2, R3', {R2: 0x1, R3: 0x2}), {R2: 0x1, R3: 0x2, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x0})
+        self.assertEqual(compute('CMN   R2, R3', {R2: 0x0, R3: 0xffffffff}), {R2: 0x0, R3: 0xffffffff, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x1})
+        self.assertEqual(compute('CMN   R2, R3', {R2: 0xffffffff, R3: 0x0}), {R2: 0xffffffff, R3: 0x0, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x1})
+        self.assertEqual(compute('CMN   R2, R3', {R2: 0x1, R3: 0x7fffffff}), {R2: 0x1, R3: 0x7fffffff, of: 0x1, zf: 0x0, cf: 0x0, nf: 0x1})
+        self.assertEqual(compute('CMN   R2, R3', {R2: 0x7fffffff, R3: 0x1}), {R2: 0x7fffffff, R3: 0x1, of: 0x1, zf: 0x0, cf: 0x0, nf: 0x1})
+        self.assertEqual(compute('CMN   R2, R3', {R2: 0x80000000, R3: 0x80000001}), {R2: 0x80000000, R3: 0x80000001, of: 0x1, zf: 0x0, cf: 0x1, nf: 0x0})
+        self.assertEqual(compute('CMN   R2, R3', {R2: 0x80000001, R3: 0x80000000}), {R2: 0x80000001, R3: 0x80000000, of: 0x1, zf: 0x0, cf: 0x1, nf: 0x0})
 
     def test_CMP(self):
-        self.assertEqual(compute('CMP   R2, R3', {R2: 0x2L, R3: 0x1L}), {R2: 0x2L, R3: 0x1L, of: 0x0L, zf: 0x0L, cf: 0x1L, nf: 0x0L})
-        self.assertEqual(compute('CMP   R2, R3', {R2: 0x1L, R3: 0x2L}), {R2: 0x1L, R3: 0x2L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x1L})
-        self.assertEqual(compute('CMP   R2, R3', {R2: 0x0L, R3: 0xffffffffL}), {R2: 0x0L, R3: 0xffffffffL, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x0L})
-        self.assertEqual(compute('CMP   R2, R3', {R2: 0xffffffffL, R3: 0x0L}), {R2: 0xffffffffL, R3: 0x0L, of: 0x0L, zf: 0x0L, cf: 0x1L, nf: 0x1L})
-        self.assertEqual(compute('CMP   R2, R3', {R2: 0x1L, R3: 0x7fffffffL}), {R2: 0x1L, R3: 0x7fffffffL, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x1L})
-        self.assertEqual(compute('CMP   R2, R3', {R2: 0x7fffffffL, R3: 0x1L}), {R2: 0x7fffffffL, R3: 0x1L, of: 0x0L, zf: 0x0L, cf: 0x1L, nf: 0x0L})
-        self.assertEqual(compute('CMP   R2, R3', {R2: 0x80000000L, R3: 0x80000001L}), {R2: 0x80000000L, R3: 0x80000001L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x1L})
-        self.assertEqual(compute('CMP   R2, R3', {R2: 0x80000001L, R3: 0x80000000L}), {R2: 0x80000001L, R3: 0x80000000L, of: 0x0L, zf: 0x0L, cf: 0x1L, nf: 0x0L})
+        self.assertEqual(compute('CMP   R2, R3', {R2: 0x2, R3: 0x1}), {R2: 0x2, R3: 0x1, of: 0x0, zf: 0x0, cf: 0x1, nf: 0x0})
+        self.assertEqual(compute('CMP   R2, R3', {R2: 0x1, R3: 0x2}), {R2: 0x1, R3: 0x2, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x1})
+        self.assertEqual(compute('CMP   R2, R3', {R2: 0x0, R3: 0xffffffff}), {R2: 0x0, R3: 0xffffffff, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x0})
+        self.assertEqual(compute('CMP   R2, R3', {R2: 0xffffffff, R3: 0x0}), {R2: 0xffffffff, R3: 0x0, of: 0x0, zf: 0x0, cf: 0x1, nf: 0x1})
+        self.assertEqual(compute('CMP   R2, R3', {R2: 0x1, R3: 0x7fffffff}), {R2: 0x1, R3: 0x7fffffff, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x1})
+        self.assertEqual(compute('CMP   R2, R3', {R2: 0x7fffffff, R3: 0x1}), {R2: 0x7fffffff, R3: 0x1, of: 0x0, zf: 0x0, cf: 0x1, nf: 0x0})
+        self.assertEqual(compute('CMP   R2, R3', {R2: 0x80000000, R3: 0x80000001}), {R2: 0x80000000, R3: 0x80000001, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x1})
+        self.assertEqual(compute('CMP   R2, R3', {R2: 0x80000001, R3: 0x80000000}), {R2: 0x80000001, R3: 0x80000000, of: 0x0, zf: 0x0, cf: 0x1, nf: 0x0})
 
     def test_EORS(self):
-        self.assertEqual(compute('EORS   R2, R2, R3', {R2: 0x2L, R3: 0x1L}), {zf: 0x0L, R2: 0x3L, nf: 0x0L, R3: 0x1L})
-        self.assertEqual(compute('EORS   R2, R2, R3', {R2: 0x1L, R3: 0x2L}), {zf: 0x0L, R2: 0x3L, nf: 0x0L, R3: 0x2L})
-        self.assertEqual(compute('EORS   R2, R2, R3', {R2: 0x0L, R3: 0xffffffffL}), {zf: 0x0L, R2: 0xffffffffL, nf: 0x1L, R3: 0xffffffffL})
-        self.assertEqual(compute('EORS   R2, R2, R3', {R2: 0xffffffffL, R3: 0x0L}), {zf: 0x0L, R2: 0xffffffffL, nf: 0x1L, R3: 0x0L})
-        self.assertEqual(compute('EORS   R2, R2, R3', {R2: 0x1L, R3: 0x7fffffffL}), {zf: 0x0L, R2: 0x7ffffffeL, nf: 0x0L, R3: 0x7fffffffL})
-        self.assertEqual(compute('EORS   R2, R2, R3', {R2: 0x7fffffffL, R3: 0x1L}), {zf: 0x0L, R2: 0x7ffffffeL, nf: 0x0L, R3: 0x1L})
-        self.assertEqual(compute('EORS   R2, R2, R3', {R2: 0x80000000L, R3: 0x80000001L}), {zf: 0x0L, R2: 0x1L, nf: 0x0L, R3: 0x80000001L})
-        self.assertEqual(compute('EORS   R2, R2, R3', {R2: 0x80000001L, R3: 0x80000000L}), {zf: 0x0L, R2: 0x1L, nf: 0x0L, R3: 0x80000000L})
+        self.assertEqual(compute('EORS   R2, R2, R3', {R2: 0x2, R3: 0x1}), {zf: 0x0, R2: 0x3, nf: 0x0, R3: 0x1})
+        self.assertEqual(compute('EORS   R2, R2, R3', {R2: 0x1, R3: 0x2}), {zf: 0x0, R2: 0x3, nf: 0x0, R3: 0x2})
+        self.assertEqual(compute('EORS   R2, R2, R3', {R2: 0x0, R3: 0xffffffff}), {zf: 0x0, R2: 0xffffffff, nf: 0x1, R3: 0xffffffff})
+        self.assertEqual(compute('EORS   R2, R2, R3', {R2: 0xffffffff, R3: 0x0}), {zf: 0x0, R2: 0xffffffff, nf: 0x1, R3: 0x0})
+        self.assertEqual(compute('EORS   R2, R2, R3', {R2: 0x1, R3: 0x7fffffff}), {zf: 0x0, R2: 0x7ffffffe, nf: 0x0, R3: 0x7fffffff})
+        self.assertEqual(compute('EORS   R2, R2, R3', {R2: 0x7fffffff, R3: 0x1}), {zf: 0x0, R2: 0x7ffffffe, nf: 0x0, R3: 0x1})
+        self.assertEqual(compute('EORS   R2, R2, R3', {R2: 0x80000000, R3: 0x80000001}), {zf: 0x0, R2: 0x1, nf: 0x0, R3: 0x80000001})
+        self.assertEqual(compute('EORS   R2, R2, R3', {R2: 0x80000001, R3: 0x80000000}), {zf: 0x0, R2: 0x1, nf: 0x0, R3: 0x80000000})
 
     def test_MULS(self):
-        self.assertEqual(compute('MULS   R2, R2, R3', {R2: 0x2L, R3: 0x1L}), {zf: 0x0L, R2: 0x2L, nf: 0x0L, R3: 0x1L})
-        self.assertEqual(compute('MULS   R2, R2, R3', {R2: 0x1L, R3: 0x2L}), {zf: 0x0L, R2: 0x2L, nf: 0x0L, R3: 0x2L})
-        self.assertEqual(compute('MULS   R2, R2, R3', {R2: 0x0L, R3: 0xffffffffL}), {zf: 0x1L, R2: 0x0L, nf: 0x0L, R3: 0xffffffffL})
-        self.assertEqual(compute('MULS   R2, R2, R3', {R2: 0xffffffffL, R3: 0x0L}), {zf: 0x1L, R2: 0x0L, nf: 0x0L, R3: 0x0L})
-        self.assertEqual(compute('MULS   R2, R2, R3', {R2: 0x1L, R3: 0x7fffffffL}), {zf: 0x0L, R2: 0x7fffffffL, nf: 0x0L, R3: 0x7fffffffL})
-        self.assertEqual(compute('MULS   R2, R2, R3', {R2: 0x7fffffffL, R3: 0x1L}), {zf: 0x0L, R2: 0x7fffffffL, nf: 0x0L, R3: 0x1L})
-        self.assertEqual(compute('MULS   R2, R2, R3', {R2: 0x80000000L, R3: 0x80000001L}), {zf: 0x0L, R2: 0x80000000L, nf: 0x1L, R3: 0x80000001L})
-        self.assertEqual(compute('MULS   R2, R2, R3', {R2: 0x80000001L, R3: 0x80000000L}), {zf: 0x0L, R2: 0x80000000L, nf: 0x1L, R3: 0x80000000L})
+        self.assertEqual(compute('MULS   R2, R2, R3', {R2: 0x2, R3: 0x1}), {zf: 0x0, R2: 0x2, nf: 0x0, R3: 0x1})
+        self.assertEqual(compute('MULS   R2, R2, R3', {R2: 0x1, R3: 0x2}), {zf: 0x0, R2: 0x2, nf: 0x0, R3: 0x2})
+        self.assertEqual(compute('MULS   R2, R2, R3', {R2: 0x0, R3: 0xffffffff}), {zf: 0x1, R2: 0x0, nf: 0x0, R3: 0xffffffff})
+        self.assertEqual(compute('MULS   R2, R2, R3', {R2: 0xffffffff, R3: 0x0}), {zf: 0x1, R2: 0x0, nf: 0x0, R3: 0x0})
+        self.assertEqual(compute('MULS   R2, R2, R3', {R2: 0x1, R3: 0x7fffffff}), {zf: 0x0, R2: 0x7fffffff, nf: 0x0, R3: 0x7fffffff})
+        self.assertEqual(compute('MULS   R2, R2, R3', {R2: 0x7fffffff, R3: 0x1}), {zf: 0x0, R2: 0x7fffffff, nf: 0x0, R3: 0x1})
+        self.assertEqual(compute('MULS   R2, R2, R3', {R2: 0x80000000, R3: 0x80000001}), {zf: 0x0, R2: 0x80000000, nf: 0x1, R3: 0x80000001})
+        self.assertEqual(compute('MULS   R2, R2, R3', {R2: 0x80000001, R3: 0x80000000}), {zf: 0x0, R2: 0x80000000, nf: 0x1, R3: 0x80000000})
 
     def test_ORRS(self):
-        self.assertEqual(compute('ORRS   R2, R2, R3', {R2: 0x2L, R3: 0x1L}), {zf: 0x0L, R2: 0x3L, nf: 0x0L, R3: 0x1L})
-        self.assertEqual(compute('ORRS   R2, R2, R3', {R2: 0x1L, R3: 0x2L}), {zf: 0x0L, R2: 0x3L, nf: 0x0L, R3: 0x2L})
-        self.assertEqual(compute('ORRS   R2, R2, R3', {R2: 0x0L, R3: 0xffffffffL}), {zf: 0x0L, R2: 0xffffffffL, nf: 0x1L, R3: 0xffffffffL})
-        self.assertEqual(compute('ORRS   R2, R2, R3', {R2: 0xffffffffL, R3: 0x0L}), {zf: 0x0L, R2: 0xffffffffL, nf: 0x1L, R3: 0x0L})
-        self.assertEqual(compute('ORRS   R2, R2, R3', {R2: 0x1L, R3: 0x7fffffffL}), {zf: 0x0L, R2: 0x7fffffffL, nf: 0x0L, R3: 0x7fffffffL})
-        self.assertEqual(compute('ORRS   R2, R2, R3', {R2: 0x7fffffffL, R3: 0x1L}), {zf: 0x0L, R2: 0x7fffffffL, nf: 0x0L, R3: 0x1L})
-        self.assertEqual(compute('ORRS   R2, R2, R3', {R2: 0x80000000L, R3: 0x80000001L}), {zf: 0x0L, R2: 0x80000001L, nf: 0x1L, R3: 0x80000001L})
-        self.assertEqual(compute('ORRS   R2, R2, R3', {R2: 0x80000001L, R3: 0x80000000L}), {zf: 0x0L, R2: 0x80000001L, nf: 0x1L, R3: 0x80000000L})
+        self.assertEqual(compute('ORRS   R2, R2, R3', {R2: 0x2, R3: 0x1}), {zf: 0x0, R2: 0x3, nf: 0x0, R3: 0x1})
+        self.assertEqual(compute('ORRS   R2, R2, R3', {R2: 0x1, R3: 0x2}), {zf: 0x0, R2: 0x3, nf: 0x0, R3: 0x2})
+        self.assertEqual(compute('ORRS   R2, R2, R3', {R2: 0x0, R3: 0xffffffff}), {zf: 0x0, R2: 0xffffffff, nf: 0x1, R3: 0xffffffff})
+        self.assertEqual(compute('ORRS   R2, R2, R3', {R2: 0xffffffff, R3: 0x0}), {zf: 0x0, R2: 0xffffffff, nf: 0x1, R3: 0x0})
+        self.assertEqual(compute('ORRS   R2, R2, R3', {R2: 0x1, R3: 0x7fffffff}), {zf: 0x0, R2: 0x7fffffff, nf: 0x0, R3: 0x7fffffff})
+        self.assertEqual(compute('ORRS   R2, R2, R3', {R2: 0x7fffffff, R3: 0x1}), {zf: 0x0, R2: 0x7fffffff, nf: 0x0, R3: 0x1})
+        self.assertEqual(compute('ORRS   R2, R2, R3', {R2: 0x80000000, R3: 0x80000001}), {zf: 0x0, R2: 0x80000001, nf: 0x1, R3: 0x80000001})
+        self.assertEqual(compute('ORRS   R2, R2, R3', {R2: 0x80000001, R3: 0x80000000}), {zf: 0x0, R2: 0x80000001, nf: 0x1, R3: 0x80000000})
 
     def test_RSBS(self):
-        self.assertEqual(compute('RSBS   R2, R2, R3', {R2: 0x2L, R3: 0x1L}), {R2: 0xffffffffL, R3: 0x1L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x1L})
-        self.assertEqual(compute('RSBS   R2, R2, R3', {R2: 0x1L, R3: 0x2L}), {R2: 0x1L, R3: 0x2L, of: 0x0L, zf: 0x0L, cf: 0x1L, nf: 0x0L})
-        self.assertEqual(compute('RSBS   R2, R2, R3', {R2: 0x0L, R3: 0xffffffffL}), {R2: 0xffffffffL, R3: 0xffffffffL, of: 0x0L, zf: 0x0L, cf: 0x1L, nf: 0x1L})
-        self.assertEqual(compute('RSBS   R2, R2, R3', {R2: 0xffffffffL, R3: 0x0L}), {R2: 0x1L, R3: 0x0L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x0L})
-        self.assertEqual(compute('RSBS   R2, R2, R3', {R2: 0x1L, R3: 0x7fffffffL}), {R2: 0x7ffffffeL, R3: 0x7fffffffL, of: 0x0L, zf: 0x0L, cf: 0x1L, nf: 0x0L})
-        self.assertEqual(compute('RSBS   R2, R2, R3', {R2: 0x7fffffffL, R3: 0x1L}), {R2: 0x80000002L, R3: 0x1L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x1L})
-        self.assertEqual(compute('RSBS   R2, R2, R3', {R2: 0x80000000L, R3: 0x80000001L}), {R2: 0x1L, R3: 0x80000001L, of: 0x0L, zf: 0x0L, cf: 0x1L, nf: 0x0L})
-        self.assertEqual(compute('RSBS   R2, R2, R3', {R2: 0x80000001L, R3: 0x80000000L}), {R2: 0xffffffffL, R3: 0x80000000L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x1L})
+        self.assertEqual(compute('RSBS   R2, R2, R3', {R2: 0x2, R3: 0x1}), {R2: 0xffffffff, R3: 0x1, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x1})
+        self.assertEqual(compute('RSBS   R2, R2, R3', {R2: 0x1, R3: 0x2}), {R2: 0x1, R3: 0x2, of: 0x0, zf: 0x0, cf: 0x1, nf: 0x0})
+        self.assertEqual(compute('RSBS   R2, R2, R3', {R2: 0x0, R3: 0xffffffff}), {R2: 0xffffffff, R3: 0xffffffff, of: 0x0, zf: 0x0, cf: 0x1, nf: 0x1})
+        self.assertEqual(compute('RSBS   R2, R2, R3', {R2: 0xffffffff, R3: 0x0}), {R2: 0x1, R3: 0x0, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x0})
+        self.assertEqual(compute('RSBS   R2, R2, R3', {R2: 0x1, R3: 0x7fffffff}), {R2: 0x7ffffffe, R3: 0x7fffffff, of: 0x0, zf: 0x0, cf: 0x1, nf: 0x0})
+        self.assertEqual(compute('RSBS   R2, R2, R3', {R2: 0x7fffffff, R3: 0x1}), {R2: 0x80000002, R3: 0x1, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x1})
+        self.assertEqual(compute('RSBS   R2, R2, R3', {R2: 0x80000000, R3: 0x80000001}), {R2: 0x1, R3: 0x80000001, of: 0x0, zf: 0x0, cf: 0x1, nf: 0x0})
+        self.assertEqual(compute('RSBS   R2, R2, R3', {R2: 0x80000001, R3: 0x80000000}), {R2: 0xffffffff, R3: 0x80000000, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x1})
 
     def test_SUBS(self):
-        self.assertEqual(compute('SUBS   R2, R2, R3', {R2: 0x2L, R3: 0x1L}), {R2: 0x1L, R3: 0x1L, of: 0x0L, zf: 0x0L, cf: 0x1L, nf: 0x0L})
-        self.assertEqual(compute('SUBS   R2, R2, R3', {R2: 0x1L, R3: 0x2L}), {R2: 0xffffffffL, R3: 0x2L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x1L})
-        self.assertEqual(compute('SUBS   R2, R2, R3', {R2: 0x0L, R3: 0xffffffffL}), {R2: 0x1L, R3: 0xffffffffL, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x0L})
-        self.assertEqual(compute('SUBS   R2, R2, R3', {R2: 0xffffffffL, R3: 0x0L}), {R2: 0xffffffffL, R3: 0x0L, of: 0x0L, zf: 0x0L, cf: 0x1L, nf: 0x1L})
-        self.assertEqual(compute('SUBS   R2, R2, R3', {R2: 0x1L, R3: 0x7fffffffL}), {R2: 0x80000002L, R3: 0x7fffffffL, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x1L})
-        self.assertEqual(compute('SUBS   R2, R2, R3', {R2: 0x7fffffffL, R3: 0x1L}), {R2: 0x7ffffffeL, R3: 0x1L, of: 0x0L, zf: 0x0L, cf: 0x1L, nf: 0x0L})
-        self.assertEqual(compute('SUBS   R2, R2, R3', {R2: 0x80000000L, R3: 0x80000001L}), {R2: 0xffffffffL, R3: 0x80000001L, of: 0x0L, zf: 0x0L, cf: 0x0L, nf: 0x1L})
-        self.assertEqual(compute('SUBS   R2, R2, R3', {R2: 0x80000001L, R3: 0x80000000L}), {R2: 0x1L, R3: 0x80000000L, of: 0x0L, zf: 0x0L, cf: 0x1L, nf: 0x0L})
+        self.assertEqual(compute('SUBS   R2, R2, R3', {R2: 0x2, R3: 0x1}), {R2: 0x1, R3: 0x1, of: 0x0, zf: 0x0, cf: 0x1, nf: 0x0})
+        self.assertEqual(compute('SUBS   R2, R2, R3', {R2: 0x1, R3: 0x2}), {R2: 0xffffffff, R3: 0x2, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x1})
+        self.assertEqual(compute('SUBS   R2, R2, R3', {R2: 0x0, R3: 0xffffffff}), {R2: 0x1, R3: 0xffffffff, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x0})
+        self.assertEqual(compute('SUBS   R2, R2, R3', {R2: 0xffffffff, R3: 0x0}), {R2: 0xffffffff, R3: 0x0, of: 0x0, zf: 0x0, cf: 0x1, nf: 0x1})
+        self.assertEqual(compute('SUBS   R2, R2, R3', {R2: 0x1, R3: 0x7fffffff}), {R2: 0x80000002, R3: 0x7fffffff, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x1})
+        self.assertEqual(compute('SUBS   R2, R2, R3', {R2: 0x7fffffff, R3: 0x1}), {R2: 0x7ffffffe, R3: 0x1, of: 0x0, zf: 0x0, cf: 0x1, nf: 0x0})
+        self.assertEqual(compute('SUBS   R2, R2, R3', {R2: 0x80000000, R3: 0x80000001}), {R2: 0xffffffff, R3: 0x80000001, of: 0x0, zf: 0x0, cf: 0x0, nf: 0x1})
+        self.assertEqual(compute('SUBS   R2, R2, R3', {R2: 0x80000001, R3: 0x80000000}), {R2: 0x1, R3: 0x80000000, of: 0x0, zf: 0x0, cf: 0x1, nf: 0x0})
 
     def test_TEQ(self):
-        self.assertEqual(compute('TEQ   R2, R3', {R2: 0x2L, R3: 0x1L}), {zf: 0x0L, R2: 0x2L, nf: 0x0L, R3: 0x1L})
-        self.assertEqual(compute('TEQ   R2, R3', {R2: 0x1L, R3: 0x2L}), {zf: 0x0L, R2: 0x1L, nf: 0x0L, R3: 0x2L})
-        self.assertEqual(compute('TEQ   R2, R3', {R2: 0x0L, R3: 0xffffffffL}), {zf: 0x0L, R2: 0x0L, nf: 0x1L, R3: 0xffffffffL})
-        self.assertEqual(compute('TEQ   R2, R3', {R2: 0xffffffffL, R3: 0x0L}), {zf: 0x0L, R2: 0xffffffffL, nf: 0x1L, R3: 0x0L})
-        self.assertEqual(compute('TEQ   R2, R3', {R2: 0x1L, R3: 0x7fffffffL}), {zf: 0x0L, R2: 0x1L, nf: 0x0L, R3: 0x7fffffffL})
-        self.assertEqual(compute('TEQ   R2, R3', {R2: 0x7fffffffL, R3: 0x1L}), {zf: 0x0L, R2: 0x7fffffffL, nf: 0x0L, R3: 0x1L})
-        self.assertEqual(compute('TEQ   R2, R3', {R2: 0x80000000L, R3: 0x80000001L}), {zf: 0x0L, R2: 0x80000000L, nf: 0x0L, R3: 0x80000001L})
-        self.assertEqual(compute('TEQ   R2, R3', {R2: 0x80000001L, R3: 0x80000000L}), {zf: 0x0L, R2: 0x80000001L, nf: 0x0L, R3: 0x80000000L})
+        self.assertEqual(compute('TEQ   R2, R3', {R2: 0x2, R3: 0x1}), {zf: 0x0, R2: 0x2, nf: 0x0, R3: 0x1})
+        self.assertEqual(compute('TEQ   R2, R3', {R2: 0x1, R3: 0x2}), {zf: 0x0, R2: 0x1, nf: 0x0, R3: 0x2})
+        self.assertEqual(compute('TEQ   R2, R3', {R2: 0x0, R3: 0xffffffff}), {zf: 0x0, R2: 0x0, nf: 0x1, R3: 0xffffffff})
+        self.assertEqual(compute('TEQ   R2, R3', {R2: 0xffffffff, R3: 0x0}), {zf: 0x0, R2: 0xffffffff, nf: 0x1, R3: 0x0})
+        self.assertEqual(compute('TEQ   R2, R3', {R2: 0x1, R3: 0x7fffffff}), {zf: 0x0, R2: 0x1, nf: 0x0, R3: 0x7fffffff})
+        self.assertEqual(compute('TEQ   R2, R3', {R2: 0x7fffffff, R3: 0x1}), {zf: 0x0, R2: 0x7fffffff, nf: 0x0, R3: 0x1})
+        self.assertEqual(compute('TEQ   R2, R3', {R2: 0x80000000, R3: 0x80000001}), {zf: 0x0, R2: 0x80000000, nf: 0x0, R3: 0x80000001})
+        self.assertEqual(compute('TEQ   R2, R3', {R2: 0x80000001, R3: 0x80000000}), {zf: 0x0, R2: 0x80000001, nf: 0x0, R3: 0x80000000})
 
     def test_TST(self):
-        self.assertEqual(compute('TST   R2, R3', {R2: 0x2L, R3: 0x1L}), {zf: 0x1L, R2: 0x2L, nf: 0x0L, R3: 0x1L})
-        self.assertEqual(compute('TST   R2, R3', {R2: 0x1L, R3: 0x2L}), {zf: 0x1L, R2: 0x1L, nf: 0x0L, R3: 0x2L})
-        self.assertEqual(compute('TST   R2, R3', {R2: 0x0L, R3: 0xffffffffL}), {zf: 0x1L, R2: 0x0L, nf: 0x0L, R3: 0xffffffffL})
-        self.assertEqual(compute('TST   R2, R3', {R2: 0xffffffffL, R3: 0x0L}), {zf: 0x1L, R2: 0xffffffffL, nf: 0x0L, R3: 0x0L})
-        self.assertEqual(compute('TST   R2, R3', {R2: 0x1L, R3: 0x7fffffffL}), {zf: 0x0L, R2: 0x1L, nf: 0x0L, R3: 0x7fffffffL})
-        self.assertEqual(compute('TST   R2, R3', {R2: 0x7fffffffL, R3: 0x1L}), {zf: 0x0L, R2: 0x7fffffffL, nf: 0x0L, R3: 0x1L})
-        self.assertEqual(compute('TST   R2, R3', {R2: 0x80000000L, R3: 0x80000001L}), {zf: 0x0L, R2: 0x80000000L, nf: 0x1L, R3: 0x80000001L})
-        self.assertEqual(compute('TST   R2, R3', {R2: 0x80000001L, R3: 0x80000000L}), {zf: 0x0L, R2: 0x80000001L, nf: 0x1L, R3: 0x80000000L})
+        self.assertEqual(compute('TST   R2, R3', {R2: 0x2, R3: 0x1}), {zf: 0x1, R2: 0x2, nf: 0x0, R3: 0x1})
+        self.assertEqual(compute('TST   R2, R3', {R2: 0x1, R3: 0x2}), {zf: 0x1, R2: 0x1, nf: 0x0, R3: 0x2})
+        self.assertEqual(compute('TST   R2, R3', {R2: 0x0, R3: 0xffffffff}), {zf: 0x1, R2: 0x0, nf: 0x0, R3: 0xffffffff})
+        self.assertEqual(compute('TST   R2, R3', {R2: 0xffffffff, R3: 0x0}), {zf: 0x1, R2: 0xffffffff, nf: 0x0, R3: 0x0})
+        self.assertEqual(compute('TST   R2, R3', {R2: 0x1, R3: 0x7fffffff}), {zf: 0x0, R2: 0x1, nf: 0x0, R3: 0x7fffffff})
+        self.assertEqual(compute('TST   R2, R3', {R2: 0x7fffffff, R3: 0x1}), {zf: 0x0, R2: 0x7fffffff, nf: 0x0, R3: 0x1})
+        self.assertEqual(compute('TST   R2, R3', {R2: 0x80000000, R3: 0x80000001}), {zf: 0x0, R2: 0x80000000, nf: 0x1, R3: 0x80000001})
+        self.assertEqual(compute('TST   R2, R3', {R2: 0x80000001, R3: 0x80000000}), {zf: 0x0, R2: 0x80000001, nf: 0x1, R3: 0x80000000})
 
     def test_UMUL(self):
-        self.assertEqual(compute('UMULL R1, R2, R4, R5', {R4: 0x0L, R5: 0x0L}), {R1: 0x0L, R2: 0x0L, R4: 0x0L, R5: 0x0L})
-        self.assertEqual(compute('UMULL R0, R1, R2, R3', {R2: 0x1L, R3: 0x80808080L}), {R0: 0x80808080L, R1: 0x0L, R2: 0x1L, R3: 0x80808080L})
-        self.assertEqual(compute('UMULL R2, R3, R4, R5', {R4: 0x12345678L, R5: 0x87654321L}), {R2: 0x70b88d78L, R3: 0x09a0cd05L, R4: 0x12345678L, R5: 0x87654321L})
-        self.assertEqual(compute('UMULL R2, R3, R4, R5', {R4: 0xffffffffL, R5: 0x00000002L}), {R2: 0xfffffffeL, R3: 0x00000001L, R4: 0xffffffffL, R5: 0x00000002L})
+        self.assertEqual(compute('UMULL R1, R2, R4, R5', {R4: 0x0, R5: 0x0}), {R1: 0x0, R2: 0x0, R4: 0x0, R5: 0x0})
+        self.assertEqual(compute('UMULL R0, R1, R2, R3', {R2: 0x1, R3: 0x80808080}), {R0: 0x80808080, R1: 0x0, R2: 0x1, R3: 0x80808080})
+        self.assertEqual(compute('UMULL R2, R3, R4, R5', {R4: 0x12345678, R5: 0x87654321}), {R2: 0x70b88d78, R3: 0x09a0cd05, R4: 0x12345678, R5: 0x87654321})
+        self.assertEqual(compute('UMULL R2, R3, R4, R5', {R4: 0xffffffff, R5: 0x00000002}), {R2: 0xfffffffe, R3: 0x00000001, R4: 0xffffffff, R5: 0x00000002})
 
     def test_UMLAL(self):
-        self.assertEqual(compute('UMLAL R1, R2, R4, R5', {R1: 0x0L, R2: 0x0L, R4: 0x1L, R5: 0x0L}), {R1: 0x0L, R2: 0x0L, R4: 0x1L, R5: 0x0L})
-        self.assertEqual(compute('UMLAL R0, R1, R2, R3', {R0: 0x0L, R1: 0x0L, R2: 0x1L, R3: 0x80808080L}), {R0: 0x80808080L, R1: 0x0L, R2: 0x1L, R3: 0x80808080L})
-        self.assertEqual(compute('UMLAL R2, R3, R4, R5', {R2: 0xffffffffL, R3: 0x0L, R4: 0x12345678L, R5: 0x87654321L}), {R2: 0x70b88d77L, R3: 0x09a0cd06L, R4: 0x12345678L, R5: 0x87654321L})
-        self.assertEqual(compute('UMLAL R2, R3, R4, R5', {R2: 0xffffffffL, R3: 0x2L, R4: 0x12345678L, R5: 0x87654321L}), {R2: 0x70b88d77L, R3: 0x09a0cd08L, R4: 0x12345678L, R5: 0x87654321L})
+        self.assertEqual(compute('UMLAL R1, R2, R4, R5', {R1: 0x0, R2: 0x0, R4: 0x1, R5: 0x0}), {R1: 0x0, R2: 0x0, R4: 0x1, R5: 0x0})
+        self.assertEqual(compute('UMLAL R0, R1, R2, R3', {R0: 0x0, R1: 0x0, R2: 0x1, R3: 0x80808080}), {R0: 0x80808080, R1: 0x0, R2: 0x1, R3: 0x80808080})
+        self.assertEqual(compute('UMLAL R2, R3, R4, R5', {R2: 0xffffffff, R3: 0x0, R4: 0x12345678, R5: 0x87654321}), {R2: 0x70b88d77, R3: 0x09a0cd06, R4: 0x12345678, R5: 0x87654321})
+        self.assertEqual(compute('UMLAL R2, R3, R4, R5', {R2: 0xffffffff, R3: 0x2, R4: 0x12345678, R5: 0x87654321}), {R2: 0x70b88d77, R3: 0x09a0cd08, R4: 0x12345678, R5: 0x87654321})
 
     def test_SMUL(self):
-        self.assertEqual(compute('SMULL R1, R2, R4, R5', {R4: 0x0L, R5: 0x0L}), {R1: 0x0L, R2: 0x0L, R4: 0x0L, R5: 0x0L})
-        self.assertEqual(compute('SMULL R0, R1, R2, R3', {R2: 0x1L, R3: 0x80808080L}), {R0: 0x80808080L, R1: 0xffffffffL, R2: 0x1L, R3: 0x80808080L})
-        self.assertEqual(compute('SMULL R0, R1, R2, R3', {R2: 0xffff0000L, R3: 0xffff0000L}), {R0: 0x0L, R1: 0x1L, R2: 0xffff0000L, R3: 0xffff0000L})
-        self.assertEqual(compute('SMULL R2, R3, R4, R5', {R4: 0x12345678L, R5: 0x87654321L}), {R2: 0x70b88d78L, R3: 0xf76c768dL, R4: 0x12345678L, R5: 0x87654321L})
-        self.assertEqual(compute('SMULL R2, R3, R4, R5', {R4: 0xffffffffL, R5: 0x00000002L}), {R2: 0xfffffffeL, R3: 0xffffffffL, R4: 0xffffffffL, R5: 0x00000002L})
+        self.assertEqual(compute('SMULL R1, R2, R4, R5', {R4: 0x0, R5: 0x0}), {R1: 0x0, R2: 0x0, R4: 0x0, R5: 0x0})
+        self.assertEqual(compute('SMULL R0, R1, R2, R3', {R2: 0x1, R3: 0x80808080}), {R0: 0x80808080, R1: 0xffffffff, R2: 0x1, R3: 0x80808080})
+        self.assertEqual(compute('SMULL R0, R1, R2, R3', {R2: 0xffff0000, R3: 0xffff0000}), {R0: 0x0, R1: 0x1, R2: 0xffff0000, R3: 0xffff0000})
+        self.assertEqual(compute('SMULL R2, R3, R4, R5', {R4: 0x12345678, R5: 0x87654321}), {R2: 0x70b88d78, R3: 0xf76c768d, R4: 0x12345678, R5: 0x87654321})
+        self.assertEqual(compute('SMULL R2, R3, R4, R5', {R4: 0xffffffff, R5: 0x00000002}), {R2: 0xfffffffe, R3: 0xffffffff, R4: 0xffffffff, R5: 0x00000002})
 
     def test_SMLAL(self):
-        self.assertEqual(compute('SMLAL R1, R2, R4, R5', {R1: 0x0L, R2: 0x0L, R4: 0x1L, R5: 0x0L}), {R1: 0x0L, R2: 0x0L, R4: 0x1L, R5: 0x0L})
-        self.assertEqual(compute('SMLAL R0, R1, R2, R3', {R0: 0x0L, R1: 0x0L, R2: 0x1L, R3: 0x80808080L}), {R0: 0x80808080L, R1: 0xffffffffL, R2: 0x1L, R3: 0x80808080L})
-        self.assertEqual(compute('SMLAL R2, R3, R4, R5', {R2: 0xffffffffL, R3: 0x0L, R4: 0x12345678L, R5: 0x87654321L}), {R2: 0x70b88d77L, R3: 0xf76c768eL, R4: 0x12345678L, R5: 0x87654321L})
-        self.assertEqual(compute('SMLAL R2, R3, R4, R5', {R2: 0xffffffffL, R3: 0x00000002L, R4: 0x12345678L, R5: 0x87654321L}), {R2: 0x70b88d77L, R3: 0xf76c7690L, R4: 0x12345678L, R5: 0x87654321L})
+        self.assertEqual(compute('SMLAL R1, R2, R4, R5', {R1: 0x0, R2: 0x0, R4: 0x1, R5: 0x0}), {R1: 0x0, R2: 0x0, R4: 0x1, R5: 0x0})
+        self.assertEqual(compute('SMLAL R0, R1, R2, R3', {R0: 0x0, R1: 0x0, R2: 0x1, R3: 0x80808080}), {R0: 0x80808080, R1: 0xffffffff, R2: 0x1, R3: 0x80808080})
+        self.assertEqual(compute('SMLAL R2, R3, R4, R5', {R2: 0xffffffff, R3: 0x0, R4: 0x12345678, R5: 0x87654321}), {R2: 0x70b88d77, R3: 0xf76c768e, R4: 0x12345678, R5: 0x87654321})
+        self.assertEqual(compute('SMLAL R2, R3, R4, R5', {R2: 0xffffffff, R3: 0x00000002, R4: 0x12345678, R5: 0x87654321}), {R2: 0x70b88d77, R3: 0xf76c7690, R4: 0x12345678, R5: 0x87654321})
 
 if __name__ == '__main__':
     testsuite = unittest.TestLoader().loadTestsFromTestCase(TestARMSemantic)
diff --git a/test/arch/mep/asm/test_asm.py b/test/arch/mep/asm/test_asm.py
index ddf91ed6..217def86 100644
--- a/test/arch/mep/asm/test_asm.py
+++ b/test/arch/mep/asm/test_asm.py
@@ -1,9 +1,11 @@
 # Toshiba MeP-c4 - Misc unit tests
 # Guillaume Valadon <guillaume@valadon.net>
 
+from __future__ import print_function
+from miasm2.core.utils import decode_hex, encode_hex
 from miasm2.arch.mep.arch import mn_mep
 
-class TestMisc:
+class TestMisc(object):
 
     def test(self):
 
@@ -18,21 +20,23 @@ class TestMisc:
         unit_tests += [("SW R7, 0x50(SP)", "4752")]
 
         for mn_str, mn_hex in unit_tests:
-            print "-" * 49  # Tests separation
+            print("-" * 49)  # Tests separation
 
             # Dissassemble
-            mn_bin = mn_hex.decode("hex")
+            mn_bin = decode_hex(mn_hex)
             mn = mn_mep.dis(mn_bin, "b")
 
-            print "dis: %s -> %s" % (mn_hex.rjust(20), str(mn).rjust(20))
+            print("dis: %s -> %s" % (mn_hex.rjust(20), str(mn).rjust(20)))
             assert(str(mn) == mn_str)  # dissassemble assertion
 
             # Assemble and return all possible candidates
             instr = mn_mep.fromstring(str(mn), "b")
             instr.mode = "b"
-            asm_list = [i.encode("hex") for i in mn_mep.asm(instr)]
+            asm_list = [encode_hex(i).decode() for i in mn_mep.asm(instr)]
 
             # Print the results
-            print "asm: %s -> %s" % (mn_str.rjust(20),
-                                     ", ".join(asm_list).rjust(20))
+            print("asm: %s -> %s" % (
+                mn_str.rjust(20),
+                ", ".join(asm_list).rjust(20))
+            )
             assert(mn_hex in asm_list)  # assemble assertion
diff --git a/test/arch/mep/asm/test_major_opcode_0.py b/test/arch/mep/asm/test_major_opcode_0.py
index 69a9685c..db288e47 100644
--- a/test/arch/mep/asm/test_major_opcode_0.py
+++ b/test/arch/mep/asm/test_major_opcode_0.py
@@ -4,7 +4,7 @@
 from ut_helpers_asm import check_instruction
 
 
-class TestMajor0:
+class TestMajor0(object):
 
     def test_MOV(self):
         """Test the MOV instruction"""
diff --git a/test/arch/mep/asm/test_major_opcode_1.py b/test/arch/mep/asm/test_major_opcode_1.py
index c401bfd2..3a3c6538 100644
--- a/test/arch/mep/asm/test_major_opcode_1.py
+++ b/test/arch/mep/asm/test_major_opcode_1.py
@@ -4,7 +4,7 @@
 from ut_helpers_asm import check_instruction
 
 
-class TestMajor1:
+class TestMajor1(object):
 
     def test_OR(self):
         """Test the OR instruction"""
diff --git a/test/arch/mep/asm/test_major_opcode_10.py b/test/arch/mep/asm/test_major_opcode_10.py
index f1089c61..e10992c8 100644
--- a/test/arch/mep/asm/test_major_opcode_10.py
+++ b/test/arch/mep/asm/test_major_opcode_10.py
@@ -4,7 +4,7 @@
 from ut_helpers_asm import check_instruction
 
 
-class TestMajor10:
+class TestMajor10(object):
 
     def test_BEQZ(self):
         """Test the BEQZ instruction"""
diff --git a/test/arch/mep/asm/test_major_opcode_11.py b/test/arch/mep/asm/test_major_opcode_11.py
index b5d8a278..38f93e8b 100644
--- a/test/arch/mep/asm/test_major_opcode_11.py
+++ b/test/arch/mep/asm/test_major_opcode_11.py
@@ -4,7 +4,7 @@
 from ut_helpers_asm import check_instruction
 
 
-class TestMajor11:
+class TestMajor11(object):
 
     def test_BRA(self):
         """Test the BRA instruction"""
diff --git a/test/arch/mep/asm/test_major_opcode_12.py b/test/arch/mep/asm/test_major_opcode_12.py
index e721d287..c353861e 100644
--- a/test/arch/mep/asm/test_major_opcode_12.py
+++ b/test/arch/mep/asm/test_major_opcode_12.py
@@ -4,7 +4,7 @@
 from ut_helpers_asm import check_instruction
 
 
-class TestMajor12:
+class TestMajor12(object):
 
     def test_ADD3(self):
         """Test the ADD3 instruction"""
diff --git a/test/arch/mep/asm/test_major_opcode_13.py b/test/arch/mep/asm/test_major_opcode_13.py
index 996b47e3..bf95572c 100644
--- a/test/arch/mep/asm/test_major_opcode_13.py
+++ b/test/arch/mep/asm/test_major_opcode_13.py
@@ -4,7 +4,7 @@
 from ut_helpers_asm import check_instruction
 
 
-class TestMajor13:
+class TestMajor13(object):
 
     def test_MOVU(self):
         """Test the MOVU instruction"""
diff --git a/test/arch/mep/asm/test_major_opcode_14.py b/test/arch/mep/asm/test_major_opcode_14.py
index 6ad3c757..9ec99550 100644
--- a/test/arch/mep/asm/test_major_opcode_14.py
+++ b/test/arch/mep/asm/test_major_opcode_14.py
@@ -4,7 +4,7 @@
 from ut_helpers_asm import check_instruction
 
 
-class TestMajor14:
+class TestMajor14(object):
 
     def test_BEQI(self):
         """Test the BEQI instruction"""
diff --git a/test/arch/mep/asm/test_major_opcode_15.py b/test/arch/mep/asm/test_major_opcode_15.py
index ecad8b3f..891626e8 100644
--- a/test/arch/mep/asm/test_major_opcode_15.py
+++ b/test/arch/mep/asm/test_major_opcode_15.py
@@ -4,7 +4,7 @@
 from ut_helpers_asm import check_instruction
 
 
-class TestMajor15:
+class TestMajor15(object):
 
     def test_DSP(self):
         """Test the DSP instruction"""
diff --git a/test/arch/mep/asm/test_major_opcode_2.py b/test/arch/mep/asm/test_major_opcode_2.py
index 07743813..4cbe36ca 100644
--- a/test/arch/mep/asm/test_major_opcode_2.py
+++ b/test/arch/mep/asm/test_major_opcode_2.py
@@ -4,7 +4,7 @@
 from ut_helpers_asm import check_instruction
 
 
-class TestMajor2:
+class TestMajor2(object):
 
     def test_BSETM(self):
         """Test the BSETM instruction"""
diff --git a/test/arch/mep/asm/test_major_opcode_3.py b/test/arch/mep/asm/test_major_opcode_3.py
index 3e0c5864..793a4e87 100644
--- a/test/arch/mep/asm/test_major_opcode_3.py
+++ b/test/arch/mep/asm/test_major_opcode_3.py
@@ -4,7 +4,7 @@
 from ut_helpers_asm import check_instruction
 
 
-class TestMajor3:
+class TestMajor3(object):
 
     def test_SWCPI(self):
         """Test the SWCPI instruction"""
diff --git a/test/arch/mep/asm/test_major_opcode_4.py b/test/arch/mep/asm/test_major_opcode_4.py
index e52acf3f..a6f57ac2 100644
--- a/test/arch/mep/asm/test_major_opcode_4.py
+++ b/test/arch/mep/asm/test_major_opcode_4.py
@@ -4,7 +4,7 @@
 from ut_helpers_asm import check_instruction
 
 
-class TestMajor4:
+class TestMajor4(object):
 
     def test_ADD3(self):
         """Test the ADD3 instruction"""
diff --git a/test/arch/mep/asm/test_major_opcode_5.py b/test/arch/mep/asm/test_major_opcode_5.py
index e39230f4..2250c123 100644
--- a/test/arch/mep/asm/test_major_opcode_5.py
+++ b/test/arch/mep/asm/test_major_opcode_5.py
@@ -4,7 +4,7 @@
 from ut_helpers_asm import check_instruction
 
 
-class TestMajor5:
+class TestMajor5(object):
 
     def test_MOV(self):
         """Test the MOV instruction"""
diff --git a/test/arch/mep/asm/test_major_opcode_6.py b/test/arch/mep/asm/test_major_opcode_6.py
index 5eda1ea6..e10d1064 100644
--- a/test/arch/mep/asm/test_major_opcode_6.py
+++ b/test/arch/mep/asm/test_major_opcode_6.py
@@ -4,7 +4,7 @@
 from ut_helpers_asm import check_instruction
 
 
-class TestMajor6:
+class TestMajor6(object):
 
     def test_ADD(self):
         """Test the ADD instruction"""
diff --git a/test/arch/mep/asm/test_major_opcode_7.py b/test/arch/mep/asm/test_major_opcode_7.py
index 15a045da..1b1fba78 100644
--- a/test/arch/mep/asm/test_major_opcode_7.py
+++ b/test/arch/mep/asm/test_major_opcode_7.py
@@ -4,7 +4,7 @@
 from ut_helpers_asm import check_instruction
 
 
-class TestMajor7:
+class TestMajor7(object):
 
     def test_DI(self):
         """Test the DI instruction"""
diff --git a/test/arch/mep/asm/test_major_opcode_8.py b/test/arch/mep/asm/test_major_opcode_8.py
index 7f15f9e8..900cf004 100644
--- a/test/arch/mep/asm/test_major_opcode_8.py
+++ b/test/arch/mep/asm/test_major_opcode_8.py
@@ -4,7 +4,7 @@
 from ut_helpers_asm import check_instruction
 
 
-class TestMajor8:
+class TestMajor8(object):
 
     def test_SB(self):
         """Test the SB instruction"""
diff --git a/test/arch/mep/asm/test_major_opcode_9.py b/test/arch/mep/asm/test_major_opcode_9.py
index b8949887..9e59a863 100644
--- a/test/arch/mep/asm/test_major_opcode_9.py
+++ b/test/arch/mep/asm/test_major_opcode_9.py
@@ -4,7 +4,7 @@
 from ut_helpers_asm import check_instruction
 
 
-class TestMajor9:
+class TestMajor9(object):
 
     def test_ADD3(self):
         """Test the ADD3 instruction"""
diff --git a/test/arch/mep/asm/ut_helpers_asm.py b/test/arch/mep/asm/ut_helpers_asm.py
index af010afc..26520787 100644
--- a/test/arch/mep/asm/ut_helpers_asm.py
+++ b/test/arch/mep/asm/ut_helpers_asm.py
@@ -1,6 +1,11 @@
 # Toshiba MeP-c4 - unit tests helpers
 # Guillaume Valadon <guillaume@valadon.net>
 
+from __future__ import print_function
+
+from builtins import range
+
+from miasm2.core.utils import decode_hex, encode_hex
 from miasm2.arch.mep.arch import mn_mep
 from miasm2.core.cpu import Disasm_Exception
 from miasm2.core.locationdb import LocationDB
@@ -11,7 +16,7 @@ import re
 
 def dis(mn_hex):
     """Disassembly helper"""
-    mn_bin = mn_hex.decode("hex")
+    mn_bin = decode_hex(mn_hex)
     try:
         return mn_mep.dis(mn_bin, "b")
     except Disasm_Exception:
@@ -50,7 +55,7 @@ def check_instruction(mn_str, mn_hex, multi=None, offset=0):
                 addr = loc_db.get_location_offset(mn.args[i].loc_key)
                 mn.args[i] = ExprInt(addr, args_size[i])
 
-    print "dis: %s -> %s" % (mn_hex.rjust(20), str(mn).rjust(20))
+    print("dis: %s -> %s" % (mn_hex.rjust(20), str(mn).rjust(20)))
     assert(str(mn) == mn_str)  # disassemble assertion
 
     # Assemble and return all possible candidates
@@ -59,21 +64,25 @@ def check_instruction(mn_str, mn_hex, multi=None, offset=0):
     instr.mode = "b"
     if instr.offset:
         instr.fixDstOffset()
-    asm_list = [i.encode("hex") for i in mn_mep.asm(instr)]
+    asm_list = [encode_hex(i).decode() for i in mn_mep.asm(instr)]
 
     # Check instructions variants
     if multi:
-        print "Instructions count:", len(asm_list)
+        print("Instructions count:", len(asm_list))
         assert(len(asm_list) == multi)
 
         # Ensure that variants correspond to the same disassembled instruction
-        for mn_hex in asm_list:
-            mn = dis(mn_hex)
-            print "dis: %s -> %s" % (mn_hex.rjust(20), str(mn).rjust(20))
+        for mn_hex_tmp in asm_list:
+            mn = dis(mn_hex_tmp)
+            print("dis: %s -> %s" % (mn_hex_tmp.rjust(20), str(mn).rjust(20)))
 
     # Check the assembly result
-    print "asm: %s -> %s" % (mn_str.rjust(20),
-                             ", ".join(asm_list).rjust(20))
+    print(
+        "asm: %s -> %s" % (
+            mn_str.rjust(20),
+            ", ".join(asm_list).rjust(20)
+        )
+    )
     assert(mn_hex in asm_list)  # assemble assertion
 
 
@@ -83,10 +92,10 @@ def launch_tests(obj):
     test_methods = [name for name in dir(obj) if name.startswith("test")]
 
     for method in test_methods:
-        print method
+        print(method)
         try:
             getattr(obj, method)()
         except AttributeError as e:
-            print "Method not found: %s" % method
+            print("Method not found: %s" % method)
             assert(False)
-        print '-' * 42
+        print('-' * 42)
diff --git a/test/arch/mep/ir/test_arithmetic.py b/test/arch/mep/ir/test_arithmetic.py
index 6da938e9..2e0dbf32 100644
--- a/test/arch/mep/ir/test_arithmetic.py
+++ b/test/arch/mep/ir/test_arithmetic.py
@@ -6,7 +6,7 @@ from ut_helpers_ir import exec_instruction
 from miasm2.expression.expression import ExprId, ExprInt, ExprCond, ExprOp
 
 
-class TestArithmetic:
+class TestArithmetic(object):
 
     def test_add3(self):
         """Test ADD3 execution"""
diff --git a/test/arch/mep/ir/test_bitmanipulation.py b/test/arch/mep/ir/test_bitmanipulation.py
index 06466f9d..f4ea2f29 100644
--- a/test/arch/mep/ir/test_bitmanipulation.py
+++ b/test/arch/mep/ir/test_bitmanipulation.py
@@ -6,7 +6,7 @@ from ut_helpers_ir import exec_instruction
 from miasm2.expression.expression import ExprId, ExprInt, ExprMem
 
 
-class TestBitManipulation:
+class TestBitManipulation(object):
 
     def test_bsetm(self):
         """Test BSETM execution"""
diff --git a/test/arch/mep/ir/test_branchjump.py b/test/arch/mep/ir/test_branchjump.py
index 3f78558b..7e0953fd 100644
--- a/test/arch/mep/ir/test_branchjump.py
+++ b/test/arch/mep/ir/test_branchjump.py
@@ -6,7 +6,7 @@ from ut_helpers_ir import exec_instruction
 from miasm2.expression.expression import ExprId, ExprInt
 
 
-class TestBranchJump:
+class TestBranchJump(object):
 
     def test_bra(self):
         """Test BRA execution"""
diff --git a/test/arch/mep/ir/test_control.py b/test/arch/mep/ir/test_control.py
index a1b3c7c7..92dcb371 100644
--- a/test/arch/mep/ir/test_control.py
+++ b/test/arch/mep/ir/test_control.py
@@ -6,7 +6,7 @@ from ut_helpers_ir import exec_instruction
 from miasm2.expression.expression import ExprId, ExprInt, ExprCond, ExprOp
 
 
-class TestControl:
+class TestControl(object):
 
     def test_stc(self):
         """Test STC execution"""
diff --git a/test/arch/mep/ir/test_coprocessor.py b/test/arch/mep/ir/test_coprocessor.py
index e9b745ff..e9829c08 100644
--- a/test/arch/mep/ir/test_coprocessor.py
+++ b/test/arch/mep/ir/test_coprocessor.py
@@ -6,7 +6,7 @@ from ut_helpers_ir import exec_instruction
 from miasm2.expression.expression import ExprId, ExprMem, ExprInt
 
 
-class TestCoprocessor:
+class TestCoprocessor(object):
 
     def test_swcp(self):
         """Test SWCP execution"""
diff --git a/test/arch/mep/ir/test_datacache.py b/test/arch/mep/ir/test_datacache.py
index a462315d..7d92f9c7 100644
--- a/test/arch/mep/ir/test_datacache.py
+++ b/test/arch/mep/ir/test_datacache.py
@@ -4,7 +4,7 @@
 from ut_helpers_ir import exec_instruction
 
 
-class TestDataCache:
+class TestDataCache(object):
 
     def test_cache(self):
         """Test CACHE execution"""
diff --git a/test/arch/mep/ir/test_debug.py b/test/arch/mep/ir/test_debug.py
index 53f4064d..b25e3a19 100644
--- a/test/arch/mep/ir/test_debug.py
+++ b/test/arch/mep/ir/test_debug.py
@@ -6,7 +6,7 @@ from ut_helpers_ir import exec_instruction
 from miasm2.expression.expression import ExprId, ExprInt, ExprCond, ExprOp
 
 
-class TestDebug:
+class TestDebug(object):
 
     def test_dret(self):
         """Test DRET execution"""
diff --git a/test/arch/mep/ir/test_divide.py b/test/arch/mep/ir/test_divide.py
index a63d0c5e..e3e4cb99 100644
--- a/test/arch/mep/ir/test_divide.py
+++ b/test/arch/mep/ir/test_divide.py
@@ -7,7 +7,7 @@ from miasm2.expression.expression import ExprId, ExprInt, ExprCond, ExprOp
 from miasm2.jitter.csts import EXCEPT_DIV_BY_ZERO
 
 
-class TestDivide:
+class TestDivide(object):
 
     def test_div(self):
         """Test DIV execution"""
diff --git a/test/arch/mep/ir/test_extension.py b/test/arch/mep/ir/test_extension.py
index 72423220..10f16ebf 100644
--- a/test/arch/mep/ir/test_extension.py
+++ b/test/arch/mep/ir/test_extension.py
@@ -6,7 +6,7 @@ from ut_helpers_ir import exec_instruction
 from miasm2.expression.expression import ExprId, ExprMem, ExprInt
 
 
-class TestExtension:
+class TestExtension(object):
 
     def test_extb(self):
         """Test EXTB execution"""
diff --git a/test/arch/mep/ir/test_ir.py b/test/arch/mep/ir/test_ir.py
index 3fec9ec9..be717db8 100644
--- a/test/arch/mep/ir/test_ir.py
+++ b/test/arch/mep/ir/test_ir.py
@@ -1,6 +1,9 @@
 # Toshiba MeP-c4 - Misc unit tests
 # Guillaume Valadon <guillaume@valadon.net>
 
+from __future__ import print_function
+
+from miasm2.core.utils import decode_hex
 from miasm2.arch.mep.arch import mn_mep
 from miasm2.arch.mep.regs import regs_init
 from miasm2.arch.mep.ira import ir_mepb, ir_a_mepb
@@ -9,7 +12,7 @@ from miasm2.ir.symbexec import SymbolicExecutionEngine
 from miasm2.core.locationdb import LocationDB
 
 
-class TestMisc:
+class TestMisc(object):
 
     def test(self):
 
@@ -18,16 +21,16 @@ class TestMisc:
         def exec_instruction(hex_asm, init_values):
             """Symbolically execute an instruction"""
 
-            print "Hex:", hex_asm
+            print("Hex:", hex_asm)
 
             # Disassemble an instruction
-            mn = mn_mep.dis(hex_asm.decode("hex"), "b")
-            print "Dis:", mn
+            mn = mn_mep.dis(decode_hex(hex_asm), "b")
+            print("Dis:", mn)
 
             # Get the IR
             im = ir_mepb()
             iir, eiir, = im.get_ir(mn)
-            print "\nInternal representation:", iir
+            print("\nInternal representation:", iir)
 
             # Symbolic execution
             loc_db = LocationDB()
@@ -37,13 +40,13 @@ class TestMisc:
             for reg_expr_id, reg_expr_value in init_values:
                 sb.symbols[reg_expr_id] = reg_expr_value
 
-            print "\nModified registers:", [reg for reg in sb.modified(mems=False)]
-            print "Modified memories:", [mem for mem in sb.modified()]
+            print("\nModified registers:", [reg for reg in sb.modified(mems=False)])
+            print("Modified memories:", [mem for mem in sb.modified()])
 
-            print "\nFinal registers:"
+            print("\nFinal registers:")
             sb.dump(mems=False)
 
-            print "\nFinal mems:"
+            print("\nFinal mems:")
             sb.dump()
 
         for hex_asm, init_values in [("6108", [(ExprId("R1", 32), ExprInt(0x40, 32))]),
@@ -52,5 +55,5 @@ class TestMisc:
                                      ("0948", [(ExprId("R4", 32), ExprInt(0x41, 32)),
                                                (ExprId("R9", 32), ExprInt(0x28, 32)),
                                                (ExprMem(ExprInt(0x41, 32), 8), ExprInt(0, 8))])]:
-            print "-" * 49  # Tests separation
+            print("-" * 49)  # Tests separation
             exec_instruction(hex_asm, init_values)
diff --git a/test/arch/mep/ir/test_ldz.py b/test/arch/mep/ir/test_ldz.py
index 02960b60..668030c8 100644
--- a/test/arch/mep/ir/test_ldz.py
+++ b/test/arch/mep/ir/test_ldz.py
@@ -6,7 +6,7 @@ from ut_helpers_ir import exec_instruction
 from miasm2.expression.expression import ExprId, ExprInt, ExprCond, ExprOp
 
 
-class TestLdz:
+class TestLdz(object):
 
     def test_ldz(self):
         """Test LDZ execution"""
diff --git a/test/arch/mep/ir/test_loadstore.py b/test/arch/mep/ir/test_loadstore.py
index c6b40d55..22cb4304 100644
--- a/test/arch/mep/ir/test_loadstore.py
+++ b/test/arch/mep/ir/test_loadstore.py
@@ -6,7 +6,7 @@ from ut_helpers_ir import exec_instruction
 from miasm2.expression.expression import ExprId, ExprMem, ExprInt
 
 
-class TestLoadStore:
+class TestLoadStore(object):
 
     def test_sb(self):
         """Test SB execution"""
diff --git a/test/arch/mep/ir/test_logical.py b/test/arch/mep/ir/test_logical.py
index 61cbbf0a..e78b5488 100644
--- a/test/arch/mep/ir/test_logical.py
+++ b/test/arch/mep/ir/test_logical.py
@@ -6,7 +6,7 @@ from ut_helpers_ir import exec_instruction
 from miasm2.expression.expression import ExprId, ExprInt, ExprCond, ExprOp
 
 
-class TestLogical:
+class TestLogical(object):
 
     def test_or(self):
         """Test OR execution"""
diff --git a/test/arch/mep/ir/test_move.py b/test/arch/mep/ir/test_move.py
index 56a4225e..8da7a18a 100644
--- a/test/arch/mep/ir/test_move.py
+++ b/test/arch/mep/ir/test_move.py
@@ -6,7 +6,7 @@ from ut_helpers_ir import exec_instruction
 from miasm2.expression.expression import ExprId, ExprMem, ExprInt
 
 
-class TestMove:
+class TestMove(object):
 
     def test_mov(self):
         """Test MOV execution"""
diff --git a/test/arch/mep/ir/test_multiply.py b/test/arch/mep/ir/test_multiply.py
index 0618f69f..5673994c 100644
--- a/test/arch/mep/ir/test_multiply.py
+++ b/test/arch/mep/ir/test_multiply.py
@@ -6,7 +6,7 @@ from ut_helpers_ir import exec_instruction
 from miasm2.expression.expression import ExprId, ExprInt, ExprCond, ExprOp
 
 
-class TestMultiply:
+class TestMultiply(object):
 
     def test_mul(self):
         """Test MUL execution"""
diff --git a/test/arch/mep/ir/test_repeat.py b/test/arch/mep/ir/test_repeat.py
index 252764b1..1e0e2f86 100644
--- a/test/arch/mep/ir/test_repeat.py
+++ b/test/arch/mep/ir/test_repeat.py
@@ -6,7 +6,7 @@ from ut_helpers_ir import exec_instruction
 from miasm2.expression.expression import ExprId, ExprInt, ExprCond, ExprOp
 
 
-class TestRepeat:
+class TestRepeat(object):
 
     def test_repeat(self):
         """Test REPEAT execution"""
diff --git a/test/arch/mep/ir/test_shift.py b/test/arch/mep/ir/test_shift.py
index b63f9ed7..99755ba5 100644
--- a/test/arch/mep/ir/test_shift.py
+++ b/test/arch/mep/ir/test_shift.py
@@ -7,7 +7,7 @@ from miasm2.expression.expression import ExprId, ExprInt, ExprCond, ExprOp
 from miasm2.core.cpu import sign_ext
 
 
-class TestShift:
+class TestShift(object):
 
     def test_sra(self):
         """Test SRA execution"""
diff --git a/test/arch/mep/ir/ut_helpers_ir.py b/test/arch/mep/ir/ut_helpers_ir.py
index 9c9efdfa..26eebeda 100644
--- a/test/arch/mep/ir/ut_helpers_ir.py
+++ b/test/arch/mep/ir/ut_helpers_ir.py
@@ -1,6 +1,8 @@
 # Toshiba MeP-c4 - unit tests helpers
 # Guillaume Valadon <guillaume@valadon.net>
 
+from __future__ import print_function
+
 from miasm2.arch.mep.arch import mn_mep
 from miasm2.arch.mep.sem import ir_mepb
 from miasm2.arch.mep.regs import regs_init
@@ -10,7 +12,8 @@ from miasm2.core.locationdb import LocationDB
 from miasm2.core.utils import Disasm_Exception
 from miasm2.ir.ir import AssignBlock
 from miasm2.arch.mep.ira import ir_a_mepb
-from miasm2.expression.expression import ExprId, ExprInt, ExprOp, ExprMem, ExprAssign, ExprLoc
+from miasm2.expression.expression import ExprId, ExprInt, ExprOp, ExprMem, \
+    ExprAssign, ExprLoc
 
 
 def exec_instruction(mn_str, init_values, results, index=0, offset=0):
@@ -67,8 +70,8 @@ def exec_instruction(mn_str, init_values, results, index=0, offset=0):
 
     # Ensure that all expected results were verified
     if len(results) is not matched_results:
-        print "Expected:", results
-        print "Modified:", [r for r in sb.modified(mems=False)]
+        print("Expected:", results)
+        print("Modified:", [r for r in sb.modified(mems=False)])
         assert(False)
 
 
@@ -78,10 +81,10 @@ def launch_tests(obj):
     test_methods = [name for name in dir(obj) if name.startswith("test")]
 
     for method in test_methods:
-        print method
+        print(method)
         try:
             getattr(obj, method)()
         except AttributeError as e:
-            print "Method not found: %s" % method
+            print("Method not found: %s" % method)
             assert(False)
-        print '-' * 42
+        print('-' * 42)
diff --git a/test/arch/mep/jit/test_jit_branchjump.py b/test/arch/mep/jit/test_jit_branchjump.py
index baf602d8..1f932aa9 100644
--- a/test/arch/mep/jit/test_jit_branchjump.py
+++ b/test/arch/mep/jit/test_jit_branchjump.py
@@ -4,7 +4,7 @@
 from ut_helpers_jit import jit_instructions
 
 
-class TestBranchJump:
+class TestBranchJump(object):
 
     def test_blti(self):
         """Test BLTI jit"""
diff --git a/test/arch/mep/jit/test_jit_repeat.py b/test/arch/mep/jit/test_jit_repeat.py
index 9fa64fa5..eaac1a1d 100644
--- a/test/arch/mep/jit/test_jit_repeat.py
+++ b/test/arch/mep/jit/test_jit_repeat.py
@@ -4,7 +4,7 @@
 from ut_helpers_jit import jit_instructions
 
 
-class TestRepeat:
+class TestRepeat(object):
     def test_repeat(self):
         """Test REPEAT jit"""
 
diff --git a/test/arch/mep/jit/ut_helpers_jit.py b/test/arch/mep/jit/ut_helpers_jit.py
index 590c534f..999ead42 100644
--- a/test/arch/mep/jit/ut_helpers_jit.py
+++ b/test/arch/mep/jit/ut_helpers_jit.py
@@ -1,6 +1,8 @@
 # Toshiba MeP-c4 - unit tests helpers
 # Guillaume Valadon <guillaume@valadon.net>
 
+from __future__ import print_function
+
 from miasm2.analysis.machine import Machine
 from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE
 
@@ -13,7 +15,7 @@ def jit_instructions(mn_str):
     mn_mep = machine.mn()
 
     # Assemble the instructions
-    asm = ""
+    asm = b""
     for instr_str in mn_str.split("\n"):
         instr = mn_mep.fromstring(instr_str, "b")
         instr.mode = "b"
@@ -40,10 +42,10 @@ def launch_tests(obj):
     test_methods = [name for name in dir(obj) if name.startswith("test")]
 
     for method in test_methods:
-        print method
+        print(method)
         try:
             getattr(obj, method)()
         except AttributeError as e:
-            print "Method not found: %s" % method
+            print("Method not found: %s" % method)
             assert(False)
-        print '-' * 42
+        print('-' * 42)
diff --git a/test/arch/mips32/arch.py b/test/arch/mips32/arch.py
index 1cbb554d..f71d3ee8 100644
--- a/test/arch/mips32/arch.py
+++ b/test/arch/mips32/arch.py
@@ -1,6 +1,8 @@
+from __future__ import print_function
 import time
 from pdb import pm
 
+from miasm2.core.utils import decode_hex, encode_hex
 from miasm2.core.locationdb import LocationDB
 from miasm2.arch.mips32.arch import *
 
@@ -217,20 +219,20 @@ reg_tests_mips32 = [
 
 ts = time.time()
 def h2i(s):
-    return s.replace(' ', '').decode('hex')
+    return decode_hex(s.replace(' ', ''))
 
 for s, l in reg_tests_mips32:
-    print "-" * 80
+    print("-" * 80)
     s = s[12:]
     b = h2i((l))
     mn = mn_mips32.dis(b, 'b')
-    print [str(x) for x in mn.args]
-    print s
-    print mn
+    print([str(x) for x in mn.args])
+    print(s)
+    print(mn)
     assert(str(mn) == s)
     l = mn_mips32.fromstring(s, loc_db, 'b')
     assert(str(l) == s)
     a = mn_mips32.asm(l, 'b')
-    print [x for x in a]
-    print repr(b)
+    print([x for x in a])
+    print(repr(b))
     assert(b in a)
diff --git a/test/arch/mips32/unit/asm_test.py b/test/arch/mips32/unit/asm_test.py
index da792874..7a50b38e 100644
--- a/test/arch/mips32/unit/asm_test.py
+++ b/test/arch/mips32/unit/asm_test.py
@@ -1,6 +1,8 @@
 import sys
 import os
 
+from future.utils import viewitems
+
 from miasm2.arch.mips32.arch import mn_mips32
 from miasm2.core import parse_asm
 from miasm2.expression.expression import *
@@ -30,10 +32,10 @@ class Asm_Test(object):
         loc_db.set_location_offset(loc_db.get_name_location("main"), 0x0)
         s = StrPatchwork()
         patches = asmblock.asm_resolve_final(mn_mips32, blocks, loc_db)
-        for offset, raw in patches.items():
+        for offset, raw in viewitems(patches):
             s[offset] = raw
 
-        s = str(s)
+        s = bytes(s)
         self.assembly = s
 
     def run(self):
diff --git a/test/arch/msp430/arch.py b/test/arch/msp430/arch.py
index 91de95b3..eea87091 100644
--- a/test/arch/msp430/arch.py
+++ b/test/arch/msp430/arch.py
@@ -1,12 +1,15 @@
+from __future__ import print_function
+
 import time
 from pdb import pm
+from miasm2.core.utils import decode_hex, encode_hex
 from miasm2.arch.msp430.arch import *
 from miasm2.core.locationdb import LocationDB
 
 loc_db = LocationDB()
 
 def h2i(s):
-    return s.replace(' ', '').decode('hex')
+    return decode_hex(s.replace(' ', ''))
 
 
 def u16swap(i):
@@ -86,18 +89,18 @@ reg_tests_msp = [
 ts = time.time()
 
 for s, l in reg_tests_msp:
-    print "-" * 80
+    print("-" * 80)
     s = s[8:]
     b = h2i((l))
-    print repr(b)
+    print(repr(b))
     mn = mn_msp430.dis(b, None)
-    print [str(x) for x in mn.args]
-    print s
-    print mn
+    print([str(x) for x in mn.args])
+    print(s)
+    print(mn)
     assert(str(mn) == s)
     l = mn_msp430.fromstring(s, loc_db, None)
     assert(str(l) == s)
     a = mn_msp430.asm(l)
-    print [x for x in a]
-    print repr(b)
+    print([x for x in a])
+    print(repr(b))
     assert(b in a)
diff --git a/test/arch/msp430/sem.py b/test/arch/msp430/sem.py
index 10e57e36..88aa990d 100755
--- a/test/arch/msp430/sem.py
+++ b/test/arch/msp430/sem.py
@@ -1,9 +1,12 @@
 #! /usr/bin/env python2
 #-*- coding:utf-8 -*-
 
+from __future__ import print_function
 import unittest
 import logging
 
+from future.utils import viewitems
+
 from miasm2.ir.symbexec import SymbolicExecutionEngine
 from miasm2.arch.msp430.arch import mn_msp430 as mn, mode_msp430 as mode
 from miasm2.arch.msp430.sem import ir_msp430 as ir_arch
@@ -22,7 +25,7 @@ def M(addr):
 def compute(asm, inputstate={}, debug=False):
     loc_db = LocationDB()
     sympool = dict(regs_init)
-    sympool.update({k: ExprInt(v, k.size) for k, v in inputstate.iteritems()})
+    sympool.update({k: ExprInt(v, k.size) for k, v in viewitems(inputstate)})
     ir_tmp = ir_arch(loc_db)
     ircfg = ir_tmp.new_ircfg()
     symexec = SymbolicExecutionEngine(ir_tmp, sympool)
@@ -33,11 +36,13 @@ def compute(asm, inputstate={}, debug=False):
     loc_key = ir_tmp.add_instr_to_ircfg(instr, ircfg)
     symexec.run_at(ircfg, loc_key)
     if debug:
-        for k, v in symexec.symbols.items():
+        for k, v in viewitems(symexec.symbols):
             if regs_init.get(k, None) != v:
-                print k, v
-    return {k: v.arg.arg for k, v in symexec.symbols.items()
-            if k not in EXCLUDE_REGS and regs_init.get(k, None) != v}
+                print(k, v)
+    return {
+        k: v.arg.arg for k, v in viewitems(symexec.symbols)
+        if k not in EXCLUDE_REGS and regs_init.get(k, None) != v
+    }
 
 
 class TestMSP430Semantic(unittest.TestCase):
diff --git a/test/arch/sh4/arch.py b/test/arch/sh4/arch.py
index f744b215..f52ed070 100644
--- a/test/arch/sh4/arch.py
+++ b/test/arch/sh4/arch.py
@@ -1,13 +1,15 @@
+from __future__ import print_function
 import time
 from pdb import pm
 from sys import stderr
+from miasm2.core.utils import decode_hex, encode_hex
 from miasm2.arch.sh4.arch import *
 from miasm2.core.locationdb import LocationDB
 
 loc_db = LocationDB()
 
 def h2i(s):
-    return s.replace(' ', '').decode('hex')
+    return decode_hex(s.replace(' ', ''))
 
 reg_tests_sh4 = [
     # vxworks
@@ -389,25 +391,25 @@ reg_tests_sh4 = [
 ]
 
 for s, l in reg_tests_sh4:
-    print "-" * 80
+    print("-" * 80)
     s = s[12:]
     b = h2i((l))
-    print b.encode('hex')
+    print(encode_hex(b))
     mn = mn_sh4.dis(b, None)
-    print [str(x) for x in mn.args]
-    print s
-    print mn
+    print([str(x) for x in mn.args])
+    print(s)
+    print(mn)
     assert(str(mn) == s)
     l = mn_sh4.fromstring(s, loc_db, None)
     assert(str(l) == s)
     a = mn_sh4.asm(l)
-    print [x for x in a]
-    print repr(b)
+    print([x for x in a])
+    print(repr(b))
     assert(b in a)
 
 
 # speed test
-o = ""
+o = b""
 for s, l, in reg_tests_sh4:
     s = s[12:]
     b = h2i((l))
@@ -421,10 +423,10 @@ instr_num = 0
 ts = time.time()
 while off < bs.getlen():
     mn = mn_sh4.dis(bs, None, off)
-    print instr_num, off, mn.l, str(mn)
+    print(instr_num, off, mn.l, str(mn))
     instr_num += 1
     off += mn.l
-print 'instr per sec:', instr_num / (time.time() - ts)
+print('instr per sec:', instr_num // (time.time() - ts))
 
 import cProfile
-cProfile.run(r'mn_sh4.dis("\x17\xfe", None)')
+cProfile.run(r'mn_sh4.dis(b"\x17\xfe", None)')
diff --git a/test/arch/x86/arch.py b/test/arch/x86/arch.py
index d2204d77..b4cebd28 100644
--- a/test/arch/x86/arch.py
+++ b/test/arch/x86/arch.py
@@ -1,5 +1,8 @@
+from __future__ import print_function
 import time
 from pdb import pm
+
+from miasm2.core.utils import decode_hex, encode_hex
 import miasm2.expression.expression as m2_expr
 from miasm2.arch.x86.arch import mn_x86, deref_mem_ad, \
     base_expr, rmarg, print_size
@@ -22,7 +25,7 @@ reg_and_id.update({'mylabel16': mylabel16,
 
 
 def h2i(s):
-    return int(s.replace(' ', '').decode('hex')[::].encode('hex'), 16)
+    return int(encode_hex(decode_hex(s.replace(' ', ''))[::]), 16)
 
 
 m16 = 16  # (16, 16)
@@ -3101,56 +3104,58 @@ reg_tests = [
 ]
 
 
-test_file = {16: open('regression_test16_ia32.bin', 'w'),
-             32: open('regression_test32_ia32.bin', 'w'),
-             64: open('regression_test64_ia32.bin', 'w')}
+test_file = {
+    16: open('regression_test16_ia32.bin', 'wb'),
+    32: open('regression_test32_ia32.bin', 'wb'),
+    64: open('regression_test64_ia32.bin', 'wb')
+}
 ts = time.time()
 for mode, s, l, in reg_tests:
-    print "-" * 80
+    print("-" * 80)
     s = s[12:]
-    b = l.decode('hex')
-    print mode, repr(b)
+    b = decode_hex(l)
+    print(mode, repr(b))
     mn = mn_x86.dis(b, mode)
-    print "dis args", [(str(x), x.size) for x in mn.args]
-    print s
-    print mn
+    print("dis args", [(str(x), x.size) for x in mn.args])
+    print(s)
+    print(mn)
     assert(str(mn).strip() == s)
-    print 'fromstring', repr(s)
+    print('fromstring', repr(s))
     l = mn_x86.fromstring(s, loc_db, mode)
-    print 'str args', [(str(x), x.size) for x in l.args]
+    print('str args', [(str(x), x.size) for x in l.args])
     assert(str(l).strip(' ') == s)
     a = mn_x86.asm(l)
-    print 'asm result', [x for x in a]
-    print repr(b)
+    print('asm result', [x for x in a])
+    print(repr(b))
 
     for x in a:
-        print "BYTES", repr(x)
+        print("BYTES", repr(x))
         test_file[mode].write(x)
-    test_file[mode].write("\x90" * 2)
+    test_file[mode].write(b"\x90" * 2)
 
-    print 'test re dis'
+    print('test re dis')
     for x in a:
-        print repr(x)
+        print(repr(x))
         rl = mn_x86.dis(x, mode)
         assert(str(rl).strip(' ') == s)
-    print repr(b), a
+    print(repr(b), a)
     assert(b in a)
-print 'TEST time', time.time() - ts
+print('TEST time', time.time() - ts)
 
 
 # speed test thumb
-o = ""
+o = b""
 mode_x = m32
 for mode, s, l, in reg_tests:
     if mode != mode_x:
         continue
     s = s[12:]
-    b = l.decode('hex')
+    b = decode_hex(l)
     o += b
 
 while len(o) < 1000:
     o += o
-open('x86_speed_reg_test.bin', 'w').write(o)
+open('x86_speed_reg_test.bin', 'wb').write(o)
 
 
 def profile_dis(o):
@@ -3163,12 +3168,12 @@ def profile_dis(o):
         # print instr_num, off, mn.l, str(mn)
         instr_num += 1
         off += mn.l
-    print 'instr per sec:', instr_num / (time.time() - ts)
+    print('instr per sec:', instr_num // (time.time() - ts))
 
 import cProfile
 cProfile.run('profile_dis(o)')
 
 # Test instruction representation with prefix
-instr_bytes = '\x65\xc7\x00\x09\x00\x00\x00'
+instr_bytes = b'\x65\xc7\x00\x09\x00\x00\x00'
 inst = mn_x86.dis(instr_bytes, 32, 0)
 assert(inst.b == instr_bytes)
diff --git a/test/arch/x86/qemu/testqemu.py b/test/arch/x86/qemu/testqemu.py
index dccd9c83..264a84b9 100644
--- a/test/arch/x86/qemu/testqemu.py
+++ b/test/arch/x86/qemu/testqemu.py
@@ -1,36 +1,42 @@
+from __future__ import print_function
 import os
-import sys
 import struct
 import logging
+from sys import stdout
 from pdb import pm
 
+try:
+    stdout = stdout.buffer
+except AttributeError:
+    pass
+
 from miasm2.analysis.sandbox import Sandbox_Linux_x86_32
 from miasm2.jitter.jitload import log_func
 from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE
 
 # Utils
 def parse_fmt(s):
-    fmt = s[:]+"\x00"
+    fmt = s[:]+b"\x00"
     out = []
     i = 0
     while i < len(fmt):
-        c = fmt[i]
-        if c != "%":
+        c = fmt[i:i+1]
+        if c != b"%":
             i+=1
             continue
-        if fmt[i+1] == "%":
+        if fmt[i+1:i+2] == b"%":
             i+=2
             continue
         j = 0
         i+=1
-        while fmt[i+j] in "0123456789$.-":
+        while fmt[i+j:i+j+1] in b"0123456789$.-":
             j+=1
-        if fmt[i+j] in ['l']:
+        if fmt[i+j:i+j+1] in [b'l']:
             j +=1
-        if fmt[i+j] == "h":
+        if fmt[i+j:i+j+1] == b"h":
             x = fmt[i+j:i+j+2]
         else:
-            x = fmt[i+j]
+            x = fmt[i+j:i+j+1]
         i+=j
         out.append(x)
     return out
@@ -44,25 +50,24 @@ def xxx___printf_chk(jitter):
         raise RuntimeError("Not implemented")
     fmt = jitter.get_str_ansi(args.format)
     # Manage llx
-    fmt = fmt.replace("llx", "lx")
-    fmt = fmt.replace("%016lx", "%016z")
+    fmt = fmt.replace(b"llx", b"lx")
+    fmt = fmt.replace(b"%016lx", b"%016z")
 
     fmt_a = parse_fmt(fmt)
     esp = jitter.cpu.ESP
     args = []
     i = 0
-
     for x in fmt_a:
         a = jitter.vm.get_u32(esp + 8 + 4*i)
-        if x == "s":
+        if x == b"s":
             a = jitter.get_str_ansi(a)
-        elif x.lower() in ("x", 'd'):
+        elif x in (b"x", b'X', b"d"):
             pass
-        elif x.lower() in ("f", "l"):
+        elif x.lower() in (b"f", b"l"):
             a2 = jitter.vm.get_u32(esp + 8 + 4*(i+1))
             a = struct.unpack("d", struct.pack("Q", a2 << 32 | a))[0]
             i += 1
-        elif x.lower() == 'z':
+        elif x.lower() == b'z':
             a2 = jitter.vm.get_u32(esp + 8 + 4*(i+1))
             a = a2 << 32 | a
             i += 1
@@ -70,23 +75,22 @@ def xxx___printf_chk(jitter):
             raise RuntimeError("Not implemented format")
         args.append(a)
         i += 1
-
-    fmt = fmt.replace("%016z", "%016lx")
+    fmt = fmt.replace(b"%016z", b"%016lx")
     output = fmt%(tuple(args))
     # NaN bad repr in Python
-    output = output.replace("nan", "-nan")
+    output = output.replace(b"nan", b"-nan")
 
-    if "\n" not in output:
+    if b"\n" not in output:
         raise RuntimeError("Format must end with a \\n")
 
     # Check with expected result
-    line = expected.next()
-    if output != line:
-        print "Expected:", line
-        print "Obtained:", output
+    line = next(expected)
+    if output != line.encode():
+        print("Expected:", line)
+        print("Obtained:", output)
         raise RuntimeError("Bad semantic")
 
-    sys.stdout.write("[%d] %s" % (nb_tests, output))
+    stdout.write(b"[%d] %s" % (nb_tests, output))
     nb_tests += 1
     jitter.func_ret_systemv(ret_ad, 0)
 
@@ -100,10 +104,10 @@ def xxx_puts(jitter):
     ret_addr, args = jitter.func_args_systemv(['target'])
     output = jitter.get_str_ansi(args.target)
     # Check with expected result
-    line = expected.next()
-    if output != line.rstrip():
-        print "Expected:", line
-        print "Obtained:", output
+    line = next(expected)
+    if output != line.rstrip().encode():
+        print("Expected:", line)
+        print("Obtained:", output)
         raise RuntimeError("Bad semantic")
     return jitter.func_ret_systemv(ret_addr, 1)
 
@@ -120,7 +124,7 @@ expected = open(options.expected)
 # Create sandbox
 sb = Sandbox_Linux_x86_32(options.filename, options, globals())
 try:
-    addr = sb.elf.getsectionbyname(".symtab").symbols[options.funcname].value
+    addr = sb.elf.getsectionbyname(".symtab")[options.funcname].value
 except AttributeError:
     raise RuntimeError("The target binary must have a symtab section")
 
@@ -129,7 +133,7 @@ log_func.setLevel(logging.ERROR)
 # Segmentation
 sb.jitter.cpu.set_segm_base(8, 0x7fff0000)
 sb.jitter.cpu.GS = 8
-sb.jitter.vm.add_memory_page(0x7fff0000 + 0x14, PAGE_READ | PAGE_WRITE, "AAAA")
+sb.jitter.vm.add_memory_page(0x7fff0000 + 0x14, PAGE_READ | PAGE_WRITE, b"AAAA")
 
 
 # Run
diff --git a/test/arch/x86/qemu/testqemu64.py b/test/arch/x86/qemu/testqemu64.py
index bd82d414..4fe51992 100644
--- a/test/arch/x86/qemu/testqemu64.py
+++ b/test/arch/x86/qemu/testqemu64.py
@@ -1,36 +1,42 @@
+from __future__ import print_function
 import os
-import sys
 import struct
 import logging
+from sys import stdout
 from pdb import pm
 
+try:
+    stdout = stdout.buffer
+except AttributeError:
+    pass
+
 from miasm2.analysis.sandbox import Sandbox_Linux_x86_64
 from miasm2.jitter.jitload import log_func
 from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE
 
 # Utils
 def parse_fmt(s):
-    fmt = s[:]+"\x00"
+    fmt = s[:]+b"\x00"
     out = []
     i = 0
     while i < len(fmt):
-        c = fmt[i]
-        if c != "%":
+        c = fmt[i:i+1]
+        if c != b"%":
             i+=1
             continue
-        if fmt[i+1] == "%":
+        if fmt[i+1:i+2] == b"%":
             i+=2
             continue
         j = 0
         i+=1
-        while fmt[i+j] in "0123456789$.-":
+        while fmt[i+j:i+j+1] in b"0123456789$.-":
             j+=1
-        if fmt[i+j] in ['l']:
+        if fmt[i+j:i+j+1] in [b'l']:
             j +=1
-        if fmt[i+j] == "h":
+        if fmt[i+j:i+j+1] == b"h":
             x = fmt[i+j:i+j+2]
         else:
-            x = fmt[i+j]
+            x = fmt[i+j:i+j+1]
         i+=j
         out.append(x)
     return out
@@ -44,8 +50,8 @@ def xxx___printf_chk(jitter):
         raise RuntimeError("Not implemented")
     fmt = jitter.get_str_ansi(args.format)
     # Manage llx
-    fmt = fmt.replace("llx", "lx")
-    fmt = fmt.replace("%016lx", "%016z")
+    fmt = fmt.replace(b"llx", b"lx")
+    fmt = fmt.replace(b"%016lx", b"%016z")
 
     fmt_a = parse_fmt(fmt)
     args = []
@@ -53,11 +59,11 @@ def xxx___printf_chk(jitter):
 
     for x in fmt_a:
         a = jitter.get_arg_n_systemv(2 + i)
-        if x == "s":
+        if x == b"s":
             a = jitter.get_str_ansi(a)
-        elif x.lower() in ("x", 'd', 'z'):
+        elif x in (b"x", b'X', b'd', b'z', b'Z'):
             pass
-        elif x.lower() in ("f", "l"):
+        elif x.lower() in (b"f","l"):
             a = struct.unpack("d", struct.pack("Q", a))[0]
             i += 1
         else:
@@ -65,22 +71,22 @@ def xxx___printf_chk(jitter):
         args.append(a)
         i += 1
 
-    fmt = fmt.replace("%016z", "%016lx")
+    fmt = fmt.replace(b"%016z", b"%016lx")
     output = fmt%(tuple(args))
     # NaN bad repr in Python
-    output = output.replace("nan", "-nan")
+    output = output.replace(b"nan", b"-nan")
 
-    if "\n" not in output:
+    if b"\n" not in output:
         raise RuntimeError("Format must end with a \\n")
 
     # Check with expected result
-    line = expected.next()
-    if output != line:
-        print "Expected:", line
-        print "Obtained:", output
+    line = next(expected)
+    if output != line.encode():
+        print("Expected:", line)
+        print("Obtained:", output)
         raise RuntimeError("Bad semantic")
 
-    sys.stdout.write("[%d] %s" % (nb_tests, output))
+    stdout.write(b"[%d] %s" % (nb_tests, output))
     nb_tests += 1
     jitter.func_ret_systemv(ret_ad, 0)
 
@@ -94,10 +100,10 @@ def xxx_puts(jitter):
     ret_addr, args = jitter.func_args_systemv(['target'])
     output = jitter.get_str_ansi(args.target)
     # Check with expected result
-    line = expected.next()
+    line = next(expected)
     if output != line.rstrip():
-        print "Expected:", line
-        print "Obtained:", output
+        print("Expected:", line)
+        print("Obtained:", output)
         raise RuntimeError("Bad semantic")
     return jitter.func_ret_systemv(ret_addr, 1)
 
@@ -114,7 +120,7 @@ expected = open(options.expected)
 # Create sandbox
 sb = Sandbox_Linux_x86_64(options.filename, options, globals())
 try:
-    addr = sb.elf.getsectionbyname(".symtab").symbols[options.funcname].value
+    addr = sb.elf.getsectionbyname(".symtab")[options.funcname].value
 except AttributeError:
     raise RuntimeError("The target binary must have a symtab section")
 
@@ -123,7 +129,7 @@ log_func.setLevel(logging.ERROR)
 # Segmentation
 sb.jitter.cpu.set_segm_base(8, 0x7fff0000)
 sb.jitter.cpu.FS = 8
-sb.jitter.vm.add_memory_page(0x7fff0000 + 0x28, PAGE_READ | PAGE_WRITE, "AAAAAAAA")
+sb.jitter.vm.add_memory_page(0x7fff0000 + 0x28, PAGE_READ | PAGE_WRITE, b"AAAAAAAA")
 
 
 # Run
diff --git a/test/arch/x86/sem.py b/test/arch/x86/sem.py
index 0783089d..c0cfc8f2 100755
--- a/test/arch/x86/sem.py
+++ b/test/arch/x86/sem.py
@@ -3,6 +3,11 @@
 
 # Loosely based on ARM's sem.py
 
+from __future__ import print_function
+from builtins import range
+
+from future.utils import viewitems
+
 import unittest
 import logging
 import copy
@@ -30,11 +35,13 @@ def symb_exec(lbl, ir_arch, ircfg, inputstate, debug):
     symexec = SymbolicExecutionEngine(ir_arch, sympool)
     symexec.run_at(ircfg, lbl)
     if debug:
-        for k, v in symexec.symbols.items():
+        for k, v in viewitems(symexec.symbols):
             if regs_init.get(k, None) != v:
-                print k, v
-    return {k: v for k, v in symexec.symbols.items()
-            if k not in EXCLUDE_REGS and regs_init.get(k, None) != v}
+                print(k, v)
+    return {
+        k: v for k, v in viewitems(symexec.symbols)
+        if k not in EXCLUDE_REGS and regs_init.get(k, None) != v
+    }
 
 def compute(ir, mode, asm, inputstate={}, debug=False):
     loc_db = LocationDB()
@@ -60,7 +67,7 @@ def compute_txt(ir, mode, txt, inputstate={}, debug=False):
 op_add = lambda a, b: a+b
 op_sub = lambda a, b: a-b
 op_mul = lambda a, b: a*b
-op_div = lambda a, b: a/b
+op_div = lambda a, b: a //b
 
 op_and = lambda a, b: a&b
 op_or  = lambda a, b: a|b
@@ -72,8 +79,8 @@ def int_vec_op(op, elt_size, reg_size, arg1, arg2):
     assert(reg_size % elt_size == 0)
     ret = 0
     mask = (1<<elt_size)-1
-    nelts = reg_size/elt_size
-    for i in xrange(0, nelts):
+    nelts = reg_size // elt_size
+    for i in range(0, nelts):
         ret |= (op(arg1 & mask, arg2 & mask) & mask) << (i*elt_size)
         arg1 >>= elt_size
         arg2 >>= elt_size
diff --git a/test/arch/x86/unit/access_xmm.py b/test/arch/x86/unit/access_xmm.py
index 950c8b56..8354c30f 100644
--- a/test/arch/x86/unit/access_xmm.py
+++ b/test/arch/x86/unit/access_xmm.py
@@ -10,7 +10,7 @@ myjit = Machine("x86_32").jitter("python")
 assert myjit.cpu.XMM0 == 0
 
 # Test set
-myjit.cpu.XMM1 = 0x00112233445566778899aabbccddeeffL
+myjit.cpu.XMM1 = 0x00112233445566778899aabbccddeeff
 
 # Ensure set has been correctly handled
-assert myjit.cpu.XMM1 == 0x00112233445566778899aabbccddeeffL
+assert myjit.cpu.XMM1 == 0x00112233445566778899aabbccddeeff
diff --git a/test/arch/x86/unit/asm_test.py b/test/arch/x86/unit/asm_test.py
index 91da1942..a87fe278 100644
--- a/test/arch/x86/unit/asm_test.py
+++ b/test/arch/x86/unit/asm_test.py
@@ -1,6 +1,10 @@
+from builtins import str
+from builtins import object
 import sys
 import os
 
+from future.utils import viewitems
+
 from miasm2.arch.x86.arch import mn_x86, base_expr, variable
 from miasm2.core import parse_asm
 from miasm2.expression.expression import *
@@ -46,10 +50,10 @@ class Asm_Test(object):
         loc_db.set_location_offset(loc_db.get_name_location("main"), 0x0)
         s = StrPatchwork()
         patches = asmblock.asm_resolve_final(mn_x86, blocks, loc_db)
-        for offset, raw in patches.items():
+        for offset, raw in viewitems(patches):
             s[offset] = raw
 
-        s = str(s)
+        s = bytes(s)
         self.assembly = s
 
     def check(self):
diff --git a/test/arch/x86/unit/mn_getset128.py b/test/arch/x86/unit/mn_getset128.py
index a084d663..f20f452e 100644
--- a/test/arch/x86/unit/mn_getset128.py
+++ b/test/arch/x86/unit/mn_getset128.py
@@ -35,15 +35,15 @@ class Test_get_set_128(Asm_Test_32):
         assert self.myjit.cpu.get_gpreg()['XMM0'] == val
 
     def check(self):
-        assert self.myjit.cpu.XMM0 == 0xffffffffffffffff0000000000000000L
+        assert self.myjit.cpu.XMM0 == 0xffffffffffffffff0000000000000000
         assert self.myjit.cpu.XMM1 == 0x11223345
 
         # Check 128 get / set
-        assert self.myjit.cpu.get_gpreg()['XMM0'] == 0xffffffffffffffff0000000000000000L
+        assert self.myjit.cpu.get_gpreg()['XMM0'] == 0xffffffffffffffff0000000000000000
         assert self.myjit.cpu.get_gpreg()['XMM1'] == 0x11223345
 
-        assert self.myjit.cpu.get_gpreg()['XMM2'] == 0x11112222333344445555666677778888L
-        assert self.myjit.cpu.get_gpreg()['XMM2'] == 0x11112222333344445555666677778888L
+        assert self.myjit.cpu.get_gpreg()['XMM2'] == 0x11112222333344445555666677778888
+        assert self.myjit.cpu.get_gpreg()['XMM2'] == 0x11112222333344445555666677778888
 
 
 if __name__ == "__main__":
diff --git a/test/arch/x86/unit/mn_pcmpeq.py b/test/arch/x86/unit/mn_pcmpeq.py
index e934d6b5..b8eeafba 100755
--- a/test/arch/x86/unit/mn_pcmpeq.py
+++ b/test/arch/x86/unit/mn_pcmpeq.py
@@ -81,7 +81,7 @@ class Test_PCMPEQQ(Asm_Test_32):
         self.myjit.cpu.XMM0 = val
 
     def check(self):
-        assert self.myjit.cpu.XMM0 == 0xffffffffffffffff0000000000000000L
+        assert self.myjit.cpu.XMM0 == 0xffffffffffffffff0000000000000000
         assert self.myjit.cpu.XMM1 == 0x11223345
 
 
diff --git a/test/arch/x86/unit/mn_pshufb.py b/test/arch/x86/unit/mn_pshufb.py
index d10c18e3..9167b0c1 100755
--- a/test/arch/x86/unit/mn_pshufb.py
+++ b/test/arch/x86/unit/mn_pshufb.py
@@ -18,8 +18,8 @@ class Test_PSHUFB(Asm_Test_32):
     '''
 
     def check(self):
-        assert self.myjit.cpu.MM0 == 0x1122334455667788L
-        assert self.myjit.cpu.MM1 == 0x8877665544332211L
+        assert self.myjit.cpu.MM0 == 0x1122334455667788
+        assert self.myjit.cpu.MM1 == 0x8877665544332211
 
 
 if __name__ == "__main__":
diff --git a/test/arch/x86/unit/mn_psrl_psll.py b/test/arch/x86/unit/mn_psrl_psll.py
index a5428dab..7d9572b0 100755
--- a/test/arch/x86/unit/mn_psrl_psll.py
+++ b/test/arch/x86/unit/mn_psrl_psll.py
@@ -22,10 +22,10 @@ class Test_PSRL(Asm_Test_32):
     '''
 
     def check(self):
-        assert self.myjit.cpu.MM0 == 0x1122334455667788L
-        assert self.myjit.cpu.MM1 == 0x0112033405560778L
-        assert self.myjit.cpu.MM2 == 0x0112233405566778L
-        assert self.myjit.cpu.MM3 == 0x0112233445566778L
+        assert self.myjit.cpu.MM0 == 0x1122334455667788
+        assert self.myjit.cpu.MM1 == 0x0112033405560778
+        assert self.myjit.cpu.MM2 == 0x0112233405566778
+        assert self.myjit.cpu.MM3 == 0x0112233445566778
 
 class Test_PSLL(Asm_Test_32):
     TXT = '''
@@ -46,10 +46,10 @@ class Test_PSLL(Asm_Test_32):
     '''
 
     def check(self):
-        assert self.myjit.cpu.MM0 == 0x1122334455667788L
-        assert self.myjit.cpu.MM1 == 0x1220344056607880L
-        assert self.myjit.cpu.MM2 == 0x1223344056677880L
-        assert self.myjit.cpu.MM3 == 0x1223344556677880L
+        assert self.myjit.cpu.MM0 == 0x1122334455667788
+        assert self.myjit.cpu.MM1 == 0x1220344056607880
+        assert self.myjit.cpu.MM2 == 0x1223344056677880
+        assert self.myjit.cpu.MM3 == 0x1223344556677880
 
 
 if __name__ == "__main__":
diff --git a/test/arch/x86/unit/mn_pushpop.py b/test/arch/x86/unit/mn_pushpop.py
index 6e9005ca..fedd197b 100755
--- a/test/arch/x86/unit/mn_pushpop.py
+++ b/test/arch/x86/unit/mn_pushpop.py
@@ -25,7 +25,7 @@ class Test_PUSHAD_32(Asm_Test_32):
 
     def test_init(self):
         init_regs(self)
-        self.buf = ""
+        self.buf = b""
         for reg_name in reversed(["EAX", "ECX",
                                   "EDX", "EBX",
                                   "ESP", "EBP",
@@ -52,7 +52,7 @@ class Test_PUSHA_32(Asm_Test_32):
 
     def test_init(self):
         init_regs(self)
-        self.buf = ""
+        self.buf = b""
         for reg_name in reversed(["AX", "CX",
                                   "DX", "BX",
                                   "SP", "BP",
@@ -79,7 +79,7 @@ class Test_PUSHA_16(Asm_Test_16):
 
     def test_init(self):
         init_regs(self)
-        self.buf = ""
+        self.buf = b""
         for reg_name in reversed(["AX", "CX",
                                   "DX", "BX",
                                   "SP", "BP",
@@ -106,7 +106,7 @@ class Test_PUSHAD_16(Asm_Test_16):
 
     def test_init(self):
         init_regs(self)
-        self.buf = ""
+        self.buf = b""
         for reg_name in reversed(["EAX", "ECX",
                                   "EDX", "EBX",
                                   "ESP", "EBP",
@@ -133,7 +133,7 @@ class Test_PUSH_mode32_32(Asm_Test_32):
 
     def test_init(self):
         init_regs(self)
-        self.buf = ""
+        self.buf = b""
         self.buf += pck32(0x11223344)
 
     TXT = '''
@@ -156,7 +156,7 @@ class Test_PUSH_mode32_16(Asm_Test_32):
 
     def test_init(self):
         init_regs(self)
-        self.buf = ""
+        self.buf = b""
         self.buf += pck16(0x1122)
 
     TXT = '''
@@ -179,7 +179,7 @@ class Test_PUSH_mode16_16(Asm_Test_16):
 
     def test_init(self):
         init_regs(self)
-        self.buf = ""
+        self.buf = b""
         self.buf += pck16(0x1122)
 
     TXT = '''
@@ -202,7 +202,7 @@ class Test_PUSH_mode16_32(Asm_Test_16):
 
     def test_init(self):
         init_regs(self)
-        self.buf = ""
+        self.buf = b""
         self.buf += pck32(0x11223344)
 
     TXT = '''
diff --git a/test/arch/x86/unit/mn_seh.py b/test/arch/x86/unit/mn_seh.py
index dd3fd4ef..1fa0900e 100755
--- a/test/arch/x86/unit/mn_seh.py
+++ b/test/arch/x86/unit/mn_seh.py
@@ -1,4 +1,5 @@
 #! /usr/bin/env python2
+from __future__ import print_function
 import sys
 
 from miasm2.os_dep.win_api_x86_32_seh import fake_seh_handler, build_teb, \
@@ -15,7 +16,7 @@ class Test_SEH(Asm_Test_32):
 
     @staticmethod
     def deal_exception_priv(jitter):
-        print 'Exception Priv', hex(jitter.cpu.ESP)
+        print('Exception Priv', hex(jitter.cpu.ESP))
         pc = fake_seh_handler(jitter, EXCEPTION_PRIV_INSTRUCTION)
         jitter.pc = pc
         jitter.cpu.EIP = pc
diff --git a/test/core/asmblock.py b/test/core/asmblock.py
index c3e1d11d..48e81e78 100644
--- a/test/core/asmblock.py
+++ b/test/core/asmblock.py
@@ -1,5 +1,10 @@
+from __future__ import print_function
+from builtins import map
 from pdb import pm
 
+from future.utils import viewitems
+
+from miasm2.core.utils import decode_hex
 from miasm2.analysis.machine import Machine
 from miasm2.analysis.binary import Container
 from miasm2.core.asmblock import AsmCFG, AsmConstraint, AsmBlock, \
@@ -9,7 +14,7 @@ from miasm2.core.graph import DiGraphSimplifier, MatchGraphJoker
 from miasm2.expression.expression import ExprId
 
 # Initial data: from 'samples/simple_test.bin'
-data = "5589e583ec10837d08007509c745fc01100000eb73837d08017709c745fc02100000eb64837d08057709c745fc03100000eb55837d080774138b450801c083f80e7509c745fc04100000eb3c8b450801c083f80e7509c745fc05100000eb298b450883e03085c07409c745fc06100000eb16837d08427509c745fc07100000eb07c745fc081000008b45fcc9c3".decode("hex")
+data = decode_hex("5589e583ec10837d08007509c745fc01100000eb73837d08017709c745fc02100000eb64837d08057709c745fc03100000eb55837d080774138b450801c083f80e7509c745fc04100000eb3c8b450801c083f80e7509c745fc05100000eb298b450883e03085c07409c745fc06100000eb16837d08427509c745fc07100000eb07c745fc081000008b45fcc9c3")
 cont = Container.from_string(data)
 
 # Test Disasm engine
@@ -18,12 +23,12 @@ mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db)
 ## Disassembly of one block
 first_block = mdis.dis_block(0)
 assert len(first_block.lines) == 5
-print first_block
+print(first_block)
 
 ## Test redisassemble asmcfg
 first_block_bis = mdis.dis_block(0)
 assert len(first_block.lines) == len(first_block_bis.lines)
-print first_block_bis
+print(first_block_bis)
 
 ## Disassembly of several block, with cache
 asmcfg = mdis.dis_multiblock(0)
@@ -214,7 +219,7 @@ assert len(asmcfg.pendings) == 0
 asmcfg.sanity_check()
 
 # Test block_merge
-data2 = "31c0eb0c31c9750c31d2eb0c31ffebf831dbebf031edebfc31f6ebf031e4c3".decode("hex")
+data2 = decode_hex("31c0eb0c31c9750c31d2eb0c31ffebf831dbebf031edebfc31f6ebf031e4c3")
 cont2 = Container.from_string(data2)
 mdis = machine.dis_engine(cont2.bin_stream, loc_db=cont2.loc_db)
 ## Elements to merge
@@ -234,35 +239,35 @@ assert len(asmcfg) == 5
 assert len(list(asmcfg.get_bad_blocks())) == 1
 ### Check "special" asmcfg
 entry_asmcfg = asmcfg.heads()
-bad_block_lbl = (lbl for lbl in entry_asmcfg
-                 if isinstance(asmcfg.loc_key_to_block(lbl), AsmBlockBad)).next()
+bad_block_lbl = next((lbl for lbl in entry_asmcfg
+                 if isinstance(asmcfg.loc_key_to_block(lbl), AsmBlockBad)))
 entry_asmcfg.remove(bad_block_lbl)
-alone_block = (asmcfg.loc_key_to_block(lbl) for lbl in entry_asmcfg
-               if len(asmcfg.successors(lbl)) == 0).next()
+alone_block = next((asmcfg.loc_key_to_block(lbl) for lbl in entry_asmcfg
+               if len(asmcfg.successors(lbl)) == 0))
 entry_asmcfg.remove(alone_block.loc_key)
 assert alone_block.lines[-1].name == "RET"
 assert len(alone_block.lines) == 2
 ### Check resulting function
 entry_block = asmcfg.loc_key_to_block(entry_asmcfg.pop())
 assert len(entry_block.lines) == 4
-assert map(str, entry_block.lines) == ['XOR        EAX, EAX',
+assert list(map(str, entry_block.lines)) == ['XOR        EAX, EAX',
                                        'XOR        EBX, EBX',
                                        'XOR        ECX, ECX',
                                        'JNZ        loc_key_3']
 assert len(asmcfg.successors(entry_block.loc_key)) == 2
 assert len(entry_block.bto) == 2
-nextb = asmcfg.loc_key_to_block((cons.loc_key for cons in entry_block.bto
-                              if cons.c_t == AsmConstraint.c_next).next())
-tob = asmcfg.loc_key_to_block((cons.loc_key for cons in entry_block.bto
-                            if cons.c_t == AsmConstraint.c_to).next())
+nextb = asmcfg.loc_key_to_block(next((cons.loc_key for cons in entry_block.bto
+                              if cons.c_t == AsmConstraint.c_next)))
+tob = asmcfg.loc_key_to_block(next((cons.loc_key for cons in entry_block.bto
+                            if cons.c_t == AsmConstraint.c_to)))
 assert len(nextb.lines) == 4
-assert map(str, nextb.lines) == ['XOR        EDX, EDX',
+assert list(map(str, nextb.lines)) == ['XOR        EDX, EDX',
                                  'XOR        ESI, ESI',
                                  'XOR        EDI, EDI',
                                  'JMP        loc_key_4']
 assert asmcfg.successors(nextb.loc_key) == [nextb.loc_key]
 assert len(tob.lines) == 2
-assert map(str, tob.lines) == ['XOR        EBP, EBP',
+assert list(map(str, tob.lines)) == ['XOR        EBP, EBP',
                                'JMP        loc_key_3']
 assert asmcfg.successors(tob.loc_key) == [tob.loc_key]
 
@@ -283,13 +288,13 @@ asmcfg.apply_splitting(mdis.loc_db)
 assert len(asmcfg) == 6
 assert len(asmcfg.pendings) == 0
 assert len(entry_block.lines) == 2
-assert map(str, entry_block.lines) == ['XOR        EAX, EAX',
+assert list(map(str, entry_block.lines)) == ['XOR        EAX, EAX',
                                        'XOR        EBX, EBX']
 assert len(asmcfg.successors(entry_block.loc_key)) == 1
 lbl_newb = asmcfg.successors(entry_block.loc_key)[0]
 newb = asmcfg.loc_key_to_block(lbl_newb)
 assert len(newb.lines) == 2
-assert map(str, newb.lines) == ['XOR        ECX, ECX',
+assert list(map(str, newb.lines)) == ['XOR        ECX, ECX',
                                 'JNZ        loc_key_3']
 preds = asmcfg.predecessors(lbl_newb)
 assert len(preds) == 2
@@ -300,7 +305,7 @@ assert asmcfg.edges2constraint[(tob.loc_key, lbl_newb)] == AsmConstraint.c_to
 
 
 # Check double block split
-data = "74097405b8020000007405b803000000b804000000c3".decode('hex')
+data = decode_hex("74097405b8020000007405b803000000b804000000c3")
 cont = Container.from_string(data)
 mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db)
 asmcfg = mdis.dis_multiblock(0)
@@ -322,7 +327,7 @@ matcher += bbl0 >> bblB
 solutions = list(matcher.match(asmcfg))
 assert len(solutions) == 1
 solution = solutions.pop()
-for jbbl, label in solution.iteritems():
+for jbbl, label in viewitems(solution):
     offset = mdis.loc_db.get_location_offset(label)
     assert offset == int(jbbl._name, 16)
 
diff --git a/test/core/graph.py b/test/core/graph.py
index b71c3d51..484591b7 100644
--- a/test/core/graph.py
+++ b/test/core/graph.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 from miasm2.core.graph import *
 
 g = DiGraph()
@@ -9,13 +10,13 @@ g.add_edge('a', 'c')
 g.add_edge('a', 'c')
 g.add_edge('c', 'c')
 
-print g
+print(g)
 
-print [x for x in g.successors('a')]
-print [x for x in g.predecessors('a')]
-print [x for x in g.predecessors('b')]
-print [x for x in g.predecessors('c')]
-print [x for x in g.successors('c')]
+print([x for x in g.successors('a')])
+print([x for x in g.predecessors('a')])
+print([x for x in g.predecessors('b')])
+print([x for x in g.predecessors('c')])
+print([x for x in g.successors('c')])
 
 
 """
@@ -226,7 +227,7 @@ j2 = MatchGraphJoker(name="son")
 ### Check '>>' helper
 matcher = j1 >> j2 >> j1
 ### Check __str__
-print matcher
+print(matcher)
 ### Ensure form
 assert isinstance(matcher, MatchGraph)
 assert len(matcher.nodes()) == 2
diff --git a/test/core/interval.py b/test/core/interval.py
index 97d45a39..76c95d66 100755
--- a/test/core/interval.py
+++ b/test/core/interval.py
@@ -1,6 +1,7 @@
 #! /usr/bin/env python2
 #-*- coding:utf-8 -*-
 
+from builtins import range
 from miasm2.core.interval import *
 from random import randint
 from pdb import pm
@@ -107,7 +108,7 @@ assert(i_empty.hull() == (None, None))
 
 def gen_random_interval(l=100):
     r = []
-    for j in xrange(5):
+    for j in range(5):
         a = randint(0, l)
         b = a + randint(0, l)
         r.append((a, b))
@@ -117,7 +118,7 @@ def gen_random_interval(l=100):
 def check_add(r1, r2):
     i_sum = interval(r1) + interval(r2)
     for a, b in r1 + r2:
-        for i in xrange(a, b + 1):
+        for i in range(a, b + 1):
             assert(i in i_sum)
 
 
@@ -126,7 +127,7 @@ def check_sub(r1, r2):
     i2 = interval(r2)
     i_sub = i1 - i2
     for a, b in r1:
-        for i in xrange(a, b + 1):
+        for i in range(a, b + 1):
             if i in i2:
                 assert(i not in i_sub)
             else:
@@ -138,14 +139,14 @@ def check_and(r1, r2):
     i2 = interval(r2)
     i_and = i1 & i2
     for a, b in r1:
-        for i in xrange(a, b + 1):
+        for i in range(a, b + 1):
             if i in i2:
                 assert(i in i_and)
             else:
                 assert(i not in i_and)
 
 
-for i in xrange(1000):
+for i in range(1000):
     r1 = gen_random_interval()
     r2 = gen_random_interval()
     r3 = gen_random_interval()
diff --git a/test/core/locationdb.py b/test/core/locationdb.py
index 61bc4563..3db760d8 100644
--- a/test/core/locationdb.py
+++ b/test/core/locationdb.py
@@ -1,3 +1,4 @@
+from builtins import str
 from miasm2.core.locationdb import LocationDB
 
 
@@ -57,9 +58,9 @@ loc_db.consistency_check()
 
 # Names manipulation
 loc_key5 = loc_db.add_location()
-name1 = "name1"
-name2 = "name2"
-name3 = "name3"
+name1 = b"name1"
+name2 = b"name2"
+name3 = b"name3"
 assert len(loc_db.get_location_names(loc_key5)) == 0
 loc_db.add_location_name(loc_key5, name1)
 loc_db.add_location_name(loc_key5, name2)
diff --git a/test/core/parse_asm.py b/test/core/parse_asm.py
index ddb195d2..ade9040d 100755
--- a/test/core/parse_asm.py
+++ b/test/core/parse_asm.py
@@ -1,6 +1,7 @@
 #! /usr/bin/env python2
 #-*- coding:utf-8 -*-
 
+from builtins import range
 import unittest
 
 
@@ -69,7 +70,7 @@ class TestParseAsm(unittest.TestCase):
                                     asmcfg,
                                     loc_db)
         lbls = []
-        for i in xrange(6):
+        for i in range(6):
             lbls.append(loc_db.get_name_location('lbl%d' % i))
         # align test
         offset = loc_db.get_location_offset(lbls[5])
@@ -97,7 +98,7 @@ class TestParseAsm(unittest.TestCase):
 
         asmcfg, loc_db = parse_txt(mn_x86, 32, ASM0)
         lbls = []
-        for i in xrange(2):
+        for i in range(2):
             lbls.append(loc_db.get_name_location('lbl%d' % i))
         lbl2block = {}
         for block in asmcfg.blocks:
diff --git a/test/core/sembuilder.py b/test/core/sembuilder.py
index f7a96b89..53e9e60e 100644
--- a/test/core/sembuilder.py
+++ b/test/core/sembuilder.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 import inspect
 from pdb import pm
 
@@ -50,18 +51,18 @@ ir = IR(loc_db)
 instr = Instr()
 res = test(ir, instr, a, b, c)
 
-print "[+] Returned:"
-print res
-print "[+] DocString:", test.__doc__
+print("[+] Returned:")
+print(res)
+print("[+] DocString:", test.__doc__)
 
-print "[+] Cur instr:"
+print("[+] Cur instr:")
 for statement in res[0]:
-    print statement
+    print(statement)
 
-print "[+] Blocks:"
+print("[+] Blocks:")
 for irb in res[1]:
-    print irb.loc_key
+    print(irb.loc_key)
     for assignblk in irb:
         for expr in assignblk:
-            print expr
-        print
+            print(expr)
+        print()
diff --git a/test/core/test_types.py b/test/core/test_types.py
index 92867748..e3914185 100755
--- a/test/core/test_types.py
+++ b/test/core/test_types.py
@@ -2,8 +2,11 @@
 
 # miasm2.core.types tests
 
+from __future__ import print_function
+from builtins import range
 import struct
 
+from miasm2.core.utils import int_to_byte
 from miasm2.analysis.machine import Machine
 from miasm2.core.types import MemStruct, Num, Ptr, Str, \
                               Array, RawStruct, Union, \
@@ -40,7 +43,7 @@ addr_str = 0x1100
 addr_str2 = 0x1200
 addr_str3 = 0x1300
 # Initialize all mem with 0xaa
-jitter.vm.add_memory_page(addr, PAGE_READ | PAGE_WRITE, "\xaa"*size)
+jitter.vm.add_memory_page(addr, PAGE_READ | PAGE_WRITE, b"\xaa"*size)
 
 
 # MemStruct tests
@@ -64,7 +67,7 @@ assert mstruct.flags == 0
 assert mstruct.other.val == 0
 assert mstruct.s.val == 0
 assert mstruct.i.val == 0
-mstruct.memset('\x11')
+mstruct.memset(b'\x11')
 assert mstruct.num == 0x11111111
 assert mstruct.flags == 0x11
 assert mstruct.other.val == 0x11111111
@@ -122,10 +125,10 @@ assert memval == 8
 memstr = Str().lval(jitter.vm, addr_str)
 memstr.val = ""
 assert memstr.val == ""
-assert jitter.vm.get_mem(memstr.get_addr(), 1) == '\x00'
+assert jitter.vm.get_mem(memstr.get_addr(), 1) == b'\x00'
 memstr.val = "lala"
-assert jitter.vm.get_mem(memstr.get_addr(), memstr.get_size()) == 'lala\x00'
-jitter.vm.set_mem(memstr.get_addr(), 'MIAMs\x00')
+assert jitter.vm.get_mem(memstr.get_addr(), memstr.get_size()) == b'lala\x00'
+jitter.vm.set_mem(memstr.get_addr(), b'MIAMs\x00')
 assert memstr.val == 'MIAMs'
 
 ## Ptr(Str()) manipulations
@@ -148,7 +151,7 @@ memstr3 = Str("utf16").lval(jitter.vm, addr_str3)
 memstr3.val = "That's all folks!"
 assert memstr3.get_addr() != memstr.get_addr()
 assert memstr3.get_size() != memstr.get_size() # Size is different
-assert str(memstr3) != str(memstr) # Mem representation is different
+assert bytes(memstr3) != bytes(memstr) # Mem representation is different
 assert memstr3 != memstr # Encoding is different, so they are not eq
 assert memstr3.val == memstr.val # But the python value is the same
 
@@ -163,13 +166,13 @@ memarray = Array(Num("I")).lval(jitter.vm, alloc_addr)
 memarray[0] = 0x02
 assert memarray[0] == 0x02
 assert jitter.vm.get_mem(memarray.get_addr(),
-                         Num("I").size) == '\x02\x00\x00\x00'
+                         Num("I").size) == b'\x02\x00\x00\x00'
 memarray[2] = 0xbbbbbbbb
 assert memarray[2] == 0xbbbbbbbb
 assert jitter.vm.get_mem(memarray.get_addr() + 2 * Num("I").size,
-                         Num("I").size) == '\xbb\xbb\xbb\xbb'
+                         Num("I").size) == b'\xbb\xbb\xbb\xbb'
 try:
-    s = str(memarray)
+    s = bytes(memarray)
     assert False, "Should raise"
 except (NotImplementedError, ValueError):
     pass
@@ -194,16 +197,16 @@ except ValueError:
 memsarray = Array(Num("I"), 10).lval(jitter.vm)
 # And Array(type, size).lval generates statically sized types
 assert memsarray.sizeof() == Num("I").size * 10
-memsarray.memset('\xcc')
+memsarray.memset(b'\xcc')
 assert memsarray[0] == 0xcccccccc
 assert len(memsarray) == 10 * 4
-assert str(memsarray) == '\xcc' * (4 * 10)
+assert bytes(memsarray) == b'\xcc' * (4 * 10)
 for val in memsarray:
     assert val == 0xcccccccc
 assert list(memsarray) == [0xcccccccc] * 10
 memsarray[0] = 2
 assert memsarray[0] == 2
-assert str(memsarray) == '\x02\x00\x00\x00' + '\xcc' * (4 * 9)
+assert bytes(memsarray) == b'\x02\x00\x00\x00' + b'\xcc' * (4 * 9)
 
 
 # Atypical fields (RawStruct and Array)
@@ -214,7 +217,7 @@ class MyStruct2(MemStruct):
     ]
 
 ms2 = MyStruct2(jitter.vm)
-ms2.memset('\xaa')
+ms2.memset(b'\xaa')
 assert len(ms2) == 15
 
 ## RawStruct
@@ -241,7 +244,7 @@ for val in ms2.s2:
 
 ### Field assignment (MemSizedArray)
 array2 = Array(Num("B"), 10).lval(jitter.vm)
-jitter.vm.set_mem(array2.get_addr(), '\x02'*10)
+jitter.vm.set_mem(array2.get_addr(), b'\x02'*10)
 for val in array2:
     assert val == 2
 ms2.s2 = array2
@@ -272,7 +275,7 @@ assert cont.one == 0
 assert cont.last == 0
 assert cont.instruct.foo == 0
 assert cont.instruct.bar == 0
-cont.memset('\x11')
+cont.memset(b'\x11')
 assert cont.one == 0x11
 assert cont.last == 0x11
 assert cont.instruct.foo == 0x11
@@ -286,7 +289,7 @@ assert cont.one == 0x01
 assert cont.instruct.foo == 0x02
 assert cont.instruct.bar == 0x03
 assert cont.last == 0x04
-assert jitter.vm.get_mem(cont.get_addr(), len(cont)) == '\x01\x02\x03\x04'
+assert jitter.vm.get_mem(cont.get_addr(), len(cont)) == b'\x01\x02\x03\x04'
 
 
 # Union test
@@ -301,7 +304,7 @@ class UniStruct(MemStruct):
     ]
 
 uni = UniStruct(jitter.vm)
-jitter.vm.set_mem(uni.get_addr(), ''.join(chr(x) for x in xrange(len(uni))))
+jitter.vm.set_mem(uni.get_addr(), b''.join(int_to_byte(x) for x in range(len(uni))))
 assert len(uni) == 6 # 1 + max(InStruct.sizeof(), 4) + 1
 assert uni.one == 0x00
 assert uni.union.instruct.foo == 0x01
@@ -535,18 +538,18 @@ for idx, off in ((0, 0), (1, 2), (30, 60)):
 
 # Repr tests
 
-print "Some struct reprs:\n"
-print repr(mstruct), '\n'
-print repr(ms2), '\n'
-print repr(cont), '\n'
-print repr(uni), '\n'
-print repr(bit), '\n'
-print repr(ideas), '\n'
-print repr(Array(MyStruct2.get_type(), 2).lval(jitter.vm, addr)), '\n'
-print repr(Num("f").lval(jitter.vm, addr)), '\n'
-print repr(memarray)
-print repr(memsarray)
-print repr(memstr)
-print repr(memstr3)
-
-print "\nOk" # That's all folks!
+print("Some struct reprs:\n")
+print(repr(mstruct), '\n')
+print(repr(ms2), '\n')
+print(repr(cont), '\n')
+print(repr(uni), '\n')
+print(repr(bit), '\n')
+print(repr(ideas), '\n')
+print(repr(Array(MyStruct2.get_type(), 2).lval(jitter.vm, addr)), '\n')
+print(repr(Num("f").lval(jitter.vm, addr)), '\n')
+print(repr(memarray))
+print(repr(memsarray))
+print(repr(memstr))
+print(repr(memstr3))
+
+print("\nOk") # That's all folks!
diff --git a/test/core/utils.py b/test/core/utils.py
index b506f904..6f69fdf1 100755
--- a/test/core/utils.py
+++ b/test/core/utils.py
@@ -2,6 +2,8 @@
 
 #-*- coding:utf-8 -*-
 
+from __future__ import print_function
+from builtins import range
 import unittest
 
 
@@ -12,7 +14,7 @@ class TestUtils(unittest.TestCase):
 
         # Use a callback
         def logger(key):
-            print "DELETE", key
+            print("DELETE", key)
 
         # Create a 5/2 dictionary
         bd = BoundedDict(5, 2, initialdata={"element": "value"},
@@ -26,9 +28,9 @@ class TestUtils(unittest.TestCase):
         # Increase 'element2' use
         _ = bd["element2"]
 
-        for i in xrange(6):
+        for i in range(6):
             bd[i] = i
-            print "Insert %d -> %s" % (i, bd)
+            print("Insert %d -> %s" % (i, bd))
 
         assert(len(bd) == 2)
 
diff --git a/test/expr_type/test_chandler.py b/test/expr_type/test_chandler.py
index 09c588cb..92ebd0f2 100644
--- a/test/expr_type/test_chandler.py
+++ b/test/expr_type/test_chandler.py
@@ -4,7 +4,11 @@ Regression test for objc
 * C Miasm expression to native expression
 * Miasm expression to type
 """
+from __future__ import print_function
 
+from future.utils import viewitems
+from past.builtins import cmp
+from builtins import str
 from miasm2.expression.expression import ExprInt, ExprId, ExprMem
 from miasm2.expression.simplifications import expr_simp
 
@@ -147,18 +151,18 @@ types_ast.add_c_decl(text_2)
 
 types_mngr = CTypesManagerNotPacked(types_ast, base_types)
 
-for type_id, type_desc in types_mngr.types_ast._types.iteritems():
-    print type_id
+for type_id, type_desc in viewitems(types_mngr.types_ast._types):
+    print(type_id)
     obj = types_mngr.get_objc(type_id)
-    print obj
-    print repr(obj)
+    print(obj)
+    print(repr(obj))
     types_mngr.check_objc(obj)
 
-for type_id, type_desc in types_mngr.types_ast._typedefs.iteritems():
-    print type_id
+for type_id, type_desc in viewitems(types_mngr.types_ast._typedefs):
+    print(type_id)
     obj = types_mngr.get_objc(type_id)
-    print obj
-    print repr(obj)
+    print(obj)
+    print(repr(obj))
     types_mngr.check_objc(obj)
 
 void_ptr = types_mngr.void_ptr
@@ -200,9 +204,9 @@ ptr_recurse = ExprId("ptr_recurse", 64)
 
 
 obj_test_st = types_mngr.get_objc(CTypeStruct("test_st"))
-print repr(obj_test_st)
+print(repr(obj_test_st))
 obj_test_context = types_mngr.get_objc(CTypeStruct("test_context"))
-print repr(obj_test_context)
+print(repr(obj_test_context))
 assert obj_test_context.size > obj_test_st.size
 
 assert cmp(obj_test_st, obj_recurse) != 0
@@ -513,8 +517,8 @@ mychandler.updt_expr_types(expr_types)
 
 
 for (expr, result) in tests:
-    print "*" * 80
-    print "Native expr:", expr
+    print("*" * 80)
+    print("Native expr:", expr)
     result = set(result)
     expr_c = mychandler.expr_to_c(expr)
     types = mychandler.expr_to_types(expr)
@@ -524,7 +528,7 @@ for (expr, result) in tests:
     access_c_gen = ExprToAccessC(expr_types, types_mngr)
     computed = set()
     for c_str, ctype in mychandler.expr_to_c_and_types(expr):
-        print c_str, ctype
+        print(c_str, ctype)
         computed.add((str(ctype), c_str))
     assert computed == result
 
@@ -532,12 +536,12 @@ for (expr, result) in tests:
     for out_type, out_str in computed:
         parsed_expr = mychandler.c_to_expr(out_str)
         parsed_type = mychandler.c_to_type(out_str)
-        print "Access expr:", parsed_expr
-        print "Access type:", parsed_type
+        print("Access expr:", parsed_expr)
+        print("Access type:", parsed_type)
 
         ast = parse_access(out_str)
         access_c = ast_get_c_access_expr(ast, c_context)
-        print "Generated access:", access_c
+        print("Generated access:", access_c)
 
         parsed_expr_bis, parsed_type_bis = mychandler.exprc2expr.get_expr(access_c, c_context)
         assert parsed_expr_bis is not None
@@ -551,5 +555,5 @@ for (expr, result) in tests:
 
         expr_new1 = expr_simp(parsed_expr)
         expr_new2 = expr_simp(expr)
-        print "\t", expr_new1
+        print("\t", expr_new1)
         assert expr_new1 == expr_new2
diff --git a/test/expression/expr_pickle.py b/test/expression/expr_pickle.py
index 870f761a..16b87db7 100644
--- a/test/expression/expr_pickle.py
+++ b/test/expression/expr_pickle.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 import pickle
 from miasm2.expression.expression import ExprInt, ExprAssign, ExprId, \
     Expr, ExprCompose, ExprMem
@@ -12,15 +13,15 @@ f = a[:8]
 aff = ExprAssign(a, b)
 
 
-print 'Pickling'
+print('Pickling')
 out = pickle.dumps((a, b, c, d, e, f, aff))
-print 'Unpickling'
+print('Unpickling')
 new_a, new_b, new_c, new_d, new_e, new_f, new_aff = pickle.loads(out)
-print 'Result'
-print a, b, c, aff
-print id(a), id(b), id(c), id(d), id(e), id(f), id(aff)
-print new_a, new_b, new_c, new_d, new_e, new_f, new_aff
-print id(new_a), id(new_b), id(new_c), id(new_d), id(new_e), id(new_f), id(new_aff)
+print('Result')
+print(a, b, c, aff)
+print(id(a), id(b), id(c), id(d), id(e), id(f), id(aff))
+print(new_a, new_b, new_c, new_d, new_e, new_f, new_aff)
+print(id(new_a), id(new_b), id(new_c), id(new_d), id(new_e), id(new_f), id(new_aff))
 
 assert a == new_a
 assert b == new_b
diff --git a/test/expression/expression.py b/test/expression/expression.py
index 1b39ab9f..b8a2642a 100644
--- a/test/expression/expression.py
+++ b/test/expression/expression.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 #
 # Expression regression tests  #
 #
@@ -42,15 +43,15 @@ for expr in [
                     ExprCond(cond2, cst3, cst4)),
         ExprCond(ExprCond(cond1, cst1, cst2), cst3, cst4),
 ]:
-    print "*" * 80
-    print expr
+    print("*" * 80)
+    print(expr)
     sol = possible_values(expr)
-    print sol
-    print "Resulting constraints:"
+    print(sol)
+    print("Resulting constraints:")
     for consval in sol:
-        print "For value %s" % consval.value
+        print("For value %s" % consval.value)
         for constraint in consval.constraints:
-            print "\t%s" % constraint.to_constraint()
+            print("\t%s" % constraint.to_constraint())
 
 # Repr
 for expr in [
@@ -63,7 +64,7 @@ for expr in [
         A.msb(),
         ExprAssign(A, cst1),
 ]:
-    print repr(expr)
+    print(repr(expr))
     assert expr == eval(repr(expr))
 
 
diff --git a/test/expression/expression_helper.py b/test/expression/expression_helper.py
index 35873ca4..6c6fb2a9 100755
--- a/test/expression/expression_helper.py
+++ b/test/expression/expression_helper.py
@@ -1,6 +1,9 @@
 #! /usr/bin/env python2
 #-*- coding:utf-8 -*-
 
+from __future__ import print_function
+
+from future.utils import viewitems
 import unittest
 
 
@@ -25,13 +28,13 @@ class TestExpressionExpressionHelper(unittest.TestCase):
         vi = Variables_Identifier(exprf)
 
         # Use __str__
-        print vi
+        print(vi)
 
         # Test the result
         new_expr = vi.equation
 
         ## Force replace in the variable dependency order
-        for var_id, var_value in reversed(vi.vars.items()):
+        for var_id, var_value in reversed(list(viewitems(vi.vars))):
             new_expr = new_expr.replace_expr({var_id: var_value})
         self.assertEqual(exprf, new_expr)
 
@@ -39,12 +42,12 @@ class TestExpressionExpressionHelper(unittest.TestCase):
         vi = Variables_Identifier(exprf, var_prefix="prefix_v")
 
         ## Use __str__
-        print vi
+        print(vi)
 
         ## Test the result
         new_expr = vi.equation
         ### Force replace in the variable dependency order
-        for var_id, var_value in reversed(vi.vars.items()):
+        for var_id, var_value in reversed(list(viewitems(vi.vars))):
             new_expr = new_expr.replace_expr({var_id: var_value})
         self.assertEqual(exprf, new_expr)
 
@@ -55,7 +58,7 @@ class TestExpressionExpressionHelper(unittest.TestCase):
         ## Test the result
         new_expr = vi2.equation
         ### Force replace in the variable dependency order
-        for var_id, var_value in reversed(vi2.vars.items()):
+        for var_id, var_value in reversed(list(viewitems(vi2.vars))):
             new_expr = new_expr.replace_expr({var_id: var_value})
         self.assertEqual(vi.equation, new_expr)
 
@@ -72,7 +75,7 @@ class TestExpressionExpressionHelper(unittest.TestCase):
         ## Test the result
         new_expr = vi2.equation
         ### Force replace in the variable dependency order
-        for var_id, var_value in reversed(vi2.vars.items()):
+        for var_id, var_value in reversed(list(viewitems(vi2.vars))):
             new_expr = new_expr.replace_expr({var_id: var_value})
         self.assertEqual(vi.equation, new_expr)
 
diff --git a/test/expression/modint.py b/test/expression/modint.py
index 17c12907..a833ee80 100644
--- a/test/expression/modint.py
+++ b/test/expression/modint.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 from miasm2.expression.modint import *
 
 a = uint8(0x42)
@@ -10,12 +11,12 @@ e = uint1(1)
 f = uint8(0x1)
 g = int8(-3)
 
-print a, b, c
-print a + b, a + c, b + c
-print a == a, a == b, a == 0x42, a == 0x78
-print a != b, a != a
-print d, e
-print d + e, d + d, e + e, e + e + e, e + 0x11
+print(a, b, c)
+print(a + b, a + c, b + c)
+print(a == a, a == b, a == 0x42, a == 0x78)
+print(a != b, a != a)
+print(d, e)
+print(d + e, d + d, e + e, e + e + e, e + 0x11)
 
 assert(f == 1)
 assert(f + 1 == 2)
@@ -24,10 +25,10 @@ assert(f + 0xff == 0)
 assert(f & 0 == 0)
 assert(f & 0xff == f)
 assert(0xff & f == f)
-assert(f / 1 == f)
-assert(1 / f == f)
+assert(f // 1 == f)
+assert(1 // f == f)
+assert(int(f) == 1)
 assert(int(f) == 1)
-assert(long(f) == 1)
 assert(~f == 0xfe)
 assert(f << 1 == 2)
 assert(f << 8 == 0)
@@ -53,20 +54,20 @@ assert(f ^ f == 0)
 assert(f ^ 0 == f)
 assert(0 ^ f == f)
 assert(1 ^ f == 0)
-assert(c / g == -1)
-assert(c / -3 == -1)
+assert(c // g == -1)
+assert(c // -3 == -1)
 assert(c % g == 1)
 assert(c % -3 == 1)
 
-print e + c, c + e, c - e, e - c
-print 1000 * a
-print hex(a)
+print(e + c, c + e, c - e, e - c)
+print(1000 * a)
+print(hex(a))
 
 define_int(128)
 define_uint(128)
 h = uint128(0x11223344556677889900AABBCCDDEEFF)
 i = int128(-0x9900AABBCCDDEEFF1122334455667788)
 
-assert(i / h == 6)
+assert(i //h == 6)
 assert(i % h == 0x3221aa32bb43cd58d9cc54dd65ee7e)
 
diff --git a/test/expression/parser.py b/test/expression/parser.py
index ccae49b0..d05f8262 100644
--- a/test/expression/parser.py
+++ b/test/expression/parser.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 from miasm2.expression.parser import str_to_expr
 from miasm2.expression.expression import ExprInt, ExprId, ExprSlice, ExprMem, \
     ExprCond, ExprCompose, ExprOp, ExprAssign, ExprLoc, LocKey
@@ -13,5 +14,5 @@ for expr_test in [ExprInt(0x12, 32),
                   ExprAssign(ExprId('EAX', 32),  ExprInt(0x12, 32)),
                   ]:
 
-    print 'Test: %s' % expr_test
+    print('Test: %s' % expr_test)
     assert str_to_expr(repr(expr_test)) == expr_test
diff --git a/test/expression/simplifications.py b/test/expression/simplifications.py
index cc33fc54..ae9eb1c0 100644
--- a/test/expression/simplifications.py
+++ b/test/expression/simplifications.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 #
 # Expression simplification regression tests  #
 #
@@ -28,18 +29,18 @@ if args.z3:
 
     def check(expr_in, expr_out):
         """Check that expr_in is always equals to expr_out"""
-        print "Ensure %s = %s" % (expr_in, expr_out)
+        print("Ensure %s = %s" % (expr_in, expr_out))
         solver = z3.Solver()
         solver.add(trans.from_expr(expr_in) != trans.from_expr(expr_out))
 
         result = solver.check()
 
         if result != z3.unsat:
-            print "ERROR: a counter-example has been founded:"
+            print("ERROR: a counter-example has been founded:")
             model = solver.model()
-            print model
+            print(model)
 
-            print "Reinjecting in the simplifier:"
+            print("Reinjecting in the simplifier:")
             to_rep = {}
             expressions = expr_in.get_r().union(expr_out.get_r())
             for expr in expressions:
@@ -54,10 +55,10 @@ if args.z3:
             new_expr_in = expr_in.replace_expr(to_rep)
             new_expr_out = expr_out.replace_expr(to_rep)
 
-            print "Check %s = %s" % (new_expr_in, new_expr_out)
+            print("Check %s = %s" % (new_expr_in, new_expr_out))
             simp_in = expr_simp_explicit(new_expr_in)
             simp_out =  expr_simp_explicit(new_expr_out)
-            print "[%s] %s = %s" % (simp_in == simp_out, simp_in, simp_out)
+            print("[%s] %s = %s" % (simp_in == simp_out, simp_in, simp_out))
 
             # Either the simplification does not stand, either the test is wrong
             raise RuntimeError("Bad simplification")
@@ -313,7 +314,7 @@ to_test = [(ExprInt(1, 32) - ExprInt(1, 32), ExprInt(0, 32)),
      (ExprCompose(a, ExprInt(0, 32)) * ExprInt(0x123, 64))[32:64]),
 
     (ExprInt(0x12, 32),
-     ExprInt(0x12L, 32)),
+     ExprInt(0x12, 32)),
 
 
     (ExprCompose(a, b, c)[:16],
@@ -335,32 +336,32 @@ to_test = [(ExprInt(1, 32) - ExprInt(1, 32), ExprInt(0, 32)),
     (ExprCompose(a, b, c)[48:80],
      ExprCompose(b[16:], c[:16])),
 
-    (ExprCompose(a[0:8], b[8:16], ExprInt(0x0L, 48))[12:32],
+    (ExprCompose(a[0:8], b[8:16], ExprInt(0x0, 48))[12:32],
      ExprCompose(b[12:16], ExprInt(0, 16))
        ),
 
-    (ExprCompose(ExprCompose(a[:8], ExprInt(0x0L, 56))[8:32]
+    (ExprCompose(ExprCompose(a[:8], ExprInt(0x0, 56))[8:32]
                   &
-                  ExprInt(0x1L, 24),
-                  ExprInt(0x0L, 40)),
+                  ExprInt(0x1, 24),
+                  ExprInt(0x0, 40)),
      ExprInt(0, 64)),
 
-    (ExprCompose(ExprCompose(a[:8], ExprInt(0x0L, 56))[:8]
+    (ExprCompose(ExprCompose(a[:8], ExprInt(0x0, 56))[:8]
                  &
-                 ExprInt(0x1L, 8),
-                 (ExprInt(0x0L, 56))),
+                 ExprInt(0x1, 8),
+                 (ExprInt(0x0, 56))),
      ExprCompose(a[:8]&ExprInt(1, 8), ExprInt(0, 56))),
 
     (ExprCompose(ExprCompose(a[:8],
-                             ExprInt(0x0L, 56))[:32]
+                             ExprInt(0x0, 56))[:32]
                  &
-                 ExprInt(0x1L, 32),
-                 ExprInt(0x0L, 32)),
+                 ExprInt(0x1, 32),
+                 ExprInt(0x0, 32)),
      ExprCompose(ExprCompose(ExprSlice(a, 0, 8),
-                             ExprInt(0x0L, 24))
+                             ExprInt(0x0, 24))
                  &
-                 ExprInt(0x1L, 32),
-                 ExprInt(0x0L, 32))
+                 ExprInt(0x1, 32),
+                 ExprInt(0x0, 32))
        ),
     (ExprCompose(a[:16], b[:16])[8:32],
      ExprCompose(a[8:16], b[:16])),
@@ -472,9 +473,9 @@ to_test = [(ExprInt(1, 32) - ExprInt(1, 32), ExprInt(0, 32)),
 ]
 
 for e_input, e_check in to_test:
-    print "#" * 80
+    print("#" * 80)
     e_new = expr_simp_explicit(e_input)
-    print "original: ", str(e_input), "new: ", str(e_new)
+    print("original: ", str(e_input), "new: ", str(e_new))
     rez = e_new == e_check
     if not rez:
         raise ValueError(
@@ -741,10 +742,10 @@ to_test = [
 ]
 
 for e_input, e_check in to_test:
-    print "#" * 80
+    print("#" * 80)
     e_check = expr_simp(e_check)
     e_new = expr_simp(e_input)
-    print "original: ", str(e_input), "new: ", str(e_new)
+    print("original: ", str(e_input), "new: ", str(e_new))
     rez = e_new == e_check
     if not rez:
         raise ValueError(
@@ -780,10 +781,10 @@ expr_simp.enable_passes(ExpressionSimplifier.PASS_COND)
 
 
 for e_input, e_check in to_test:
-    print "#" * 80
+    print("#" * 80)
     e_check = expr_simp(e_check)
     e_new = expr_simp(e_input)
-    print "original: ", str(e_input), "new: ", str(e_new)
+    print("original: ", str(e_input), "new: ", str(e_new))
     rez = e_new == e_check
     if not rez:
         raise ValueError(
@@ -902,6 +903,6 @@ for x, y in to_test:
 
     assert(x == y)
     assert(str(x) == str(y))
-    print x
+    print(x)
 
-print 'all tests ok'
+print('all tests ok')
diff --git a/test/expression/stp.py b/test/expression/stp.py
index 38bbf9c8..7650bf45 100755
--- a/test/expression/stp.py
+++ b/test/expression/stp.py
@@ -1,6 +1,7 @@
 #! /usr/bin/env python2
 #-*- coding:utf-8 -*-
 
+from builtins import range
 import unittest
 
 
@@ -11,7 +12,7 @@ class TestIrIr2STP(unittest.TestCase):
         from miasm2.ir.translators.translator  import Translator
         translator_smt2 = Translator.to_language("smt2")
 
-        args = [ExprInt(i, 32) for i in xrange(9)]
+        args = [ExprInt(i, 32) for i in range(9)]
 
         self.assertEqual(
             translator_smt2.from_expr(ExprOp('|',  *args[:2])), r'(bvor (_ bv0 32) (_ bv1 32))')
@@ -26,7 +27,7 @@ class TestIrIr2STP(unittest.TestCase):
         from miasm2.ir.translators.translator  import Translator
         translator_smt2 = Translator.to_language("smt2")
 
-        args = [ExprInt(i, 32) for i in xrange(9)]
+        args = [ExprInt(i, 32) for i in range(9)]
 
         self.assertEqual(
             translator_smt2.from_expr(args[0][1:2]), r'((_ extract 1 1) (_ bv0 32))')
diff --git a/test/ir/ir.py b/test/ir/ir.py
index 072c90f6..3dd95c3e 100644
--- a/test/ir/ir.py
+++ b/test/ir/ir.py
@@ -1,3 +1,5 @@
+from future.utils import viewitems
+
 from miasm2.expression.expression import *
 from miasm2.ir.ir import AssignBlock
 from miasm2.expression.simplifications import expr_simp
@@ -34,10 +36,11 @@ else:
 assert assignblk1.get_r() == set([id_b])
 assert assignblk1.get_w() == set([id_a])
 assert assignblk1.get_rw() == {id_a: set([id_b])}
-assert assignblk1.keys() == [id_a]
+assert list(assignblk1) == [id_a]
 assert dict(assignblk1) == {id_a: id_b}
 assert assignblk1[id_a] == id_b
-assert list(assignblk1.iteritems()) == assignblk1.items()
+assert list(viewitems(assignblk1)) == list(viewitems(assignblk1))
+assert set(assignblk1.iteritems()) == set(assignblk1.items())
 
 ## Simplify
 assignblk3 = AssignBlock({id_a: id_b - id_b})
diff --git a/test/ir/ir2C.py b/test/ir/ir2C.py
index 6df439c2..26683468 100755
--- a/test/ir/ir2C.py
+++ b/test/ir/ir2C.py
@@ -1,6 +1,7 @@
 #! /usr/bin/env python2
 #-*- coding:utf-8 -*-
 
+from builtins import range
 import unittest
 from miasm2.expression.expression import TOK_EQUAL
 
@@ -16,7 +17,7 @@ class TestIrIr2C(unittest.TestCase):
         from miasm2.expression.expression import ExprInt, ExprOp
         from miasm2.ir.translators.C import Translator
 
-        args = [ExprInt(i, 32) for i in xrange(9)]
+        args = [ExprInt(i, 32) for i in range(9)]
         translator = Translator.to_language("C")
 
         # Unary operators
diff --git a/test/ir/reduce_graph.py b/test/ir/reduce_graph.py
index 75ff3410..f6ebad24 100644
--- a/test/ir/reduce_graph.py
+++ b/test/ir/reduce_graph.py
@@ -1,6 +1,10 @@
 """Regression test module for DependencyGraph"""
+from __future__ import print_function
+from builtins import object
 from pdb import pm
 
+from future.utils import viewitems
+
 from miasm2.expression.expression import ExprId, ExprInt, ExprAssign, ExprCond, \
     ExprLoc, LocKey
 
@@ -162,7 +166,7 @@ for irb in [G1_RES_IRB0]:
 
 
 def cmp_ir_graph(g1, g2):
-    assert g1.blocks.items() == g2.blocks.items()
+    assert list(viewitems(g1.blocks)) == list(viewitems(g2.blocks))
     assert set(g1.edges()) == set(g2.edges())
 
 
@@ -664,11 +668,11 @@ for i, (g_test, g_ref) in enumerate(
         ], 1):
 
     heads = g_test.heads()
-    print '*'*10, 'Test', i, "*"*10
+    print('*'*10, 'Test', i, "*"*10)
     open('test_in_%d.dot' % i, 'w').write(g_test.dot())
     open('test_ref_%d.dot' % i, 'w').write(g_ref.dot())
     merge_blocks(g_test, heads)
     open('test_out_%d.dot' % i, 'w').write(g_test.dot())
 
     cmp_ir_graph(g_test, g_ref)
-    print '\t', 'OK'
+    print('\t', 'OK')
diff --git a/test/ir/symbexec.py b/test/ir/symbexec.py
index 4f01ac3c..3ab99c91 100755
--- a/test/ir/symbexec.py
+++ b/test/ir/symbexec.py
@@ -1,6 +1,10 @@
 #! /usr/bin/env python2
 #-*- coding:utf-8 -*-
 
+from __future__ import print_function
+
+from future.utils import viewitems
+
 import unittest
 
 
@@ -184,18 +188,18 @@ class TestSymbExec(unittest.TestCase):
         del sb.symbols[id_a]
         sb.dump()
         del sb.symbols[ExprMem(id_a, 8)]
-        print "*"*40, 'Orig:'
+        print("*"*40, 'Orig:')
         sb.dump()
 
         sb_cp = sb.symbols.copy()
-        print "*"*40, 'Copy:'
+        print("*"*40, 'Copy:')
         sb_cp.dump()
 
         # Add symbol at address limit
         sb.apply_change(ExprMem(ExprInt(0xFFFFFFFE, 32), 32), id_c)
         sb.dump()
         found = False
-        for dst, src in sb.symbols.iteritems():
+        for dst, src in viewitems(sb.symbols):
             if dst == ExprMem(ExprInt(0xFFFFFFFE, 32), 32) and src == id_c:
                 found = True
         assert found
@@ -205,7 +209,7 @@ class TestSymbExec(unittest.TestCase):
         sb.apply_change(ExprMem(ExprInt(0x7FFFFFFE, 32), 32), id_c)
         sb.dump()
         found = False
-        for dst, src in sb.symbols.iteritems():
+        for dst, src in viewitems(sb.symbols):
             if dst == ExprMem(ExprInt(0x7FFFFFFE, 32), 32) and src == id_c:
                 found = True
         assert found
@@ -219,7 +223,7 @@ class TestSymbExec(unittest.TestCase):
         sb.apply_change(ExprMem(ExprInt(0x2, 32), 16), ExprMem(ExprInt(0x2, 32), 16))
         sb.dump()
         found = False
-        for dst, src in sb.symbols.iteritems():
+        for dst, src in viewitems(sb.symbols):
             if dst == ExprMem(ExprInt(0xFFFFFFFE, 32), 32) and src == id_e[16:48]:
                 found = True
         assert found
@@ -230,7 +234,7 @@ class TestSymbExec(unittest.TestCase):
 
 
         # Test memory full
-        print 'full'
+        print('full')
         arch_addr8 = ir_x86_32(loc_db)
         ircfg = arch_addr8.new_ircfg()
         # Hack to obtain tiny address space
@@ -240,18 +244,18 @@ class TestSymbExec(unittest.TestCase):
         # Fulfill memory
         sb_addr8.apply_change(ExprMem(ExprInt(0, 5), 256), ExprInt(0, 256))
         sb_addr8.dump()
-        variables = sb_addr8.symbols.items()
+        variables = list(viewitems(sb_addr8.symbols))
         assert variables == [(ExprMem(ExprInt(0, 5), 256), ExprInt(0, 256))]
 
-        print sb_addr8.symbols.symbols_mem
+        print(sb_addr8.symbols.symbols_mem)
 
         sb_addr8.apply_change(ExprMem(ExprInt(0x5, 5), 256), ExprInt(0x123, 256))
         sb_addr8.dump()
-        variables = sb_addr8.symbols.items()
+        variables = list(viewitems(sb_addr8.symbols))
         assert variables == [(ExprMem(ExprInt(0x5, 5), 256), ExprInt(0x123, 256))]
-        print sb_addr8.symbols.symbols_mem
+        print(sb_addr8.symbols.symbols_mem)
 
-        print 'dump'
+        print('dump')
         sb_addr8.symbols.symbols_mem.dump()
 
 
@@ -281,7 +285,7 @@ class TestSymbExec(unittest.TestCase):
         assert sb.symbols.symbols_mem.contains_partial(ExprMem(ExprInt(0xFFFFFFFE, 32), 32))
         assert not sb.symbols.symbols_mem.contains_partial(ExprMem(ExprInt(0xFFFFFFFF, 32), 8))
 
-        assert sb_addr8.symbols.keys() == [ExprMem(ExprInt(0x5, 5), 256)]
+        assert list(sb_addr8.symbols) == [ExprMem(ExprInt(0x5, 5), 256)]
 
 
 if __name__ == '__main__':
diff --git a/test/ir/translators/smt2.py b/test/ir/translators/smt2.py
index 2b5c8df3..78472d0a 100644
--- a/test/ir/translators/smt2.py
+++ b/test/ir/translators/smt2.py
@@ -10,14 +10,26 @@ c = ExprId('c', 16)
 d = ExprId('d', 8)
 e = ExprId('e', 1)
 
-left = ExprCond(e + ExprOp('parity', a),
-                ExprMem(a * a, 64),
-                ExprMem(a, 64))
-
-cond = ExprSlice(ExprSlice(ExprSlice(a, 0, 32) + b, 0, 16) * c, 0, 8) << ExprOp('>>>', d, ExprInt(0x5L, 8))
-right = ExprCond(cond,
-                 a + ExprInt(0x64L, 64),
-                 ExprInt(0x16L, 64))
+left = ExprCond(
+    e + ExprOp('parity', a),
+    ExprMem(a * a, 64),
+    ExprMem(a, 64)
+)
+
+cond = (
+    ExprSlice(
+        ExprSlice(
+            ExprSlice(a, 0, 32) + b, 0, 16
+        ) * c,
+        0,
+        8
+    ) << ExprOp('>>>', d, ExprInt(0x5, 8))
+)
+right = ExprCond(
+    cond,
+    a + ExprInt(0x64, 64),
+    ExprInt(0x16, 64)
+)
 
 e = ExprAssign(left, right)
 
@@ -32,6 +44,7 @@ smt2 = t_smt2.to_smt2([t_smt2.from_expr(e)])
 
 # parse smt2 string with z3
 smt2_z3 = parse_smt2_string(smt2)
+
 # initialise SMT solver
 s = Solver()
 
diff --git a/test/ir/translators/z3_ir.py b/test/ir/translators/z3_ir.py
index 4806ad96..68421bea 100644
--- a/test/ir/translators/z3_ir.py
+++ b/test/ir/translators/z3_ir.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 import z3
 
 from miasm2.core.locationdb import LocationDB
@@ -174,5 +175,5 @@ cnttrailzeros3 = translator1.from_expr(ExprOp("cnttrailzeros", ExprInt(0x8000, 3
 cntleadzeros3 = translator1.from_expr(ExprOp("cntleadzeros", ExprInt(0x8000, 32)))
 assert(equiv(cnttrailzeros3, cntleadzeros3))
 
-print "TranslatorZ3 tests are OK."
+print("TranslatorZ3 tests are OK.")
 
diff --git a/test/jitter/bad_block.py b/test/jitter/bad_block.py
index ae11e696..0756dfd5 100644
--- a/test/jitter/bad_block.py
+++ b/test/jitter/bad_block.py
@@ -1,4 +1,5 @@
 import sys
+from miasm2.core.utils import decode_hex
 from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE, EXCEPT_UNK_MNEMO
 from miasm2.analysis.machine import Machine
 
@@ -15,7 +16,7 @@ jitter.init_stack()
 # nop
 # mov eax, 0x42
 # XX
-data = "90b842000000ffff90909090".decode('hex')
+data = decode_hex("90b842000000ffff90909090")
 
 # Will raise memory error at 0x40000006
 
diff --git a/test/jitter/jit_options.py b/test/jitter/jit_options.py
index a0ddbc11..91d59edd 100644
--- a/test/jitter/jit_options.py
+++ b/test/jitter/jit_options.py
@@ -1,5 +1,8 @@
+from __future__ import print_function
 import os
 import sys
+
+from miasm2.core.utils import decode_hex
 from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE
 from miasm2.analysis.machine import Machine
 from pdb import pm
@@ -16,7 +19,7 @@ from pdb import pm
 #       RET
 
 
-data = "b810000000bb0100000083e8010f44cb75f8c3".decode("hex")
+data = decode_hex("b810000000bb0100000083e8010f44cb75f8c3")
 run_addr = 0x40000000
 
 def code_sentinelle(jitter):
@@ -40,7 +43,7 @@ def init_jitter():
     return myjit
 
 # Test 'max_exec_per_call'
-print "[+] First run, to jit blocks"
+print("[+] First run, to jit blocks")
 myjit = init_jitter()
 myjit.init_run(run_addr)
 myjit.continue_run()
@@ -62,7 +65,7 @@ def cb(jitter):
     return False
 
 ## Second run
-print "[+] Second run"
+print("[+] Second run")
 myjit.push_uint32_t(0x1337beef)
 myjit.cpu.EAX = 0
 myjit.init_run(run_addr)
@@ -74,7 +77,7 @@ assert myjit.run is True
 assert myjit.cpu.EAX >= 0xA
 
 # Test 'jit_maxline'
-print "[+] Run instr one by one"
+print("[+] Run instr one by one")
 myjit = init_jitter()
 myjit.jit.options["jit_maxline"] = 1
 myjit.jit.options["max_exec_per_call"] = 1
diff --git a/test/jitter/jitload.py b/test/jitter/jitload.py
index 1a56099f..5473b7d2 100644
--- a/test/jitter/jitload.py
+++ b/test/jitter/jitload.py
@@ -1,12 +1,13 @@
 import sys
 from pdb import pm
 
+from miasm2.core.utils import decode_hex, encode_hex
 from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE
 from miasm2.analysis.machine import Machine
 from miasm2.expression.expression import ExprId, ExprAssign, ExprInt, ExprMem
 
 # Initial data: from 'example/samples/x86_32_sc.bin'
-data = "8d49048d5b0180f90174058d5bffeb038d5b0189d8c3".decode("hex")
+data = decode_hex("8d49048d5b0180f90174058d5bffeb038d5b0189d8c3")
 
 # Init jitter
 myjit = Machine("x86_32").jitter(sys.argv[1])
@@ -46,4 +47,4 @@ assert myjit.eval_expr(eax) == imm4
 ## Changes must be passed on myjit.cpu instance
 assert myjit.cpu.EAX == 4
 ## Memory
-assert myjit.eval_expr(memdata).arg.arg == int(data[::-1].encode("hex"), 16)
+assert myjit.eval_expr(memdata).arg.arg == int(encode_hex(data[::-1]), 16)
diff --git a/test/jitter/jmp_out_mem.py b/test/jitter/jmp_out_mem.py
index 93ae8304..ff137b84 100644
--- a/test/jitter/jmp_out_mem.py
+++ b/test/jitter/jmp_out_mem.py
@@ -1,4 +1,5 @@
 import sys
+from miasm2.core.utils import decode_hex
 from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE, EXCEPT_ACCESS_VIOL
 from miasm2.analysis.machine import Machine
 
@@ -17,7 +18,7 @@ jitter.init_stack()
 # mov eax, 0x42
 # jmp 0x20
 
-data = "90b842000000eb20".decode('hex')
+data = decode_hex("90b842000000eb20")
 
 # Will raise memory error at 0x40000028
 
diff --git a/test/jitter/test_post_instr.py b/test/jitter/test_post_instr.py
index 0aff667e..ab8f8a74 100644
--- a/test/jitter/test_post_instr.py
+++ b/test/jitter/test_post_instr.py
@@ -1,27 +1,31 @@
+from __future__ import print_function
 import sys
+
+from miasm2.core.utils import decode_hex
 from miasm2.analysis.machine import Machine
-from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE, EXCEPT_BREAKPOINT_MEMORY, EXCEPT_ACCESS_VIOL
+from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE, \
+    EXCEPT_BREAKPOINT_MEMORY, EXCEPT_ACCESS_VIOL
 
 machine = Machine("x86_32")
 jitter = machine.jitter(sys.argv[1])
 
 # Prepare stack and reset memory accesses to avoid an exception
-jitter.vm.add_memory_page(0x10000, PAGE_READ|PAGE_WRITE, "\x00"*0x1000, "stack")
-print jitter.vm
+jitter.vm.add_memory_page(0x10000, PAGE_READ|PAGE_WRITE, b"\x00"*0x1000, "stack")
+print(jitter.vm)
 
 jitter.cpu.ESP = 0x10000 + 0x1000
 jitter.push_uint32_t(0x0)
 jitter.push_uint32_t(0x1337beef)
 
 jitter.vm.reset_memory_access()
-print hex(jitter.vm.get_exception())
+print(hex(jitter.vm.get_exception()))
 
 # Add code, and keep memory write pending
-jitter.vm.add_memory_page(0x1000, PAGE_READ|PAGE_WRITE, "\x00"*0x1000, "code page")
+jitter.vm.add_memory_page(0x1000, PAGE_READ|PAGE_WRITE, b"\x00"*0x1000, "code page")
 
 # MOV EAX, 0x11223344
 # RET
-jitter.vm.set_mem(0x1000, "B844332211C3".decode('hex'))
+jitter.vm.set_mem(0x1000, decode_hex("B844332211C3"))
 
 
 jitter.set_trace_log()
diff --git a/test/jitter/vm_mngr.py b/test/jitter/vm_mngr.py
index 87bc6f8f..3aa4105e 100644
--- a/test/jitter/vm_mngr.py
+++ b/test/jitter/vm_mngr.py
@@ -6,7 +6,7 @@ myjit = Machine("x86_32").jitter(sys.argv[1])
 
 base_addr = 0x13371337
 page_size = 0x1000
-data = "\x00" * page_size
+data = b"\x00" * page_size
 rights = [0, PAGE_READ, PAGE_WRITE, PAGE_READ|PAGE_WRITE]
 shuffled_rights = [PAGE_READ, 0, PAGE_READ|PAGE_WRITE, PAGE_WRITE]
 
diff --git a/test/os_dep/common.py b/test/os_dep/common.py
index 5d525e32..52512075 100755
--- a/test/os_dep/common.py
+++ b/test/os_dep/common.py
@@ -1,6 +1,7 @@
 #! /usr/bin/env python2
 #-*- coding:utf-8 -*-
 
+from builtins import range
 import unittest
 import logging
 from miasm2.analysis.machine import Machine
@@ -25,7 +26,7 @@ class TestCommonAPI(unittest.TestCase):
         heap.alloc(jit, 60)
         ptr = heap.alloc(jit, 10)
         heap.alloc(jit, 80)
-        for i in xrange(10):
+        for i in range(10):
             self.assertEqual(heap.get_size(jit.vm, ptr+i), 10)
 
 if __name__ == '__main__':
diff --git a/test/os_dep/linux/stdlib.py b/test/os_dep/linux/stdlib.py
index ab39a487..80b99969 100755
--- a/test/os_dep/linux/stdlib.py
+++ b/test/os_dep/linux/stdlib.py
@@ -19,12 +19,12 @@ class TestLinuxStdlib(unittest.TestCase):
 
     def test_xxx_sprintf(self):
         def alloc_str(s):
-            s += "\x00"
+            s += b"\x00"
             ptr = heap.alloc(jit, len(s))
             jit.vm.set_mem(ptr, s)
             return ptr
-        fmt  = alloc_str("'%s' %d")
-        str_ = alloc_str("coucou")
+        fmt  = alloc_str(b"'%s' %d")
+        str_ = alloc_str(b"coucou")
         buf = heap.alloc(jit,1024)
 
         jit.push_uint32_t(1111)
@@ -34,7 +34,7 @@ class TestLinuxStdlib(unittest.TestCase):
         jit.push_uint32_t(0) # ret_ad
         stdlib.xxx_sprintf(jit)
         ret = jit.get_str_ansi(buf)
-        self.assertEqual(ret, "'coucou' 1111")
+        self.assertEqual(ret, b"'coucou' 1111")
 
 
 if __name__ == '__main__':
diff --git a/test/os_dep/linux/test_env.py b/test/os_dep/linux/test_env.py
index 0c80571f..1e8e7678 100644
--- a/test/os_dep/linux/test_env.py
+++ b/test/os_dep/linux/test_env.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 import os
 import sys
 from pdb import pm
@@ -6,7 +7,7 @@ from miasm2.analysis.sandbox import Sandbox_Linux_x86_32, Sandbox_Linux_x86_64,\
     Sandbox_Linux_arml, Sandbox_Linux_aarch64l
 
 if len(sys.argv) < 2:
-    print "Usage: %s <arch> ..." % sys.argv[0]
+    print("Usage: %s <arch> ..." % sys.argv[0])
     exit(0)
 
 arch = sys.argv[1]
diff --git a/test/os_dep/win_api_x86_32.py b/test/os_dep/win_api_x86_32.py
index f080ba89..2dcac61d 100755
--- a/test/os_dep/win_api_x86_32.py
+++ b/test/os_dep/win_api_x86_32.py
@@ -1,6 +1,7 @@
 #! /usr/bin/env python2
 #-*- coding:utf-8 -*-
 
+from builtins import range
 import unittest
 import logging
 from miasm2.analysis.machine import Machine
@@ -27,12 +28,12 @@ class TestWinAPI(unittest.TestCase):
 
     def test_msvcrt_sprintf(self):
         def alloc_str(s):
-            s += "\x00"
+            s += b"\x00"
             ptr = heap.alloc(jit, len(s))
             jit.vm.set_mem(ptr, s)
             return ptr
-        fmt  = alloc_str("'%s' %d")
-        str_ = alloc_str("coucou")
+        fmt  = alloc_str(b"'%s' %d")
+        str_ = alloc_str(b"coucou")
         buf = heap.alloc(jit,1024)
 
         jit.push_uint32_t(1111)
@@ -42,13 +43,13 @@ class TestWinAPI(unittest.TestCase):
         jit.push_uint32_t(0) # ret_ad
         winapi.msvcrt_sprintf(jit)
         ret = jit.get_str_ansi(buf)
-        self.assertEqual(ret, "'coucou' 1111")
+        self.assertEqual(ret, b"'coucou' 1111")
 
 
     def test_msvcrt_swprintf(self):
         def alloc_str(s):
             s = s.encode("utf-16le")
-            s += "\x00\x00"
+            s += b"\x00\x00"
             ptr = heap.alloc(jit, len(s))
             jit.vm.set_mem(ptr, s)
             return ptr
@@ -63,7 +64,7 @@ class TestWinAPI(unittest.TestCase):
         jit.push_uint32_t(0) # ret_ad
         winapi.msvcrt_swprintf(jit)
         ret = jit.get_str_unic(buf)
-        self.assertEqual(ret, "'coucou' 1111")
+        self.assertEqual(ret, u"'coucou' 1111")
 
 
     def test_msvcrt_realloc(self):
@@ -88,7 +89,7 @@ class TestWinAPI(unittest.TestCase):
         # Test with a buffer long enough
         addr = 0x80000
         size = len(winapi.winobjs.cur_dir)+1
-        jit.vm.add_memory_page(addr, PAGE_READ | PAGE_WRITE, "\x00" * (size), "")
+        jit.vm.add_memory_page(addr, PAGE_READ | PAGE_WRITE, b"\x00" * (size), "")
         jit.push_uint32_t(addr)   # buf
         jit.push_uint32_t(size)   # size
         jit.push_uint32_t(0)      # @return
@@ -98,7 +99,7 @@ class TestWinAPI(unittest.TestCase):
         self.assertEqual(len(dir_), size_ret)
 
         # Test with a buffer too small
-        jit.vm.set_mem(addr, "\xFF"*size)
+        jit.vm.set_mem(addr, b"\xFF"*size)
         jit.push_uint32_t(addr)   # buf
         jit.push_uint32_t(5)      # size
         jit.push_uint32_t(0)      # @return
@@ -215,7 +216,7 @@ class TestWinAPI(unittest.TestCase):
         self.assertTrue(vBool)
 
         # BOOL WINAPI Process32Next(_In_ HANDLE hSnapshot, _Out_ LPPROCESSENTRY32 lppe);
-        for i in xrange(3, -1, -1):
+        for i in range(3, -1, -1):
             jit.push_uint32_t(jit.stack_base)      # lppe
             jit.push_uint32_t(hSnap)               # hSnapshot
             jit.push_uint32_t(0)                   # @return
diff --git a/test/test_all.py b/test/test_all.py
index 008d837f..a8a0d599 100755
--- a/test/test_all.py
+++ b/test/test_all.py
@@ -1,5 +1,8 @@
 #! /usr/bin/env python2
 
+from __future__ import print_function
+from builtins import map
+from builtins import range
 import argparse
 from distutils.spawn import find_executable
 import os
@@ -52,6 +55,12 @@ testset += RegressionTest(["x86/arch.py"], base_dir="arch",
                                     "regression_test32_ia32.bin",
                                     "regression_test64_ia32.bin"])
 
+testset += RegressionTest(["arm/arch.py"], base_dir="arch")
+testset += RegressionTest(["aarch64/arch.py"], base_dir="arch")
+testset += RegressionTest(["sh4/arch.py"], base_dir="arch")
+testset += RegressionTest(["msp430/arch.py"], base_dir="arch")
+testset += RegressionTest(["mips32/arch.py"], base_dir="arch")
+
 
 
 ### ArchUnit regression tests
@@ -92,14 +101,9 @@ for script in ["x86/sem.py",
                "x86/unit/mn_getset128.py",
                "x86/unit/mn_cmov.py",
                "x86/unit/mn_rotsh.py",
-               "arm/arch.py",
                "arm/sem.py",
                "aarch64/unit/mn_ubfm.py",
-               "aarch64/arch.py",
-               "msp430/arch.py",
                "msp430/sem.py",
-               "sh4/arch.py",
-               "mips32/arch.py",
                "mips32/unit/mn_bcc.py",
                ]:
     for jitter in ArchUnitTest.jitter_engines:
@@ -359,7 +363,7 @@ testset += RegressionTest(["depgraph.py"], base_dir="analysis",
                           products=[fname for fnames in (
                               ["graph_test_%02d_00.dot" % test_nb,
                                "graph_%02d.dot" % test_nb]
-                              for test_nb in xrange(1, 18))
+                              for test_nb in range(1, 18))
                                     for fname in fnames] +
                           ["graph_test_%02d_%02d.dot" % (test_nb, res_nb)
                            for (test_nb, res_nb) in ((3, 1), (5, 1), (8, 1),
@@ -382,11 +386,11 @@ testset += RegressionTest(["range.py"], base_dir="analysis",
 testset += RegressionTest(["data_flow.py"], base_dir="analysis",
                           products=[fname for fnames in (
             ["simp_graph_%02d.dot" % test_nb, "graph_%02d.dot" % test_nb]
-            for test_nb in xrange(1, 18))
+            for test_nb in range(1, 18))
                                     for fname in fnames])
 testset += RegressionTest(["unssa.py"], base_dir="analysis")
 
-for i in xrange(1, 21):
+for i in range(1, 21):
     input_name = "cst_propag/x86_32_sc_%d" % i
     bin_name = "samples/x86_32/%s.bin" % input_name
     test_x86_32_cst = SemanticTestAsm("x86_32", None, [input_name])
@@ -410,7 +414,7 @@ class TestDepgraph(RegressionTest):
         super(TestDepgraph, self).__init__([self.launcher],
                                            *args, **kwargs)
         self.base_dir = os.path.join(self.base_dir, "analysis")
-        self.products = ["sol_%d.dot" % i for i in xrange(nb_sol)]
+        self.products = ["sol_%d.dot" % i for i in range(nb_sol)]
         if implicit:
             expected_fname = "dg_test_%.2d_implicit_expected.json"
             self.tags.append(TAGS["z3"])
@@ -507,7 +511,7 @@ class ExampleShellcode(ExampleAssembler):
         super(ExampleShellcode, self).__init__(*args, **kwargs)
         self.command_line = ["shellcode.py",
                              self.command_line[0]] + \
-                             map(Example.get_sample, self.command_line[1:3]) + \
+                             list(map(Example.get_sample, self.command_line[1:3])) + \
                              self.command_line[3:]
         self.products = [self.command_line[3], "graph.dot"]
 
@@ -709,7 +713,7 @@ for options, nb_sol, tag in [([], 8, []),
                                   "-m", "x86_32", "0x0", "0x8b",
                                   "EAX"] + options,
                                  products=["sol_%d.dot" % nb
-                                           for nb in xrange(nb_sol)],
+                                           for nb in range(nb_sol)],
                                  tags=tag)
 
 for options, nb_sol, tag in [([], 4, []),
@@ -719,7 +723,7 @@ for options, nb_sol, tag in [([], 4, []),
                                   "-m", "x86_32", "0x0", "0x19",
                                   "EAX"] + options,
                                  products=["sol_%d.dot" % nb
-                                           for nb in xrange(nb_sol)],
+                                           for nb in range(nb_sol)],
                                  depends=[test_x86_32_if_reg],
                                  tags=tag)
 
@@ -761,17 +765,6 @@ for jitter in ExampleJitter.jitter_engines:
                              ["--jitter", jitter],
                              products=[Example.get_sample("box_upx_exe_unupx.bin")],
                              tags=tags.get(jitter, []))
-    if jitter != "python":
-        tags = tags.get(jitter, []) + [TAGS["long"], TAGS["linux"]]
-        ls_path = find_executable("ls")
-        file_path = find_executable("file")
-        # Launch simulation of "file /bin/ls", with access to libs and ld info
-        testset += ExampleJitter(["run_with_linuxenv.py", "-v", "-p",
-                                  '/(.*lib.*\.so(\.\d+)?)|(/etc/ld.so.*)|(.*magic.*)|(%s)' % ls_path,
-                                  ] + ["--jitter", jitter] + [
-                                      file_path, ls_path,
-                                  ],
-                                 tags=tags)
 
 
 for script, dep in [(["x86_32.py", Example.get_sample("x86_32_sc.bin")], []),
@@ -826,10 +819,10 @@ if __name__ == "__main__":
                         action="store_true")
     parser.add_argument("-t", "--omit-tags", help="Omit tests based on tags \
 (tag1,tag2). Available tags are %s. \
-By default, no tag is omitted." % ", ".join(TAGS.keys()), default="")
+By default, no tag is omitted." % ", ".join(list(TAGS)), default="")
     parser.add_argument("-o", "--only-tags", help="Restrict to tests based on tags \
 (tag1,tag2). Available tags are %s. \
-By default, all tag are considered." % ", ".join(TAGS.keys()), default="")
+By default, all tag are considered." % ", ".join(list(TAGS)), default="")
     parser.add_argument("-n", "--do-not-clean",
                         help="Do not clean tests products", action="store_true")
     args = parser.parse_args()
@@ -848,14 +841,14 @@ By default, all tag are considered." % ", ".join(TAGS.keys()), default="")
             if not tag:
                 continue
             if tag not in TAGS:
-                print "%(red)s[TAG]%(end)s" % cosmetics.colors, \
-                    "Unknown tag '%s'" % tag
+                print("%(red)s[TAG]%(end)s" % cosmetics.colors, \
+                    "Unknown tag '%s'" % tag)
                 exit(-1)
             dest.append(TAGS[tag])
 
     if exclude_tags and include_tags:
-        print "%(red)s[TAG]%(end)s" % cosmetics.colors, \
-                "Omit and Only used together: whitelist mode"
+        print("%(red)s[TAG]%(end)s" % cosmetics.colors, \
+                "Omit and Only used together: whitelist mode")
 
     # Handle coverage
     coveragerc = None
@@ -863,8 +856,8 @@ By default, all tag are considered." % ", ".join(TAGS.keys()), default="")
         try:
             import coverage
         except ImportError:
-            print "%(red)s[Coverage]%(end)s " % cosmetics.colors + \
-                "Python 'coverage' module is required"
+            print("%(red)s[Coverage]%(end)s " % cosmetics.colors + \
+                "Python 'coverage' module is required")
             exit(-1)
 
         # Create directory
@@ -875,7 +868,7 @@ By default, all tag are considered." % ", ".join(TAGS.keys()), default="")
         coveragerc = os.path.join(cov_dir, ".coveragerc")
         coverage = os.path.join(cov_dir, ".coverage")
 
-        from ConfigParser import ConfigParser
+        from configparser import ConfigParser
         from os.path import expanduser
 
         config = ConfigParser()
@@ -894,7 +887,7 @@ By default, all tag are considered." % ", ".join(TAGS.keys()), default="")
         d = {"blue": cosmetics.colors['blue'],
              "end": cosmetics.colors['end'],
              "cov_dir": cov_dir}
-        print "[%(blue)sCoverage%(end)s] Report will be written in %(cov_dir)s" % d
+        print("[%(blue)sCoverage%(end)s] Report will be written in %(cov_dir)s" % d)
 
     # Handle llvm modularity
     llvm = True
@@ -904,8 +897,8 @@ By default, all tag are considered." % ", ".join(TAGS.keys()), default="")
         llvm = False
 
     if llvm is False:
-        print "%(red)s[LLVM]%(end)s Python" % cosmetics.colors + \
-            "'llvmlite' module is required for llvm tests"
+        print("%(red)s[LLVM]%(end)s Python" % cosmetics.colors + \
+            "'llvmlite' module is required for llvm tests")
 
         # Remove llvm tests
         if TAGS["llvm"] not in exclude_tags:
@@ -915,8 +908,8 @@ By default, all tag are considered." % ", ".join(TAGS.keys()), default="")
     try:
         import z3
     except ImportError:
-        print "%(red)s[Z3]%(end)s " % cosmetics.colors + \
-            "Z3 and its python binding are necessary for TranslatorZ3."
+        print("%(red)s[Z3]%(end)s " % cosmetics.colors + \
+            "Z3 and its python binding are necessary for TranslatorZ3.")
         if TAGS["z3"] not in exclude_tags:
             exclude_tags.append(TAGS["z3"])
 
@@ -924,8 +917,8 @@ By default, all tag are considered." % ", ".join(TAGS.keys()), default="")
     try:
         import pycparser
     except ImportError:
-        print "%(red)s[PYCPARSER]%(end)s " % cosmetics.colors + \
-            "pycparser are necessary for Objc."
+        print("%(red)s[PYCPARSER]%(end)s " % cosmetics.colors + \
+            "pycparser are necessary for Objc.")
         if TAGS["cparser"] not in exclude_tags:
             exclude_tags.append(TAGS["cparser"])
 
@@ -952,13 +945,13 @@ By default, all tag are considered." % ", ".join(TAGS.keys()), default="")
 
     # Finalize
     testset.end(clean=not args.do_not_clean)
-    print
+    print()
     print (cosmetics.colors["green"] +
            "Result: %d/%d pass" % (len(test_ok), len(test_ok) + len(test_ko)) +
            cosmetics.colors["end"])
     for test, error in test_ko:
         command_line = " ".join(test.command_line)
-        print cosmetics.colors["red"] + 'ERROR', cosmetics.colors["lightcyan"] + command_line + cosmetics.colors["end"]
-        print error
+        print(cosmetics.colors["red"] + 'ERROR', cosmetics.colors["lightcyan"] + command_line + cosmetics.colors["end"])
+        print(error)
     # Exit with an error if at least a test failed
     exit(testset.tests_passed())
diff --git a/test/utils/cosmetics.py b/test/utils/cosmetics.py
index e80e1f09..da7a6bc5 100644
--- a/test/utils/cosmetics.py
+++ b/test/utils/cosmetics.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 import os
 import platform
 
@@ -33,23 +34,27 @@ def getTerminalSize():
 
 
 WIDTH = getTerminalSize()[0]
-colors = {"red": "\033[91;1m",
-          "end": "\033[0m",
-          "green": "\033[92;1m",
-          "lightcyan": "\033[96m",
-          "blue": "\033[94;1m"}
+colors = {
+    "red": "\033[91;1m",
+    "end": "\033[0m",
+    "green": "\033[92;1m",
+    "lightcyan": "\033[96m",
+    "blue": "\033[94;1m"
+}
 
 if is_win:
-    colors = {"red": "",
-              "end": "",
-              "green": "",
-              "lightcyan": "",
-              "blue": ""}
+    colors = {
+        "red": "",
+        "end": "",
+        "green": "",
+        "lightcyan": "",
+        "blue": ""
+    }
 
 def write_colored(text, color, already_printed=0):
     text_colored = colors[color] + text + colors["end"]
-    print " " * (WIDTH - already_printed - len(text)) + text_colored
+    print(" " * (WIDTH - already_printed - len(text)) + text_colored)
 
 
 def write_underline(text):
-    print "\033[4m" + text + colors["end"]
+    print("\033[4m" + text + colors["end"])
diff --git a/test/utils/multithread.py b/test/utils/multithread.py
index 287b5ebd..d0874dd1 100644
--- a/test/utils/multithread.py
+++ b/test/utils/multithread.py
@@ -1,24 +1,25 @@
+from __future__ import print_function
 import sys
-import cosmetics
+from . import cosmetics
 import time
 
 
 def task_done(test, error, test_ok, test_ko):
     command_line = " ".join(test.command_line)
     if error is not None:
-        print cosmetics.colors["red"] + 'ERROR',
-        print cosmetics.colors["lightcyan"] + command_line + cosmetics.colors["end"]
-        print error
+        print(cosmetics.colors["red"] + 'ERROR', end=' ')
+        print(cosmetics.colors["lightcyan"] + command_line + cosmetics.colors["end"])
+        print(error)
         test_ko.append((test, error))
     else:
-        print cosmetics.colors["green"] + 'DONE',
-        print cosmetics.colors["lightcyan"] + command_line + cosmetics.colors["end"],
-        print "%ds" % (time.time() - test.start_time)
+        print(cosmetics.colors["green"] + 'DONE', end=' ')
+        print(cosmetics.colors["lightcyan"] + command_line + cosmetics.colors["end"], end=' ')
+        print("%ds" % (time.time() - test.start_time))
         test_ok.append((test, error))
 
 
 def task_new(test):
     command_line = " ".join(test.command_line)
-    print cosmetics.colors["lightcyan"],
-    print test.base_dir.upper(), command_line,
-    print cosmetics.colors["end"]
+    print(cosmetics.colors["lightcyan"], end=' ')
+    print(test.base_dir.upper(), command_line, end=' ')
+    print(cosmetics.colors["end"])
diff --git a/test/utils/testset.py b/test/utils/testset.py
index 7b60e836..eee0e6f7 100644
--- a/test/utils/testset.py
+++ b/test/utils/testset.py
@@ -1,10 +1,12 @@
+from __future__ import print_function
+from builtins import range
 import os
 import subprocess
 import sys
 import time
 from multiprocessing import cpu_count, Queue, Process
 
-from test import Test
+from .test import Test
 
 
 class Message(object):
@@ -136,7 +138,7 @@ class TestSet(object):
 
         if len(self.tests) == 0:
             # Poison pills
-            for _ in xrange(self.cpu_c):
+            for _ in range(self.cpu_c):
                 self.todo_queue.put(None)
 
         # All tasks done
@@ -201,7 +203,7 @@ class TestSet(object):
             try:
                 os.remove(product)
             except OSError:
-                print "Cleanning error: Unable to remove %s" % product
+                print("Cleanning error: Unable to remove %s" % product)
 
     def add_additional_args(self, args):
         """Add arguments to used on the test command line
@@ -218,7 +220,7 @@ class TestSet(object):
 
         # Launch workers
         processes = []
-        for _ in xrange(self.cpu_c):
+        for _ in range(self.cpu_c):
             p = Process(target=TestSet.worker, args=(self.todo_queue,
                                                      self.message_queue,
                                                      self.additional_args))