5 from collections
import defaultdict
7 from pyparsing
import Literal, Group, Optional
15 log = logging.getLogger(
"mips32dis")
16 console_handler = logging.StreamHandler()
17 console_handler.setFormatter(logging.Formatter(
"%(levelname)-5s: %(message)s"))
18 log.addHandler(console_handler)
19 log.setLevel(logging.DEBUG)
22 gpregs = cpu.reg_info(regs.regs32_str, regs.regs32_expr)
26 LPARENTHESIS = Literal(
"(")
27 RPARENTHESIS = Literal(
")")
32 raise NotImplementedError(
"TODO")
39 raise NotImplementedError(
"TODO")
42 base_expr = cpu.base_expr
44 deref_off = Group(Optional(cpu.base_expr) + LPARENTHESIS + gpregs.parser + \
45 RPARENTHESIS).setParseAction(deref2expr)
46 deref_nooff = Group(LPARENTHESIS + gpregs.parser + \
47 RPARENTHESIS).setParseAction(deref2expr_nooff)
48 deref = deref_off | deref_nooff
51 variable, operand, base_expr = cpu.gen_base_expr()
53 int_or_expr = base_expr
57 if not t
in mn_mips32.regs.all_regs_ids_byname:
60 r = mn_mips32.regs.all_regs_ids_byname[t]
68 my_var_parser = cpu.parse_ast(ast_id2expr, ast_int2expr)
69 base_expr.setParseAction(my_var_parser)
75 br_0 = [
'B',
'J',
'JR',
'BAL',
'JAL',
'JALR']
76 br_1 = [
'BGEZ',
'BLTZ',
'BGTZ',
'BLEZ',
'BC1T',
'BC1F']
77 br_2 = [
'BEQ',
'BEQL',
'BNE']
84 super(instruction_mips32, self).
__init__(*args, **kargs)
89 if isinstance(e, ExprId)
or isinstance(e, ExprInt):
91 assert(isinstance(e, ExprMem))
93 if isinstance(arg, ExprId):
95 assert(len(arg.args) == 2
and arg.op ==
'+')
96 return "%s(%s)"%(arg.args[1], arg.args[0])
101 if self.
name in br_0 + br_1 + br_2:
106 if self.
name in br_0:
108 elif self.
name in br_1:
110 elif self.
name in br_2:
113 raise NotImplementedError(
"TODO %s"%self)
117 if self.
name in [
"J",
'JAL']:
119 ad = (self.offset & (0xFFFFFFFF ^ ((1<< 28)-1))) + e
120 l = symbol_pool.getby_offset_create(ad)
121 self.args[0] =
ExprId(l, e.size)
127 if not isinstance(e, ExprInt):
129 ad = e.arg + self.offset
130 l = symbol_pool.getby_offset_create(ad)
135 if self.
name ==
'BREAK':
137 if self.
name in br_0 + br_1 + br_2:
142 if self.
name in [
'JAL',
'JALR',
'BAL']:
147 if self.
name in br_0:
148 return [self.args[0]]
149 elif self.
name in br_1:
150 return [self.args[1]]
151 elif self.
name in br_2:
152 return [self.args[2]]
153 elif self.
name in [
'JAL',
'JALR',
'JR',
'J']:
154 return [self.args[0]]
156 raise NotImplementedError(
"fix mnemo %s"%self.
name)
159 if self.
name in [
"B",
'JR',
'J']:
161 if self.
name in br_0:
163 if self.
name in br_1:
165 if self.
name in br_2:
167 if self.
name in [
'JAL',
'JALR']:
177 if self.offset
is None:
178 raise ValueError(
'symbol not resolved %s' % self.l)
179 if not isinstance(e, ExprInt):
181 off = e.arg - self.offset
183 raise ValueError(
'strange offset! %r' % off)
187 args = [a
for a
in self.args]
198 all_mn_mode = defaultdict(list)
199 all_mn_name = defaultdict(list)
200 all_mn_inst = defaultdict(list)
201 pc = {
'l':regs.PC,
'b':regs.PC}
202 sp = {
'l':regs.SP,
'b':regs.SP}
203 instruction = instruction_mips32
204 max_instruction_len = 4
219 def getbits(cls, bitstream, attrib, start, n):
225 n_offset = cls.endian_offset(attrib, offset)
226 c = cls.getbytes(bitstream, n_offset, 1)
243 return (offset & ~3) + 3 - offset % 4
247 raise NotImplementedError(
'bad attrib')
251 l = sum([x.l
for x
in fields])
252 assert l == 32,
"len %r" % l
261 return [(subcls, name, bases, dct, fields)]
264 v = super(mn_mips32, self).
value(mode)
266 return [x[::-1]
for x
in v]
268 return [x
for x
in v]
270 raise NotImplementedError(
'bad attrib')
274 def mips32op(name, fields, args=None, alias=False):
275 dct = {
"fields": fields}
279 type(name, (mn_mips32,), dct)
286 class mips32_gpreg(mips32_reg):
288 parser = reg_info.parser
291 reg_info = regs.fltregs
292 parser = reg_info.parser
296 reg_info = regs.fccregs
297 parser = reg_info.parser
300 parser = cpu.base_expr
306 v = cpu.sign_ext(v, 16, 32)
311 if not isinstance(self.
expr, ExprInt):
313 v = self.expr.arg.arg
315 nv = v & ((1 << 16) - 1)
316 assert( v == cpu.sign_ext(nv, 16, 32))
325 v = cpu.sign_ext(v, 16+2, 32)
331 if not isinstance(self.
expr, ExprInt):
334 v = int(self.expr.arg - 4)
336 nv = v & ((1 << 16+2) - 1)
337 assert( v == cpu.sign_ext(nv, 16+2, 32))
346 class mips32_soff(mips32_soff_noarg, cpu.m_arg):
357 if not isinstance(self.
expr, ExprInt):
359 v = self.expr.arg.arg
376 if not isinstance(self.
expr, ExprInt):
378 v = self.expr.arg.arg
386 imm = self.parent.imm.expr
393 if not isinstance(e, ExprMem):
396 if isinstance(arg, ExprId):
399 elif len(arg.args) == 2
and arg.op ==
"+":
400 self.parent.imm.expr = arg.args[1]
409 assert(isinstance(e, ExprMem))
411 if isinstance(arg, ExprId):
413 assert(len(arg.args) == 2
and arg.op ==
'+')
414 return "%s(%s)"%(arg.args[1], arg.args[0])
423 if not isinstance(self.
expr, ExprInt):
425 v = self.expr.arg.arg -1
436 if not isinstance(self.
expr, ExprInt):
438 v = int(self.expr.arg) + int(self.parent.epos.expr.arg) -1
446 parser = regs.regs_cpr0_info.parser
448 index = int(self.parent.cpr0.expr.arg) << 3
450 self.
expr = regs.regs_cpr0_expr[index]
454 if not e
in regs.regs_cpr0_expr:
456 index = regs.regs_cpr0_expr.index(e)
459 self.parent.cpr0.value = index
462 rs = cpu.bs(l=5, cls=(mips32_gpreg,))
463 rt = cpu.bs(l=5, cls=(mips32_gpreg,))
464 rd = cpu.bs(l=5, cls=(mips32_gpreg,))
465 ft = cpu.bs(l=5, cls=(mips32_fltpreg,))
466 fs = cpu.bs(l=5, cls=(mips32_fltpreg,))
467 fd = cpu.bs(l=5, cls=(mips32_fltpreg,))
469 s16imm = cpu.bs(l=16, cls=(mips32_s16imm,))
470 u16imm = cpu.bs(l=16, cls=(mips32_u16imm,))
471 sa = cpu.bs(l=5, cls=(mips32_u16imm,))
472 base = cpu.bs(l=5, cls=(mips32_dreg_imm,))
473 soff = cpu.bs(l=16, cls=(mips32_soff,))
475 cpr0 = cpu.bs(l=5, cls=(mips32_imm,), fname=
"cpr0")
476 cpr = cpu.bs(l=3, cls=(mips32_cpr,))
479 s16imm_noarg = cpu.bs(l=16, cls=(mips32_s16imm_noarg,), fname=
"imm",
482 hint = cpu.bs(l=5, default_val=
"00000")
483 fcc = cpu.bs(l=3, cls=(mips32_fccreg,))
485 sel = cpu.bs(l=3, cls=(mips32_u16imm,))
487 code = cpu.bs(l=20, cls=(mips32_u16imm,))
489 esize = cpu.bs(l=5, cls=(mips32_esize,))
490 epos = cpu.bs(l=5, cls=(mips32_u16imm,), fname=
"epos",
493 eposh = cpu.bs(l=5, cls=(mips32_eposh,))
495 instr_index = cpu.bs(l=26, cls=(mips32_instr_index,))
496 bs_fmt = cpu.bs_mod_name(l=5, fname=
'fmt', mn_mod={0x10:
'.S', 0x11:
'.D',
497 0x14:
'.W', 0x15:
'.L',
500 mn_mod = [
'.F',
'.UN',
'.EQ',
'.UEQ',
501 '.OLT',
'.ULT',
'.OLE',
'.ULE',
502 '.SF',
'.NGLE',
'.SEQ',
'.NGL',
503 '.LT',
'.NGE',
'.LE',
'.NGT'
507 raise NotImplementedError(
"Not implemented")
512 mn_mod = [[
'.F',
'.UN',
'.EQ',
'.UEQ',
513 '.OLT',
'.ULT',
'.OLE',
'.ULE'],
514 [
'.SF',
'.NGLE',
'.SEQ',
'.NGL',
515 '.LT',
'.NGE',
'.LE',
'.NGT']
520 for candidate
in candidates:
521 cls, name, bases, dct, fields = candidate
522 cond1 = [f
for f
in fields
if f.fname ==
"cond1"]
523 assert(len(cond1) == 1)
525 mm = self.
mn_mod[cond1.value]
526 for value, new_name
in enumerate(mm):
528 s = cpu.int2bin(value, self.args[
'l'])
529 args = dict(self.args)
530 args.update({
'strbits': s})
534 ndct[
'name'] = name + new_name
535 out.append((cls, new_name, bases, ndct, nfields))
544 mn_mod = [
'.F',
'.UN',
'.EQ',
'.UEQ',
545 '.OLT',
'.ULT',
'.OLE',
'.ULE',
546 '.SF',
'.NGLE',
'.SEQ',
'.NGL',
547 '.LT',
'.NGE',
'.LE',
'.NGT'])
551 bs_arith = cpu.bs_name(l=6, name={
'ADDU':0b100001,
564 bs_shift = cpu.bs_name(l=6, name={
'SLL':0b000000,
569 bs_shift1 = cpu.bs_name(l=6, name={
'SLLV':0b000100,
575 bs_arithfmt = cpu.bs_name(l=6, name={
'ADD':0b000000,
581 bs_s_l = cpu.bs_name(l=6, name = {
"SW": 0b101011,
597 bs_oax = cpu.bs_name(l=6, name = {
"ORI": 0b001101,
602 bs_bcc = cpu.bs_name(l=5, name = {
"BGEZ": 0b00001,
614 mips32op(
"addi", [cpu.bs(
'001000'), rs, rt, s16imm], [rt, rs, s16imm])
615 mips32op(
"addiu", [cpu.bs(
'001001'), rs, rt, s16imm], [rt, rs, s16imm])
616 mips32op(
"nop", [cpu.bs(
'0'*32)], alias =
True)
617 mips32op(
"lui", [cpu.bs(
'001111'), cpu.bs(
'00000'), rt, u16imm])
618 mips32op(
"oax", [bs_oax, rs, rt, u16imm], [rt, rs, u16imm])
620 mips32op(
"arith", [cpu.bs(
'000000'), rs, rt, rd, cpu.bs(
'00000'), bs_arith],
622 mips32op(
"shift1", [cpu.bs(
'000000'), rs, rt, rd, cpu.bs(
'00000'), bs_shift1],
625 mips32op(
"shift", [cpu.bs(
'000000'), cpu.bs(
'00000'), rt, rd, sa, bs_shift],
628 mips32op(
"rotr", [cpu.bs(
'000000'), cpu.bs(
'00001'), rt, rd, sa,
629 cpu.bs(
'000010')], [rd, rt, sa])
631 mips32op(
"mul", [cpu.bs(
'011100'), rs, rt, rd, cpu.bs(
'00000'),
632 cpu.bs(
'000010')], [rd, rs, rt])
633 mips32op(
"div", [cpu.bs(
'000000'), rs, rt, cpu.bs(
'0000000000'),
636 mips32op(
"s_l", [bs_s_l, base, rt, s16imm_noarg], [rt, base])
639 mips32op(
"mfc0", [cpu.bs(
'010000'), cpu.bs(
'00000'), rt, cpr0,
640 cpu.bs(
'00000000'), cpr])
641 mips32op(
"mfc1", [cpu.bs(
'010001'), cpu.bs(
'00000'), rt, fs,
642 cpu.bs(
'00000000000')])
644 mips32op(
"ldc1", [cpu.bs(
'110101'), base, ft, s16imm_noarg], [ft, base])
646 mips32op(
"mov", [cpu.bs(
'010001'), bs_fmt, cpu.bs(
'00000'), fs, fd,
647 cpu.bs(
'000110')], [fd, fs])
649 mips32op(
"add", [cpu.bs(
'010001'), bs_fmt, ft, fs, fd, bs_arithfmt],
652 mips32op(
"divu", [cpu.bs(
'000000'), rs, rt, cpu.bs(
'0000000000'),
654 mips32op(
"mult", [cpu.bs(
'000000'), rs, rt, cpu.bs(
'0000000000'),
656 mips32op(
"multu", [cpu.bs(
'000000'), rs, rt, cpu.bs(
'0000000000'),
658 mips32op(
"mflo", [cpu.bs(
'000000'), cpu.bs(
'0000000000'), rd,
659 cpu.bs(
'00000'), cpu.bs(
'010010')])
660 mips32op(
"mfhi", [cpu.bs(
'000000'), cpu.bs(
'0000000000'), rd,
661 cpu.bs(
'00000'), cpu.bs(
'010000')])
664 mips32op(
"b", [cpu.bs(
'000100'), cpu.bs(
'00000'), cpu.bs(
'00000'), soff],
666 mips32op(
"bne", [cpu.bs(
'000101'), rs, rt, soff])
667 mips32op(
"beq", [cpu.bs(
'000100'), rs, rt, soff])
669 mips32op(
"blez", [cpu.bs(
'000110'), rs, cpu.bs(
'00000'), soff])
671 mips32op(
"bcc", [cpu.bs(
'000001'), rs, bs_bcc, soff])
673 mips32op(
"bgtz", [cpu.bs(
'000111'), rs, cpu.bs(
'00000'), soff])
674 mips32op(
"bal", [cpu.bs(
'000001'), cpu.bs(
'00000'), cpu.bs(
'10001'), soff],
678 mips32op(
"slti", [cpu.bs(
'001010'), rs, rt, s16imm], [rt, rs, s16imm])
679 mips32op(
"sltiu", [cpu.bs(
'001011'), rs, rt, s16imm], [rt, rs, s16imm])
682 mips32op(
"j", [cpu.bs(
'000010'), instr_index])
683 mips32op(
"jal", [cpu.bs(
'000011'), instr_index])
684 mips32op(
"jalr", [cpu.bs(
'000000'), rs, cpu.bs(
'00000'), rd, hint,
686 mips32op(
"jr", [cpu.bs(
'000000'), rs, cpu.bs(
'0000000000'), hint,
689 mips32op(
"lwc1", [cpu.bs(
'110001'), base, ft, s16imm_noarg], [ft, base])
692 mips32op(
"mtc0", [cpu.bs(
'010000'), cpu.bs(
'00100'), rt, cpr0,
693 cpu.bs(
'00000000'), cpr])
694 mips32op(
"mtc1", [cpu.bs(
'010001'), cpu.bs(
'00100'), rt, fs,
695 cpu.bs(
'00000000000')])
698 mips32op(
"cfc1", [cpu.bs(
'010001'), cpu.bs(
'00010'), rt, fs,
699 cpu.bs(
'00000000000')])
701 mips32op(
"ctc1", [cpu.bs(
'010001'), cpu.bs(
'00110'), rt, fs,
702 cpu.bs(
'00000000000')])
704 mips32op(
"break", [cpu.bs(
'000000'), code, cpu.bs(
'001101')])
705 mips32op(
"syscall", [cpu.bs(
'000000'), code, cpu.bs(
'001100')])
708 mips32op(
"c", [cpu.bs(
'010001'), bs_fmt, ft, fs, fcc, cpu.bs(
'0'),
709 cpu.bs(
'0'), cpu.bs(
'11'), bs_cond], [fcc, fs, ft])
712 mips32op(
"bc1t", [cpu.bs(
'010001'), cpu.bs(
'01000'), fcc, cpu.bs(
'0'),
714 mips32op(
"bc1f", [cpu.bs(
'010001'), cpu.bs(
'01000'), fcc, cpu.bs(
'0'),
717 mips32op(
"swc1", [cpu.bs(
'111001'), base, ft, s16imm_noarg], [ft, base])
719 mips32op(
"cvt.d", [cpu.bs(
'010001'), bs_fmt, cpu.bs(
'00000'), fs, fd,
720 cpu.bs(
'100001')], [fd, fs])
721 mips32op(
"cvt.w", [cpu.bs(
'010001'), bs_fmt, cpu.bs(
'00000'), fs, fd,
722 cpu.bs(
'100100')], [fd, fs])
723 mips32op(
"cvt.s", [cpu.bs(
'010001'), bs_fmt, cpu.bs(
'00000'), fs, fd,
724 cpu.bs(
'100000')], [fd, fs])
726 mips32op(
"ext", [cpu.bs(
'011111'), rs, rt, esize, epos, cpu.bs(
'000000')],
727 [rt, rs, epos, esize])
728 mips32op(
"ins", [cpu.bs(
'011111'), rs, rt, eposh, epos, cpu.bs(
'000100')],
729 [rt, rs, epos, eposh])
731 mips32op(
"seb", [cpu.bs(
'011111'), cpu.bs(
'00000'), rt, rd, cpu.bs(
'10000'),
732 cpu.bs(
'100000')], [rd, rt])
733 mips32op(
"seh", [cpu.bs(
'011111'), cpu.bs(
'00000'), rt, rd, cpu.bs(
'11000'),
734 cpu.bs(
'100000')], [rd, rt])
735 mips32op(
"wsbh", [cpu.bs(
'011111'), cpu.bs(
'00000'), rt, rd, cpu.bs(
'00010'),
736 cpu.bs(
'100000')], [rd, rt])
738 mips32op(
"di", [cpu.bs(
'010000'), cpu.bs(
'01011'), rt, cpu.bs(
'01100'),
739 cpu.bs(
'00000'), cpu.bs(
'0'), cpu.bs(
'00'), cpu.bs(
'000')])
740 mips32op(
"ei", [cpu.bs(
'010000'), cpu.bs(
'01011'), rt, cpu.bs(
'01100'),
741 cpu.bs(
'00000'), cpu.bs(
'1'), cpu.bs(
'00'), cpu.bs(
'000')])
744 mips32op(
"tlbp", [cpu.bs(
'010000'), cpu.bs(
'1'), cpu.bs(
'0'*19),
746 mips32op(
"tlbwi", [cpu.bs(
'010000'), cpu.bs(
'1'), cpu.bs(
'0'*19),