about summary refs log tree commit diff stats
path: root/miasm2/arch/mep/jit.py
diff options
context:
space:
mode:
authorGuillaume Valadon <guillaume@valadon.net>2018-06-15 12:10:10 +0200
committerGuillaume Valadon <guillaume@valadon.net>2018-07-12 22:50:51 +0200
commitb8e5038798b0dece628846acb5ad25d9d4e60395 (patch)
tree932dd2676afcf0c4ba6bf0c57d3b574954461ad2 /miasm2/arch/mep/jit.py
parent82eb5f6eb197fc59d2e9ae21cfda05a1868e462e (diff)
downloadmiasm-b8e5038798b0dece628846acb5ad25d9d4e60395.tar.gz
miasm-b8e5038798b0dece628846acb5ad25d9d4e60395.zip
Toshiba MeP support
Diffstat (limited to 'miasm2/arch/mep/jit.py')
-rw-r--r--miasm2/arch/mep/jit.py115
1 files changed, 115 insertions, 0 deletions
diff --git a/miasm2/arch/mep/jit.py b/miasm2/arch/mep/jit.py
new file mode 100644
index 00000000..33eb5c3c
--- /dev/null
+++ b/miasm2/arch/mep/jit.py
@@ -0,0 +1,115 @@
+# Toshiba MeP-c4 - miasm jitter
+# Guillaume Valadon <guillaume@valadon.net>
+# Note: inspiration from msp430/jit.py
+
+from miasm2.jitter.jitload import Jitter
+from miasm2.core.locationdb import LocationDB
+from miasm2.core.utils import *
+from miasm2.jitter.codegen import CGen
+from miasm2.ir.translators.C import TranslatorC
+from miasm2.arch.mep.sem import ir_mepl, ir_mepb
+
+import logging
+
+log = logging.getLogger("jit_mep")
+hnd = logging.StreamHandler()
+hnd.setFormatter(logging.Formatter("[%(levelname)s]: %(message)s"))
+log.addHandler(hnd)
+log.setLevel(logging.CRITICAL)
+
+
+class mep_CGen(CGen):
+    """
+    Translate a bloc containing MeP instructions to C
+
+    Note: it is used to emulate the *REPEAT instructions
+    """
+
+    def __init__(self, ir_arch):
+        self.ir_arch = ir_arch
+        self.PC = self.ir_arch.arch.regs.PC
+        self.translator = TranslatorC(self.ir_arch.loc_db)
+        self.init_arch_C()
+
+    def gen_pre_code(self, attrib):
+        """Generate C code inserted before the current bloc"""
+
+        # Call the base class method
+        out = super(mep_CGen, self).gen_pre_code(attrib)
+
+        # Set the PC register value explicitly
+        out.append("mycpu->PC = 0x%X;" % attrib.instr.offset)
+        out.append("mycpu->last_addr = mycpu->PC;");
+
+        return out
+
+    def gen_post_code(self, attrib):
+        """Generate C code inserted after the current bloc"""
+
+        # Call the base class method
+        out = super(mep_CGen, self).gen_post_code(attrib)
+
+        # Implement the *REPEAT instructions logics
+        tmp = r"""
+        /* *REPEAT instructions logic */
+        {
+            uint32_t is_repeat_end = mycpu->is_repeat_end;
+            mycpu->is_repeat_end = !!(mycpu->last_addr == (mycpu->RPE&~0x1));
+
+            if (is_repeat_end && !mycpu->take_jmp &&
+                   (mycpu->in_erepeat || mycpu->RPC)) {
+                 if (mycpu->RPC)
+                       mycpu->RPC --;
+
+                 //printf("Go repeat  %X\n", mycpu->RPB);
+                 DST_value = mycpu->RPB;
+                 BlockDst->address = mycpu->RPB;
+                 return JIT_RET_NO_EXCEPTION;
+             }
+        }
+        """
+
+        out += tmp.split('`\n')
+        return out
+
+
+class jitter_mepl(Jitter):
+
+    C_Gen = mep_CGen
+
+    def __init__(self, *args, **kwargs):
+        sp = LocationDB()
+        Jitter.__init__(self, ir_mepl(sp), *args, **kwargs)
+        self.vm.set_little_endian()
+        self.ir_arch.jit_pc = self.ir_arch.arch.regs.PC
+
+    def push_uint16_t(self, v):
+        regs = self.cpu.get_gpreg()
+        regs["SP"] -= 2
+        self.cpu.set_gpreg(regs)
+        self.vm.set_mem(regs["SP"], pck16(v))
+
+    def pop_uint16_t(self):
+        regs = self.cpu.get_gpreg()
+        x = upck16(self.vm.get_mem(regs["SP"], 2))
+        regs["SP"] += 2
+        self.cpu.set_gpreg(regs)
+        return x
+
+    def get_stack_arg(self, n):
+        regs = self.cpu.get_gpreg()
+        x = upck16(self.vm.get_mem(regs["SP"] + 2 * n, 2))
+        return x
+
+    def init_run(self, *args, **kwargs):
+        Jitter.init_run(self, *args, **kwargs)
+        self.cpu.PC = self.pc
+
+
+class jitter_mepb(jitter_mepl):
+
+    def __init__(self, *args, **kwargs):
+        sp = LocationDB()
+        Jitter.__init__(self, ir_mepb(sp), *args, **kwargs)
+        self.vm.set_big_endian()
+        self.ir_arch.jit_pc = self.ir_arch.arch.regs.PC