diff options
Diffstat (limited to 'miasm2/arch/mep/jit.py')
| -rw-r--r-- | miasm2/arch/mep/jit.py | 115 |
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 |