about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorserpilliere <devnull@localhost>2014-08-06 17:28:13 +0200
committerserpilliere <devnull@localhost>2014-08-06 17:28:13 +0200
commit376576de29b55f10d645bb428fab793b56cf4168 (patch)
tree6b24fe2e2e44d302a92ff74f9c1ce42a0b3b06a4
parent8cbb7db586badb5102d411af479e2d7ab42ce40c (diff)
downloadmiasm-376576de29b55f10d645bb428fab793b56cf4168.tar.gz
miasm-376576de29b55f10d645bb428fab793b56cf4168.zip
Add mips32 arch
-rw-r--r--example/test_dis.py8
-rw-r--r--example/test_ida.py6
-rw-r--r--miasm2/arch/mips32/arch.py709
-rw-r--r--miasm2/arch/mips32/regs.py51
-rw-r--r--miasm2/arch/mips32/sem.py471
-rw-r--r--miasm2/core/cpu.py17
-rwxr-xr-xsetup.py1
-rw-r--r--test/arch/mips32/arch.py237
-rw-r--r--test/test_all.py1
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"],