diff options
| -rw-r--r-- | miasm/arch/mips32/arch.py | 60 | ||||
| -rw-r--r-- | miasm/arch/mips32/regs.py | 2 | ||||
| -rw-r--r-- | miasm/arch/mips32/sem.py | 69 | ||||
| -rw-r--r-- | test/arch/mips32/arch.py | 21 |
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") ] |