Miasm2
 All Classes Namespaces Files Functions Variables Typedefs Properties Macros
arch.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 #-*- coding:utf-8 -*-
3 
4 import logging
5 from collections import defaultdict
6 
7 from pyparsing import Literal, Group, Optional
8 
9 from miasm2.expression.expression import ExprMem, ExprInt, ExprInt32, ExprId
10 from miasm2.core.bin_stream import bin_stream
11 import miasm2.arch.mips32.regs as regs
12 import miasm2.core.cpu as cpu
13 from miasm2.core.asmbloc import asm_label
14 
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)
20 
21 
22 gpregs = cpu.reg_info(regs.regs32_str, regs.regs32_expr)
23 
24 
25 
26 LPARENTHESIS = Literal("(")
27 RPARENTHESIS = Literal(")")
28 
29 def deref2expr(s, l, t):
30  t = t[0]
31  if len(t) != 4:
32  raise NotImplementedError("TODO")
33 
34  return ExprMem(t[2] + t[0])
35 
36 def deref2expr_nooff(s, l, t):
37  t = t[0]
38  if len(t) != 3:
39  raise NotImplementedError("TODO")
40  return ExprMem(t[1])
41 
42 base_expr = cpu.base_expr
43 
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
49 
50 
51 variable, operand, base_expr = cpu.gen_base_expr()
52 
53 int_or_expr = base_expr
54 
55 
56 def ast_id2expr(t):
57  if not t in mn_mips32.regs.all_regs_ids_byname:
58  r = ExprId(asm_label(t))
59  else:
60  r = mn_mips32.regs.all_regs_ids_byname[t]
61  return r
62 
63 
64 def ast_int2expr(a):
65  return ExprInt32(a)
66 
67 
68 my_var_parser = cpu.parse_ast(ast_id2expr, ast_int2expr)
69 base_expr.setParseAction(my_var_parser)
70 
72  def __init__(self):
73  self.except_on_instr = False
74 
75 br_0 = ['B', 'J', 'JR', 'BAL', 'JAL', 'JALR']
76 br_1 = ['BGEZ', 'BLTZ', 'BGTZ', 'BLEZ', 'BC1T', 'BC1F']
77 br_2 = ['BEQ', 'BEQL', 'BNE']
78 
79 
80 class instruction_mips32(cpu.instruction):
81  delayslot = 1
82 
83  def __init__(self, *args, **kargs):
84  super(instruction_mips32, self).__init__(*args, **kargs)
85 
86 
87  @staticmethod
88  def arg2str(e, pos = None):
89  if isinstance(e, ExprId) or isinstance(e, ExprInt):
90  return str(e)
91  assert(isinstance(e, ExprMem))
92  arg = e.arg
93  if isinstance(arg, ExprId):
94  return "(%s)"%arg
95  assert(len(arg.args) == 2 and arg.op == '+')
96  return "%s(%s)"%(arg.args[1], arg.args[0])
97 
98  def dstflow(self):
99  if self.name == 'BREAK':
100  return False
101  if self.name in br_0 + br_1 + br_2:
102  return True
103  return False
104 
105  def get_dst_num(self):
106  if self.name in br_0:
107  i = 0
108  elif self.name in br_1:
109  i = 1
110  elif self.name in br_2:
111  i = 2
112  else:
113  raise NotImplementedError("TODO %s"%self)
114  return i
115 
116  def dstflow2label(self, symbol_pool):
117  if self.name in ["J", 'JAL']:
118  e = self.args[0].arg
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)
122  return
123 
124  ndx = self.get_dst_num()
125  e = self.args[ndx]
126 
127  if not isinstance(e, ExprInt):
128  return
129  ad = e.arg + self.offset
130  l = symbol_pool.getby_offset_create(ad)
131  s = ExprId(l, e.size)
132  self.args[ndx] = s
133 
134  def breakflow(self):
135  if self.name == 'BREAK':
136  return False
137  if self.name in br_0 + br_1 + br_2:
138  return True
139  return False
140 
141  def is_subcall(self):
142  if self.name in ['JAL', 'JALR', 'BAL']:
143  return True
144  return False
145 
146  def getdstflow(self, symbol_pool):
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]]
155  else:
156  raise NotImplementedError("fix mnemo %s"%self.name)
157 
158  def splitflow(self):
159  if self.name in ["B", 'JR', 'J']:
160  return False
161  if self.name in br_0:
162  return True
163  if self.name in br_1:
164  return True
165  if self.name in br_2:
166  return True
167  if self.name in ['JAL', 'JALR']:
168  return True
169  return False
170 
171  def get_symbol_size(self, symbol, symbol_pool):
172  return 32
173 
174  def fixDstOffset(self):
175  ndx = self.get_dst_num()
176  e = self.args[ndx]
177  if self.offset is None:
178  raise ValueError('symbol not resolved %s' % self.l)
179  if not isinstance(e, ExprInt):
180  return
181  off = e.arg - self.offset
182  if int(off % 4):
183  raise ValueError('strange offset! %r' % off)
184  self.args[ndx] = ExprInt32(off)
185 
186  def get_args_expr(self):
187  args = [a for a in self.args]
188  return args
189 
190 
191 class mn_mips32(cpu.cls_mn):
192  delayslot = 0
193  name = "mips32"
194  regs = regs
195  bintree = {}
196  num = 0
197  all_mn = []
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
205 
206  @classmethod
207  def getpc(cls, attrib = None):
208  return regs.PC
209 
210  @classmethod
211  def getsp(cls, attrib = None):
212  return regs.SP
213 
214  def additional_info(self):
215  info = additional_info()
216  return info
217 
218  @classmethod
219  def getbits(cls, bitstream, attrib, start, n):
220  if not n:
221  return 0
222  o = 0
223  while n:
224  offset = start / 8
225  n_offset = cls.endian_offset(attrib, offset)
226  c = cls.getbytes(bitstream, n_offset, 1)
227  if not c:
228  raise IOError
229  c = ord(c)
230  r = 8 - start % 8
231  c &= (1 << r) - 1
232  l = min(r, n)
233  c >>= (r - l)
234  o <<= l
235  o |= c
236  n -= l
237  start += l
238  return o
239 
240  @classmethod
241  def endian_offset(cls, attrib, offset):
242  if attrib == "l":
243  return (offset & ~3) + 3 - offset % 4
244  elif attrib == "b":
245  return offset
246  else:
247  raise NotImplementedError('bad attrib')
248 
249  @classmethod
250  def check_mnemo(cls, fields):
251  l = sum([x.l for x in fields])
252  assert l == 32, "len %r" % l
253 
254  @classmethod
255  def getmn(cls, name):
256  return name.upper()
257 
258  @classmethod
259  def gen_modes(cls, subcls, name, bases, dct, fields):
260  dct['mode'] = None
261  return [(subcls, name, bases, dct, fields)]
262 
263  def value(self, mode):
264  v = super(mn_mips32, self).value(mode)
265  if mode == 'l':
266  return [x[::-1] for x in v]
267  elif mode == 'b':
268  return [x for x in v]
269  else:
270  raise NotImplementedError('bad attrib')
271 
272 
273 
274 def mips32op(name, fields, args=None, alias=False):
275  dct = {"fields": fields}
276  dct["alias"] = alias
277  if args is not None:
278  dct['args'] = args
279  type(name, (mn_mips32,), dct)
280  #type(name, (mn_mips32b,), dct)
281 
282 
283 class mips32_reg(cpu.reg_noarg, cpu.m_arg):
284  pass
285 
286 class mips32_gpreg(mips32_reg):
287  reg_info = gpregs
288  parser = reg_info.parser
289 
291  reg_info = regs.fltregs
292  parser = reg_info.parser
293 
294 
296  reg_info = regs.fccregs
297  parser = reg_info.parser
298 
299 class mips32_imm(cpu.imm_noarg):
300  parser = cpu.base_expr
301 
302 
304  def decode(self, v):
305  v = v & self.lmask
306  v = cpu.sign_ext(v, 16, 32)
307  self.expr = ExprInt32(v)
308  return True
309 
310  def encode(self):
311  if not isinstance(self.expr, ExprInt):
312  return False
313  v = self.expr.arg.arg
314  if v & 0x80000000:
315  nv = v & ((1 << 16) - 1)
316  assert( v == cpu.sign_ext(nv, 16, 32))
317  v = nv
318  self.value = v
319  return True
320 
322  def decode(self, v):
323  v = v & self.lmask
324  v <<= 2
325  v = cpu.sign_ext(v, 16+2, 32)
326  # Add pipeline offset
327  self.expr = ExprInt32(v + 4)
328  return True
329 
330  def encode(self):
331  if not isinstance(self.expr, ExprInt):
332  return False
333  # Remove pipeline offset
334  v = int(self.expr.arg - 4)
335  if v & 0x80000000:
336  nv = v & ((1 << 16+2) - 1)
337  assert( v == cpu.sign_ext(nv, 16+2, 32))
338  v = nv
339  self.value = v>>2
340  return True
341 
342 
344  pass
345 
346 class mips32_soff(mips32_soff_noarg, cpu.m_arg):
347  pass
348 
349 
350 class mips32_instr_index(mips32_imm, cpu.m_arg):
351  def decode(self, v):
352  v = v & self.lmask
353  self.expr = ExprInt32(v<<2)
354  return True
355 
356  def encode(self):
357  if not isinstance(self.expr, ExprInt):
358  return False
359  v = self.expr.arg.arg
360  if v & 3:
361  return False
362  v>>=2
363  if v > (1<<self.l):
364  return False
365  self.value = v
366  return True
367 
368 
369 class mips32_u16imm(mips32_imm, cpu.m_arg):
370  def decode(self, v):
371  v = v & self.lmask
372  self.expr = ExprInt32(v)
373  return True
374 
375  def encode(self):
376  if not isinstance(self.expr, ExprInt):
377  return False
378  v = self.expr.arg.arg
379  assert(v < (1<<16))
380  self.value = v
381  return True
382 
383 class mips32_dreg_imm(cpu.m_arg):
384  parser = deref
385  def decode(self, v):
386  imm = self.parent.imm.expr
387  r = gpregs.expr[v]
388  self.expr = ExprMem(r+imm)
389  return True
390 
391  def encode(self):
392  e = self.expr
393  if not isinstance(e, ExprMem):
394  return False
395  arg = e.arg
396  if isinstance(arg, ExprId):
397  self.parent.imm.expr = ExprInt32(0)
398  r = arg
399  elif len(arg.args) == 2 and arg.op == "+":
400  self.parent.imm.expr = arg.args[1]
401  r = arg.args[0]
402  else:
403  return False
404  self.value = gpregs.expr.index(r)
405  return True
406 
407  @staticmethod
408  def arg2str(e):
409  assert(isinstance(e, ExprMem))
410  arg = e.arg
411  if isinstance(arg, ExprId):
412  return "(%s)"%arg
413  assert(len(arg.args) == 2 and arg.op == '+')
414  return "%s(%s)"%(arg.args[1], arg.args[0])
415 
416 class mips32_esize(mips32_imm, cpu.m_arg):
417  def decode(self, v):
418  v = v & self.lmask
419  self.expr = ExprInt32(v+1)
420  return True
421 
422  def encode(self):
423  if not isinstance(self.expr, ExprInt):
424  return False
425  v = self.expr.arg.arg -1
426  assert(v < (1<<16))
427  self.value = v
428  return True
429 
430 class mips32_eposh(mips32_imm, cpu.m_arg):
431  def decode(self, v):
432  self.expr = ExprInt32(v-int(self.parent.epos.expr.arg)+1)
433  return True
434 
435  def encode(self):
436  if not isinstance(self.expr, ExprInt):
437  return False
438  v = int(self.expr.arg) + int(self.parent.epos.expr.arg) -1
439  self.value = v
440  return True
441 
442 
443 
444 
445 class mips32_cpr(cpu.m_arg):
446  parser = regs.regs_cpr0_info.parser
447  def decode(self, v):
448  index = int(self.parent.cpr0.expr.arg) << 3
449  index += v
450  self.expr = regs.regs_cpr0_expr[index]
451  return True
452  def encode(self):
453  e = self.expr
454  if not e in regs.regs_cpr0_expr:
455  return False
456  index = regs.regs_cpr0_expr.index(e)
457  self.value = index & 7
458  index >>=2
459  self.parent.cpr0.value = index
460  return True
461 
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,))
468 
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,))
474 
475 cpr0 = cpu.bs(l=5, cls=(mips32_imm,), fname="cpr0")
476 cpr = cpu.bs(l=3, cls=(mips32_cpr,))
477 
478 
479 s16imm_noarg = cpu.bs(l=16, cls=(mips32_s16imm_noarg,), fname="imm",
480  order=-1)
481 
482 hint = cpu.bs(l=5, default_val="00000")
483 fcc = cpu.bs(l=3, cls=(mips32_fccreg,))
484 
485 sel = cpu.bs(l=3, cls=(mips32_u16imm,))
486 
487 code = cpu.bs(l=20, cls=(mips32_u16imm,))
488 
489 esize = cpu.bs(l=5, cls=(mips32_esize,))
490 epos = cpu.bs(l=5, cls=(mips32_u16imm,), fname="epos",
491  order=-1)
492 
493 eposh = cpu.bs(l=5, cls=(mips32_eposh,))
494 
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',
498  0x16: '.PS'})
499 class bs_cond(cpu.bs_mod_name):
500  mn_mod = ['.F', '.UN', '.EQ', '.UEQ',
501  '.OLT', '.ULT', '.OLE', '.ULE',
502  '.SF', '.NGLE', '.SEQ', '.NGL',
503  '.LT', '.NGE', '.LE', '.NGT'
504  ]
505 
506  def modname(self, name, f_i):
507  raise NotImplementedError("Not implemented")
508 
509 
510 class bs_cond_name(cpu.bs_divert):
511  prio = 2
512  mn_mod = [['.F', '.UN', '.EQ', '.UEQ',
513  '.OLT', '.ULT', '.OLE', '.ULE'],
514  ['.SF', '.NGLE', '.SEQ', '.NGL',
515  '.LT', '.NGE', '.LE', '.NGT']
516  ]
517 
518  def divert(self, index, candidates):
519  out = []
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)
524  cond1 = cond1.pop()
525  mm = self.mn_mod[cond1.value]
526  for value, new_name in enumerate(mm):
527  nfields = fields[:]
528  s = cpu.int2bin(value, self.args['l'])
529  args = dict(self.args)
530  args.update({'strbits': s})
531  f = cpu.bs(**args)
532  nfields[index] = f
533  ndct = dict(dct)
534  ndct['name'] = name + new_name
535  out.append((cls, new_name, bases, ndct, nfields))
536  return out
537 
538 
539 
540 class bs_cond_mod(cpu.bs_mod_name):
541  prio = 1
542 
543 bs_cond = bs_cond_mod(l=4,
544  mn_mod = ['.F', '.UN', '.EQ', '.UEQ',
545  '.OLT', '.ULT', '.OLE', '.ULE',
546  '.SF', '.NGLE', '.SEQ', '.NGL',
547  '.LT', '.NGE', '.LE', '.NGT'])
548 
549 
550 
551 bs_arith = cpu.bs_name(l=6, name={'ADDU':0b100001,
552  'SUBU':0b100011,
553  'OR':0b100101,
554  'AND':0b100100,
555  'SLTU':0b101011,
556  'XOR':0b100110,
557  'SLT':0b101010,
558  'SUBU':0b100011,
559  'NOR':0b100111,
560  'MOVN':0b001011,
561  'MOVZ':0b001010,
562  })
563 
564 bs_shift = cpu.bs_name(l=6, name={'SLL':0b000000,
565  'SRL':0b000010,
566  'SRA':0b000011,
567  })
568 
569 bs_shift1 = cpu.bs_name(l=6, name={'SLLV':0b000100,
570  'SRLV':0b000110,
571  'SRAV':0b000111,
572  })
573 
574 
575 bs_arithfmt = cpu.bs_name(l=6, name={'ADD':0b000000,
576  'SUB':0b000001,
577  'MUL':0b000010,
578  'DIV':0b000011,
579  })
580 
581 bs_s_l = cpu.bs_name(l=6, name = {"SW": 0b101011,
582  "SH": 0b101001,
583  "SB": 0b101000,
584  "LW": 0b100011,
585  "LH": 0b100001,
586  "LB": 0b100000,
587  "LHU": 0b100101,
588  "LBU": 0b100100,
589  "LWL": 0b100010,
590  "LWR": 0b100110,
591 
592  "SWL": 0b101010,
593  "SWR": 0b101110,
594  })
595 
596 
597 bs_oax = cpu.bs_name(l=6, name = {"ORI": 0b001101,
598  "ANDI": 0b001100,
599  "XORI": 0b001110,
600  })
601 
602 bs_bcc = cpu.bs_name(l=5, name = {"BGEZ": 0b00001,
603  "BGEZL": 0b00011,
604  "BGEZAL": 0b10001,
605  "BGEZALL": 0b10011,
606  "BLTZ": 0b00000,
607  "BLTZL": 0b00010,
608  "BLTZAL": 0b10000,
609  "BLTZALL": 0b10010,
610  })
611 
612 
613 
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])
619 
620 mips32op("arith", [cpu.bs('000000'), rs, rt, rd, cpu.bs('00000'), bs_arith],
621  [rd, rs, rt])
622 mips32op("shift1", [cpu.bs('000000'), rs, rt, rd, cpu.bs('00000'), bs_shift1],
623  [rd, rt, rs])
624 
625 mips32op("shift", [cpu.bs('000000'), cpu.bs('00000'), rt, rd, sa, bs_shift],
626  [rd, rt, sa])
627 
628 mips32op("rotr", [cpu.bs('000000'), cpu.bs('00001'), rt, rd, sa,
629  cpu.bs('000010')], [rd, rt, sa])
630 
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'),
634  cpu.bs('011010')])
635 
636 mips32op("s_l", [bs_s_l, base, rt, s16imm_noarg], [rt, base])
637 
638 #mips32op("mfc0", [bs('010000'), bs('00000'), rt, rd, bs('00000000'), sel])
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')])
643 
644 mips32op("ldc1", [cpu.bs('110101'), base, ft, s16imm_noarg], [ft, base])
645 
646 mips32op("mov", [cpu.bs('010001'), bs_fmt, cpu.bs('00000'), fs, fd,
647  cpu.bs('000110')], [fd, fs])
648 
649 mips32op("add", [cpu.bs('010001'), bs_fmt, ft, fs, fd, bs_arithfmt],
650  [fd, fs, ft])
651 
652 mips32op("divu", [cpu.bs('000000'), rs, rt, cpu.bs('0000000000'),
653  cpu.bs('011011')])
654 mips32op("mult", [cpu.bs('000000'), rs, rt, cpu.bs('0000000000'),
655  cpu.bs('011000')])
656 mips32op("multu", [cpu.bs('000000'), rs, rt, cpu.bs('0000000000'),
657  cpu.bs('011001')])
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')])
662 
663 
664 mips32op("b", [cpu.bs('000100'), cpu.bs('00000'), cpu.bs('00000'), soff],
665  alias = True)
666 mips32op("bne", [cpu.bs('000101'), rs, rt, soff])
667 mips32op("beq", [cpu.bs('000100'), rs, rt, soff])
668 
669 mips32op("blez", [cpu.bs('000110'), rs, cpu.bs('00000'), soff])
670 
671 mips32op("bcc", [cpu.bs('000001'), rs, bs_bcc, soff])
672 
673 mips32op("bgtz", [cpu.bs('000111'), rs, cpu.bs('00000'), soff])
674 mips32op("bal", [cpu.bs('000001'), cpu.bs('00000'), cpu.bs('10001'), soff],
675  alias = True)
676 
677 
678 mips32op("slti", [cpu.bs('001010'), rs, rt, s16imm], [rt, rs, s16imm])
679 mips32op("sltiu", [cpu.bs('001011'), rs, rt, s16imm], [rt, rs, s16imm])
680 
681 
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,
685  cpu.bs('001001')])
686 mips32op("jr", [cpu.bs('000000'), rs, cpu.bs('0000000000'), hint,
687  cpu.bs('001000')])
688 
689 mips32op("lwc1", [cpu.bs('110001'), base, ft, s16imm_noarg], [ft, base])
690 
691 #mips32op("mtc0", [bs('010000'), bs('00100'), rt, rd, bs('00000000'), sel])
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')])
696 
697 # XXXX TODO CFC1
698 mips32op("cfc1", [cpu.bs('010001'), cpu.bs('00010'), rt, fs,
699  cpu.bs('00000000000')])
700 # XXXX TODO CTC1
701 mips32op("ctc1", [cpu.bs('010001'), cpu.bs('00110'), rt, fs,
702  cpu.bs('00000000000')])
703 
704 mips32op("break", [cpu.bs('000000'), code, cpu.bs('001101')])
705 mips32op("syscall", [cpu.bs('000000'), code, cpu.bs('001100')])
706 
707 
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])
710 
711 
712 mips32op("bc1t", [cpu.bs('010001'), cpu.bs('01000'), fcc, cpu.bs('0'),
713  cpu.bs('1'), soff])
714 mips32op("bc1f", [cpu.bs('010001'), cpu.bs('01000'), fcc, cpu.bs('0'),
715  cpu.bs('0'), soff])
716 
717 mips32op("swc1", [cpu.bs('111001'), base, ft, s16imm_noarg], [ft, base])
718 
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])
725 
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])
730 
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])
737 
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')])
742 
743 
744 mips32op("tlbp", [cpu.bs('010000'), cpu.bs('1'), cpu.bs('0'*19),
745  cpu.bs('001000')])
746 mips32op("tlbwi", [cpu.bs('010000'), cpu.bs('1'), cpu.bs('0'*19),
747  cpu.bs('000010')])