about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--miasm/arch/mep/sem.py185
-rw-r--r--miasm/arch/mips32/sem.py28
-rw-r--r--miasm/core/sembuilder.py21
-rw-r--r--miasm/expression/simplifications_common.py11
-rw-r--r--test/core/sembuilder.py6
5 files changed, 154 insertions, 97 deletions
diff --git a/miasm/arch/mep/sem.py b/miasm/arch/mep/sem.py
index dccfc20d..221d18f8 100644
--- a/miasm/arch/mep/sem.py
+++ b/miasm/arch/mep/sem.py
@@ -24,6 +24,12 @@ def compute_u_inf(x, y):
     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,
@@ -53,28 +59,33 @@ def mep_nop_2_args(arg1, arg2):
 
 # Register indirect addressing mode
 
-@sbuild.parse
-def sb(reg_src, deref_dst):
+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
-    mem8[deref_dst.ptr] = reg_src[:8]
+    e = []
+    e.append(ExprAssign(ExprMem(deref_dst.ptr, 8), reg_src[:8]))
+    return e, []
 
+manual_functions["sb"] = sb
 
-@sbuild.parse
-def sh(reg_src, deref_dst):
+
+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
-    mem16[deref_dst.ptr & i32(0xFFFFFFFE)] = reg_src[:16]
+    e = []
+    e.append(ExprAssign(ExprMem(deref_dst.ptr & i32(0xFFFFFFFE), 16), reg_src[:16]))
+    return e, []
 
+manual_functions["sh"] = sh
 
-@sbuild.parse
-def sw(reg_src, deref_dst):
+
+def sw(ir, instr, reg_src, deref_dst):
     """SW - Store Word into memory"""
 
     # MemWord(Rm31..2||00) <- Rn31..0
@@ -82,8 +93,11 @@ def sw(reg_src, deref_dst):
     # 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, []
 
-    mem32[deref_dst.ptr & i32(0xFFFFFFFC)] = reg_src
+manual_functions["sw"] = sw
 
 # Without the sembuilder
 #def sw(ir, instr, reg_src, deref_reg_or_imm, deref_reg=None):
@@ -108,55 +122,70 @@ def sw(reg_src, deref_dst):
 #    return [ExprAssign(dst, reg_src)], []
 
 
-@sbuild.parse
-def lb(reg_dst, deref_dst):
+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)
-    reg_dst = mem8[deref_dst.ptr].signExtend(32)
+    e = []
+    e.append(ExprAssign(reg_dst, ExprMem(deref_dst.ptr, 8).signExtend(32)))
+    return e, []
 
+manual_functions["lb"] = lb
 
-@sbuild.parse
-def lh(reg_dst, deref_dst):
+
+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))
-    reg_dst = mem16[deref_dst.ptr & i32(0xFFFFFFFE)].signExtend(32)
+    e = []
+    e.append(ExprAssign(reg_dst, ExprMem(deref_dst.ptr & i32(0xFFFFFFFE), 16).signExtend(32)))
+    return e, []
 
+manual_functions["lh"] = lh
 
-@sbuild.parse
-def lw(reg_dst, deref_dst):
+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))
-    reg_dst = mem32[deref_dst.ptr & i32(0xFFFFFFFC)]
+    e = []
+    e.append(ExprAssign(reg_dst, ExprMem(deref_dst.ptr & i32(0xFFFFFFFC), 32)))
+    return e, []
 
+manual_functions["lw"] = lw
 
-@sbuild.parse
-def lbu(reg_dst, deref_dst):
+
+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))
-    reg_dst = mem8[deref_dst.ptr].zeroExtend(32)
+    e = []
+    e.append(ExprAssign(reg_dst, ExprMem(deref_dst.ptr, 8).zeroExtend(32)))
+    return e, []
 
+manual_functions["lbu"] = lbu
 
-@sbuild.parse
-def lhu(reg_dst, deref_dst):
+
+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))
-    reg_dst = mem16[deref_dst.ptr & i32(0xFFFFFFFE)].zeroExtend(32)
+    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
@@ -763,47 +792,62 @@ manual_functions["ldcb"] = mep_nop_2_args
 
 ### Bit manipulation instruction option
 
-@sbuild.parse
-def bsetm(rm_deref, imm3):
+def bsetm(ir, instr, rm_deref, imm3):
     """BSETM - Bit Set Memory"""
 
     # MemByte(Rm) <- MemByte(Rm) or (1<<imm3)
-    mem8[rm_deref.ptr] = ExprOp("|", mem8[rm_deref.ptr], (i8(1) << imm3[:8]))
+    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
 
-@sbuild.parse
-def bclrm(rm_deref, imm3):
+
+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])
-    mem8[rm_deref.ptr] = ExprOp("&", mem8[rm_deref.ptr], shift.__invert__())
+    e.append(ExprAssign(ExprMem(rm_deref.ptr, 8), ExprOp("&", ExprMem(rm_deref.ptr, 8), shift.__invert__())))
+    return e, []
 
+manual_functions["bclrm"] = bclrm
 
-@sbuild.parse
-def bnotm(rm_deref, imm3):
+
+def bnotm(ir, instr, rm_deref, imm3):
     """BNOTM - Bit Not Memory"""
 
     # MemByte(Rm) <- MemByte(Rm) xor (1<<imm3)
-    mem8[rm_deref.ptr] = ExprOp("^", mem8[rm_deref.ptr], (i8(1) << imm3[:8]))
+    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
 
-@sbuild.parse
-def btstm(r0, rm_deref, imm3):
+
+def btstm(ir, instr, r0, rm_deref, imm3):
     """BTSTM - Bit Test Memory"""
 
     # R0 <- ZeroExt( MemByte(Rm) and (1<<imm3) )
-    r0 = ExprOp("&", mem8[rm_deref.ptr], i8(1) << imm3[:8]).zeroExtend(32)
+    e = []
+    e.append(ExprAssign(r0, ExprOp("&", ExprMem(rm_deref.ptr, 8), i8(1) << imm3[:8]).zeroExtend(32)))
+    return e, []
 
+manual_functions["btstm"] = btstm
 
-@sbuild.parse
-def tas(rn, rm_deref):
+
+def tas(ir, instr, rn, rm_deref):
     """TAS - Load And Set"""
 
     # temp <- Rm; Rn <- ZeroExt(MemByte(temp)); MemByte(temp) <- 1
+    e = []
     temp = rm_deref
-    rn = mem8[temp.ptr].zeroExtend(32)
-    mem8[temp.ptr] = i8(1)
+    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
@@ -1072,56 +1116,73 @@ manual_functions["swcp"] = sw
 manual_functions["lwcp"] = lw
 
 
-@sbuild.parse
-def smcp(reg_src, deref_dst):
+def smcp(ir, instr, reg_src, deref_dst):
     """SMCP - Store Word to memory from a coprocessor register"""
 
     # MemDword(Rm31..3||000) <- CRn
-    mem32[deref_dst.ptr & i32(0xFFFFFFF8)] = reg_src
+    e = []
+    e.append(ExprAssign(ExprMem(deref_dst.ptr & i32(0xFFFFFFF8), 32), reg_src))
+    return e, []
 
+manual_functions["smcp"] = smcp
 
-@sbuild.parse
-def lmcp(reg_dst, deref_src):
+
+def lmcp(ir, instr, reg_dst, deref_src):
     """LMCP - Load Word from memory to a coprocessor register"""
 
     # CRn <- MemDword(Rm31..3||000)
-    reg_dst = mem32[deref_src.ptr & i32(0xFFFFFFF8)]
+    e = []
+    e.append(ExprAssign(reg_dst, ExprMem(deref_src.ptr & i32(0xFFFFFFF8), 32)))
+    return e, []
 
+manual_functions["lmcp"] = lmcp
 
-@sbuild.parse
-def swcpi(reg_src, deref_dst):
+
+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
-    mem32[deref_dst.ptr & i32(0xFFFFFFFC)] = reg_src
-    deref_dst.ptr = deref_dst.ptr + i32(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
 
-@sbuild.parse
-def lwcpi(reg_dst, deref_src):
+
+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
-    reg_dst = mem32[deref_src.ptr & i32(0xFFFFFFFC)]
-    deref_src.ptr = deref_src.ptr + i32(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
 
-@sbuild.parse
-def smcpi(reg_src, deref_dst):
+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
-    mem32[deref_dst.ptr & i32(0xFFFFFFF8)] = reg_src
-    deref_dst.ptr = deref_dst.ptr + i32(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
 
-@sbuild.parse
-def lmcpi(reg_dst, deref_src):
+
+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
-    reg_dst = mem32[deref_src.ptr & i32(0xFFFFFFFC)]
-    deref_src.ptr = deref_src.ptr + i32(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
diff --git a/miasm/arch/mips32/sem.py b/miasm/arch/mips32/sem.py
index a7e649b0..65af7a38 100644
--- a/miasm/arch/mips32/sem.py
+++ b/miasm/arch/mips32/sem.py
@@ -64,24 +64,24 @@ def l_b(arg1):
 def lbu(arg1, arg2):
     """A byte is loaded (unsigned extended) into a register @arg1 from the
     specified address @arg2."""
-    arg1 = mem8[arg2.ptr].zeroExtend(32)
+    arg1 = m2_expr.ExprMem(arg2.ptr, 8).zeroExtend(32)
 
 @sbuild.parse
 def lh(arg1, arg2):
     """A word is loaded into a register @arg1 from the
     specified address @arg2."""
-    arg1 = mem16[arg2.ptr].signExtend(32)
+    arg1 = m2_expr.ExprMem(arg2.ptr, 16).signExtend(32)
 
 @sbuild.parse
 def lhu(arg1, arg2):
     """A word is loaded (unsigned extended) into a register @arg1 from the
     specified address @arg2."""
-    arg1 = mem16[arg2.ptr].zeroExtend(32)
+    arg1 = m2_expr.ExprMem(arg2.ptr, 16).zeroExtend(32)
 
 @sbuild.parse
 def lb(arg1, arg2):
     "A byte is loaded into a register @arg1 from the specified address @arg2."
-    arg1 = mem8[arg2.ptr].signExtend(32)
+    arg1 = m2_expr.ExprMem(arg2.ptr, 8).signExtend(32)
 
 @sbuild.parse
 def ll(arg1, arg2):
@@ -212,15 +212,17 @@ def slt(arg1, arg2, arg3):
 def l_sub(arg1, arg2, arg3):
     arg1 = arg2 - arg3
 
-@sbuild.parse
 def sb(arg1, arg2):
     """The least significant byte of @arg1 is stored at the specified address
     @arg2."""
-    mem8[arg2.ptr] = arg1[:8]
+    e = []
+    e.append(m2_expr.ExprMem(arg2.ptr, 8), arg1[:8])
+    return e, []
 
-@sbuild.parse
 def sh(arg1, arg2):
-    mem16[arg2.ptr] = arg1[:16]
+    e = []
+    e.append(m2_expr.ExprMem(arg2.ptr, 16), arg1[:16])
+    return e, []
 
 @sbuild.parse
 def movn(arg1, arg2, arg3):
@@ -578,7 +580,8 @@ def tne(ir, instr, arg1, arg2):
 
 
 mnemo_func = sbuild.functions
-mnemo_func.update({
+mnemo_func.update(
+    {
         'add.d': add_d,
         'addu': addiu,
         'addi': addiu,
@@ -605,8 +608,11 @@ mnemo_func.update({
         'clz': clz,
         'teq': teq,
         'tne': tne,
-        'break': break_
-        })
+        'break': break_,
+        'sb': sb,
+        'sh': sh,
+    }
+)
 
 def get_mnemo_expr(ir, instr, *args):
     instr, extra_ir = mnemo_func[instr.name.lower()](ir, instr, *args)
diff --git a/miasm/core/sembuilder.py b/miasm/core/sembuilder.py
index 653ac46b..24470656 100644
--- a/miasm/core/sembuilder.py
+++ b/miasm/core/sembuilder.py
@@ -62,27 +62,6 @@ class MiasmTransformer(ast.NodeTransformer):
 
         return node
 
-    def visit_Subscript(self, node):
-        """memX[Y] -> ExprMem(Y, X)"""
-
-        # Recursive visit
-        node = self.generic_visit(node)
-
-        # Detect the syntax
-        if not isinstance(node.value, ast.Name):
-            return node
-        name = node.value.id
-        mem = self.parse_mem.search(name)
-        if mem is None:
-            return node
-
-        # Do replacement
-        addr = self.visit(node.slice.value)
-        call = ast.Call(func=ast.Name(id='ExprMem', ctx=ast.Load()),
-                        args=[addr, ast.Num(n=int(mem.groups()[0]))],
-                        keywords=[], starargs=None, kwargs=None)
-        return call
-
     def visit_IfExp(self, node):
         """X if Y else Z -> ExprCond(Y, X, Z)"""
         # Recursive visit
diff --git a/miasm/expression/simplifications_common.py b/miasm/expression/simplifications_common.py
index 85af9dc4..68d98c00 100644
--- a/miasm/expression/simplifications_common.py
+++ b/miasm/expression/simplifications_common.py
@@ -853,6 +853,17 @@ def simp_cc_conds(_, expr):
             ExprInt(1, expr.size)
         )
 
+    elif (expr.is_op("CC_S>=") and
+          len(expr.args) == 2 and
+          expr.args[0].is_op("FLAG_SIGN_SUB") and
+          expr.args[0].args[1].is_int(0) and
+          expr.args[1].is_int(0)):
+        expr = ExprOp(
+            TOK_INF_EQUAL_SIGNED,
+            expr.args[0].args[1],
+            expr.args[0].args[0],
+        )
+
     elif (expr.is_op("CC_S<") and
           test_cc_eq_args(
               expr,
diff --git a/test/core/sembuilder.py b/test/core/sembuilder.py
index 7c3d578e..f7cc1282 100644
--- a/test/core/sembuilder.py
+++ b/test/core/sembuilder.py
@@ -31,9 +31,9 @@ sb = SemBuilder(m2_expr.__dict__)
 def test(Arg1, Arg2, Arg3):
     "Test docstring"
     Arg1 = Arg2
-    mem32[Arg1] = Arg2
-    mem32[Arg2] = Arg3  + i32(4) - mem32[Arg1]
-    Arg3 = Arg3 if Arg2 else i32(0)
+    value1 = Arg2
+    value2 = Arg3  + i32(4) - ExprMem(Arg1, 32)
+    Arg3 = Arg3 if Arg2 + value1 else i32(0) + value2
     tmpvar = 'myop'(i32(2))
     Arg2 = ('myopsize%d' % Arg1.size)(tmpvar, Arg1)
     alias = Arg1[:24]