about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--miasm/arch/mips32/arch.py60
-rw-r--r--miasm/arch/mips32/regs.py2
-rw-r--r--miasm/arch/mips32/sem.py69
-rw-r--r--test/arch/mips32/arch.py21
4 files changed, 147 insertions, 5 deletions
diff --git a/miasm/arch/mips32/arch.py b/miasm/arch/mips32/arch.py
index dcdfb707..0398be37 100644
--- a/miasm/arch/mips32/arch.py
+++ b/miasm/arch/mips32/arch.py
@@ -321,6 +321,26 @@ class mips32_s16imm_noarg(mips32_imm):
         self.value = v
         return True
 
+
+class mips32_s09imm_noarg(mips32_imm):
+    def decode(self, v):
+        v = v & self.lmask
+        v = cpu.sign_ext(v, 9, 32)
+        self.expr = ExprInt(v, 32)
+        return True
+
+    def encode(self):
+        if not isinstance(self.expr, ExprInt):
+            return False
+        v = int(self.expr)
+        if v & 0x80000000:
+            nv = v & ((1 << 9) - 1)
+            assert( v == cpu.sign_ext(nv, 9, 32))
+            v = nv
+        self.value = v
+        return True
+
+
 class mips32_soff_noarg(mips32_imm):
     def decode(self, v):
         v = v & self.lmask
@@ -346,6 +366,9 @@ class mips32_soff_noarg(mips32_imm):
 class mips32_s16imm(mips32_s16imm_noarg, mips32_arg):
     pass
 
+class mips32_s09imm(mips32_s09imm_noarg, mips32_arg):
+    pass
+
 class mips32_soff(mips32_soff_noarg, mips32_arg):
     pass
 
@@ -471,16 +494,22 @@ fd = cpu.bs(l=5, cls=(mips32_fltpreg,))
 
 s16imm = cpu.bs(l=16, cls=(mips32_s16imm,))
 u16imm = cpu.bs(l=16, cls=(mips32_u16imm,))
+s09imm = cpu.bs(l=9, cls=(mips32_s09imm,))
 sa = cpu.bs(l=5, cls=(mips32_u16imm,))
 base = cpu.bs(l=5, cls=(mips32_dreg_imm,))
 soff = cpu.bs(l=16, cls=(mips32_soff,))
+oper = cpu.bs(l=5, cls=(mips32_u16imm,))
 
 cpr0 = cpu.bs(l=5, cls=(mips32_imm,), fname="cpr0")
 cpr =  cpu.bs(l=3, cls=(mips32_cpr,))
 
+stype = cpu.bs(l=5, cls=(mips32_u16imm,))
+hint_pref = cpu.bs(l=5, cls=(mips32_u16imm,))
 
 s16imm_noarg = cpu.bs(l=16, cls=(mips32_s16imm_noarg,), fname="imm",
                   order=-1)
+s09imm_noarg = cpu.bs(l=9, cls=(mips32_s09imm_noarg,), fname="imm",
+                  order=-1)
 
 hint = cpu.bs(l=5, default_val="00000")
 fcc = cpu.bs(l=3, cls=(mips32_fccreg,))
@@ -703,7 +732,6 @@ mips32op("mtc0",    [cpu.bs('010000'), cpu.bs('00100'), rt, cpr0,
                      cpu.bs('00000000'), cpr])
 mips32op("mtc1",    [cpu.bs('010001'), cpu.bs('00100'), rt, fs,
                      cpu.bs('00000000000')])
-
 # XXXX TODO CFC1
 mips32op("cfc1",    [cpu.bs('010001'), cpu.bs('00010'), rt, fs,
                      cpu.bs('00000000000')])
@@ -763,3 +791,33 @@ mips32op("tlbwi",   [cpu.bs('010000'), cpu.bs('1'), cpu.bs('0'*19),
 
 mips32op("teq",     [cpu.bs('000000'), rs, rt, bs_code, cpu.bs('110100')],
          [rs, rt])
+mips32op("tne",     [cpu.bs('000000'), rs, rt, bs_code, cpu.bs('110110')],         
+         [rs, rt])
+
+mips32op("clz",     [cpu.bs('011100'), rs, rt, rd, cpu.bs('00000'), cpu.bs('100000')],
+        [rd, rs])
+mips32op("clz",     [cpu.bs('000000'), rs, cpu.bs('00000'), rd, cpu.bs('00001010000')],
+        [rd, rs])
+
+mips32op("ll",      [cpu.bs('110000'), base, rt, s16imm_noarg], [rt, base])
+mips32op("ll",      [cpu.bs('011111'), base, rt, s09imm_noarg, cpu.bs('0110110')], [rt, base])
+
+mips32op("sc",      [cpu.bs('111000'), base, rt, s16imm_noarg], [rt, base])
+mips32op("sc",      [cpu.bs('011111'), base, rt, s09imm_noarg, cpu.bs('0'), cpu.bs('100110')], [rt, base])
+
+mips32op("sync",    [cpu.bs('000000000000000000000'), stype, cpu.bs('001111')], [stype])
+
+mips32op("pref",    [cpu.bs('110011'), base, hint_pref, s16imm_noarg], [hint_pref, base])
+mips32op("pref",    [cpu.bs('011111'), base, hint_pref, s09imm_noarg, cpu.bs('0110101')], [hint_pref, base])
+
+mips32op("tlbwr",   [cpu.bs('01000010000000000000000000000110')], [])
+mips32op("tlbr",    [cpu.bs('01000010000000000000000000000001')], [])
+
+mips32op("cache",   [cpu.bs('101111'), base, oper, s16imm_noarg], [oper, base])
+mips32op("cache",   [cpu.bs('011111'), base, oper, s09imm_noarg, cpu.bs('0100101')], [oper, base])
+
+mips32op("eret",    [cpu.bs('01000010000000000000000000011000')], [])
+
+mips32op("mtlo",    [cpu.bs('000000'), rs, cpu.bs('000000000000000'), cpu.bs('010011')], [rs])
+mips32op("mthi",    [cpu.bs('000000'), rs, cpu.bs('000000000000000'), cpu.bs('010001')], [rs])
+
diff --git a/miasm/arch/mips32/regs.py b/miasm/arch/mips32/regs.py
index eee17caf..967b7458 100644
--- a/miasm/arch/mips32/regs.py
+++ b/miasm/arch/mips32/regs.py
@@ -71,7 +71,7 @@ cpr0_str[131] = "CONFIG3"
 cpr0_str[132] = "CONFIG4"
 cpr0_str[133] = "CONFIG5"
 cpr0_str[152] = "WATCHHI"
-cpr0_str[250] = "KSCRATCH0"
+cpr0_str[250] = "KSCRATCH"
 cpr0_str[251] = "KSCRATCH1"
 cpr0_str[252] = "KSCRATCH2"
 cpr0_str[253] = "KSCRATCH3"
diff --git a/miasm/arch/mips32/sem.py b/miasm/arch/mips32/sem.py
index 5032432c..9f935a5e 100644
--- a/miasm/arch/mips32/sem.py
+++ b/miasm/arch/mips32/sem.py
@@ -84,6 +84,11 @@ def lb(arg1, arg2):
     arg1 = mem8[arg2.ptr].signExtend(32)
 
 @sbuild.parse
+def ll(arg1, arg2):
+    "To load a word from memory for an atomic read-modify-write"
+    arg1 = arg2
+
+@sbuild.parse
 def beq(arg1, arg2, arg3):
     "Branches on @arg3 if the quantities of two registers @arg1, @arg2 are eq"
     dst = arg3 if ExprOp(m2_expr.TOK_EQUAL, arg1, arg2) else ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size)
@@ -140,6 +145,14 @@ def nop():
     """Do nothing"""
 
 @sbuild.parse
+def sync(arg1):
+    """Syncronize Shared Memory"""
+
+@sbuild.parse
+def pref(arg1, arg2):
+    """To move data between memory and cache"""
+
+@sbuild.parse
 def j(arg1):
     """Jump to an address @arg1"""
     PC = arg1
@@ -372,6 +385,14 @@ def tlbwi():
 def tlbp():
     "TODO XXX"
 
+@sbuild.parse
+def tlbwr():
+    "TODO XXX"
+
+@sbuild.parse
+def tlbr():
+    "TODO XXX"
+
 def ins(ir, instr, a, b, c, d):
     e = []
     pos = int(c)
@@ -488,6 +509,24 @@ def ei(arg1):
 def ehb(arg1):
     "NOP"
 
+@sbuild.parse
+def sc(arg1, arg2):
+    arg2 = arg1;
+    arg1 = ExprInt(0x1, 32)
+
+@sbuild.parse
+def mthi(arg1):
+    R_HI = arg1
+
+@sbuild.parse
+def mtlo(arg1):
+    R_LOW = arg1
+
+def clz(ir, instr, rs, rd):
+    e = []
+    e.append(ExprAssign(rd, ExprOp('cntleadzeros', rs)))
+    return e, []
+
 def teq(ir, instr, arg1, arg2):
     e = []
 
@@ -499,7 +538,7 @@ def teq(ir, instr, arg1, arg2):
     do_except.append(m2_expr.ExprAssign(exception_flags, m2_expr.ExprInt(
         EXCEPT_DIV_BY_ZERO, exception_flags.size)))
     do_except.append(m2_expr.ExprAssign(ir.IRDst, loc_next_expr))
-    blk_except = IRBlock(loc_except.index, [AssignBlock(do_except, instr)])
+    blk_except = IRBlock(loc_except, [AssignBlock(do_except, instr)])
 
     cond = arg1 - arg2
 
@@ -510,6 +549,28 @@ def teq(ir, instr, arg1, arg2):
 
     return e, [blk_except]
 
+def tne(ir, instr, arg1, arg2):
+    e = []
+
+    loc_except, loc_except_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
+    loc_next = ir.get_next_loc_key(instr)
+    loc_next_expr = m2_expr.ExprLoc(loc_next, ir.IRDst.size)
+
+    do_except = []
+    do_except.append(m2_expr.ExprAssign(exception_flags, m2_expr.ExprInt(
+        EXCEPT_DIV_BY_ZERO, exception_flags.size)))
+    do_except.append(m2_expr.ExprAssign(ir.IRDst, loc_next_expr))
+    blk_except = IRBlock(loc_except, [AssignBlock(do_except, instr)])
+
+    cond = arg1 ^ arg2
+
+
+    e = []
+    e.append(m2_expr.ExprAssign(ir.IRDst,
+                             m2_expr.ExprCond(cond, loc_next_expr, loc_except_expr)))
+
+    return e, [blk_except]
+
 
 mnemo_func = sbuild.functions
 mnemo_func.update({
@@ -536,8 +597,10 @@ mnemo_func.update({
         'subu': l_sub,
         'xor': l_xor,
         'xori': l_xor,
-        'teq': teq
-})
+        'clz': clz,
+        'teq': teq,
+        'tne': tne
+        })
 
 def get_mnemo_expr(ir, instr, *args):
     instr, extra_ir = mnemo_func[instr.name.lower()](ir, instr, *args)
diff --git a/test/arch/mips32/arch.py b/test/arch/mips32/arch.py
index e14eda8a..de6d4547 100644
--- a/test/arch/mips32/arch.py
+++ b/test/arch/mips32/arch.py
@@ -231,6 +231,27 @@ reg_tests_mips32 = [
      "45020008"),
     ("XXXXXXXX    BC1TL      FCC0, 0xB8",
      "4503002D"),
+
+    ("XXXXXXXX    CLZ        K0, K1",
+     "737AD020"),
+
+    ("XXXXXXXX    LL         A0, 0x123(A1)",
+     "C0A40123"),
+    ("XXXXXXXX    SC         A1, 0x123(A0)",
+     "E0850123"),
+
+    ("XXXXXXXX    SYNC       0x19",
+     "0000064F"),
+    ("XXXXXXXX    TLBR       ",
+     "42000001"),
+
+    ("XXXXXXXX    ERET       ",
+     "42000018"),
+
+    ("XXXXXXXX    MTHI       A0",
+     "00800011"),
+    ("XXXXXXXX    MTLO       A1",
+     "00A00013")
 ]