def p_aAA8_Rd(va, val, buf, off, tsize): # mov 0x2### iflags = 0 op = val >> 12 Rd = (val >> 8) & 0xf aAA8 = val & 0xff opers = ( H8AbsAddrOper(aAA8, tsize, aasize=1), H8RegDirOper(Rd, tsize, va, 0), ) return (op, None, opers, iflags, 2)
def p_aAA24_Rd(va, val, buf, off, tsize): val2, = struct.unpack('>I', buf[off + 2:off + 6]) iflags = 0 op = val >> 4 Rd = val & 0xf aAA24 = val2 & 0xffffff opers = ( H8AbsAddrOper(aAA24, tsize, aasize=4), H8RegDirOper(Rd, tsize, va), ) return (op, None, opers, iflags, 6)
def p_aAA16_Rd(va, val, buf, off, tsize): val2, = struct.unpack('>H', buf[off + 2:off + 4]) iflags = 0 op = val >> 4 Rd = val & 0xf aAA16 = val2 opers = ( H8AbsAddrOper(aAA16, tsize, aasize=2), H8RegDirOper(Rd, tsize, va), ) return (op, None, opers, iflags, 4)
def p_7f(va, val, buf, off, tsize): # bset, bnor, bclr, bist, bst val2, = struct.unpack('>H', buf[off + 2:off + 4]) op, mnem, iflags = getBitDbl_OpMnem(val2) op |= ((val & 0xff00) << 8) aa = val & 0xff immreg = (val2 >> 4) & 0x7 if val2 & 0x1c00: opers = ( H8ImmOper(immreg, tsize), H8AbsAddrOper(aa, tsize, 1), ) else: opers = ( H8RegDirOper(immreg, tsize, va), H8AbsAddrOper(aa, tsize, 1), ) return op, mnem, opers, iflags, 4
def p_Rn_aAA8(va, val, buf, off, tsize): # bclr, bset, btst val2, = struct.unpack('>H', buf[off + 2:off + 4]) iflags = 0 op = (val & 0xff00) | ((val2 >> 4) & 0xff0) | (val2 & 0xf) Rn = (val2 >> 4) & 0xf aAA8 = val & 0xff opers = ( H8RegDirOper(Rn, tsize, va, 0), H8AbsAddrOper(aAA8, tsize, aasize=1), ) return (op, None, opers, iflags, 4)
def p_i3_aAA8(va, val, buf, off, tsize): # band, bclr, biand, bild, bior, bist, bixor, bld, bnot, bor, bset, bst, btst, bxor val2, = struct.unpack('>H', buf[off + 2:off + 4]) iflags = 0 op = (val >> 16) | (val & 0xf) | (val2 >> 15) | (val & 0xf) i3 = (val2 >> 4) & 0x7 aa = val & 0xff opers = ( H8ImmOper(i3, tsize), H8AbsAddrOper(aa, tsize, aasize=1), ) return (op, None, opers, iflags, 4)
def p_01(va, val, buf, off, tsize): mnem = None iflags = 0 opers = None diff = (val >> 4) & 0xf if diff == 8: # sleep op = 0x0180 mnem = 'sleep' opers = tuple() return op, mnem, opers, iflags, 2 val2, = struct.unpack('>H', buf[off + 2:off + 4]) isz = 4 op = (val << 9) | (val2 >> 7) if diff == 0: mnem = 'mov' # all 0100#### opcodes share these: tsize = 4 iflags |= IF_L d2 = val2 >> 8 # mov 0100##... where ## is basically another mov encoding with different register sizes if d2 == 0x69: erd = (val2 >> 4) & 7 ers = val2 & 7 if val2 & 0x80: opers = ( H8RegDirOper(ers, tsize, va), H8RegIndirOper(erd, tsize, va), ) else: opers = ( H8RegIndirOper(erd, tsize, va), H8RegDirOper(ers, tsize, va), ) elif d2 == 0x6b: if val2 & 0x20: isz = 8 val3, = struct.unpack('>I', buf[off + 4:off + 8]) if val2 & 0x80: # a erd = val2 & 7 aa = val3 & 0xffffffff opers = ( H8RegDirOper(erd, tsize, va), H8AbsAddrOper(aa, tsize, aasize=4), ) else: # 2 ers = val2 & 7 aa = val3 & 0xffffffff opers = ( H8AbsAddrOper(aa, tsize, aasize=4), H8RegDirOper(ers, tsize, va), ) else: val3, = struct.unpack('>H', buf[off + 4:off + 6]) isz = 6 if val2 & 0x80: # 8 erd = val2 & 7 aa = val3 & 0xffff opers = ( H8RegDirOper(erd, tsize, va), H8AbsAddrOper(aa, tsize, aasize=2), ) else: # 0 ers = val2 & 7 aa = val3 & 0xffff opers = ( H8AbsAddrOper(aa, tsize, aasize=2), H8RegDirOper(ers, tsize, va), ) elif d2 == 0x6d: # TODO: test me!! newop, mnem, opers, iflags, nisz = p_6c_6d_0100( va, val2, buf, off + 2, 4) isz = nisz + 2 op = newop | (0x01000000) elif d2 == 0x6f: disp, = struct.unpack('>H', buf[off + 4:off + 6]) isz = 6 er0 = val2 & 7 er1 = (val2 >> 4) & 7 if val2 & 0x80: # mov.l ERs, @(d:16,ERd) opers = ( H8RegDirOper(er0, tsize, va), H8RegIndirOper(er1, tsize, va, disp, dispsz=2), ) else: # mov.l @(d:16,ERs), ERd opers = ( H8RegIndirOper(er1, tsize, va, disp, dispsz=2), H8RegDirOper(er0, tsize, va), ) elif d2 == 0x78: isz = 10 val3, disp = struct.unpack('>HI', buf[off + 4:off + 10]) if val3 & 0xff20 != 0x6b20: raise envi.InvalidInstruction(bytez=buf[off:off + 16], va=va) er0 = val3 & 7 er1 = (val2 >> 4) & 7 if (val3 & 0x80): # mov.l ERs, @(d:24,ERd) opers = ( H8RegDirOper(er0, tsize, va), H8RegIndirOper(er1, tsize, va, disp, dispsz=4), ) else: # mov.l @(d:24,ERs), ERd opers = ( H8RegIndirOper(er1, tsize, va, disp, dispsz=4), H8RegDirOper(er0, tsize, va), ) elif diff in (1, 2, 3): # ldm/stm (ERn-ERn+diff), @-SP iflags = IF_L tsize = 4 optest = val2 & 0xfff8 rn = val2 & 0x7 rcount = diff + 1 if optest == 0x6df0: mnem = 'stm' opers = ( H8RegMultiOper(rn, rcount), H8RegIndirOper(REG_SP, tsize, va, 0, oflags=OF_PREDEC), ) elif optest == 0x6d70: mnem = 'ldm' opers = ( H8RegIndirOper(REG_SP, tsize, va, 0, oflags=OF_POSTINC), H8RegMultiOper(rn - diff, rcount), ) else: raise envi.InvalidInstruction(bytez=buf[off:off + 16], va=va) elif diff == 4: # ldc/stc - anything that touches ccr or exr # we'll build it for ldc, and reverse it if it's stc d2 = val2 >> 8 isStc = (val2 >> 7) & 1 oflags = 0 tsize = 2 exr = val & 0x1 if d2 == 6: op, nmnem, opers, iflags, nisz = p_i8_CCR(va, val2, buf, off, tsize, exr) return op, 'andc', opers, iflags, isz elif d2 == 5: op, nmnem, opers, iflags, nisz = p_i8_CCR(va, val2, buf, off, tsize, exr) return op, 'xorc', opers, iflags, isz else: iflags = IF_W tsize = 2 if d2 == 0x04: ##xx:8, EXR op, nmnem, opers, iflags, nisz = p_i8_CCR( va, val2, buf, off, tsize, exr) return op, 'orc', opers, iflags, isz elif d2 == 0x07: ##xx:8, EXR op, nmnem, opers, niflags, nisz = p_i8_CCR( va, val2, buf, off, tsize, exr) iflags = IF_B return op, 'ldc', opers, iflags, isz elif d2 in (0x69, 0x6d): #@ERs,CCR / @ERs+,CCR if d2 == 0x6d: oflags = OF_POSTINC ers = (val2 >> 4) & 0x7 opers = (H8RegIndirOper(ers, tsize, va, oflags=oflags), H8RegDirOper(REG_CCR + exr, 4, va)) elif d2 in (0x6f, 0x78): #@(d:16,ERs),CCR / @(d:24,ERs) if d2 == 0x78: val3, disp = struct.unpack('>HI', buf[off + 4:off + 10]) isStc = (val3 >> 7) & 1 isz = 10 dispsz = 4 else: disp, = struct.unpack('>H', buf[off + 4:off + 6]) isz = 6 dispsz = 2 ers = (val2 >> 4) & 0x7 opers = (H8RegIndirOper(ers, tsize, va, disp, dispsz), H8RegDirOper(REG_CCR + exr, 4, va)) elif d2 == 0x6b: #@aa:16,CCR / @aa:24,CCR if val2 & 0x20: aa, = struct.unpack('>I', buf[off + 4:off + 8]) isz = 8 aasize = 4 else: aa, = struct.unpack('>H', buf[off + 4:off + 6]) isz = 6 aasize = 2 isStc = (val2 >> 7) & 1 opers = (H8AbsAddrOper(aa, tsize, aasize), H8RegDirOper(REG_CCR + exr, 4, va)) # after all the decisions... mnem = ('ldc', 'stc')[isStc] if isStc: opers = opers[::-1] elif diff == 0xc: if val2 & 0xfd00 == 0x5000: # mulxs mnem = 'mulxs' op, nmnem, opers, iflags, nisz = p_Rs_Rd_4b(va, val, buf, off, tsize=1) else: raise envi.InvalidInstruction(bytez=buf[off:off + 16], va=va) elif diff == 0xd: if val2 & 0xfd00 == 0x5100: mnem = 'divxs' # divxs op, nmnem, opers, iflags, nisz = p_Rs_Rd_4b( va, val, buf, off, tsize) else: raise envi.InvalidInstruction(bytez=buf[off:off + 16], va=va) elif diff == 0xe: if val2 & 0xff00 == 0x7b00: mnem = 'tas' # FIXME: check out what this decodes to tsize = 1 erd = (val2 >> 4) & 7 opers = (H8RegIndirOper(erd, tsize, va, oflags=0), ) else: raise envi.InvalidInstruction(bytez=buf[off:off + 16], va=va) elif diff == 0xf: if val2 & 0xfc00 == 0x6400: # or/xor/and nop, nmnem, opers, iflags, nisz = p_ERs_ERd(va, val2, buf, off, tsize=4) op = (val << 8) | (val2 >> 8) mnembits = (val2 >> 8) & 3 mnem = ('or', 'xor', 'and')[mnembits] else: raise envi.InvalidInstruction(bytez=buf[off:off + 16], va=va) else: raise envi.InvalidInstruction(bytez=buf[off:off + 16], va=va) return (op, mnem, opers, iflags, isz)