def p_6A_6B(va, val, buf, off, tsize): op = val >> 4 diff = op & 0xf osz = 1 + ((val >> 8) & 1) if op & 0x8: # Rs, @aa:16/24 if diff == 0xa: op, mnem, opers, iflags, isz = p_Rs_aAA24(va, val, buf, off, tsize) iflags |= e_const.OSZ_FLAGS[osz] return op, mnem, opers, iflags, isz elif diff == 0x8: op, mnem, opers, iflags, isz = p_Rs_aAA16(va, val, buf, off, tsize) iflags |= e_const.OSZ_FLAGS[osz] return op, mnem, opers, iflags, isz else: raise envi.InvalidInstruction(bytez=buf[off:off + 16], va=va) else: # @aa:16/24, Rd if diff == 0x2: op, mnem, opers, iflags, isz = p_aAA24_Rd(va, val, buf, off, tsize) iflags |= e_const.OSZ_FLAGS[osz] return op, mnem, opers, iflags, isz elif diff == 0x0: op, mnem, opers, iflags, isz = p_aAA16_Rd(va, val, buf, off, tsize) iflags |= e_const.OSZ_FLAGS[osz] return op, mnem, opers, iflags, isz elif val in (0x6a10, 0x6a18, 0x6a30, 0x6a38): # non-MOV instructions isz, aasize, fmt = (None, (6, 2, '>HH'), None, (8, 4, '>IH'))[(val >> 4) & 3] aa, val2 = struct.unpack(fmt, buf[off + 2:off + isz]) op, mnem, niflags = getBitDbl_OpMnem(val2) if val2 & 0x1c00: i3 = (val2 >> 4) & 7 opers = ( h8_operands.H8ImmOper(i3, tsize), h8_operands.H8AbsAddrOper(aa, tsize, aasize), ) else: rn = (val2 >> 4) & 0xf opers = ( h8_operands.H8RegDirOper( rn, tsize, va, ), h8_operands.H8AbsAddrOper(aa, tsize, aasize), ) return op, mnem, opers, 0, isz else: raise envi.InvalidInstruction(bytez=buf[off:off + 16], va=va)
def p_aAA24(va, val, buf, off, tsize): # jmp, jsr val2, = struct.unpack('>H', buf[off + 2:off + 4]) iflags = 0 op = val >> 8 aAA24 = ((val & 0xf) << 16) | val2 opers = (h8_operands.H8AbsAddrOper(aAA24, tsize, aasize=3), ) return (op, None, opers, iflags, 4)
def p_7e(va, val, buf, off, tsize): # btst, bor, bior, bxor, bixor, band, biand, bid, bild (erd) val2, = struct.unpack('>H', buf[off + 2:off + 4]) op, mnem, iflags = getBitDbl_OpMnem(val2) op |= ((val & 0xff80) << 9) aa = val & 0xff telltale = (val2 >> 8) # FIXME: is any of this redundant with previous encodings? if telltale == 0x63: # btst (0x####63## mnem = 'btst' rn = (val2 >> 4) & 0xf opers = ( h8_operands.H8RegDirOper(rn, tsize, va, 0), h8_operands.H8AbsAddrOper(aa, tsize=tsize, aasize=1), ) elif telltale == 0x73: # btst (0x####73## mnem = 'btst' i3 = (val2 >> 4) & 0x7 opers = ( h8_operands.H8ImmOper(i3, tsize), h8_operands.H8AbsAddrOper(aa, tsize=tsize, aasize=1), ) elif 0x78 > telltale > 0x73: # other bit-halves: tsize = 1 i3 = (val2 >> 4) & 0x7 opers = ( h8_operands.H8ImmOper(i3, tsize), h8_operands.H8AbsAddrOper(aa, tsize=tsize, aasize=1), ) else: raise envi.InvalidInstruction(bytez=buf[off:off + 16], va=va) return op, mnem, opers, iflags, 4
def p_Rs_aAA8(va, val, buf, off, tsize): # mov 0x3### iflags = 0 op = val >> 12 Rs = (val >> 8) & 0xf aAA8 = val & 0xff opers = ( h8_operands.H8RegDirOper(Rs, tsize, va, 0), h8_operands.H8AbsAddrOper(aAA8, tsize, aasize=1), ) 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 = ( h8_operands.H8AbsAddrOper(aAA24, tsize, aasize=4), h8_operands.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 = ( h8_operands.H8AbsAddrOper(aAA16, tsize, aasize=2), h8_operands.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 = ( h8_operands.H8ImmOper(immreg, tsize), h8_operands.H8AbsAddrOper(aa, tsize, 1), ) else: opers = ( h8_operands.H8RegDirOper(immreg, tsize, va), h8_operands.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 = ( h8_operands.H8RegDirOper(Rn, tsize, va, 0), h8_operands.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 = ( h8_operands.H8ImmOper(i3, tsize), h8_operands.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 |= e_const.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 = ( h8_operands.H8RegDirOper(ers, tsize, va), h8_operands.H8RegIndirOper(erd, tsize, va), ) else: opers = ( h8_operands.H8RegIndirOper(erd, tsize, va), h8_operands.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 = ( h8_operands.H8RegDirOper(erd, tsize, va), h8_operands.H8AbsAddrOper(aa, tsize, aasize=4), ) else: # 2 ers = val2 & 7 aa = val3 & 0xffffffff opers = ( h8_operands.H8AbsAddrOper(aa, tsize, aasize=4), h8_operands.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 = ( h8_operands.H8RegDirOper(erd, tsize, va), h8_operands.H8AbsAddrOper(aa, tsize, aasize=2), ) else: # 0 ers = val2 & 7 aa = val3 & 0xffff opers = ( h8_operands.H8AbsAddrOper(aa, tsize, aasize=2), h8_operands.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 = ( h8_operands.H8RegDirOper(er0, tsize, va), h8_operands.H8RegIndirOper(er1, tsize, va, disp, dispsz=2), ) else: # mov.l @(d:16,ERs), ERd opers = ( h8_operands.H8RegIndirOper(er1, tsize, va, disp, dispsz=2), h8_operands.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 = ( h8_operands.H8RegDirOper(er0, tsize, va), h8_operands.H8RegIndirOper(er1, tsize, va, disp, dispsz=4), ) else: # mov.l @(d:24,ERs), ERd opers = ( h8_operands.H8RegIndirOper(er1, tsize, va, disp, dispsz=4), h8_operands.H8RegDirOper(er0, tsize, va), ) elif diff in (1, 2, 3): # ldm/stm (ERn-ERn+diff), @-SP iflags = e_const.IF_L tsize = 4 optest = val2 & 0xfff8 rn = val2 & 0x7 rcount = diff + 1 if optest == 0x6df0: mnem = 'stm' opers = ( h8_operands.H8RegMultiOper(rn, rcount), h8_operands.H8RegIndirOper(e_const.REG_SP, tsize, va, 0, oflags=e_const.OF_PREDEC), ) elif optest == 0x6d70: mnem = 'ldm' opers = ( h8_operands.H8RegIndirOper(e_const.REG_SP, tsize, va, 0, oflags=e_const.OF_POSTINC), h8_operands.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 = e_const.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 = e_const.IF_B return op, 'ldc', opers, iflags, isz elif d2 in (0x69, 0x6d): # @ERs,CCR / @ERs+,CCR if d2 == 0x6d: oflags = e_const.OF_POSTINC ers = (val2 >> 4) & 0x7 opers = (h8_operands.H8RegIndirOper(ers, tsize, va, oflags=oflags), h8_operands.H8RegDirOper(e_regs.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 = (h8_operands.H8RegIndirOper(ers, tsize, va, disp, dispsz), h8_operands.H8RegDirOper(e_regs.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 = (h8_operands.H8AbsAddrOper(aa, tsize, aasize), h8_operands.H8RegDirOper(e_regs.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 = (h8_operands.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)