diff options
| author | serpilliere <devnull@localhost> | 2014-08-06 17:28:13 +0200 |
|---|---|---|
| committer | serpilliere <devnull@localhost> | 2014-08-06 17:28:13 +0200 |
| commit | 376576de29b55f10d645bb428fab793b56cf4168 (patch) | |
| tree | 6b24fe2e2e44d302a92ff74f9c1ce42a0b3b06a4 | |
| parent | 8cbb7db586badb5102d411af479e2d7ab42ce40c (diff) | |
| download | miasm-376576de29b55f10d645bb428fab793b56cf4168.tar.gz miasm-376576de29b55f10d645bb428fab793b56cf4168.zip | |
Add mips32 arch
| -rw-r--r-- | example/test_dis.py | 8 | ||||
| -rw-r--r-- | example/test_ida.py | 6 | ||||
| -rw-r--r-- | miasm2/arch/mips32/arch.py | 709 | ||||
| -rw-r--r-- | miasm2/arch/mips32/regs.py | 51 | ||||
| -rw-r--r-- | miasm2/arch/mips32/sem.py | 471 | ||||
| -rw-r--r-- | miasm2/core/cpu.py | 17 | ||||
| -rwxr-xr-x | setup.py | 1 | ||||
| -rw-r--r-- | test/arch/mips32/arch.py | 237 | ||||
| -rw-r--r-- | test/test_all.py | 1 |
9 files changed, 1501 insertions, 0 deletions
diff --git a/example/test_dis.py b/example/test_dis.py index 4400ec14..ae969a7d 100644 --- a/example/test_dis.py +++ b/example/test_dis.py @@ -120,6 +120,14 @@ elif options.machine == "msp430": from miasm2.arch.msp430.disasm import dis_msp430 as dis_engine from miasm2.arch.msp430.arch import mn_msp430 as mn from miasm2.arch.msp430.ira import ir_a_msp430 as ira +elif options.machine == "mips32b": + from miasm2.arch.mips32.disasm import dis_mips32b as dis_engine + from miasm2.arch.mips32.arch import mn_mips32b as mn + from miasm2.arch.mips32.ira import ir_a_mips32 as ira +elif options.machine == "mips32l": + from miasm2.arch.mips32.disasm import dis_mips32l as dis_engine + from miasm2.arch.mips32.arch import mn_mips32l as mn + from miasm2.arch.mips32.ira import ir_a_mips32 as ira else: raise ValueError('unknown machine') log.info('ok') diff --git a/example/test_ida.py b/example/test_ida.py index af5727d0..405696de 100644 --- a/example/test_ida.py +++ b/example/test_ida.py @@ -210,6 +210,12 @@ elif processor_name == "msp430": # TODO ARM/thumb from miasm2.arch.msp430.disasm import dis_msp430 as dis_engine from miasm2.arch.msp430.ira import ir_a_msp430 as ira +elif processor_name == "mipsl": + from miasm2.arch.mips32.disasm import dis_mips32l as dis_engine + from miasm2.arch.mips32.ira import ir_a_mips32 as ira +elif processor_name == "mipsb": + from miasm2.arch.mips32.disasm import dis_mips32b as dis_engine + from miasm2.arch.mips32.ira import ir_a_mips32 as ira else: print repr(processor_name) diff --git a/miasm2/arch/mips32/arch.py b/miasm2/arch/mips32/arch.py new file mode 100644 index 00000000..146dfc67 --- /dev/null +++ b/miasm2/arch/mips32/arch.py @@ -0,0 +1,709 @@ +#!/usr/bin/env python +#-*- coding:utf-8 -*- + +import logging +from pyparsing import * +from miasm2.expression.expression import * +from miasm2.core.cpu import * +from collections import defaultdict +from miasm2.core.bin_stream import bin_stream +import regs as regs_module +from regs import * +from pdb import pm + +log = logging.getLogger("mips32dis") +console_handler = logging.StreamHandler() +console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s")) +log.addHandler(console_handler) +log.setLevel(logging.DEBUG) + + +gpregs = reg_info(regs32_str, regs32_expr) + + + +LPARENTHESIS = Literal("(") +RPARENTHESIS = Literal(")") + +def deref2expr(s, l, t): + t = t[0] + if len(t) != 4: + raise NotImplementedError("TODO") + + return ExprMem(t[2] + t[0]) + +def deref2expr_nooff(s, l, t): + t = t[0] + if len(t) != 3: + raise NotImplementedError("TODO") + return ExprMem(t[1]) + +my_var_parser = parse_ast(ast_id2expr, ast_int2expr) +base_expr.setParseAction(my_var_parser) + + +deref_off = Group(Optional(base_expr) + LPARENTHESIS + gpregs.parser + RPARENTHESIS).setParseAction(deref2expr) +deref_nooff = Group(LPARENTHESIS + gpregs.parser + RPARENTHESIS).setParseAction(deref2expr_nooff) +deref = deref_off | deref_nooff + + +class additional_info: + def __init__(self): + self.except_on_instr = False +br_flt = ['BC1F'] + +br_0 = ['B', 'JR', 'BAL', 'JALR'] +br_1 = ['BGEZ', 'BLTZ', 'BGTZ', 'BLEZ', 'BC1T', 'BC1F'] + br_flt +br_2 = ['BEQ', 'BEQL', 'BNE'] + + +class instruction_mips32(instruction): + delayslot = 1 + + def __init__(self, *args, **kargs): + super(instruction_mips32, self).__init__(*args, **kargs) + + + @staticmethod + def arg2str(e, pos = None): + if isinstance(e, ExprId) or isinstance(e, ExprInt): + return str(e) + assert(isinstance(e, ExprMem)) + arg = e.arg + if isinstance(arg, ExprId): + return "(%s)"%arg + assert(len(arg.args) == 2 and arg.op == '+') + return "%s(%s)"%(arg.args[1], arg.args[0]) + + def dstflow(self): + if self.name == 'BREAK': + return False + if self.name.startswith('B'): + return True + if self.name in ['JAL', 'JALR', 'JR', 'J']: + return True + return False + + def get_dst_num(self): + if self.name in br_0: + i = 0 + elif self.name in br_1: + i = 1 + elif self.name in br_2: + i = 2 + else: + raise NotImplementedError("TODO %s"%self) + return i + + def dstflow2label(self, symbol_pool): + if self.name == "J": + e = self.args[0].arg + ad = (self.offset & (0xFFFFFFFF ^ ((1<< 28)-1))) + e + l = symbol_pool.getby_offset_create(ad) + self.args[0] = ExprId(l, e.size) + return + + ndx = self.get_dst_num() + e = self.args[ndx] + + if not isinstance(e, ExprInt): + return + ad = e.arg + self.offset + 4 + l = symbol_pool.getby_offset_create(ad) + s = ExprId(l, e.size) + self.args[ndx] = s + + def breakflow(self): + if self.name == 'BREAK': + return False + if self.name.startswith('B') or self.name in ['JR', 'J', 'JALR']: + return True + return False + + def is_subcall(self): + if self.name in ['JAL', 'JALR']: + return True + return False + + if self.name == 'BLX': + return True + return self.additional_info.lnk + + def getdstflow(self, symbol_pool): + if self.name in br_0: + return [self.args[0]] + elif self.name in br_1: + return [self.args[1]] + elif self.name in br_2: + return [self.args[2]] + elif self.name in ['JAL', 'JALR', 'JR', 'J']: + return [self.args[0]] + else: + raise NotImplementedError("fix mnemo %s"%self.name) + + def splitflow(self): + if self.name in ["B", 'JR', 'J']: + return False + if self.name in br_0: + return True + if self.name in br_1: + return True + if self.name in br_2: + return True + if self.name in ['JAL', 'JALR']: + return True + return False + + def get_symbol_size(self, symbol, symbol_pool): + return 32 + + def fixDstOffset(self): + ndx = self.get_dst_num() + e = self.args[ndx] + print 'FIX', ndx, e, self.offset, self.l + if self.offset is None: + raise ValueError('symbol not resolved %s' % l) + if not isinstance(e, ExprInt): + return + off = e.arg - (self.offset + self.l) + print "diff", e, hex(self.offset) + print hex(off) + if int(off % 4): + raise ValueError('strange offset! %r' % off) + self.args[ndx] = ExprInt32(off) + print 'final', self + + def get_args_expr(self): + args = [a for a in self.args] + return args + + +class mn_mips32b(cls_mn): + delayslot = 0 + name = "mips32l" + regs = regs_module + bintree = {} + num = 0 + all_mn = [] + all_mn_mode = defaultdict(list) + all_mn_name = defaultdict(list) + all_mn_inst = defaultdict(list) + pc = PC + sp = SP + instruction = instruction_mips32 + max_instruction_len = 4 + + @classmethod + def getpc(cls, attrib = None): + return PC + + @classmethod + def getsp(cls, attrib = None): + return SP + + def additional_info(self): + info = additional_info() + return info + + @classmethod + def getbits(cls, bs, start, n): + if not n: + return 0 + o = 0 + if n > bs.getlen() * 8: + raise ValueError('not enought bits %r %r' % (n, len(bs.bin) * 8)) + while n: + offset = start / 8 + n_offset = cls.endian_offset(offset) + c = cls.getbytes(bs, n_offset, 1) + if not c: + raise IOError + c = ord(c) + r = 8 - start % 8 + c &= (1 << r) - 1 + l = min(r, n) + c >>= (r - l) + o <<= l + o |= c + n -= l + start += l + return o + + @classmethod + def endian_offset(cls, offset): + return offset + + @classmethod + def check_mnemo(cls, fields): + l = sum([x.l for x in fields]) + assert l == 32, "len %r" % l + + @classmethod + def getmn(cls, name): + return name.upper() + + @classmethod + def gen_modes(cls, subcls, name, bases, dct, fields): + dct['mode'] = None + return [(subcls, name, bases, dct, fields)] + + def value(self, mode): + v = super(mn_mips32b, self).value(mode) + return [x for x in v] + + + + +class mn_mips32l(mn_mips32b): + delayslot = 0 + name = "mips32b" + regs = regs_module + bintree = {} + num = 0 + all_mn = [] + all_mn_mode = defaultdict(list) + all_mn_name = defaultdict(list) + all_mn_inst = defaultdict(list) + pc = PC + sp = SP + instruction = instruction_mips32 + max_instruction_len = 4 + + @classmethod + def endian_offset(cls, offset): + return (offset & ~3) + 3 - offset % 4 + + def value(self, mode): + v = super(mn_mips32b, self).value(mode) + return [x[::-1] for x in v] + + +def mips32op(name, fields, args=None, alias=False): + dct = {"fields": fields} + dct["alias"] = alias + if args is not None: + dct['args'] = args + type(name, (mn_mips32l,), dct) + type(name, (mn_mips32b,), dct) + + +class mips32_reg(reg_noarg, m_arg): + pass + +class mips32_gpreg(mips32_reg): + reg_info = gpregs + parser = reg_info.parser + +class mips32_fltpreg(mips32_reg): + reg_info = fltregs + parser = reg_info.parser + + +class mips32_fccreg(mips32_reg): + reg_info = fccregs + parser = reg_info.parser + +class mips32_imm(imm_noarg): + parser = base_expr + + +class mips32_s16imm_noarg(mips32_imm): + def decode(self, v): + v = v & self.lmask + v = sign_ext(v, 16, 32) + self.expr = ExprInt32(v) + return True + + def encode(self): + if not isinstance(self.expr, ExprInt): + return False + v = self.expr.arg.arg + if v & 0x80000000: + nv = v & ((1 << 16) - 1) + assert( v == sign_ext(nv, 16, 32)) + v = nv + self.value = v + return True + +class mips32_soff_noarg(mips32_imm): + def decode(self, v): + v = v & self.lmask + v <<= 2 + v = sign_ext(v, 16+2, 32) + self.expr = ExprInt32(v) + return True + + def encode(self): + if not isinstance(self.expr, ExprInt): + return False + v = self.expr.arg.arg + if v & 0x80000000: + nv = v & ((1 << 16+2) - 1) + assert( v == sign_ext(nv, 16+2, 32)) + v = nv + self.value = v>>2 + return True + + +class mips32_s16imm(mips32_s16imm_noarg, m_arg): + pass + +class mips32_soff(mips32_soff_noarg, m_arg): + pass + + +class mips32_instr_index(mips32_imm, m_arg): + def decode(self, v): + v = v & self.lmask + self.expr = ExprInt32(v<<2) + return True + + def encode(self): + if not isinstance(self.expr, ExprInt): + return False + v = self.expr.arg.arg + if v & 3: + return False + v>>=2 + if v > (1<<self.l): + return False + self.value = v + return True + + +class mips32_u16imm(mips32_imm, m_arg): + def decode(self, v): + v = v & self.lmask + self.expr = ExprInt32(v) + return True + + def encode(self): + if not isinstance(self.expr, ExprInt): + return False + v = self.expr.arg.arg + assert(v < (1<<16)) + self.value = v + return True + +class mips32_dreg_imm(m_arg): + parser = deref + def decode(self, v): + imm = self.parent.imm.expr + r = gpregs.expr[v] + self.expr = ExprMem(r+imm) + return True + + def encode(self): + e = self.expr + if not isinstance(e, ExprMem): + return False + arg = e.arg + if isinstance(arg, ExprId): + self.parent.imm.expr = ExprInt32(0) + r = arg + elif len(arg.args) == 2 and arg.op == "+": + self.parent.imm.expr = arg.args[1] + r = arg.args[0] + else: + return False + self.value = gpregs.expr.index(r) + return True + + @staticmethod + def arg2str(e): + assert(isinstance(e, ExprMem)) + arg = e.arg + if isinstance(arg, ExprId): + return "(%s)"%arg + assert(len(arg.args) == 2 and arg.op == '+') + return "%s(%s)"%(arg.args[1], arg.args[0]) + +class mips32_esize(mips32_imm, m_arg): + def decode(self, v): + v = v & self.lmask + self.expr = ExprInt32(v+1) + return True + + def encode(self): + if not isinstance(self.expr, ExprInt): + return False + v = self.expr.arg.arg -1 + assert(v < (1<<16)) + self.value = v + return True + +class mips32_eposh(mips32_imm, m_arg): + def decode(self, v): + self.expr = ExprInt32(v-int(self.parent.epos.expr.arg)+1) + return True + + def encode(self): + if not isinstance(self.expr, ExprInt): + return False + v = int(self.expr.arg) + int(self.parent.epos.expr.arg) -1 + self.value = v + return True + + +class mips32_imm(mips32_imm): + pass + + +class mips32_cpr(m_arg): + parser = regs_cpr0_info.parser + def decode(self, v): + index = int(self.parent.cpr0.expr.arg) << 3 + index += v + self.expr = regs_cpr0_expr[index] + return True + def encode(self): + e = self.expr + if not e in regs_cpr0_expr: + return False + index = regs_cpr0_expr.index(e) + self.value = index & 7 + index >>=2 + self.parent.cpr0.value = index + return True + +rs = bs(l=5, cls=(mips32_gpreg,)) +rt = bs(l=5, cls=(mips32_gpreg,)) +rd = bs(l=5, cls=(mips32_gpreg,)) +ft = bs(l=5, cls=(mips32_fltpreg,)) +fs = bs(l=5, cls=(mips32_fltpreg,)) +fd = bs(l=5, cls=(mips32_fltpreg,)) + +s16imm = bs(l=16, cls=(mips32_s16imm,)) +u16imm = bs(l=16, cls=(mips32_u16imm,)) +sa = bs(l=5, cls=(mips32_u16imm,)) +base = bs(l=5, cls=(mips32_dreg_imm,)) +soff = bs(l=16, cls=(mips32_soff,)) + +cpr0 = bs(l=5, cls=(mips32_imm,), fname="cpr0") +cpr = bs(l=3, cls=(mips32_cpr,)) + + +s16imm_noarg = bs(l=16, cls=(mips32_s16imm_noarg,), fname="imm", + order=-1) + +hint = bs(l=5, default_val="00000") +fcc = bs(l=3, cls=(mips32_fccreg,)) + +sel = bs(l=3, cls=(mips32_u16imm,)) + +code = bs(l=20, cls=(mips32_u16imm,)) + +esize = bs(l=5, cls=(mips32_esize,)) +epos = bs(l=5, cls=(mips32_u16imm,), fname="epos", + order=-1) + +eposh = bs(l=5, cls=(mips32_eposh,)) + +instr_index = bs(l=26, cls=(mips32_instr_index,)) +bs_fmt = bs_mod_name(l=5, fname='fmt', mn_mod={0x10: '.S', 0x11: '.D', 0x14: '.W', + 0x15: '.L', 0x16: '.PS'}) +class bs_cond(bs_mod_name): + mn_mod = ['.F', '.UN', '.EQ', '.UEQ', + '.OLT', '.ULT', '.OLE', '.ULE', + '.SF', '.NGLE', '.SEQ', '.NGL', + '.LT', '.NGE', '.LE', '.NGT' + ] + + def modname(self, name, f_i): + fds + return name + self.args['mn_mod'][f_i] + + +class bs_cond_name(bs_divert): + prio = 2 + mn_mod = [['.F', '.UN', '.EQ', '.UEQ', + '.OLT', '.ULT', '.OLE', '.ULE'], + ['.SF', '.NGLE', '.SEQ', '.NGL', + '.LT', '.NGE', '.LE', '.NGT'] + ] + + def divert(self, i, candidates): + out = [] + for candidate in candidates: + cls, name, bases, dct, fields = candidate + cond1 = [f for f in fields if f.fname == "cond1"] + assert(len(cond1) == 1) + cond1 = cond1.pop() + mm = self.mn_mod[cond1.value] + for value, new_name in enumerate(mm): + nfields = fields[:] + s = int2bin(value, self.args['l']) + args = dict(self.args) + args.update({'strbits': s}) + f = bs(**args) + nfields[i] = f + ndct = dict(dct) + ndct['name'] = name + new_name + out.append((cls, new_name, bases, ndct, nfields)) + return out + + + +class bs_cond_mod(bs_mod_name): + prio = 1 + +bs_cond = bs_cond_mod(l=4, + mn_mod = ['.F', '.UN', '.EQ', '.UEQ', + '.OLT', '.ULT', '.OLE', '.ULE', + '.SF', '.NGLE', '.SEQ', '.NGL', + '.LT', '.NGE', '.LE', '.NGT']) + + + +bs_arith = bs_name(l=6, name={'ADDU':0b100001, + 'SUBU':0b100011, + 'OR':0b100101, + 'AND':0b100100, + 'SLTU':0b101011, + 'XOR':0b100110, + 'SLT':0b101010, + 'SUBU':0b100011, + 'NOR':0b100111, + 'MOVN':0b001011, + }) + +bs_shift = bs_name(l=6, name={'SLL':0b000000, + 'SRL':0b000010, + 'SRA':0b000011, + }) + +bs_shift1 = bs_name(l=6, name={'SLLV':0b000100, + 'SRLV':0b000110, + 'SRAV':0b000111, + }) + + +bs_arithfmt = bs_name(l=6, name={'ADD':0b000000, + 'SUB':0b000001, + 'MUL':0b000010, + 'DIV':0b000011, + }) + +bs_s_l = bs_name(l=6, name = {"SW": 0b101011, + "SH": 0b101001, + "SB": 0b101000, + "LW": 0b100011, + "LH": 0b100001, + "LB": 0b100000, + "LHU": 0b100101, + "LBU": 0b100100, + "LWL": 0b100010, + "LWR": 0b100110, + + "SWL": 0b101010, + "SWR": 0b101110, + }) + + +bs_oax = bs_name(l=6, name = {"ORI": 0b001101, + "ANDI": 0b001100, + "XORI": 0b001110, + }) + +bs_bcc = bs_name(l=5, name = {"BGEZ": 0b00001, + "BGEZL": 0b00011, + "BGEZAL": 0b10001, + "BGEZALL": 0b10011, + "BLTZ": 0b00000, + "BLTZL": 0b00010, + "BLTZAL": 0b10000, + "BLTZALL": 0b10010, + }) + + + +mips32op("addiu", [bs('001001'), rs, rt, s16imm], [rt, rs, s16imm]) +mips32op("nop", [bs('0'*32)], alias = True) +mips32op("lui", [bs('001111'), bs('00000'), rt, u16imm]) +mips32op("oax", [bs_oax, rs, rt, u16imm], [rt, rs, u16imm]) + +mips32op("arith", [bs('000000'), rs, rt, rd, bs('00000'), bs_arith], [rd, rs, rt]) +mips32op("shift1", [bs('000000'), rs, rt, rd, bs('00000'), bs_shift1], [rd, rt, rs]) + +mips32op("shift", [bs('000000'), bs('00000'), rt, rd, sa, bs_shift], [rd, rt, sa]) + +mips32op("rotr", [bs('000000'), bs('00001'), rt, rd, sa, bs('000010')], [rd, rt, sa]) + +mips32op("mul", [bs('011100'), rs, rt, rd, bs('00000'), bs('000010')], [rd, rs, rt]) +mips32op("div", [bs('000000'), rs, rt, bs('0000000000'), bs('011010')]) + +mips32op("s_l", [bs_s_l, base, rt, s16imm_noarg], [rt, base]) + +#mips32op("mfc0", [bs('010000'), bs('00000'), rt, rd, bs('00000000'), sel]) +mips32op("mfc0", [bs('010000'), bs('00000'), rt, cpr0, bs('00000000'), cpr]) +mips32op("mfc1", [bs('010001'), bs('00000'), rt, fs, bs('00000000000')]) + +mips32op("mov", [bs('010001'), bs_fmt, bs('00000'), fs, fd, bs('000110')], [fd, fs]) + +mips32op("add", [bs('010001'), bs_fmt, ft, fs, fd, bs_arithfmt], [fd, fs, ft]) + +mips32op("divu", [bs('000000'), rs, rt, bs('0000000000'), bs('011011')]) +mips32op("mult", [bs('000000'), rs, rt, bs('0000000000'), bs('011000')]) +mips32op("multu", [bs('000000'), rs, rt, bs('0000000000'), bs('011001')]) +mips32op("mflo", [bs('000000'), bs('0000000000'), rd, bs('00000'), bs('010010')]) +mips32op("mfhi", [bs('000000'), bs('0000000000'), rd, bs('00000'), bs('010000')]) + + +mips32op("b", [bs('000100'), bs('00000'), bs('00000'), soff], alias = True) +mips32op("bne", [bs('000101'), rs, rt, soff]) +mips32op("beq", [bs('000100'), rs, rt, soff]) + +mips32op("blez", [bs('000110'), rs, bs('00000'), soff]) + +mips32op("bcc", [bs('000001'), rs, bs_bcc, soff]) + +mips32op("bgtz", [bs('000111'), rs, bs('00000'), soff]) +mips32op("bal", [bs('000001'), bs('00000'), bs('10001'), soff], alias = True) + + +mips32op("slti", [bs('001010'), rs, rt, s16imm], [rt, rs, s16imm]) +mips32op("sltiu", [bs('001011'), rs, rt, s16imm], [rt, rs, s16imm]) + + +mips32op("j", [bs('000010'), instr_index]) +mips32op("jalr", [bs('000000'), rs, bs('00000'), rd, hint, bs('001001')]) +mips32op("jr", [bs('000000'), rs, bs('0000000000'), hint, bs('001000')]) + +mips32op("lwc1", [bs('110001'), base, ft, s16imm_noarg], [ft, base]) + +#mips32op("mtc0", [bs('010000'), bs('00100'), rt, rd, bs('00000000'), sel]) +mips32op("mtc0", [bs('010000'), bs('00100'), rt, cpr0, bs('00000000'), cpr]) +mips32op("mtc1", [bs('010001'), bs('00100'), rt, fs, bs('00000000000')]) + +# XXXX TODO CFC1 +mips32op("cfc1", [bs('010001'), bs('00010'), rt, fs, bs('00000000000')]) +# XXXX TODO CTC1 +mips32op("ctc1", [bs('010001'), bs('00110'), rt, fs, bs('00000000000')]) + +mips32op("break", [bs('000000'), code, bs('001101')]) +mips32op("syscall", [bs('000000'), code, bs('001100')]) + + +mips32op("c", [bs('010001'), bs_fmt, ft, fs, fcc, bs('0'), bs('0'), bs('11'), bs_cond], [fcc, fs, ft]) + + +mips32op("bc1t", [bs('010001'), bs('01000'), fcc, bs('0'), bs('1'), soff]) +mips32op("bc1f", [bs('010001'), bs('01000'), fcc, bs('0'), bs('0'), soff]) + +mips32op("swc1", [bs('111001'), base, ft, s16imm_noarg], [ft, base]) + +mips32op("cvt.d", [bs('010001'), bs_fmt, bs('00000'), fs, fd, bs('100001')], [fd, fs]) +mips32op("cvt.w", [bs('010001'), bs_fmt, bs('00000'), fs, fd, bs('100100')], [fd, fs]) +mips32op("cvt.s", [bs('010001'), bs_fmt, bs('00000'), fs, fd, bs('100000')], [fd, fs]) + +mips32op("ext", [bs('011111'), rs, rt, esize, epos, bs('000000')], [rt, rs, epos, esize]) +mips32op("ins", [bs('011111'), rs, rt, eposh, epos, bs('000100')], [rt, rs, epos, eposh]) + +mips32op("seb", [bs('011111'), bs('00000'), rt, rd, bs('10000'), bs('100000')], [rd, rt]) +mips32op("wsbh", [bs('011111'), bs('00000'), rt, rd, bs('00010'), bs('100000')], [rd, rt]) + +mips32op("di", [bs('010000'), bs('01011'), rt, bs('01100'), bs('00000'), bs('0'), bs('00'), bs('000')]) + + +mips32op("tlbp", [bs('010000'), bs('1'), bs('0'*19), bs('001000')]) +mips32op("tlbwi", [bs('010000'), bs('1'), bs('0'*19), bs('000010')]) diff --git a/miasm2/arch/mips32/regs.py b/miasm2/arch/mips32/regs.py new file mode 100644 index 00000000..2667f482 --- /dev/null +++ b/miasm2/arch/mips32/regs.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python +#-*- coding:utf-8 -*- + +from miasm2.expression.expression import * +from miasm2.core.cpu import gen_reg, gen_regs + +gen_reg('PC', globals()) + +gen_reg('R_LO', globals()) +gen_reg('R_HI', globals()) + +regs32_str = ["ZERO", 'AT', 'V0', 'V1'] +\ + ['A%d'%i for i in xrange(4)] +\ + ['T%d'%i for i in xrange(8)] +\ + ['S%d'%i for i in xrange(8)] +\ + ['T%d'%i for i in xrange(8, 10)] +\ + ['K0', 'K1'] +\ + ['GP', 'SP', 'FP', 'RA'] + +regs32_expr = [ExprId(x, 32) for x in regs32_str] + +regs_flt_str = ['F%d'%i for i in xrange(0x20)] + +regs_fcc_str = ['FCC%d'%i for i in xrange(8)] + + +cpr0_str = ["CPR0_%d"%x for x in xrange(0x100)] +cpr0_str[0] = "INDEX" +cpr0_str[16] = "ENTRYLO0" +cpr0_str[24] = "ENTRYLO1" +cpr0_str[40] = "PAGEMASK" +cpr0_str[72] = "COUNT" +cpr0_str[80] = "ENTRYHI" +cpr0_str[104] = "CAUSE" +cpr0_str[128] = "CONFIG" +cpr0_str[152] = "WATCHHI" + +regs_cpr0_expr, regs_cpr0_init, regs_cpr0_info = gen_regs(cpr0_str, globals()) + +gpregs_expr, gpregs_init, gpregs = gen_regs(regs32_str, globals()) +regs_flt_expr, regs_flt_init, fltregs = gen_regs(regs_flt_str, globals()) +regs_fcc_expr, regs_fcc_init, fccregs = gen_regs(regs_fcc_str, globals()) + + +all_regs_ids = gpregs_expr + regs_flt_expr + regs_fcc_expr +all_regs_ids_byname = dict([(x.name, x) for x in all_regs_ids]) +all_regs_ids_init = gpregs_init + regs_flt_init + regs_fcc_init + +regs_init = {} +for i, r in enumerate(all_regs_ids): + regs_init[r] = all_regs_ids_init[i] diff --git a/miasm2/arch/mips32/sem.py b/miasm2/arch/mips32/sem.py new file mode 100644 index 00000000..1913a117 --- /dev/null +++ b/miasm2/arch/mips32/sem.py @@ -0,0 +1,471 @@ +from miasm2.expression.expression import * +from miasm2.ir.ir import ir, irbloc +from miasm2.arch.mips32.arch import mn_mips32l, mn_mips32b +from miasm2.arch.mips32.regs import * + +def addiu(ir, instr, a, b, c): + e = [] + e.append(ExprAff(a, b+c)) + return None, e, [] + +def lw(ir, instr, a, b): + e = [] + e.append(ExprAff(a, b)) + return None, e, [] + +def sw(ir, instr, a, b): + e = [] + e.append(ExprAff(b, a)) + return None, e, [] + +def jalr(ir, instr, a, b): + e = [] + n = ExprId(ir.get_next_break_label(instr)) + e.append(ExprAff(PC, a)) + e.append(ExprAff(b, n)) + return a, e, [] + +def bal(ir, instr, a): + e = [] + n = ExprId(ir.get_next_break_label(instr)) + e.append(ExprAff(PC, a)) + e.append(ExprAff(RA, n)) + return a, e, [] + +def l_b(ir, instr, a): + e = [] + e.append(ExprAff(PC, a)) + return a, e, [] + +def lbu(ir, instr, a, b): + e = [] + b = ExprMem(b.arg, 8) + e.append(ExprAff(a, b.zeroExtend(32))) + return None, e, [] + +def lhu(ir, instr, a, b): + e = [] + b = ExprMem(b.arg, 16) + e.append(ExprAff(a, b.zeroExtend(32))) + return None, e, [] + +def beq(ir, instr, a, b, c): + e = [] + n = ExprId(ir.get_next_break_label(instr)) + dst_o = ExprCond(a-b, c, n) + e = [ExprAff(PC, dst_o)] + return dst_o, e, [] + +def bgez(ir, instr, a, b): + e = [] + n = ExprId(ir.get_next_break_label(instr)) + dst_o = ExprCond(a.msb(), n, b) + e = [ExprAff(PC, dst_o)] + return dst_o, e, [] + +def bne(ir, instr, a, b, c): + e = [] + n = ExprId(ir.get_next_break_label(instr)) + dst_o = ExprCond(a-b, n, c) + e = [ExprAff(PC, dst_o)] + return dst_o, e, [] + +def lui(ir, instr, a, b): + e = [] + e.append(ExprAff(a, ExprCompose([(ExprInt16(0), 0, 16), + (b[:16], 16, 32)]))) + return None, e, [] + +def nop(ir, instr): + return None, [], [] + +def j(ir, instr, a): + e = [] + e.append(ExprAff(PC, a)) + return a, e, [] + +def l_or(ir, instr, a, b, c): + e = [] + e.append(ExprAff(a, b|c)) + return None, e, [] + +def nor(ir, instr, a, b, c): + e = [] + e.append(ExprAff(a, (b|c)^ExprInt32(0xFFFFFFFF))) + return None, e, [] + +def l_and(ir, instr, a, b, c): + e = [] + e.append(ExprAff(a, b&c)) + return None, e, [] + +def ext(ir, instr, a, b, c, d): + e = [] + pos = int(c.arg) + size = int(d.arg) + e.append(ExprAff(a, b[pos:pos+size].zeroExtend(32))) + return None, e, [] + +def mul(ir, instr, a, b, c): + e = [] + e.append(ExprAff(a, ExprOp('imul', b, c))) + return None, e, [] + +def sltu(ir, instr, a, b, c): + e = [] + e.append(ExprAff(a, (b-c).msb().zeroExtend(32))) + return None, e, [] + +def slt(ir, instr, a, b, c): + e = [] + #nf - of + # TODO CHECK + f = (b-c).msb() ^ (((a ^ c) & (~(a ^ b)))).msb() + e.append(ExprAff(a, f.zeroExtend(32))) + return None, e, [] + +def l_sub(ir, instr, a, b, c): + e = [] + e.append(ExprAff(a, b-c)) + return None, e, [] + +def sb(ir, instr, a, b): + e = [] + b = ExprMem(b.arg, 8) + e.append(ExprAff(b, a[:8])) + return None, e, [] + +def sh(ir, instr, a, b): + e = [] + b = ExprMem(b.arg, 16) + e.append(ExprAff(b, a[:16])) + return None, e, [] + +def movn(ir, instr, a, b, c): + lbl_do = ExprId(ir.gen_label(), instr.mode) + lbl_skip = ExprId(ir.get_next_label(instr), instr.mode) + e_do = [] + e_do.append(ExprAff(a, b)) + + return ExprCond(c, lbl_do, lbl_skip), [], [irbloc(lbl_do.name, lbl_skip, [e_do])] + +def srl(ir, instr, a, b, c): + e = [] + e.append(ExprAff(a, b >> c)) + return None, e, [] + +def sra(ir, instr, a, b, c): + e = [] + e.append(ExprAff(a, ExprOp('a>>', b, c))) + return None, e, [] + +def srav(ir, instr, a, b, c): + e = [] + e.append(ExprAff(a, ExprOp('a>>', b, c&ExprInt32(0x1F)))) + return None, e, [] + +def sll(ir, instr, a, b, c): + e = [] + e.append(ExprAff(a, b<<c)) + return None, e, [] + +def srlv(ir, instr, a, b, c): + e = [] + e.append(ExprAff(a, b >> (c & ExprInt32(0x1F)))) + return None, e, [] + +def sllv(ir, instr, a, b, c): + e = [] + e.append(ExprAff(a, b << (c & ExprInt32(0x1F)))) + return None, e, [] + +def l_xor(ir, instr, a, b, c): + e = [] + e.append(ExprAff(a, b^c)) + return None, e, [] + +def seb(ir, instr, a, b): + e = [] + e.append(ExprAff(a, b[:8].signExtend(32))) + return None, e, [] + +def bltz(ir, instr, a, b): + e = [] + n = ExprId(ir.get_next_break_label(instr)) + dst_o = ExprCond(a.msb(), b, n) + e = [ExprAff(PC, dst_o)] + return dst_o, e, [] + +def blez(ir, instr, a, b): + e = [] + n = ExprId(ir.get_next_break_label(instr)) + cond = ExprCond(a, ExprInt1(1), ExprInt1(0)) | a.msb() + dst_o = ExprCond(cond, b, n) + e = [ExprAff(PC, dst_o)] + return dst_o, e, [] + +def bgtz(ir, instr, a, b): + e = [] + n = ExprId(ir.get_next_break_label(instr)) + cond = ExprCond(a, ExprInt1(1), ExprInt1(0)) | a.msb() + dst_o = ExprCond(cond, n, b) + e = [ExprAff(PC, dst_o)] + return dst_o, e, [] + +def wsbh(ir, instr, a, b): + e = [ExprAff(a, ExprCompose([(b[8:16], 0, 8) , + (b[0:8] , 8, 16) , + (b[24:32], 16, 24), + (b[16:24], 24, 32)]))] + return None, e, [] + +def rotr(ir, instr, a, b, c): + e = [] + e.append(ExprAff(a, ExprOp('>>>', b, c))) + return None, e, [] + +def add_d(ir, instr, a, b, c): + # XXX TODO check + e = [] + e.append(ExprAff(a, ExprOp('fadd', b, c))) + return None, e, [] + +def sub_d(ir, instr, a, b, c): + # XXX TODO check + e = [] + e.append(ExprAff(a, ExprOp('fsub', b, c))) + return None, e, [] + +def div_d(ir, instr, a, b, c): + # XXX TODO check + e = [] + e.append(ExprAff(a, ExprOp('fdiv', b, c))) + return None, e, [] + +def mul_d(ir, instr, a, b, c): + # XXX TODO check + e = [] + e.append(ExprAff(a, ExprOp('fmul', b, c))) + return None, e, [] + +def mov_d(ir, instr, a, b): + # XXX TODO check + e = [] + e.append(ExprAff(a, b)) + return None, e, [] + +def mfc0(ir, instr, a, b): + e = [] + e.append(ExprAff(a, b)) + return None, e, [] + +def mfc1(ir, instr, a, b): + e = [] + e.append(ExprAff(a, b)) + return None, e, [] + +def mtc0(ir, instr, a, b): + e = [] + e.append(ExprAff(b, a)) + return None, e, [] + +def mtc1(ir, instr, a, b): + e = [] + e.append(ExprAff(b, a)) + return None, e, [] + +def tlbwi(ir, instr): + # TODO XXX + e = [] + return None, e, [] + +def tlbp(ir, instr): + # TODO XXX + e = [] + return None, e, [] + +def ins(ir, instr, a, b, c, d): + e = [] + pos = int(c.arg) + l = int(d.arg) + + my_slices = [] + if pos != 0: + my_slices.append((a[:pos], 0, pos)) + if l != 0: + my_slices.append((b[:l], pos, pos+l)) + if pos + l != 32: + my_slices.append((a[pos+l:], pos+l, 32)) + r = ExprCompose(my_slices) + e.append(ExprAff(a, r)) + return None, e, [] + + +def lwc1(ir, instr, a, b): + e = [] + src = ExprOp('mem_%.2d_to_single' % b.size, b) + e.append(ExprAff(a, src)) + return None, e, [] + +def swc1(ir, instr, a, b): + e = [] + src = ExprOp('single_to_mem_%.2d' % a.size, a) + e.append(ExprAff(b, src)) + return None, e, [] + +def c_lt_d(ir, instr, a, b, c): + e = [] + e.append(ExprAff(a, ExprOp('fcomp_lt', b, c))) + return None, e, [] + +def c_eq_d(ir, instr, a, b, c): + e = [] + e.append(ExprAff(a, ExprOp('fcomp_eq', b, c))) + return None, e, [] + +def c_le_d(ir, instr, a, b, c): + e = [] + e.append(ExprAff(a, ExprOp('fcomp_le', b, c))) + return None, e, [] + +def bc1t(ir, instr, a, b): + e = [] + n = ExprId(ir.get_next_break_label(instr)) + dst_o = ExprCond(a, b, n) + e = [ExprAff(PC, dst_o)] + return dst_o, e, [] + +def bc1f(ir, instr, a, b): + e = [] + n = ExprId(ir.get_next_break_label(instr)) + dst_o = ExprCond(a, n, b) + e = [ExprAff(PC, dst_o)] + return dst_o, e, [] + +def cvt_d_w(ir, instr, a, b): + e = [] + # TODO XXX + e.append(ExprAff(a, ExprOp('flt_d_w', b))) + return None, e, [] + +def mult(ir, instr, a, b): + e = [] + size = a.size + r = a.signExtend(size * 2) * b.signExtend(size * 2) + + e.append(ExprAff(R_LO, r[:32])) + e.append(ExprAff(R_HI, r[32:])) + return None, e, [] + +def mfhi(ir, instr, a): + e = [] + e.append(ExprAff(a, R_HI)) + return None, e, [] + +def mflo(ir, instr, a): + e = [] + e.append(ExprAff(a, R_LO)) + return None, e, [] + + +mnemo_func = { + "addiu": addiu, + "addu": addiu, + "lw" : lw, + "sw" : sw, + "sh" : sh, + "sb" : sb, + "jalr" : jalr, + "bal" : bal, + "b" : l_b, + "lbu" : lbu, + "lhu" : lhu, + "beq" : beq, + "bgez" : bgez, + "bltz" : bltz, + "bgtz" : bgtz, + "bne" : bne, + "lui" : lui, + "nop" : nop, + "j" : j, + "jr" : j, + "ori" : l_or, + "or" : l_or, + "nor" : nor, + "and" : l_and, + "andi" : l_and, + "ext" : ext, + "mul" : mul, + "sltu" : sltu, + "slt" : slt, + "slti" : slt, + "sltiu" : sltu, + "subu" : l_sub, + "movn" : movn, + "srl" : srl, + "sra" : sra, + "srav" : srav, + "sll" : sll, + "srlv" : srlv, + "sllv" : sllv, + "xori" : l_xor, + "xor" : l_xor, + "seb" : seb, + "bltz" : bltz, + "blez" : blez, + "wsbh" : wsbh, + "rotr" : rotr, + "mfc0" : mfc0, + "mfc1" : mfc1, + "mtc0" : mtc0, + "mtc1" : mtc1, + "tlbwi" : tlbwi, + "tlbp" : tlbp, + "ins" : ins, + + "add.d" : add_d, + "sub.d" : sub_d, + "div.d" : div_d, + "mul.d" : mul_d, + "mov.d" : mov_d, + "lwc1" : lwc1, + "swc1" : swc1, + "c.lt.d" : c_lt_d, + "c.eq.d" : c_eq_d, + "c.le.d" : c_le_d, + "bc1t" : bc1t, + "bc1f" : bc1f, + "cvt.d.w":cvt_d_w, + "mult" : mult, + + "mfhi" : mfhi, + "mflo" : mflo, + + } + +def get_mnemo_expr(ir, instr, *args): + dst, instr, extra_ir = mnemo_func[instr.name.lower()](ir, instr, *args) + return dst, instr, extra_ir + +class ir_mips32(ir): + + def __init__(self, symbol_pool=None): + ir.__init__(self, mn_mips32l, None, symbol_pool) + self.pc = mn_mips32l.getpc() + self.sp = mn_mips32l.getsp() + + def get_ir(self, instr): + args = instr.args + dst, instr_ir, extra_ir = get_mnemo_expr(self, instr, *args) + + for i, x in enumerate(instr_ir): + x = ExprAff(x.dst, x.src.replace_expr( + {self.pc: ExprInt32(instr.offset + 4)})) + instr_ir[i] = x + for b in extra_ir: + for irs in b.irs: + for i, x in enumerate(irs): + x = ExprAff(x.dst, x.src.replace_expr( + {self.pc: ExprInt32(instr.offset + 4)})) + irs[i] = x + return dst, instr_ir, extra_ir diff --git a/miasm2/core/cpu.py b/miasm2/core/cpu.py index 652ba020..42c4566d 100644 --- a/miasm2/core/cpu.py +++ b/miasm2/core/cpu.py @@ -131,6 +131,23 @@ def gen_reg(rname, env, sz=32): env["bs" + rnamel] = bs(l=0, cls=(c,)) return r, regi + +def gen_regs(rnames, env, sz=32): + regs_str = [] + regs_expr = [] + regs_init = [] + for rname in rnames: + r = ExprId(rname, sz) + r_init = ExprId(rname+'_init', sz) + regs_str.append(rname) + regs_expr.append(r) + regs_init.append(r_init) + env[rname] = r + + reginfo = reg_info(regs_str, regs_expr) + return regs_expr, regs_init, reginfo + + LPARENTHESIS = Literal("(") RPARENTHESIS = Literal(")") diff --git a/setup.py b/setup.py index 5292a849..fcc8f7a6 100755 --- a/setup.py +++ b/setup.py @@ -12,6 +12,7 @@ def buil_all(): 'miasm2/arch/arm', 'miasm2/arch/msp430', 'miasm2/arch/sh4', + 'miasm2/arch/mips32', 'miasm2/core', 'miasm2/expression', 'miasm2/ir', diff --git a/test/arch/mips32/arch.py b/test/arch/mips32/arch.py new file mode 100644 index 00000000..3bfef457 --- /dev/null +++ b/test/arch/mips32/arch.py @@ -0,0 +1,237 @@ +import os, sys +import time +from pdb import pm + +sys.path.append('/home/serpilliere/projet/m2_devel') +from miasm2.arch.mips32.arch import * + +import sys + + +filename = os.environ.get('PYTHONSTARTUP') +if filename and os.path.isfile(filename): + execfile(filename) + + +reg_tests_mips32 = [ + ("004496D8 ADDU GP, GP, T9", + "0399E021"), + ("004496DC ADDIU SP, SP, 0xFFFFFDA0", + "27BDFDA0"), + ("0449724 NOP ", + "00000000"), + ('00449734 ADDIU A0, ZERO, 0xA', + "2404000A"), + ('00400320 LUI V1, 0x7FF0', + "3C037FF0"), + ('00400350 ORI V1, V1, 0x1', + "34630001"), + ('00400304 SUBU A0, ZERO, T1', + "00092023"), + ("0040031C OR A0, A0, T2", + "008A2025"), + ("00400344 AND A1, A2, A1", + "00C52824"), + ("00400348 SRL V0, V0, 0x1F", + "000217C2"), + ("00400354 SLTU V0, V0, V1", + "0043102B"), + ("00400374 SRA V0, T3, 0x1E", + "000B1783"), + ("004002F0 SW RA, 0x1C(SP)", + "AFBF001C"), + ("XXXXXXXX SW RA, (SP)", + "AFBF0000"), + ("004002FC MFC1 T1, F14", + "44097000"), + ("00400324 MOV.D F0, F12", + "46206006"), + ("00400334 BNE A0, ZERO, 0x28", + "1480000A"), + ("00400360 B 0x338", + "100000CE"), + ("00400378 LW T9, 0xFFFF9C90(GP)", + "8F999C90"), + ("00400384 JR T9", + "03200008"), + ("0040038C ANDI V0, V0, 0x2", + "30420002"), + ("00400364 ADD.D F0, F0, F14", + "462E0000"), + ("004003A4 BEQ S0, V0, 0x120", + "12020048"), + ("004003A8 SLTI V0, S0, 0x3", + "2A020003"), + ("004005A4 BGEZ T3, 0x20", + "05610008"), + ("00400428 LWC1 F0, 0x4344(V0)", + "C4404344"), + ("004005D0 JALR T9, RA", + "0320F809"), + ("00400500 MTC1 ZERO, F0", + "44800000"), + ("004005D4 DIV.D F12, F0, F14", + "462E0303"), + ("0040062C XOR V0, A2, A0", + "00C41026"), + ("00400684 SUB.D F0, F12, F0", + "46206001"), + ("00400148 LBU V0, 0xFFFF8880(S1)", + "92228880"), + ("004001C4 SB V0, 0xFFFF8880(S1)", + "A2228880"), + ("00400274 BAL 0x4", + "04110001"), + ("0040073C C.LT.D FCC0, F0, F12", + "462C003C"), + ("00400744 BC1F FCC0, 0x20", + "45000008"), + ("00403A80 BC1T FCC0, 0xB4", + "4501002D"), + ("00400764 MUL.D F12, F0, F0", + "46200302"), + ("004007C8 SLL V1, A2, 0x3", + "000618C0"), + ("00400E28 SWC1 F26, 0x5C(SP)", + "E7BA005C"), + ("00400EA8 SLT V0, V1, S2", + "0072102A"), + ("00400F30 SUBU V0, V0, V1", + "00431023"), + ("00400F34 SRLV V1, A1, V0", + "00451806"), + ("00400F38 SLLV V0, V1, V0", + "00431004"), + ("00400F60 SRAV V1, S3, V0", + "00531807"), + ("00401040 BLTZ S6, 0x58", + "06C00016"), + ("00400D18 BLEZ V1, 0x7C", + "1860001F"), + ("00401200 BGTZ S4, 0x10", + "1E800004"), + ("004014A4 CVT.D.W F8, F0", + "46800221"), + ("00400864 CVT.W.D F0, F2", + "46201024"), + ("00401748 NOR A3, ZERO, A3", + "00073827"), + ("00403E6C BREAK 0x1C00", + "0007000D"), + ("00405744 SYSCALL 0x0", + "0000000C"), + ("004095A4 LH V0, (V0)", + "84420000"), + ("0040ACBC LB V0, 0x1(A1)", + "80A20001"), + ("00412A34 DIV A0, V1", + "0083001A"), + ("00419ED8 LWL T0, (A1)", + "88A80000"), + ("00419FA4 LWL T0, (A1)", + "88A80000"), + ("0041A024 SWL A1, (A0)", + "A8850000"), + ("0044E194 SWR V0, 0x3(A0)", + "B8820003"), + ("00433974 CVT.S.D F0, F0", + "46200020"), + + + ("0044A120 MULT V1, V0", + "00620018"), + ("00404194 MULTU A1, V1", + "00A30019"), + ("00403E68 DIVU V0, T1", + "0049001B"), + ("00403E70 MFLO T4", + "00006012"), + ("004040CC MFHI A0", + "00002010"), + + ("00401748 NOR A3, ZERO, A3", + "00073827"), + + ("8BA1025C MTC0 T0, WATCHHI", + "40889800"), + ("8BA10260 MTC0 ZERO, WATCHHI", + "40809800"), + ("8BA10264 MTC0 ZERO, CAUSE", + "40806800"), + ("8BA0FD68 MTC0 V0, ENTRYLO0", + "40821000"), + ("8BA0FD70 MTC0 V0, ENTRYLO1", + "40821800"), + ("8BA0FD78 MTC0 V0, PAGEMASK", + "40822800"), + ("8BA0FD94 MTC0 V1, ENTRYHI", + "40835000"), + + + ("8BA0FDA8 MFC0 V0, INDEX", + "40020000"), + ("8BA10268 MFC0 T0, CONFIG", + "40088000"), + ("8BA0FBD4 MFC0 V0, COUNT", + "40024800"), + ("800001F8 EXT V0, V1, 0x10, 0x3", + "7C621400 "), + + ("80000318 J 0x1E0", + "08000078"), + + ("8BA0F0C0 LHU V1, 0x20(SP)", + "97A30020"), + + ("8BA0F168 MUL V0, V1, S0", + "70701002"), + ("8BA0F288 MOVN A2, T0, V0", + "0102300B"), + + ("8BA0F32C XORI V1, V1, 0x11", + "38630011"), + ("8BA0F37C SEB S6, V0", + "7C02B420"), + ("8BA0F468 DI ZERO", + "41606000"), + ("8BA0F78C WSBH V1, V1", + "7C0318A0"), + ("8BA0F790 ROTR V1, V1, 0x10", + "00231C02"), + + ("8BA0F794 SLTIU V0, V1, 0x5", + "2C620005"), + ("8BA0FDA0 TLBP ", + "42000008"), + ("8BA0FDC0 TLBWI ", + "42000002"), + ("8BA10124 INS A0, A1, 0x0, 0x8", + "7CA43804"), + + +] + + +ts = time.time() +def h2i(s): + return s.replace(' ', '').decode('hex') + +for s, l in reg_tests_mips32: + print "-" * 80 + s = s[12:] + b = h2i((l)) + mn = mn_mips32b.dis(b) + print [str(x) for x in mn.args] + print s + print mn + assert(str(mn) == s) + # print hex(b) + # print [str(x.get()) for x in mn.args] + l = mn_mips32b.fromstring(s) + # print l + assert(str(l) == s) + a = mn_mips32b.asm(l) + print [x for x in a] + print repr(b) + # print mn.args + assert(b in a) diff --git a/test/test_all.py b/test/test_all.py index eb1e7fcd..039234db 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -29,6 +29,7 @@ all_tests = { ["arch/msp430/arch.py"], ["arch/msp430/sem.py"], ["arch/sh4/arch.py"], + ["arch/mips32/arch.py"], ], "core": [ ["core/interval.py"], |