about summary refs log tree commit diff stats
path: root/miasm/arch/mep/sem.py
diff options
context:
space:
mode:
Diffstat (limited to 'miasm/arch/mep/sem.py')
-rw-r--r--miasm/arch/mep/sem.py1240
1 files changed, 0 insertions, 1240 deletions
diff --git a/miasm/arch/mep/sem.py b/miasm/arch/mep/sem.py
deleted file mode 100644
index 0ac50c58..00000000
--- a/miasm/arch/mep/sem.py
+++ /dev/null
@@ -1,1240 +0,0 @@
-# Toshiba MeP-c4 - miasm instructions side effects
-# Guillaume Valadon <guillaume@valadon.net>
-
-from miasm.core.sembuilder import SemBuilder
-from miasm.ir.ir import Lifter
-from miasm.arch.mep.arch import mn_mep
-from miasm.arch.mep.regs import PC, SP, LP, SAR, TP, RPB, RPE, RPC, EPC, NPC, \
-    take_jmp, in_erepeat
-from miasm.arch.mep.regs import EXC, HI, LO, PSW, DEPC, DBG
-from miasm.expression.expression import ExprId, ExprInt, ExprOp, TOK_EQUAL
-from miasm.expression.expression import ExprAssign, ExprCond, ExprMem
-from miasm.core.cpu import sign_ext
-from miasm.jitter.csts import EXCEPT_DIV_BY_ZERO
-
-from miasm.arch.mep.regs import exception_flags
-
-
-def compute_s_inf(arg1, arg2):
-    """Signed comparison operator"""
-    return ((arg1 - arg2) ^ ((arg1 ^ arg2) & ((arg1 - arg2) ^ arg1))).msb()
-
-def compute_u_inf(x, y):
-    """Unsigned comparison operator"""
-    result = (((x - y) ^ ((x ^ y) & ((x - y) ^ x))) ^ x ^ y).msb()
-    return result
-
-def i8(value):
-    return ExprInt(value, 8)
-
-def i32(value):
-    return ExprInt(value, 32)
-
-
-# SemBuilder context
-ctx = {"PC": PC, "SP": SP, "LP": LP, "SAR": SAR, "TP": TP,
-       "RPB": RPB, "RPE": RPE, "RPC": RPC, "EPC": EPC, "NPC": NPC,
-       "EXC": EXC, "HI": HI, "LO": LO, "PSW": PSW, "DEPC": DEPC, "DBG": DBG,
-       "exception_flags": exception_flags, "compute_s_inf": compute_s_inf,
-       "compute_u_inf": compute_u_inf, "take_jmp": take_jmp,
-       "in_erepeat": in_erepeat, "EXCEPT_DIV_BY_ZERO": EXCEPT_DIV_BY_ZERO}
-sbuild = SemBuilder(ctx)
-
-
-# Functions used to get an instruction IR
-manual_functions = dict()
-
-
-@sbuild.parse
-def mep_nop():
-    """Dummy instruction"""
-
-
-@sbuild.parse
-def mep_nop_2_args(arg1, arg2):
-    """Dummy instruction with two arguments"""
-
-
-### Load/Store instructions
-
-# Register indirect addressing mode
-
-def sb(ir, instr, reg_src, deref_dst):
-    """SB - Store Byte into memory"""
-
-    # MemByte(Rm31..0) <- Rn7..0
-    # MemByte((ZeroExt(disp7)+TP)31..0)) <- Rn7..0
-    # MemByte((SignExt(disp16)+Rm)31..0) <- Rn7..0
-    e = []
-    e.append(ExprAssign(ExprMem(deref_dst.ptr, 8), reg_src[:8]))
-    return e, []
-
-manual_functions["sb"] = sb
-
-
-def sh(ir, instr, reg_src, deref_dst):
-    """SH - Store Halfword into memory"""
-
-    # MemHword(Rm31..1||0) <- Rn15..0
-    # MemHword((ZeroExt((disp7)6..1||0)+TP)31..1||0)) <- Rn15..0
-    # MemHword((SignExt(disp16)+Rm)31..1||0) <- Rn15..0
-    e = []
-    e.append(ExprAssign(ExprMem(deref_dst.ptr & i32(0xFFFFFFFE), 16), reg_src[:16]))
-    return e, []
-
-manual_functions["sh"] = sh
-
-
-def sw(ir, instr, reg_src, deref_dst):
-    """SW - Store Word into memory"""
-
-    # MemWord(Rm31..2||00) <- Rn31..0
-    # MemWord((ZeroExt((disp7)6..2||00)+SP)31..2||00)) <- Rn31..0
-    # MemWord((ZeroExt((disp7)6..2||00)+TP)31..2||00)) <- Rn31..0
-    # MemWord((SignExt(disp16)+Rm)31..2||00) <- Rn31..0
-    # MemWord(ZeroExt((abs24)23..2||00)) - Rn31..0
-    e = []
-    e.append(ExprAssign(ExprMem(deref_dst.ptr & i32(0xFFFFFFFC), 32), reg_src))
-    return e, []
-
-manual_functions["sw"] = sw
-
-# Without the sembuilder
-#def sw(ir, instr, reg_src, deref_reg_or_imm, deref_reg=None):
-#    """SW - store Word into memory.
-#
-#       Note: there are three variants to get the memory address:
-#            - from a register
-#            - relatively to SP
-#            - relatively to TP"""
-#
-#    if isinstance(deref_reg_or_imm, ExprMem):
-#        # MemWord(Rm31..2||00) <- Rn31..0
-#        dst = deref_reg_or_imm
-#
-#    elif isinstance(deref_reg_or_imm, ExprInt) and deref_reg:
-#        # MemWord((ZeroExt((disp7)6..2||00)+SP)31..2||00)) <- Rn31..0
-#        # MemWord((ZeroExt((disp7)6..2||00)+TP)31..2||00)) <- Rn31..0
-#
-#        imm = deref_reg_or_imm.zeroExtend(32)
-#        dst = ExprMem(ExprOp("+", imm, deref_reg.arg))
-#
-#    return [ExprAssign(dst, reg_src)], []
-
-
-def lb(ir, instr, reg_dst, deref_dst):
-    """LB - Load Byte from memory"""
-
-    # Rn <- SignExt(MemByte(Rm31..0))
-    # Rn <- SignExt(MemByte((ZeroExt(disp7)+TP)31..0))
-    # Rn <- SignExt(MemByte((SignExt(disp16)+Rm)31..0)
-    e = []
-    e.append(ExprAssign(reg_dst, ExprMem(deref_dst.ptr, 8).signExtend(32)))
-    return e, []
-
-manual_functions["lb"] = lb
-
-
-def lh(ir, instr, reg_dst, deref_dst):
-    """LH - Load Halfword from memory"""
-
-    # Rn <- SignExt(MemHword(Rm31..1||0))
-    # Rn <- SignExt(MemHword((ZeroExt((disp7)6..1||0)+TP)31..1||0)
-    # Rn <- SignExt(MemHword((SignExt(disp16)+Rm)31..1||0))
-    e = []
-    e.append(ExprAssign(reg_dst, ExprMem(deref_dst.ptr & i32(0xFFFFFFFE), 16).signExtend(32)))
-    return e, []
-
-manual_functions["lh"] = lh
-
-def lw(ir, instr, reg_dst, deref_dst):
-    """LW - Load Word from memory"""
-
-    # Rn <- MemWord(Rm31..2||00)
-    # Rn <- MemWord((ZeroExt((disp7)6..2||00)+TP)31..2||00)
-    # Rn <- MemWord((SignExt(disp16)+Rm)31..2||00)
-    # Rn <- MemWord(ZeroExt((abs24)23..2||00))
-    e = []
-    e.append(ExprAssign(reg_dst, ExprMem(deref_dst.ptr & i32(0xFFFFFFFC), 32)))
-    return e, []
-
-manual_functions["lw"] = lw
-
-
-def lbu(ir, instr, reg_dst, deref_dst):
-    """LBU - Load an unsigned Byte from memory"""
-
-    # Rn <- ZeroExt(MemByte(Rm31..0))
-    # Rn <- ZeroExt(MemByte((ZeroExt(disp7)+TP)31..0))
-    # Rn <- ZeroExt(MemByte((SignExt(disp16)+Rm)31..0))
-    e = []
-    e.append(ExprAssign(reg_dst, ExprMem(deref_dst.ptr, 8).zeroExtend(32)))
-    return e, []
-
-manual_functions["lbu"] = lbu
-
-
-def lhu(ir, instr, reg_dst, deref_dst):
-    """LHU - Load an unsigned Halfword from memory"""
-
-    # Rn <- ZeroExt(MemHword(Rm31..1||0))
-    # Rn <- ZeroExt(MemHword((SignExt(disp16)+Rm)31..1||0))
-    # Rn <- ZeroExt(MemHword((ZeroExt((disp7)6..1||0)+TP)31..1||0))
-    e = []
-    e.append(ExprAssign(reg_dst, ExprMem(deref_dst.ptr & i32(0xFFFFFFFE), 16).zeroExtend(32)))
-    return e, []
-
-manual_functions["lhu"] = lhu
-
-
-
-### Byte/Halfword extension instructions
-
-@sbuild.parse
-def extb(reg):
-    """EXTB - Sign extend a byte"""
-
-    # Rn <- SignExt(Rn7..0)
-    reg = reg[:8].signExtend(32)
-
-
-@sbuild.parse
-def exth(reg):
-    """EXTH - Sign extend a word"""
-
-    # Rn <- ZeroExt(Rn15..0)
-    reg = reg[:16].signExtend(32)
-
-
-@sbuild.parse
-def extub(reg):
-    """EXUTB - Zero extend a byte"""
-
-    # Rn <- SignExt(Rn7..0)
-    reg = reg[:8].zeroExtend(32)
-
-
-@sbuild.parse
-def extuh(reg):
-    """EXTUH - Zero extend a word"""
-
-    # Rn <- ZeroExt(Rn15..0)
-    reg = reg[:16].zeroExtend(32)
-
-
-### Shift amount manipulation instructions
-
-#@sbuild.parse
-#def ssarb(deref_reg):
-
-
-### Move instructions
-
-@sbuild.parse
-def mov(reg, value):
-    """MOV - Copy 'value' to a register. The three alternatives are handled."""
-
-    # Rn <- Rm
-    # Rn <- SignExt(imm8)
-    # Rn <- SignExt(imm16)
-    reg = value.signExtend(32)
-
-
-@sbuild.parse
-def movu(reg, value):
-    """MOV - Copy 'value' to a register. The two alternatives are handled."""
-
-    # Rn[0-7] <- ZeroExt(imm24)
-    # Rn <- ZeroExt(imm16)
-    reg = value.zeroExtend(32)
-
-
-@sbuild.parse
-def movh(reg, imm16):
-    """MOVH - Copy a shifted imm16 to a register."""
-
-    # Rn <- imm16 <<16
-    reg = imm16.zeroExtend(32) << i32(16)
-
-
-### Arithmetic instructions
-
-def add3(ir, instr, reg_dst, reg_src, reg_or_imm):
-    """ADD3 - Add two register and store the result to a register, or
-              add a register and an immediate and store the result to a register"""
-
-    if isinstance(reg_or_imm, ExprId):
-        # Rl <- Rn + Rm
-        result = ExprOp("+", reg_src, reg_or_imm)
-    else:
-        # Rn <- Rm + SignExt(imm16)
-        value = int(reg_or_imm)
-        result = ExprOp("+", reg_src, ExprInt(value, 32))
-
-    return [ExprAssign(reg_dst, result)], []
-
-manual_functions["add3"] = add3
-
-
-@sbuild.parse
-def add(arg1, arg2):
-    """ADD - Add a register and an immediate."""
-
-    # Rn <- Rn + SignExt(imm6)
-    arg1 = arg1 + arg2.signExtend(32)
-
-
-@sbuild.parse
-def advck3(r0, rn, rm):
-    """ADVCK3 - Check addition overflow."""
-
-    # if(Overflow(Rn+Rm)) R0<-1 else R0<-0 (Signed)
-    r0 = i32(1) if compute_u_inf(i64(0xFFFFFFFF), rn.zeroExtend(64) + rm.zeroExtend(64)) else i32(0)
-
-
-@sbuild.parse
-def sub(reg1, reg2):
-    """SUB - Subtract one register to another."""
-
-    # Rn <- Rn - Rm
-    reg1 = reg1 - reg2
-
-
-def sbvck3(ir, instr, r0, rn, rm):
-    """SBVCK3 - Check subtraction overflow"""
-
-    # if(Overflow(Rn-Rm)) R0<-1 else R0<-0 (Signed)
-
-    # Subtract registers
-    reg_sub = ExprOp("+", rn, rm)
-
-    # Get the register storing the highest value
-    max_rn_rm = ExprCond(ExprOp(">", rn, rm), rn, rm)
-
-    # Check for an overflow
-    overflow_test = ExprOp(">", reg_sub, max_rn_rm)
-
-    # Return the result
-    condition = ExprCond(overflow_test, ExprInt(1, 32), ExprInt(0, 32))
-    return [ExprAssign(r0, condition)], []
-
-manual_functions["sbvck3"] = sbvck3
-
-
-@sbuild.parse
-def neg(reg1, reg2):
-    """NEG - Negate one register."""
-
-    # Rn <- - Rm
-    reg1 = - reg2
-
-
-@sbuild.parse
-def slt3(r0, rn, rm_or_imm5):
-    """SLT3 - Set on less than (signed)."""
-
-    # if (Rn<Rm) R0<-1 else R0<-0 (Signed)
-    # if (Rn<ZeroExt(imm5)) R0<-1 else R0<-0(Signed)
-    r0 = i32(1) if compute_s_inf(rn, rm_or_imm5.signExtend(32)) else i32(0)
-
-if False:
-    rm_ext = rm_or_imm5
-
-    # Mask sign bits
-    sign_mask = i32(0x80000000)
-    sign_rn = rn & sign_mask
-    sign_rm = rm_ext & sign_mask
-
-    # Check if both numbers are positive or negative
-    are_both_neg = sign_rn & sign_rm
-    are_both_pos = ~(sign_rn & sign_rm) >> i32(31)
-
-    # rn is positive and rm negative, return 1
-    r0_mixed = i32(1) if sign_rn else i32(0)
-
-    # rn & rm are both positives, test and return 1 or 0
-    r0_pos = (i32(1) if "<"(rn, rm_ext) else i32(0)) if are_both_pos else r0_mixed
-
-    # rn & rm are both negatives, test and return 0 or 1
-    r0 = (i32(0) if "<"(rn, rm_ext) else i32(1)) if are_both_neg else r0_pos
-
-
-@sbuild.parse
-def sltu3(r0, rn, rm_or_imm5):
-    """SLTU3 - Set on less than (unsigned)."""
-
-    # if (Rn<Rm) R0<-1 else R0<-0 (Unsigned)
-    # if (Rn<ZeroExt(imm5)) R0<-1 else R0<-0(Unsigned)
-    r0 = i32(1) if compute_u_inf(rn, rm_or_imm5) else i32(0)
-
-
-@sbuild.parse
-def sl1ad3(r0, rn, rm):
-    """SL1AD3 - Shift a register one bit left, then add another one."""
-
-    # R0 <- (Rn<<1) + Rm
-    r0 = (rn << i32(1)) + rm
-
-
-@sbuild.parse
-def sl2ad3(r0, rn, rm):
-    """SL2AD3 - Shift a register two bits left, then add another one."""
-
-    # R0 <- (Rn<<2) + Rm
-    r0 = (rn << i32(2)) + rm
-
-
-### Logical instructions
-
-@sbuild.parse
-def logical_or(rn, rm):
-    """OR - Logical OR between two registers."""
-
-    # Rn <- Rn or Rm
-    rn = rn | rm
-
-manual_functions["or"] = logical_or
-
-
-@sbuild.parse
-def logical_and(rn, rm):
-    """AND - Logical AND between two registers."""
-
-    # Rn <- Rn and Rm
-    rn = rn & rm
-
-manual_functions["and"] = logical_and
-
-
-@sbuild.parse
-def xor(rn, rm):
-    """XOR - Logical XOR between two registers."""
-
-    # Rn <- Rn xor Rm
-    rn = rn ^ rm
-
-
-@sbuild.parse
-def nor(rn, rm):
-    """NOR - Logical NOR between two registers."""
-
-    # Rn <- Rn nor Rm
-    rn = ~ (rn | rm)
-
-
-@sbuild.parse
-def or3(rn, rm, imm16):
-    """OR3 - Logical OR between a register and an immediate"""
-
-    # Rn <- Rm or ZeroExt(imm16)
-    rn = rm | imm16
-
-
-@sbuild.parse
-def and3(rn, rm, imm16):
-    """AND3 - Logical AND between a register and an immediate"""
-
-    # Rn <- Rm and ZeroExt(imm16)
-    rn = rm & imm16
-
-
-@sbuild.parse
-def xor3(rn, rm, imm16):
-    """XOR3 - Logical XOR between a register and an immediate"""
-
-    # Rn <- Rm xor ZeroExt(imm16)
-    rn = rm ^ imm16
-
-
-### Shift instruction
-
-@sbuild.parse
-def sra(rn, rm_or_imm5):
-    """SRA - Shift Right signed"""
-
-    # Rn <- (Signed) Rn >> Rm4..0
-    # Rn <- (Signed) Rn >> imm5
-
-    # Unsigned result
-    shift_u = rn >> rm_or_imm5
-
-    # Signed result
-    shift_mask = i32(32) - rm_or_imm5
-    mask = (i32(0xFFFFFFFF) >> shift_mask) << shift_mask
-    shift_s = shift_u | mask
-
-    rn = shift_s if rn.msb() else shift_u
-
-
-@sbuild.parse
-def srl(rn, rm_or_imm5):
-    """SRL - Shift Right unsigned."""
-
-    # Rn <- (Unsigned) Rn >> Rm4..0
-    # Rn <- (Unsigned) Rn >> imm5
-    rn = rn >> rm_or_imm5
-
-
-@sbuild.parse
-def sll(rn, rm_or_imm5):
-    """SLL - Shift Left unsigned."""
-
-    # Rn <- (Unsigned) Rn >> Rm4..0
-    # Rn <- (Unsigned) Rn << imm5
-    rn = rn << rm_or_imm5
-
-
-@sbuild.parse
-def sll3(r0, rn, imm5):
-    """SLL3 - Shift Left unsigned, with 3 arguments."""
-
-    # R0 <- (Unsigned) Rn << imm5
-    r0 = rn << imm5
-
-
-@sbuild.parse
-def fsft(rn, rm):
-    """FSFT - Funnel shift."""
-
-    # Rn <- ((Rn||Rm)<<SAR5..0)63..32
-    # Note: lowest Rm bits are discarded
-
-    sar = SAR[:5].zeroExtend(32)
-    tmp_rn = rn << sar  # Shift Rn
-    tmp_rm = rm >> (i32(32) - sar)  # Shift Rm in the reverse order
-    rn = tmp_rn | tmp_rm  # Concatenate registers
-
-
-## Branch/Jump instructions
-
-@sbuild.parse
-def bra(disp12):
-    """BRA - Branch to an address."""
-
-    # PC <- PC + SignExt((disp12)11..1||0)
-    dst = disp12
-    PC = dst
-    take_jmp = ExprInt(1, 32)
-    ir.IRDst = dst
-
-
-@sbuild.parse
-def beqz(reg_test, disp8):
-    """BEQZ - Branch if the register stores zero."""
-
-    # if(Rn==0) PC <- PC +SignExt((disp8)7..1||0)
-    dst = ExprLoc(ir.get_next_break_loc_key(instr), 32) if reg_test else disp8
-    take_jmp = ExprInt(0, 32) if reg_test else ExprInt(1, 32)
-    PC = dst
-    ir.IRDst = dst
-
-
-@sbuild.parse
-def bnez(reg_test, disp8):
-    """BNEZ - Branch if the register does not store zero."""
-
-    # if(Rn!=0) PC <- PC + SignExt((disp8)7..1||0)
-    dst = disp8 if reg_test else ExprLoc(ir.get_next_break_loc_key(instr), 32)
-    take_jmp = ExprInt(1, 32) if reg_test else ExprInt(0, 32)
-    PC = dst
-    ir.IRDst = dst
-
-
-@sbuild.parse
-def beqi(reg_test, imm4, disp16):
-    """BEQI - Branch if the register stores imm4."""
-
-    # if(Rn==ZeroExt(imm4)) PC <- PC +SignExt((disp17)16..1||0)
-    dst = ExprLoc(ir.get_next_break_loc_key(instr), 32) if (reg_test - imm4) else disp16
-    take_jmp = ExprInt(0, 32) if (reg_test - imm4) else ExprInt(1, 32)
-    PC = dst
-    ir.IRDst = dst
-
-
-@sbuild.parse
-def bnei(reg_test, imm4, disp16):
-    """BNEI - Branch if the register does not store imm4."""
-
-    # if(Rn!=ZeroExt(imm4)) PC <- PC+SignExt((disp17)16..1||0)
-    dst = disp16 if (reg_test - imm4) else ExprLoc(ir.get_next_break_loc_key(instr), 32)
-    take_jmp = ExprInt(1, 32) if (reg_test - imm4) else ExprInt(0, 32)
-    PC = dst
-    ir.IRDst = dst
-
-
-@sbuild.parse
-def blti(reg_test, imm4, disp16):
-    """BLTI - Branch if the register is lower than imm4."""
-
-    # if(Rn< ZeroExt(imm4)) PC <- PC +SignExt((disp17)16..1||0) - (Signed comparison)
-    dst = disp16 if compute_s_inf(reg_test, imm4) else ExprLoc(ir.get_next_break_loc_key(instr), 32)
-    take_jmp = ExprInt(1, 32) if compute_s_inf(reg_test, imm4) else ExprInt(0, 32)
-    PC = dst
-    ir.IRDst = dst
-
-
-@sbuild.parse
-def bgei(reg_test, imm4, disp16):
-    """BGEI - Branch if the register is greater or equal to imm4."""
-
-    # if(Rn>=ZeroExt(imm4)) PC <- PC +SignExt((disp17)16..1||0) - (Signed comparison)
-    cond = i32(1) if ExprOp(TOK_EQUAL, reg_test, imm4) else compute_s_inf(imm4, reg_test).zeroExtend(32)
-    dst = disp16 if cond else ExprLoc(ir.get_next_break_loc_key(instr), 32)
-    take_jmp = ExprInt(1, 32) if cond else ExprInt(0, 32)
-    PC = dst
-    ir.IRDst = dst
-
-
-@sbuild.parse
-def beq(rn, rm, disp16):
-    """BEQ - Branch if the two registers are equal."""
-
-    # if(Rn==Rm) PC <- PC +SignExt((disp17)16..1||0)
-    dst = ExprLoc(ir.get_next_break_loc_key(instr), 32) if (rn - rm) else disp16
-    take_jmp = ExprInt(0, 32) if (rn - rm) else ExprInt(1, 32)
-    PC = dst
-    ir.IRDst = dst
-
-
-@sbuild.parse
-def bne(rn, rm, disp16):
-    """BNE - Branch if the two registers are not equal."""
-
-    # if(Rn!=Rm) PC <- PC +SignExt((disp17)16..1||0)
-    dst = disp16 if (rn - rm) else ExprLoc(ir.get_next_break_loc_key(instr), 32)
-    take_jmp = ExprInt(1, 32) if (rn - rm) else ExprInt(0, 32)
-    PC = dst
-    ir.IRDst = dst
-
-
-@sbuild.parse
-def bsr(disp):
-    """BSR - Branch to an address, and store the return address."""
-
-    # 16-bit variant: LP <- PC + 2; PC <- PC +SignExt((disp12)11..1||0)
-    # 32-bit variant: LP <- PC + 4; PC <- PC +SignExt((disp24)23..1||0)
-
-    # Set LP
-    LP = ExprLoc(ir.get_next_break_loc_key(instr), 32)
-    take_jmp = ExprInt(1, 32)
-
-    # Set PC according to the immediate size
-    dst = disp
-    PC = dst
-    ir.IRDst = dst
-
-
-def jmp(ir, instr, reg_or_imm):
-    """JMP - Change PC to a register content or an immediate.
-       Note: the behavior in VLIW mode is not implemented"""
-
-    take_jmp = ExprInt(1, 32)
-
-    if isinstance(reg_or_imm, ExprId):
-        # PC <- Rm31..1||0
-        new_PC = ExprAssign(PC, reg_or_imm)
-    else:
-        # PC <- PC31..28||0000||(target24)23..1||0
-        new_PC = ExprAssign(PC, ExprOp("+", ExprOp("&", PC, ExprInt(0xF0000000, 32)), reg_or_imm))
-
-    return [new_PC, ExprAssign(ir.IRDst, new_PC)], []
-
-manual_functions["jmp"] = jmp
-
-
-@sbuild.parse
-def jsr(reg):
-    """JSR - Jump to the register, and store the return address."""
-
-    # LP <- PC + 2; PC <- Rm31..1||0
-    LP = ExprLoc(ir.get_next_break_loc_key(instr), 32)
-    take_jmp = ExprInt(1, 32)
-    PC = reg
-    ir.IRDst = reg
-
-
-@sbuild.parse
-def ret():
-    """RET - Return from a function call.
-       Note: the behavior in VLIW mode is not implemented"""
-
-    # PC <- LP31..1||0
-    dst = LP
-    PC = dst
-    ir.IRDst = dst
-
-
-# Repeat instructions
-
-@sbuild.parse
-def repeat(rn, disp17):
-    """REPEAT - This instruction repeats an instruction block. It sets the RPB,
-       RPE and RPC control registers."""
-
-    # RPB <- pc+4 // Repeat Begin
-    RPB = PC + i32(4)
-    # RPE <- pc+SignExt((disp17)16..1||0)) // Repeat End
-    RPE = PC + i32(int(disp17) & 0xFFFFFFFE)
-    # RPC <- Rn
-    RPC = rn
-    in_erepeat = ExprInt(0, 32)
-
-
-@sbuild.parse
-def erepeat(disp17):
-    """EREPEAT - This instruction repeats an instruction block. It sets the RPB
-       and RPE control registers. To distinguish from the repeat instruction,
-       the least significant bit in the RPE register (ELR) is set to 1."""
-
-    # RPB <- pc+4 // Repeat Begin
-    RPB = PC + i32(4)
-    # RPE <- pc+SignExt((disp17)16..1||1)) (EREPEAT)
-    RPE = PC + i32(int(disp17) + 1)
-    # RPC <- undefined
-    in_erepeat = ExprInt(1, 32)
-
-
-## Control Instructions
-
-@sbuild.parse
-def stc(reg, control_reg):
-    """STC - Copy a general-purpose register into a control register."""
-
-    # ControlReg(imm5) <- Rn
-    control_reg = reg
-
-
-@sbuild.parse
-def ldc(reg, control_reg):
-    """LDC - Copy a control register into a general-purpose register."""
-
-    # Rn <- ControlReg(imm5)
-    reg = control_reg
-
-
-@sbuild.parse
-def di():
-    """DI - Disable Interrupt"""
-
-    # PSW.IEC<-0
-    PSW = PSW & i32(0xFFFFFFFE)  # PSW.IEC: bit 0
-
-
-@sbuild.parse
-def ei():
-    """EI - Enable Interrupt"""
-
-    # PSW.IEC<-1
-    PSW = PSW ^ i32(0b1)  # PSW.IEC: bit 0
-
-
-@sbuild.parse
-def reti():
-    """RETI - Return from the exception/interrupt handler.
-       Note: the behavior in VLIW mode is not implemented"""
-
-    #if (PSW.NMI==1) {
-    #   PC <- NPC31..1 || 0; PSW.NMI<-0;
-    #} else {
-    #   PC <- EPC31..1 || 0;
-    #   PSW.UMC <- PSW.UMP; PSW.IEC <- PSW.IEP
-    #}
-
-    # PSW.NMI == bit 9
-    NMI_mask = i32(1 << 9)
-
-    # PSW.UMP == bit 3
-    # PSW.IEP == bit 1
-    UMP_IEP_mask = i32((1 << 3) ^ (1 << 1))
-
-    # PSW.UMC == bit 2
-    # PSW.IEC == bit 0
-    UMC_IEC_mask = (PSW & UMP_IEP_mask) >> i32(1)
-
-    # Get PSW.NMI
-    PSW_NMI = (PSW & NMI_mask) >> i32(9)
-
-    # Set PC
-    dst = NPC & i32(0xFFFFFFFE) if PSW_NMI else EPC & i32(0xFFFFFFFE)
-    PC = dst
-
-    # Set flags
-    PSW = PSW ^ NMI_mask if PSW_NMI else PSW ^ UMC_IEC_mask
-
-    ir.IRDst = dst
-
-
-@sbuild.parse
-def swi(imm2):
-    """SWI - Software Interrupt"""
-
-    # if(imm2==0) EXC.SIP0 <- 1
-    # else if (imm2==1) EXC.SIP1 <- 1
-    # else if (imm2==2) EXC.SIP2 <- 1
-    # else if (imm2==3) EXC.SIP3 <- 1
-
-    # EXC.SIP0 == bit 4
-    # EXC.SIP1 == bit 5
-    # EXC.SIP2 == bit 6
-    # EXC.SIP3 == bit 7
-
-    EXC = EXC ^ (i32(1) << (i32(4) + imm2))
-
-
-# Note: the following instructions can't be implemented
-manual_functions["halt"] = mep_nop
-manual_functions["sleep"] = mep_nop
-manual_functions["break"] = mep_nop
-manual_functions["syncm"] = mep_nop
-manual_functions["stcb"] = mep_nop_2_args
-manual_functions["ldcb"] = mep_nop_2_args
-
-
-### Bit manipulation instruction option
-
-def bsetm(ir, instr, rm_deref, imm3):
-    """BSETM - Bit Set Memory"""
-
-    # MemByte(Rm) <- MemByte(Rm) or (1<<imm3)
-    e = []
-    e.append(ExprAssign(ExprMem(rm_deref.ptr, 8), ExprOp("|", ExprMem(rm_deref.ptr, 8), (i8(1) << imm3[:8]))))
-    return e, []
-
-manual_functions["bsetm"] = bsetm
-
-
-def bclrm(ir, instr, rm_deref, imm3):
-    """BCLRM - Bit Clear Memory"""
-
-    # MemByte(Rm) <- MemByte(Rm) and ~(1<<imm3)
-    e = []
-    shift = ExprOp("<<", i8(1), imm3[:8])
-    e.append(ExprAssign(ExprMem(rm_deref.ptr, 8), ExprOp("&", ExprMem(rm_deref.ptr, 8), shift.__invert__())))
-    return e, []
-
-manual_functions["bclrm"] = bclrm
-
-
-def bnotm(ir, instr, rm_deref, imm3):
-    """BNOTM - Bit Not Memory"""
-
-    # MemByte(Rm) <- MemByte(Rm) xor (1<<imm3)
-    e = []
-    e.append(ExprAssign(ExprMem(rm_deref.ptr, 8), ExprOp("^", ExprMem(rm_deref.ptr, 8), (i8(1) << imm3[:8]))))
-    return e, []
-
-manual_functions["bnotm"] = bnotm
-
-
-def btstm(ir, instr, r0, rm_deref, imm3):
-    """BTSTM - Bit Test Memory"""
-
-    # R0 <- ZeroExt( MemByte(Rm) and (1<<imm3) )
-    e = []
-    e.append(ExprAssign(r0, ExprOp("&", ExprMem(rm_deref.ptr, 8), i8(1) << imm3[:8]).zeroExtend(32)))
-    return e, []
-
-manual_functions["btstm"] = btstm
-
-
-def tas(ir, instr, rn, rm_deref):
-    """TAS - Load And Set"""
-
-    # temp <- Rm; Rn <- ZeroExt(MemByte(temp)); MemByte(temp) <- 1
-    e = []
-    temp = rm_deref
-    e.append(ExprAssign(rn, ExprMem(temp.ptr, 8).zeroExtend(32)))
-    e.append(ExprAssign(ExprMem(temp.ptr, 8),  i8(1)))
-    return e, []
-
-manual_functions["tas"] = tas
-
-
-### Data cache option
-
-# Note: the following instruction can't be implemented
-manual_functions["cache"] = mep_nop_2_args
-
-
-### 32-bit multiply instruction option
-
-@sbuild.parse
-def mul(rn, rm):
-    """MUL - Signed 32-bit multiplication"""
-
-    # HI||LO <- Rn * Rm (Signed)
-    result = rn.signExtend(64) * rm.signExtend(64)  # expand registers size
-    HI = result[32:64]
-    LO = result[:32]
-
-
-@sbuild.parse
-def mulu(rn, rm):
-    """MUL - Unsigned 32-bit multiplication"""
-
-    # HI||LO <- Rn * Rm (Unsigned)
-    result = rn.zeroExtend(64) * rm.zeroExtend(64)  # expand registers size
-    HI = result[32:64]
-    LO = result[0:32]
-
-
-@sbuild.parse
-def mulr(rn, rm):
-    """MULR - Signed 32-bit multiplication & store LO in Rn"""
-
-    # HI||LO <- Rn * Rm; Rn <- LO (Signed)
-    result = rn.signExtend(64) * rm.signExtend(64)  # expand registers size
-    HI = result[32:64]
-    LO = result[:32]
-    rn = result[:32]
-
-
-@sbuild.parse
-def mulru(rn, rm):
-    """MULRU - Unsigned 32-bit multiplication & store LO in Rn"""
-
-    # HI||LO <- Rn * Rm; Rn <- LO (Unsigned)
-    result = rn.zeroExtend(64) * rm.zeroExtend(64)  # expand registers size
-    HI = result[32:64]
-    LO = result[:32]
-    rn = result[:32]
-
-
-@sbuild.parse
-def madd(rn, rm):
-    """MADD - Signed 32-bit multiplication, adding results to HI & LO registers"""
-
-    # HI||LO <- HI||LO + Rn*Rm (Signed)
-    result = (HI << i32(32)).signExtend(64) + LO.signExtend(64) + rn.signExtend(64) * rm.signExtend(64)  # expand registers size
-    HI = result[32:64]
-    LO = result[:32]
-
-
-@sbuild.parse
-def maddu(rn, rm):
-    """MADDU - Unsigned 32-bit multiplication, adding results to HI & LO registers"""
-
-    # HI||LO <- HI||LO + Rn*Rm (Unsigned)
-    result = (HI << i32(32)).zeroExtend(64) + LO.zeroExtend(64) + rn.zeroExtend(64) * rm.zeroExtend(64)  # expand registers size
-    HI = result[32:64]
-    LO = result[:32]
-
-
-@sbuild.parse
-def maddr(rn, rm):
-    """MADDR - Signed 32-bit multiplication, adding results to HI & LO registers & storing LO in Rn"""
-
-    # HI||LO <- HI||LO + Rn*Rm; Rn <- LO (Signed)
-    result = (HI << i32(32)).signExtend(64) + LO.signExtend(64) + rn.signExtend(64) * rm.signExtend(64)  # expand registers size
-    HI = result[32:64]
-    LO = result[:32]
-    rn = result[:32]
-
-
-@sbuild.parse
-def maddru(rn, rm):
-    """MADDRU - Unsigned 32-bit multiplication, adding results to HI & LO registers & storing LO in Rn"""
-
-    # HI||LO <- HI||LO + Rn*Rm; Rn <- LO (Unsigned)
-    result = (HI << i32(32)).zeroExtend(64) + LO.zeroExtend(64) + rn.zeroExtend(64) * rm.zeroExtend(64)  # expand registers size
-    HI = result[32:64]
-    LO = result[:32]
-    rn = result[:32]
-
-
-### 32-bit divide instruction option
-
-@sbuild.parse
-def div(rn, rm):
-    """DIV - Signed division"""
-
-    # LO <- Rn / Rm, HI <- Rn % Rm (Signed)
-
-    # Mask sign bits
-    sign_mask = i32(0x80000000)
-    sign_rn = rn & sign_mask
-    sign_rm = rm & sign_mask
-
-    # Check if both numbers are positive or negative
-    are_both_neg = sign_rn & sign_rm
-    are_both_pos = ExprCond(
-        are_both_neg - sign_mask,
-        ExprInt(0, are_both_neg.size),
-        ExprInt(1, are_both_neg.size)
-    )
-
-
-    # Invert both numbers
-    rn_inv = ~rn + i32(1)
-    rm_inv = ~rm + i32(1)
-
-    # Used to delay the arithmetic computations
-    tmp_rm = rm if rm else i32(1)
-    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))
-    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
-    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
-    HI_neg = rn_inv % tmp_rm_inv if are_both_neg else HI_pos
-
-    # Results if rm is equal to zero
-    LO = LO_neg if rm else LO
-    HI = HI_neg if rm else HI
-
-    exception_flags = i32(0) if rm else i32(EXCEPT_DIV_BY_ZERO)
-
-
-@sbuild.parse
-def divu(rn, rm):
-    """DIVU - Unsigned division"""
-
-    # 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
-    HI = rn % tmp_rm if rm else HI
-
-    exception_flags = i32(0) if rm else i32(EXCEPT_DIV_BY_ZERO)
-
-
-### Debug function option
-
-@sbuild.parse
-def dret():
-    """DRET - Debug Exception Return"""
-
-    # PC <- DEPC; DBG.DM <- 0
-    PC = DEPC
-    DBG = DBG & i32(0xFFFFBFFF)  # DBG.DM: bit 15
-
-
-@sbuild.parse
-def dbreak():
-    """DBREAK - Debug break"""
-
-    # The DBG.DBP bit becomes 1
-    DBG = DBG ^ i32(0b10)  # DBG.DBP: bit 2
-
-
-### Leading zero instruction option
-
-@sbuild.parse
-def ldz(rn, rm):
-    """LDZ - Count Leading Zeroes
-
-       Note: this implementation is readable, yet slow. Each bit are tested
-       individually, and the results are propagated to other bits.
-
-       Here is the commented implementation for 4-bit integers:
-       rm = 0b0001
-
-       # Invert the value
-       reversed_rm = ~rm
-      -> reversed_rm = 0b1110
-
-       # Test bits individually
-       b3 = (reversed_rm & i32(2**3)) >> i32(3) if reversed_rm else i32(0)
-      -> b3 = (0b1110 & 0b1000 >> 3) = 1
-
-       b2 = (reversed_rm & i32(2**2)) >> i32(2) if b3 else i32(0)
-      -> b2 = (0b1110 & 0b0100 >> 2) = 1
-
-       b1 = (reversed_rm & i32(2**1)) >> i32(1) if b2 else i32(0)
-      -> b1 = (0b1110 & 0b0010 >> 1) = 1
-
-       b0 = (reversed_rm & i32(2**0)) >> i32(0) if b1 else i32(0)
-      -> b0 = (0b1110 & 0b0001 >> 0) = 0
-
-       # Sum all partial results
-       rn = b3 + b2 + b1 + b0
-      -> rn = 1 + 1 + 1 + 0 = 3
-    """
-
-    # Rn <- LeadingZeroDetect(Rm)
-
-    # Invert the value
-    reversed_rm = ~rm
-
-    # Test bits individually
-    b31 = (reversed_rm & i32(2**31)) >> i32(31) if reversed_rm else i32(0)
-    b30 = (reversed_rm & i32(2**30)) >> i32(30) if b31 else i32(0)
-    b29 = (reversed_rm & i32(2**29)) >> i32(29) if b30 else i32(0)
-    b28 = (reversed_rm & i32(2**28)) >> i32(28) if b29 else i32(0)
-    b27 = (reversed_rm & i32(2**27)) >> i32(27) if b28 else i32(0)
-    b26 = (reversed_rm & i32(2**26)) >> i32(26) if b27 else i32(0)
-    b25 = (reversed_rm & i32(2**25)) >> i32(25) if b26 else i32(0)
-    b24 = (reversed_rm & i32(2**24)) >> i32(24) if b25 else i32(0)
-    b23 = (reversed_rm & i32(2**23)) >> i32(23) if b24 else i32(0)
-    b22 = (reversed_rm & i32(2**22)) >> i32(22) if b23 else i32(0)
-    b21 = (reversed_rm & i32(2**21)) >> i32(21) if b22 else i32(0)
-    b20 = (reversed_rm & i32(2**20)) >> i32(20) if b21 else i32(0)
-    b19 = (reversed_rm & i32(2**19)) >> i32(19) if b20 else i32(0)
-    b18 = (reversed_rm & i32(2**18)) >> i32(18) if b19 else i32(0)
-    b17 = (reversed_rm & i32(2**17)) >> i32(17) if b18 else i32(0)
-    b16 = (reversed_rm & i32(2**16)) >> i32(16) if b17 else i32(0)
-    b15 = (reversed_rm & i32(2**15)) >> i32(15) if b16 else i32(0)
-    b14 = (reversed_rm & i32(2**14)) >> i32(14) if b15 else i32(0)
-    b13 = (reversed_rm & i32(2**13)) >> i32(13) if b14 else i32(0)
-    b12 = (reversed_rm & i32(2**12)) >> i32(12) if b13 else i32(0)
-    b11 = (reversed_rm & i32(2**11)) >> i32(11) if b12 else i32(0)
-    b10 = (reversed_rm & i32(2**10)) >> i32(10) if b11 else i32(0)
-    b09 = (reversed_rm & i32(2 ** 9)) >> i32(9) if b10 else i32(0)
-    b08 = (reversed_rm & i32(2 ** 8)) >> i32(8) if b09 else i32(0)
-    b07 = (reversed_rm & i32(2 ** 7)) >> i32(7) if b08 else i32(0)
-    b06 = (reversed_rm & i32(2 ** 6)) >> i32(6) if b07 else i32(0)
-    b05 = (reversed_rm & i32(2 ** 5)) >> i32(5) if b06 else i32(0)
-    b04 = (reversed_rm & i32(2 ** 4)) >> i32(4) if b05 else i32(0)
-    b03 = (reversed_rm & i32(2 ** 3)) >> i32(3) if b04 else i32(0)
-    b02 = (reversed_rm & i32(2 ** 2)) >> i32(2) if b03 else i32(0)
-    b01 = (reversed_rm & i32(2 ** 1)) >> i32(1) if b02 else i32(0)
-    b00 = (reversed_rm & i32(2 ** 0)) >> i32(0) if b01 else i32(0)
-
-    # Sum all partial results
-    rn = b31 + b30 + b29 + b28 + b27 + b26 + b25 + b24 + b23 + b22 + b21 + b20 \
-        + b19 + b18 + b17 + b16 + b15 + b14 + b13 + b12 + b11 + b10 + b09 + b08 \
-        + b07 + b06 + b05 + b04 + b03 + b02 + b01 + b00
-
-
-### Coprocessor option
-
-# Note: these instructions are implemented when needed
-
-# SWCP - Store Word to memory from a coprocessor register
-#        MemWord(Rm31..2||00) <- CRn 31..0
-manual_functions["swcp"] = sw
-
-
-# LWCP - Load Word from memory to a coprocessor register
-#        CRn <- MemWord(Rm31..2||00)
-manual_functions["lwcp"] = lw
-
-
-def smcp(ir, instr, reg_src, deref_dst):
-    """SMCP - Store Word to memory from a coprocessor register"""
-
-    # MemDword(Rm31..3||000) <- CRn
-    e = []
-    e.append(ExprAssign(ExprMem(deref_dst.ptr & i32(0xFFFFFFF8), 32), reg_src))
-    return e, []
-
-manual_functions["smcp"] = smcp
-
-
-def lmcp(ir, instr, reg_dst, deref_src):
-    """LMCP - Load Word from memory to a coprocessor register"""
-
-    # CRn <- MemDword(Rm31..3||000)
-    e = []
-    e.append(ExprAssign(reg_dst, ExprMem(deref_src.ptr & i32(0xFFFFFFF8), 32)))
-    return e, []
-
-manual_functions["lmcp"] = lmcp
-
-
-def swcpi(ir, instr, reg_src, deref_dst):
-    """SWCPI - Store Word to memory, and increment the address"""
-
-    # MemWord(Rm31..2||00) <- CRn 31..0; Rm<-Rm+4
-    e = []
-    e.append(ExprAssign(ExprMem(deref_dst.ptr & i32(0xFFFFFFFC), 32), reg_src))
-    e.append(ExprAssign(deref_dst.ptr, deref_dst.ptr + i32(4)))
-    return e, []
-
-manual_functions["swcpi"] = swcpi
-
-
-def lwcpi(ir, instr, reg_dst, deref_src):
-    """LWCPI - Load Word from memory, and increment the address"""
-
-    # CRn <- MemWord(Rm31..2||00); Rm<-Rm+4
-    e = []
-    e.append(ExprAssign(reg_dst, ExprMem(deref_src.ptr & i32(0xFFFFFFFC), 32)))
-    e.append(ExprAssign(deref_src.ptr, deref_src.ptr + i32(4)))
-    return e, []
-
-manual_functions["lwcpi"] = lwcpi
-
-def smcpi(ir, instr, reg_src, deref_dst):
-    """SMCPI - Store Word to memory, and increment the address"""
-
-    # MemDword(Rm31..3||000) <- CRn; Rm<-Rm+8
-    e = []
-    e.append(ExprAssign(ExprMem(deref_dst.ptr & i32(0xFFFFFFF8), 32), reg_src))
-    e.append(ExprAssign(deref_dst.ptr, deref_dst.ptr + i32(8)))
-    return e, []
-
-manual_functions["smcpi"] = smcpi
-
-
-def lmcpi(ir, instr, reg_dst, deref_src):
-    """LMCPI - Load Word from memory, and increment the address"""
-
-    # CRn <- MemDword(Rm31..3||000); Rm<-Rm+8
-    e = []
-    e.append(ExprAssign(reg_dst, ExprMem(deref_src.ptr & i32(0xFFFFFFFC), 32)))
-    e.append(ExprAssign(deref_src.ptr, deref_src.ptr + i32(8)))
-    return e, []
-
-manual_functions["lmcpi"] = lmcpi
-
-
-### IR MeP definitions
-
-def get_mnemo_expr(ir, instr, *args):
-    """Simplify getting the IR from a miasm instruction."""
-
-    if instr.name.lower() in sbuild.functions:
-        mnemo_func = sbuild.functions[instr.name.lower()]
-    else:
-        mnemo_func = manual_functions[instr.name.lower()]
-
-    ir, extra_ir = mnemo_func(ir, instr, *args)
-    return ir, extra_ir
-
-
-class Lifter_MEPb(Lifter):
-    """Toshiba MeP miasm IR - Big Endian
-
-       It transforms an instructon into an IR.
-    """
-
-    addrsize = 32
-
-    def __init__(self, loc_db):
-        Lifter.__init__(self, mn_mep, "b", loc_db)
-        self.pc = mn_mep.getpc()
-        self.sp = mn_mep.getsp()
-        self.IRDst = ExprId("IRDst", 32)
-
-    def get_ir(self, instr):
-        """Get the IR from a miasm instruction."""
-
-        instr_ir, extra_ir = get_mnemo_expr(self, instr, *instr.args)
-
-        return instr_ir, extra_ir
-
-    def get_next_break_loc_key(self, instr):
-        """Returns a new label that identifies where the instruction is going.
-
-           Note: it eases linking IR blocks
-        """
-
-        l = self.loc_db.get_or_create_offset_location(instr.offset + instr.l)
-        return l
-
-
-class Lifter_MEPl(Lifter_MEPb):
-    """Toshiba MeP miasm IR - Little Endian"""
-
-    def __init__(self, loc_db):
-        Lifter.__init__(self, mn_mep, "l", loc_db)
-        self.pc = mn_mep.getpc()
-        self.sp = mn_mep.getsp()
-        self.IRDst = ExprId("IRDst", 32)