diff options
Diffstat (limited to '')
| -rw-r--r-- | miasm2/arch/sh4/arch.py | 1404 |
1 files changed, 1404 insertions, 0 deletions
diff --git a/miasm2/arch/sh4/arch.py b/miasm2/arch/sh4/arch.py new file mode 100644 index 00000000..c2029000 --- /dev/null +++ b/miasm2/arch/sh4/arch.py @@ -0,0 +1,1404 @@ +#!/usr/bin/env python +#-*- coding:utf-8 -*- + +import os +from pyparsing import * +from miasm2.core.cpu import * +from miasm2.expression.expression import * +from collections import defaultdict +from regs import * + + +jra = ExprId('jra') +jrb = ExprId('jrb') +jrc = ExprId('jrc') + + +# parser helper ########### +PLUS = Suppress("+") +MULT = Suppress("*") +MINUS = Suppress("-") +AND = Suppress("&") +LBRACK = Suppress("[") +RBRACK = Suppress("]") +DEREF = Suppress("@") +COMMA = Suppress(",") +LPARENT = Suppress("(") +RPARENT = Suppress(")") + + +def parse_deref_pcimm(t): + t = t[0] + return t[0] + t[1] + + +def parse_pcandimmimm(t): + t = t[0] + return (t[0] & t[1]) + t[2] + +def ast_id2expr(a): + return ExprId(a, 32) + +def ast_int2expr(a): + return ExprInt32(a) + + +my_var_parser = parse_ast(ast_id2expr, ast_int2expr) +base_expr.setParseAction(my_var_parser) + +int_or_expr = base_expr + +ref_pc = Group(LPARENT + regi_pc.parser + COMMA + + int_or_expr + RPARENT).setParseAction(parse_deref_pcimm) +ref_pcandimm = Group( + LPARENT + regi_pc.parser + AND + int_or_expr + + COMMA + int_or_expr + RPARENT).setParseAction(parse_pcandimmimm) + + +pcdisp = Group(regi_pc.parser + AND + int_or_expr + + PLUS + int_or_expr).setParseAction(parse_pcandimmimm) + +PTR = Suppress('PTR') + + +def parse_deref_mem(s, l, t): + t = t[0] + e = ExprMem(t[0], 32) + return e + + +def parse_predec(s, l, t): + t = t[0] + e = ExprOp('predec', t[0]) + return e + + +def parse_postinc(s, l, t): + t = t[0] + e = ExprOp('postinc', t[0]) + return e + + +def parse_regdisp(t): + t = t[0] + e = ExprMem(t[0] + t[1]) + return e + + +def parse_regreg(t): + t = t[0] + e = ExprMem(t[0] + t[1]) + return e + + +deref_pc = Group(DEREF + ref_pc).setParseAction(parse_deref_mem) +deref_pcimm = Group(DEREF + ref_pcandimm).setParseAction(parse_deref_mem) + +dgpregs_base = Group(DEREF + gpregs.parser).setParseAction(parse_deref_mem) +dgpregs_predec = Group( + DEREF + MINUS + gpregs.parser).setParseAction(parse_predec) +dgpregs_postinc = Group( + DEREF + gpregs.parser + PLUS).setParseAction(parse_postinc) + +dgpregs = dgpregs_base | dgpregs_predec | dgpregs_postinc + +d_gpreg_gpreg = Group(DEREF + + LPARENT + gpregs.parser + COMMA + gpregs.parser + RPARENT + ).setParseAction(parse_regdisp) +dgpregs_p = dgpregs_predec | dgpregs_postinc + + +dgpregs_ir = Group(DEREF + LPARENT + gpregs.parser + + COMMA + int_or_expr + RPARENT).setParseAction(parse_regdisp) +dgpregs_ir |= d_gpreg_gpreg + +dgbr_imm = Group(DEREF + LPARENT + regi_gbr.parser + + COMMA + int_or_expr + RPARENT).setParseAction(parse_regdisp) + +dgbr_reg = Group(DEREF + LPARENT + regi_gbr.parser + + COMMA + gpregs.parser + RPARENT).setParseAction(parse_regreg) + + +class sh4_reg(reg_noarg, m_arg): + pass + + +class sh4_gpreg(sh4_reg): + reg_info = gpregs + parser = reg_info.parser + + +class sh4_dr(sh4_reg): + reg_info = dregs + parser = reg_info.parser + + +class sh4_bgpreg(sh4_reg): + reg_info = bgpregs + parser = reg_info.parser + + +class sh4_gpreg_noarg(reg_noarg, ): + reg_info = gpregs + parser = reg_info.parser + + +class sh4_freg(sh4_reg): + reg_info = fregs + parser = reg_info.parser + + +class sh4_dgpreg(m_arg): + parser = dgpregs_base + + def fromstring(self, s, parser_result=None): + start, stop = super(sh4_dgpreg, self).fromstring(s, parser_result) + if start is None: + return start, stop + self.expr = ExprMem(self.expr.arg, self.sz) + return start, stop + + def decode(self, v): + r = gpregs.expr[v] + self.expr = ExprMem(r, self.sz) + return True + + def encode(self): + e = self.expr + if not isinstance(e, ExprMem): + return False + if not isinstance(e.arg, ExprId): + return False + v = gpregs.expr.index(e.arg) + self.value = v + return True + + @staticmethod + def arg2str(e): + ad = e.arg + if isinstance(ad, ExprOp): + s = ','.join([str(x).replace('(', '').replace(')', '') + for x in ad.args]) + s = "@(%s)" % s + else: + s = "@%s" % ad + return s + + +class sh4_dgpregpinc(m_arg): + parser = dgpregs_p + + def fromstring(self, s, parser_result=None): + start, stop = super(sh4_dgpregpinc, self).fromstring(s, parser_result) + if not isinstance(self.expr, ExprOp): + return None, None + if self.expr.op != self.op: + return None, None + return start, stop + + def decode(self, v): + r = gpregs.expr[v] + e = ExprOp(self.op, r, ExprInt32(self.sz)) + self.expr = e + return True + + def encode(self): + e = self.expr + res = MatchExpr(e, ExprOp(self.op, jra), [jra]) + if not res: + return False + r = res[jra] + if not r in gpregs.expr: + return False + v = gpregs.expr.index(r) + self.value = v + return True + + @staticmethod + def arg2str(e): + if e.op == "predec": + o = '-%s' % e.args[0] + elif e.op == "postinc": + o = '%s+' % e.args[0] + else: + raise ValueError('unknown e.op: %s' % e.op) + return "@%s" % o + + +class sh4_dgpregpdec(m_arg): + parser = dgpregs_postinc + op = "preinc" + + +class sh4_dgpreg_imm(sh4_dgpreg): + parser = dgpregs_ir + + def decode(self, v): + p = self.parent + r = gpregs.expr[v] + s = self.sz + d = ExprInt32(p.disp.value * s / 8) + e = ExprMem(r + d, s) + self.expr = e + return True + + def encode(self): + e = self.expr + p = self.parent + s = self.sz + if not isinstance(e, ExprMem): + return False + if isinstance(e.arg, ExprId): + v = gpregs.expr.index(e.arg) + p.disp.value = 0 + elif isinstance(e.arg, ExprOp): + res = MatchExpr(e, ExprMem(jra + jrb, self.sz), [jra, jrb]) + if not res: + return False + if not isinstance(res[jra], ExprId): + return False + if not isinstance(res[jrb], ExprInt): + return False + d = int(res[jrb].arg) + p.disp.value = d / (s / 8) + if not res[jra] in gpregs.expr: + return False + v = gpregs.expr.index(res[jra]) + else: + return False + self.value = v + return True + + +class sh4_imm(imm_noarg, m_arg): + parser = base_expr + pass + + +class sh4_simm(sh4_imm): + parser = base_expr + + def decode(self, v): + v = sign_ext(v, self.l, 32) + v = self.decodeval(v) + self.expr = ExprInt32(v) + return True + + def encode(self): + if not isinstance(self.expr, ExprInt): + return False + v = int(self.expr.arg) + if (1 << (self.l - 1)) & v: + v = -((0xffffffff ^ v) + 1) + v = self.encodeval(v) + self.value = (v & 0xffffffff) & self.lmask + return True + + +class sh4_dpc16imm(sh4_dgpreg): + parser = deref_pc + + def decode(self, v): + self.expr = ExprMem(PC + ExprInt32(v * 2 + 4), 16) + return True + + def calcdisp(self, v): + v = (int(v.arg) - 4) / 2 + if not 0 < v <= 0xff: + return None + return v + + def encode(self): + res = MatchExpr(self.expr, ExprMem(PC + jra, 16), [jra]) + if not res: + return False + if not isinstance(res[jra], ExprInt): + return False + v = self.calcdisp(res[jra]) + if v is None: + return False + self.value = v + return True + + +class sh4_dgbrimm8(sh4_dgpreg): + parser = dgbr_imm + + def decode(self, v): + s = self.sz + self.expr = ExprMem(GBR + ExprInt32(v * s / 8), s) + return True + + def encode(self): + e = self.expr + s = self.sz + if e == ExprMem(GBR): + self.value = 0 + return True + res = MatchExpr(self.expr, ExprMem(GBR + jra, s), [jra]) + if not res: + return False + if not isinstance(res[jra], ExprInt): + return False + self.value = int(res[jra].arg) / (s / 8) + return True + + +class sh4_dpc32imm(sh4_dpc16imm): + parser = deref_pcimm + + def decode(self, v): + self.expr = ExprMem( + (PC & ExprInt32(0xfffffffc)) + ExprInt32(v * 4 + 4)) + return True + + def calcdisp(self, v): + v = (int(v.arg) - 4) / 4 + if not 0 < v <= 0xff: + return None + return v + + def encode(self): + res = MatchExpr( + self.expr, ExprMem((PC & ExprInt32(0xFFFFFFFC)) + jra, 32), [jra]) + if not res: + return False + if not isinstance(res[jra], ExprInt): + return False + v = self.calcdisp(res[jra]) + if v is None: + return False + self.value = v + return True + + +class sh4_pc32imm(m_arg): + parser = pcdisp + + def decode(self, v): + self.expr = (PC & ExprInt32(0xfffffffc)) + ExprInt32(v * 4 + 4) + return True + + def encode(self): + res = MatchExpr(self.expr, (PC & ExprInt32(0xfffffffc)) + jra, [jra]) + if not res: + return False + if not isinstance(res[jra], ExprInt): + return False + v = (int(res[jra].arg) - 4) / 4 + if v is None: + return False + self.value = v + return True + + @staticmethod + def arg2str(e): + s = str(e).replace('(', '').replace(')', '') + return "%s" % s + + +class additional_info: + + def __init__(self): + self.except_on_instr = False + + +class instruction_sh4(instruction): + delayslot = 0 + + def __init__(self, *args, **kargs): + super(instruction_arm, self).__init__(*args, **kargs) + + def dstflow(self): + return self.name.startswith('J') + """ + def dstflow2label(self, symbol_pool): + e = self.args[0] + if not isinstance(e, ExprInt): + return + if self.name == 'BLX': + ad = e.arg+8+self.offset + else: + ad = e.arg+8+self.offset + l = symbol_pool.getby_offset_create(ad) + s = ExprId(l, e.size) + self.args[0] = s + """ + + def breakflow(self): + if self.name.startswith('J'): + return True + return False + + def is_subcall(self): + return self.name == 'JSR' + + def getdstflow(self, symbol_pool): + return [self.args[0]] + + def splitflow(self): + return self.name == 'JSR' + + def get_symbol_size(self, symbol, symbol_pool): + return 32 + + def fixDstOffset(self): + e = self.args[0] + print 'FIX', e, self.offset, self.l + if self.offset is None: + raise ValueError('symbol not resolved %s' % l) + if not isinstance(e, ExprInt): + log.warning('zarb dst %r' % e) + return + off = e.arg - (self.offset + 4 + self.l) + print hex(off) + if int(off % 4): + raise ValueError('strange offset! %r' % off) + self.args[0] = ExprInt32(off) + print 'final', self.args[0] + + def get_args_expr(self): + args = [a for a in self.args] + return args + + +class mn_sh4(cls_mn): + bintree = {} + num = 0 + all_mn = [] + all_mn_mode = defaultdict(list) + all_mn_name = defaultdict(list) + all_mn_inst = defaultdict(list) + pc = PC + # delayslot: + # http://resource.renesas.com/lib/eng/e_learnig/sh4/13/index.html + delayslot = 0 # unit is instruction instruction + + 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: + i = start / 8 + c = cls.getbytes(bs, i) + 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 getbytes(cls, bs, offset, l=1): + out = "" + for _ in xrange(l): + n_offset = (offset & ~1) + 1 - offset % 2 + out += bs.getbytes(n_offset, 1) + offset += 1 + return out + + @classmethod + def check_mnemo(cls, fields): + l = sum([x.l for x in fields]) + assert l == 16, "len %r" % l + + @classmethod + def getmn(cls, name): + return name.upper().replace('_', '.') + + @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_sh4, self).value(mode) + return [x[::-1] for x in v] + + +class bs_dr0gbr(sh4_dgpreg): + parser = dgbr_reg + + def decode(self, v): + self.expr = ExprMem(GBR + R0, 8) + return True + + def encode(self): + return self.expr == ExprMem(GBR + R0, 8) + + +class bs_dr0gp(sh4_dgpreg): + parser = d_gpreg_gpreg + + def decode(self, v): + self.expr = ExprMem(gpregs.expr[v] + R0, self.sz) + return True + + def encode(self): + res = MatchExpr(self.expr, ExprMem(R0 + jra, self.sz), [jra]) + if not res: + return False + r = res[jra] + if not r in gpregs.expr: + return False + self.value = gpregs.expr.index(r) + return True + + +class bs_dgpreg(sh4_dgpreg): + parser = dgpregs_base + + +rn = bs(l=4, cls=(sh4_gpreg,), fname="rn") +rm = bs(l=4, cls=(sh4_gpreg,), fname="rm") + + +d08_rn = bs(l=4, cls=(sh4_dgpreg,), fname="rn", sz = 8) +d16_rn = bs(l=4, cls=(sh4_dgpreg,), fname="rn", sz = 16) +d32_rn = bs(l=4, cls=(sh4_dgpreg,), fname="rn", sz = 32) +d08_rm = bs(l=4, cls=(sh4_dgpreg,), fname="rm", sz = 8) +d16_rm = bs(l=4, cls=(sh4_dgpreg,), fname="rm", sz = 16) +d32_rm = bs(l=4, cls=(sh4_dgpreg,), fname="rm", sz = 32) + + +brm = bs(l=3, cls=(sh4_bgpreg,), fname="brm") +brn = bs(l=3, cls=(sh4_bgpreg,), fname="brn") + +d08rnimm = bs(l=4, fname="rn", cls=(sh4_dgpreg_imm,), sz = 8) +d16rnimm = bs(l=4, fname="rn", cls=(sh4_dgpreg_imm,), sz = 16) +d32rnimm = bs(l=4, fname="rn", cls=(sh4_dgpreg_imm,), sz = 32) + +d08rmimm = bs(l=4, fname="rm", cls=(sh4_dgpreg_imm,), sz = 8) +d16rmimm = bs(l=4, fname="rm", cls=(sh4_dgpreg_imm,), sz = 16) +d32rmimm = bs(l=4, fname="rm", cls=(sh4_dgpreg_imm,), sz = 32) + +btype = bs(l=4, fname="btype", order=-1) + +s08imm = bs(l=8, cls=(sh4_simm,), fname="imm") +s12imm = bs(l=12, cls=(sh4_simm,), fname="imm") +dpc16imm = bs(l=8, cls=(sh4_dpc16imm,), fname="pcimm", sz=16) +dpc32imm = bs(l=8, cls=(sh4_dpc32imm,), fname="pcimm", sz=32) +dimm4 = bs(l=4, fname='disp', order=-1) +d08gbrimm8 = bs(l=8, cls=(sh4_dgbrimm8,), fname='disp', sz=8) +d16gbrimm8 = bs(l=8, cls=(sh4_dgbrimm8,), fname='disp', sz=16) +d32gbrimm8 = bs(l=8, cls=(sh4_dgbrimm8,), fname='disp', sz=32) + +pc32imm = bs(l=8, cls=(sh4_pc32imm,), fname="pcimm") + +d08rnpinc = bs(l=4, cls=(sh4_dgpregpinc,), op='postinc', sz=8, fname="rn") +d08rmpinc = bs(l=4, cls=(sh4_dgpregpinc,), op='postinc', sz=8, fname="rm") + +d16rnpinc = bs(l=4, cls=(sh4_dgpregpinc,), op='postinc', sz=16, fname="rn") +d16rmpinc = bs(l=4, cls=(sh4_dgpregpinc,), op='postinc', sz=16, fname="rm") + +d32rnpinc = bs(l=4, cls=(sh4_dgpregpinc,), op='postinc', sz=32, fname="rn") +d32rmpinc = bs(l=4, cls=(sh4_dgpregpinc,), op='postinc', sz=32, fname="rm") + +d08rnpdec = bs(l=4, cls=(sh4_dgpregpinc,), op='predec', sz=8, fname="rn") +d08rmpdec = bs(l=4, cls=(sh4_dgpregpinc,), op='predec', sz=8, fname="rm") + +d16rnpdec = bs(l=4, cls=(sh4_dgpregpinc,), op='predec', sz=16, fname="rn") +d16rmpdec = bs(l=4, cls=(sh4_dgpregpinc,), op='predec', sz=16, fname="rm") + +d32rnpdec = bs(l=4, cls=(sh4_dgpregpinc,), op='predec', sz=32, fname="rn") +d32rmpdec = bs(l=4, cls=(sh4_dgpregpinc,), op='predec', sz=32, fname="rm") + + +u08imm = bs(l=8, cls=(sh4_imm,), fname="imm") +dr0gbr = bs(l=0, cls=(bs_dr0gbr,), sz=8) + +d08gpreg = bs(l=4, cls=(bs_dgpreg,), sz=8) +d32gpreg = bs(l=4, cls=(bs_dgpreg,), sz=32) + +frn = bs(l=4, cls=(sh4_freg,), fname="frn") +frm = bs(l=4, cls=(sh4_freg,), fname="frm") + +bd08r0gp = bs(l=4, cls=(bs_dr0gp,), sz=8) +bd16r0gp = bs(l=4, cls=(bs_dr0gp,), sz=16) +bd32r0gp = bs(l=4, cls=(bs_dr0gp,), sz=32) + +drn = bs(l=3, cls=(sh4_dr,), fname="drn") +drm = bs(l=3, cls=(sh4_dr,), fname="drm") + + +def addop(name, fields, args=None, alias=False): + dct = {"fields": fields} + dct["alias"] = alias + if args is not None: + dct['args'] = args + type(name, (mn_sh4,), dct) + +addop("mov", [bs('1110'), rn, s08imm], [s08imm, rn]) +addop("mov_w", [bs('1001'), rn, dpc16imm], [dpc16imm, rn]) +addop("mov_l", [bs('1101'), rn, dpc32imm], [dpc32imm, rn]) +addop("mov", [bs('0110', fname="opc"), rn, rm, bs('0011')], [rm, rn]) +addop("mov_b", [bs('0010', fname="opc"), d08_rn, rm, bs('0000')], [rm, d08_rn]) +addop("mov_w", [bs('0010', fname="opc"), d16_rn, rm, bs('0001')], [rm, d16_rn]) +addop("mov_l", [bs('0010', fname="opc"), d32_rn, rm, bs('0010')], [rm, d32_rn]) +addop("mov_b", [bs('0110', fname="opc"), rn, d08_rm, bs('0000')], [d08_rm, rn]) +addop("mov_w", [bs('0110', fname="opc"), rn, d16_rm, bs('0001')], [d16_rm, rn]) +addop("mov_l", [bs('0110', fname="opc"), rn, d32_rm, bs('0010')], [d32_rm, rn]) +addop("mov_b", + [bs('0010', fname="opc"), d08rnpdec, rm, bs('0100')], [rm, d08rnpdec]) +addop("mov_w", + [bs('0010', fname="opc"), d16rnpdec, rm, bs('0101')], [rm, d16rnpdec]) +addop("mov_l", + [bs('0010', fname="opc"), d32rnpdec, rm, bs('0110')], [rm, d32rnpdec]) +addop("mov_b", + [bs('0110', fname="opc"), rn, d08rmpinc, bs('0100')], [rm, d08rnpinc]) +addop("mov_w", + [bs('0110', fname="opc"), rn, d16rmpinc, bs('0101')], [d16rmpinc, rn]) +addop("mov_l", + [bs('0110', fname="opc"), rn, d32rmpinc, bs('0110')], [d32rmpinc, rn]) +addop("mov_b", [bs('10000000', fname='opc'), bsr0, d08rnimm, dimm4]) +addop("mov_w", [bs('10000001', fname='opc'), bsr0, d16rnimm, dimm4]) +addop("mov_l", [bs('0001', fname='opc'), d32rnimm, rm, dimm4], [rm, d32rnimm]) +addop("mov_b", [bs('10000100', fname='opc'), d08rmimm, dimm4, bsr0]) +addop("mov_w", [bs('10000101', fname='opc'), d16rmimm, dimm4, bsr0]) +addop("mov_l", [bs('0101', fname='opc'), rn, d32rmimm, dimm4], [d32rmimm, rn]) +addop("mov_b", + [bs('0000', fname='opc'), bd08r0gp, rm, bs('0100')], [rm, bd08r0gp]) +addop("mov_w", + [bs('0000', fname='opc'), bd16r0gp, rm, bs('0101')], [rm, bd16r0gp]) +addop("mov_l", + [bs('0000', fname='opc'), bd32r0gp, rm, bs('0110')], [rm, bd32r0gp]) +addop("mov_b", + [bs('0000', fname='opc'), rn, bd08r0gp, bs('1100')], [bd08r0gp, rn]) +addop("mov_w", + [bs('0000', fname='opc'), rn, bd16r0gp, bs('1101')], [bd16r0gp, rn]) +addop("mov_l", + [bs('0000', fname='opc'), rn, bd32r0gp, bs('1110')], [bd32r0gp, rn]) + +addop("mov_b", [bs('11000000'), bsr0, d08gbrimm8]) +addop("mov_w", [bs('11000001'), bsr0, d16gbrimm8]) +addop("mov_l", [bs('11000010'), bsr0, d32gbrimm8]) + +addop("mov_b", [bs('11000100'), d08gbrimm8, bsr0]) +addop("mov_w", [bs('11000101'), d16gbrimm8, bsr0]) +addop("mov_l", [bs('11000110'), d32gbrimm8, bsr0]) + +addop("mov", [bs('11000111'), pc32imm, bsr0]) + +addop("swapb", [bs('0110'), rn, rm, bs('1000')], [rm, rn]) +addop("swapw", [bs('0110'), rn, rm, bs('1001')], [rm, rn]) +addop("xtrct", [bs('0010'), rn, rm, bs('1101')], [rm, rn]) + + +addop("add", [bs('0011'), rn, rm, bs('1100')], [rm, rn]) +addop("add", [bs('0111'), rn, s08imm], [s08imm, rn]) +addop("addc", [bs('0011'), rn, rm, bs('1110')], [rm, rn]) +addop("addv", [bs('0011'), rn, rm, bs('1111')], [rm, rn]) + + +addop("cmpeq", [bs('10001000'), s08imm, bsr0]) + + +addop("cmpeq", [bs('0011'), rn, rm, bs('0000')], [rm, rn]) +addop("cmphs", [bs('0011'), rn, rm, bs('0010')], [rm, rn]) +addop("cmpge", [bs('0011'), rn, rm, bs('0011')], [rm, rn]) +addop("cmphi", [bs('0011'), rn, rm, bs('0110')], [rm, rn]) +addop("cmpgt", [bs('0011'), rn, rm, bs('0111')], [rm, rn]) + + +addop("cmppz", [bs('0100'), rn, bs('00010001')]) +addop("cmppl", [bs('0100'), rn, bs('00010101')]) +addop("cmpstr", [bs('0010'), rn, rm, bs('1100')], [rm, rn]) + + +addop("div1", [bs('0011'), rn, rm, bs('0100')], [rm, rn]) + +addop("div0s", [bs('0010'), rn, rm, bs('0111')], [rm, rn]) +addop("div0u", [bs('0000000000011001')]) + +addop("dmuls", [bs('0011'), rn, rm, bs('1101')], [rm, rn]) +addop("dmulu", [bs('0011'), rn, rm, bs('0101')], [rm, rn]) + +addop("dt", [bs('0100'), rn, bs('00010000')]) + + +addop("extsb", [bs('0110'), rn, rm, bs('1110')], [rm, rn]) +addop("extsw", [bs('0110'), rn, rm, bs('1111')], [rm, rn]) +addop("extub", [bs('0110'), rn, rm, bs('1100')], [rm, rn]) +addop("extuw", [bs('0110'), rn, rm, bs('1101')], [rm, rn]) + +addop("mac_l", [bs('0000', fname='opc'), d32rnpinc, + d32rmpinc, bs('1111')], [d32rmpinc, d32rnpinc]) +addop("mac_w", [bs('0100', fname='opc'), d16rnpinc, + d16rmpinc, bs('1111')], [d16rmpinc, d16rnpinc]) + +addop("mull", [bs('0000'), rn, rm, bs('0111')], [rm, rn]) +addop("mulsw", [bs('0010'), rn, rm, bs('1111')], [rm, rn]) +addop("muluw", [bs('0010'), rn, rm, bs('1110')], [rm, rn]) + +addop("neg", [bs('0110'), rn, rm, bs('1011')], [rm, rn]) +addop("negc", [bs('0110'), rn, rm, bs('1010')], [rm, rn]) + +addop("sub", [bs('0011'), rn, rm, bs('1000')], [rm, rn]) +addop("subc", [bs('0011'), rn, rm, bs('1010')], [rm, rn]) +addop("subv", [bs('0011'), rn, rm, bs('1011')], [rm, rn]) + +addop("and", [bs('0010'), rn, rm, bs('1001')], [rm, rn]) +addop("and", [bs('11001001'), u08imm, bsr0]) +addop("and_b", [bs('11001101'), u08imm, dr0gbr]) + +addop("not", [bs('0110'), rn, rm, bs('0111')], [rm, rn]) + +addop("or", [bs('0010'), rn, rm, bs('1011')], [rm, rn]) + +addop("or", [bs('11001011'), u08imm, bsr0]) +addop("or_b", [bs('11001111'), u08imm, dr0gbr]) + +addop("tas_b", [bs('0100'), d08gpreg, bs('00011011')]) +addop("tst", [bs('0010'), rn, rm, bs('1000')], [rm, rn]) +addop("tst", [bs('11001000'), u08imm, bsr0]) +addop("tst_b", [bs('11001100'), u08imm, dr0gbr]) + + +addop("xor", [bs('0010'), rn, rm, bs('1010')], [rm, rn]) +addop("xor", [bs('11001010'), u08imm, bsr0]) +addop("xor_b", [bs('11001110'), u08imm, dr0gbr]) + +addop("rotl", [bs('0100'), rn, bs('00000100')]) +addop("rotr", [bs('0100'), rn, bs('00000101')]) +addop("rotcl", [bs('0100'), rn, bs('00100100')]) +addop("rotcr", [bs('0100'), rn, bs('00100101')]) + +addop("shad", [bs('0100'), rn, rm, bs('1100')], [rm, rn]) +addop("shal", [bs('0100'), rn, bs('00100000')]) +addop("shar", [bs('0100'), rn, bs('00100001')]) +addop("shld", [bs('0100'), rn, rm, bs('1101')], [rm, rn]) + +addop("shll", [bs('0100'), rn, bs('00000000')]) +addop("shlr", [bs('0100'), rn, bs('00000001')]) +addop("shll2", [bs('0100'), rn, bs('00001000')]) +addop("shlr2", [bs('0100'), rn, bs('00001001')]) +addop("shll8", [bs('0100'), rn, bs('00011000')]) +addop("shlr8", [bs('0100'), rn, bs('00011001')]) +addop("shll16", [bs('0100'), rn, bs('00101000')]) +addop("shlr16", [bs('0100'), rn, bs('00101001')]) + + +addop("bf", [bs('10001011'), s08imm]) +""" + def splitflow(self): + return True + def breakflow(self): + return True + def dstflow(self): + return True + def dstflow2label(self, symbol_pool): + e = self.args[0].expr + ad = e.arg*2+4+self.offset + l = symbol_pool.getby_offset_create(ad) + s = ExprId(l, e.size) + self.args[0].expr = s +""" + +addop("bfs", [bs('10001111'), s08imm]) +""" + delayslot = 1 +""" +addop("bt", [bs('10001001'), s08imm]) + +addop("bts", [bs('10001101'), s08imm]) + +addop("bra", [bs('1010'), s12imm]) +""" + delayslot = 1 + def breakflow(self): + return True + def dstflow(self): + return True + def dstflow2label(self, symbol_pool): + e = self.args[0].expr + ad = e.arg*2+4+self.offset + l = symbol_pool.getby_offset_create(ad) + s = ExprId(l, e.size) + self.args[0].expr = s +""" + +addop("braf", [bs('0000'), rn, bs('00100011')]) +""" + delayslot = 1 + def breakflow(self): + return True + def dstflow(self): + return True +""" +addop("bsr", [bs('1011'), s12imm]) + +addop("bsrf", [bs('0000'), rn, bs('00000011')]) +""" + delayslot = 1 + def breakflow(self): + return True + def is_subcall(self): + return True + def splitflow(self): + return True +""" + +addop("jmp_l", [bs('0100'), d32gpreg, bs('00101011')]) +""" + delayslot = 1 + def breakflow(self): + return True +""" + +addop("jsr_l", [bs('0100'), d32gpreg, bs('00001011')]) +""" + delayslot = 1 + def breakflow(self): + return True + def is_subcall(self): + return True + def splitflow(self): + return True +""" + +addop("rts", [bs('0000000000001011')]) +""" + delayslot = 1 + def breakflow(self): + return True +""" +addop("clrmac", [bs('0000000000101000')]) +addop("clrs", [bs('0000000001001000')]) +addop("clrt", [bs('0000000000001000')]) + + +addop("ldc", [bs('0100'), rm, bssr, bs('00001110')]) +addop("ldc", [bs('0100'), rm, bsgbr, bs('00011110')]) +addop("ldc", [bs('0100'), rm, bsvbr, bs('00101110')]) +addop("ldc", [bs('0100'), rm, bsssr, bs('00111110')]) +addop("ldc", [bs('0100'), rm, bsspc, bs('01001110')]) +addop("ldc", [bs('0100'), rm, bsdbr, bs('11111010')]) +addop("ldc", [bs('0100'), rm, bs('1'), brn, bs('1110')], [rm, brn]) +addop("ldc_l", [bs('0100'), d32rmpinc, bssr, bs('00000111')]) +addop("ldc_l", [bs('0100'), d32rmpinc, bsgbr, bs('00010111')]) +addop("ldc_l", [bs('0100'), d32rmpinc, bsvbr, bs('00100111')]) +addop("ldc_l", [bs('0100'), d32rmpinc, bsssr, bs('00110111')]) +addop("ldc_l", [bs('0100'), d32rmpinc, bsspc, bs('01000111')]) +addop("ldc_l", [bs('0100'), d32rmpinc, bsdbr, bs('11110110')]) +addop("ldc_l", [bs('0100'), d32rmpinc, bs('1'), brn, bs('0111')]) +addop("lds", [bs('0100'), rm, bsmach, bs('00001010')]) +addop("lds", [bs('0100'), rm, bsmacl, bs('00011010')]) +addop("lds", [bs('0100'), rm, bspr, bs('00101010')]) +addop("lds_l", [bs('0100'), d32rmpinc, bsmach, bs('00000110')]) +addop("lds_l", [bs('0100'), d32rmpinc, bsmacl, bs('00010110')]) +addop("lds_l", [bs('0100'), d32rmpinc, bspr, bs('00100110')]) +addop("ldtlb", [bs('0000000000111000')]) + +addop("movca_l", [bs('0000'), bsr0, d32gpreg, bs('11000011')]) +addop("nop", [bs('0000000000001001')]) +addop("ocbi_l", [bs('0000'), d32gpreg, bs('10010011')]) +addop("ocbp_l", [bs('0000'), d32gpreg, bs('10100011')]) +addop("ocbwb_l", [bs('0000'), d32gpreg, bs('10110011')]) +addop("pref_l", [bs('0000'), d32gpreg, bs('10000011')]) + + +addop("rte", [bs('0000000000101011')]) +addop("sets", [bs('0000000001011000')]) +addop("sett", [bs('0000000000011000')]) +addop("sleep", [bs('0000000000011011')]) +addop("stc", [bs('0000'), bssr, rn, bs('00000010')]) +addop("stc", [bs('0000'), bsgbr, rn, bs('00010010')]) +addop("stc", [bs('0000'), bsvbr, rn, bs('00100010')]) +addop("stc", [bs('0000'), bsssr, rn, bs('00110010')]) +addop("stc", [bs('0000'), bsspc, rn, bs('01000010')]) +addop("stc", [bs('0000'), bssgr, rn, bs('00111010')]) +addop("stc", [bs('0000'), bsdbr, rn, bs('11111010')]) +addop("stc", [bs('0000'), rn, bs('1'), brm, bs('0010')], [brm, rn]) + +addop("stc_l", [bs('0100'), bssr, d32rmpdec, bs('00000011')]) +addop("stc_l", [bs('0100'), bsgbr, d32rmpdec, bs('00010011')]) +addop("stc_l", [bs('0100'), bsvbr, d32rmpdec, bs('00100011')]) +addop("stc_l", [bs('0100'), bsssr, d32rmpdec, bs('00110011')]) +addop("stc_l", [bs('0100'), bsspc, d32rmpdec, bs('01000011')]) +addop("stc_l", [bs('0100'), bssgr, d32rmpdec, bs('00110010')]) +addop("stc_l", [bs('0100'), bsdbr, d32rmpdec, bs('11110010')]) +addop("stc_l", + [bs('0100'), d32rnpdec, bs('1'), brm, bs('0011')], [brm, d32rnpdec]) + +# float +addop("sts", [bs('0000'), bsmach, rm, bs('00001010')]) +addop("sts", [bs('0000'), bsmacl, rm, bs('00011010')]) +addop("sts", [bs('0000'), bspr, rm, bs('00101010')]) +addop("sts_l", [bs('0100'), bsmach, d32rmpdec, bs('00000010')]) +addop("sts_l", [bs('0100'), bsmacl, d32rmpdec, bs('00010010')]) +addop("sts_l", + [bs('0100'), d32rnpdec, bspr, bs('00100010')], [bspr, d32rnpdec]) +addop("trapa", [bs('11000011'), u08imm]) + +addop("fldi0", [bs('1111'), frn, bs('10001101')]) +addop("fldi1", [bs('1111'), frn, bs('10011101')]) +addop("fmov", [bs('1111'), frn, frm, bs('1100')], [frm, frn]) +addop("fmov_s", [bs('1111'), frn, d32gpreg, bs('1000')], [d32gpreg, frn]) +addop("fmov_s", [bs('1111'), frn, bd32r0gp, bs('0110')], [bd32r0gp, frn]) +addop("fmov_s", [bs('1111'), frn, d32rmpinc, bs('1001')], [d32rmpinc, frn]) +addop("fmov_s", [bs('1111'), d32gpreg, frm, bs('1010')], [frm, d32gpreg]) +addop("fmov_s", [bs('1111'), d32rnpdec, frm, bs('1011')], [frm, d32rnpdec]) +addop("fmov_s", [bs('1111'), bd32r0gp, frm, bs('0111')], [frm, bd32r0gp]) + +addop("flds", [bs('1111'), frm, bsfpul, bs('00011101')]) +addop("fsts", [bs('1111'), bsfpul, frm, bs('00001101')]) +addop("fabs", [bs('1111'), frn, bs('01011101')]) +addop("fadd", [bs('1111'), frn, frm, bs('0000')], [frm, frn]) +addop("fcmpeq", [bs('1111'), frn, frm, bs('0100')], [frm, frn]) +addop("fcmpgt", [bs('1111'), frn, frm, bs('0101')], [frm, frn]) +addop("fdiv", [bs('1111'), frn, frm, bs('0011')], [frm, frn]) + +addop("float", [bs('1111'), bsfpul, frn, bs('00101101')]) +addop("fmac", [bs('1111'), bsfr0, frn, frm, bs('1110')], [bsfr0, frm, frn]) +addop("fmul", [bs('1111'), frn, frm, bs('0010')], [frm, frn]) +addop("fneg", [bs('1111'), frn, bs('01001101')]) +addop("fsqrt", [bs('1111'), frn, bs('01101101')]) +addop("fsub", [bs('1111'), frn, frm, bs('0001')], [frm, frn]) +addop("ftrc", [bs('1111'), frm, bsfpul, bs('00111101')]) + + +if __name__ == '__main__': + import os + import time + filename = os.environ.get('PYTHONSTARTUP') + if filename and os.path.isfile(filename): + execfile(filename) + + def h2i(s): + return s.replace(' ', '').decode('hex') + + reg_tests_sh4 = [ + # vxworks + ("c80022f2 MOV 0x10, R6", + "10e6"), + ("c8002250 MOV 0xFFFFFFFF, R0", + "ffe0"), + ("c800226a MOV.W @(PC,0xC0), R9", + "5e99"), + ("c8002006 MOV.L @(PC&0xFFFFFFFC,0x10), R15", + "03df"), + ("c800cfc4 MOV R4, R9", + "4369"), + ("C8005004 MOV.B R1, @R2", + "1022"), + ("C8002E04 MOV.W R0, @R8", + '0128'), + ("c800223e MOV.L R1, @R14", + "122E"), + + ("c8002002 MOV.L @R1, R0", + "1260"), + ("c8002E08 MOV.W @R8, R1", + "8161"), + ("c800357c MOV.B @R4, R1", + "4061"), + + ("c8002220 MOV.L R8, @-R15", + "862f"), + ("c8022a66 MOV.B R4, @-R0", + "4420"), + ("c8002310 MOV.L @R15+, R14", + "f66e"), + ("c80038a4 MOV.W @R8+, R5", + "8565"), + ("xxxxxxxx MOV.B R0, @(R8,0x2)", + "8280"), + ("xxxxxxxx MOV.W R0, @(R8,0x4)", + "8281"), + ("c8002274 MOV.L R0, @(R9,0x8)", + "0219"), + ("xxxxxxxx MOV.B @(R8,0x8), R0", + "8884"), + ("xxxxxxxx MOV.W @(R8,0x10), R0", + "8885"), + ("c8002500 MOV.L @(R14,0x4), R5", + "e155"), + ("xxxxxxxx MOV.B R4, @(R0,R8)", + "4408"), + ("xxxxxxxx MOV.W R4, @(R0,R8)", + "4508"), + ("xxxxxxxx MOV.L R4, @(R0,R8)", + "4608"), + ("xxxxxxxx MOV.B @(R0,R4), R8", + "4c08"), + ("xxxxxxxx MOV.W @(R0,R4), R8", + "4d08"), + ("xxxxxxxx MOV.L @(R0,R4), R8", + "4e08"), + ("xxxxxxxx MOV.B R0, @(GBR,0x4)", + "04c0"), + ("xxxxxxxx MOV.W R0, @(GBR,0x8)", + "04c1"), + ("xxxxxxxx MOV.L R0, @(GBR,0x10)", + "04c2"), + ("xxxxxxxx MOV.B @(GBR,0x4), R0", + "04c4"), + ("xxxxxxxx MOV.W @(GBR,0x8), R0", + "04c5"), + ("xxxxxxxx MOV.L @(GBR,0x10), R0", + "04c6"), + #("xxxxxxxx MOV PC&0xFFFFFFFC+0x14, R0", + # "04c7"), + ("xxxxxxxx SWAPB R2, R1", + "2861"), + ("c803f492 SWAPW R4, R9", + "4969"), + ("xxxxxxxx XTRCT R4, R9", + "4d29"), + ("c8002270 ADD R12, R9", + "cc39"), + ("c8002238 ADD 0xFFFFFFFC, R15", + "FC7F"), + ("c80164cc ADDC R0, R1", + "0e31"), + ("xxxxxxxx ADDV R0, R1", + "0f31"), + ("c8002994 CMPEQ 0x20, R0", + "2088"), + ("c80029d2 CMPEQ R2, R1", + "2031"), + ("c8003964 CMPHS R5, R3", + "5233"), + ("c8002df2 CMPGE R0, R1", + "0331"), + ("c80029a4 CMPHI R1, R0", + "1630"), + ("c8002bfe CMPGT R10, R8", + "a738"), + ("c8002bf8 CMPPZ R0", + "1140"), + ("c8006294 CMPPL R2", + "1542"), + ("c8033800 CMPSTR R14, R4", + "ec24"), + ("xxxxxxxx DIV1 R14, R4", + "e434"), + ("c8d960de DIV0S R0, R3", + "0723"), + ("xxxxxxxx DIV0U ", + "1900"), + ("c800dcd8 DMULS R1, R0", + "1d30"), + ("c80164da DMULU R3, R8", + "3538"), + ("c80024e2 DT R10", + "104a"), + ("c800343a EXTSB R1, R1", + "1e61"), + ("c8002bf6 EXTSW R0, R0", + "0f60"), + ("c8002fba EXTUB R0, R0", + "0c60"), + ("c8002398 EXTUW R0, R0", + "0d60"), + ("xxxxxxxx MAC.L @R5+, @R4+", + "5f04"), + ("xxxxxxxx MAC.W @R5+, @R4+", + "5f44"), + ("c8005112 MULL R1, R3", + "1703"), + ("xxxxxxxx MULSW R1, R3", + "1F23"), + ("xxxxxxxx MULUW R1, R3", + "1e23"), + ("c8004856 NEG R1, R8", + "1b68"), + ("c80054fc NEGC R9, R7", + "9a67"), + ("c8004b36 SUB R1, R5", + "1835"), + ("c800a536 SUBC R1, R0", + "1a30"), + ("xxxxxxxx SUBV R1, R0", + "1b30"), + ("c80023ca AND R0, R5", + "0925"), + ("c800257c AND 0x2, R0", + "02c9"), + ("xxxxxxxx AND.B 0x2, @(GBR,R0)", + "02cd"), + ("c80065fe NOT R5, R1", + "5761"), + ("c8002586 OR R10, R1", + "ab21"), + ("c80023aa OR 0x4, R0", + "04cb"), + ("xxxxxxxx OR.B 0x4, @(GBR,R0)", + "04cf"), + ("xxxxxxxx TAS.B @R8", + "1b48"), + ("c8002368 TST R10, R13", + "a82d"), + ("c8003430 TST 0x11, R0", + "11c8"), + ("xxxxxxxx TST.B 0x4, @(GBR,R0)", + "04cc"), + ("c8003978 XOR R1, R6", + "1a26"), + ("c8028270 XOR 0x1, R0", + "01ca"), + ("xxxxxxxx XOR.B 0x4, @(GBR,R0)", + "04cE"), + ("xxxxxxxx ROTL R9", + "0449"), + ("xxxxxxxx ROTR R9", + "0549"), + ("xxxxxxxx ROTCL R9", + "2449"), + ("xxxxxxxx ROTCR R9", + "2549"), + ("xxxxxxxx SHAL R11", + "204b"), + ("xxxxxxxx SHAR R11", + "214b"), + ("c800236c SHLD R6, R10", + "6d4a"), + ("xxxxxxxx SHLL R11", + "004b"), + ("xxxxxxxx SHLR R11", + "014b"), + ("xxxxxxxx SHLL2 R11", + "084b"), + ("xxxxxxxx SHLR2 R11", + "094b"), + ("xxxxxxxx SHLL8 R11", + "184b"), + ("xxxxxxxx SHLR8 R11", + "194b"), + ("xxxxxxxx SHLL16 R11", + "284b"), + ("xxxxxxxx SHLR16 R11", + "294b"), + ("c8002c00 BF 0xFFFFFFF4", + "f48b"), + ("c80023c2 BFS 0xFFFFFFD8", + "d88f"), + ("c8002266 BT 0x5B", + "5b89"), + ("c8002266 BTS 0x5C", + "5c8d"), + ("c8002326 BRA 0xFFFFFFF0", + "f0af"), + ("c8004b4a BRAF R1", + "2301"), + ("c8055da4 BSR 0xFFFFFE48", + "48be"), + ("xxxxxxxx BSRF R1", + "0301"), + ("c80027b4 JMP.L @R1", + "2b41"), + ("c800200c JSR.L @R0", + "0b40"), + ("c800231a RTS ", + "0b00"), + ("xxxxxxxx CLRMAC ", + "2800"), + ("xxxxxxxx CLRS ", + "4800"), + ("xxxxxxxx CLRT ", + "0800"), + ("c8002004 LDC R0, SR", + "0e40"), + ("c800200e LDC R1, GBR", + "1e41"), + ("c8064bd4 LDC R8, VBR", + "2e48"), + ("xxxxxxxx LDC R8, SSR", + "3e48"), + ("xxxxxxxx LDC R8, SPC", + "4e48"), + ("xxxxxxxx LDC R8, DBR", + "fa48"), + ("xxxxxxxx LDC R8, R0_BANK", + "8e48"), + ("xxxxxxxx LDC.L @R8+, SR", + "0748"), + ("xxxxxxxx LDC.L @R8+, GBR", + "1748"), + ("xxxxxxxx LDC.L @R8+, VBR", + "2748"), + ("xxxxxxxx LDC.L @R8+, SSR", + "3748"), + ("xxxxxxxx LDC.L @R8+, SPC", + "4748"), + ("xxxxxxxx LDC.L @R8+, DBR", + "f648"), + ("xxxxxxxx LDC.L @R8+, R2_BANK", + "a748"), + ("xxxxxxxx LDS R8, MACH", + "0a48"), + ("xxxxxxxx LDS R8, MACL", + "1a48"), + ("xxxxxxxx LDS R8, PR", + "2a48"), + ("xxxxxxxx LDS.L @R8+, MACH", + "0648"), + ("xxxxxxxx LDS.L @R8+, MACL", + "1648"), + ("xxxxxxxx LDTLB ", + "3800"), + ("xxxxxxxx MOVCA.L R0, @R8", + "c308"), + ("xxxxxxxx NOP ", + "0900"), + ("xxxxxxxx OCBI.L @R8", + "9308"), + ("xxxxxxxx OCBP.L @R8", + "a308"), + ("xxxxxxxx OCBWB.L @R8", + "b308"), + ("xxxxxxxx PREF.L @R8", + "8308"), + ("xxxxxxxx STS MACH, R8", + "0a08"), + ("xxxxxxxx STS MACL, R8", + "1a08"), + ("xxxxxxxx STS PR, R8", + "2a08"), + ("xxxxxxxx STS.L MACH, @-R8", + "0248"), + ("xxxxxxxx STS.L MACL, @-R8", + "1248"), + ("xxxxxxxx STS.L PR, @-R8", + "2248"), + + + + + + ("c8004b50 STC GBR, R0", + "1200"), + ("c8064516 STC VBR, R1", + "2201"), + ("c8004b54 STC SSR, R1", + "3201"), + ("c801ed6c STC SPC, R0", + "4200"), + ("xxxxxxxx STC SGR, R0", + "3a00"), + ("xxxxxxxx STC DBR, R0", + "fa00"), + ("c8004b56 STC R3_BANK, R1", + "B201"), + ("xxxxxxxx STC.L SR, @-R8", + "0348"), + ("xxxxxxxx STC.L GBR, @-R8", + "1348"), + ("xxxxxxxx STC.L VBR, @-R8", + "2348"), + ("xxxxxxxx STC.L SSR, @-R8", + "3348"), + ("xxxxxxxx STC.L SPC, @-R8", + "4348"), + ("xxxxxxxx STC.L DBR, @-R8", + "f248"), + ("xxxxxxxx STC.L R7_BANK, @-R8", + "f348"), + ("c803b130 TRAPA 0xE0", + "e0c3"), + + ("xxxxxxxx FLDI0 FR8", + "8df8"), + ("xxxxxxxx FLDI1 FR8", + "9df8"), + ("c8019ca8 FMOV FR15, FR5", + "fcf5"), + ("c800affe FMOV.S @R1, FR4", + "18f4"), + ("c80283f6 FMOV.S @(R0,R14), FR5", + "e6f5"), + ("c800aff8 FMOV.S @R1+, FR5", + "19f5"), + ("c80cb692 FMOV.S FR0, @R2", + "0af2"), + ("c80cb694 FMOV.S FR1, @-R2", + "1bf2"), + ("c80283aa FMOV.S FR1, @(R0,R14)", + "17fe"), + ("c800ce16 FLDS FR13, FPUL", + "1dfd"), + ("c800ce08 FSTS FPUL, FR13", + "0dfd"), + ("xxxxxxxx FABS FR8", + "5df8"), + ("c800cf28 FADD FR2, FR6", + "20f6"), + ("c805dacc FCMPEQ FR2, FR6", + "24f6"), + ("c8028406 FCMPGT FR4, FR2", + "45f2"), + ("c8019ca4 FDIV FR2, FR12", + "23fc"), + ("c800ce5e FLOAT FPUL, FR2", + "2df2"), + ("xxxxxxxx FMAC FR0, FR1, FR2", + "1ef2"), + ("c800b006 FMUL FR2, FR4", + "22f4"), + ("c805e412 FNEG FR14", + "4dfe"), + ("xxxxxxxx FSQRT FR14", + "6dfe"), + ("c8030400 FSUB FR4, FR2", + "41f2"), + ("c80303ba FTRC FR2, FPUL", + "3df2"), + + ] + + for s, l in reg_tests_sh4: + print "-" * 80 + s = s[12:] + b = h2i((l)) + print b.encode('hex') + mn = mn_sh4.dis(b, None) + 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_sh4.fromstring(s, None) + # print l + assert(str(l) == s) + a = mn_sh4.asm(l, None) + print [x for x in a] + print repr(b) + # print mn.args + assert(b in a) + + # speed test + o = "" + for s, l, in reg_tests_sh4: + s = s[12:] + b = h2i((l)) + o += b + + while len(o) < 1000: + o += o + bs = bin_stream_str(o) + off = 0 + instr_num = 0 + ts = time.time() + while off < bs.getlen(): + mn = mn_sh4.dis(bs, None, off) + # print instr_num, off, mn.l, str(mn) + instr_num += 1 + off += mn.l + print 'instr per sec:', instr_num / (time.time() - ts) + + import cProfile + cProfile.run(r'mn_sh4.dis("\x17\xfe", None)') |