def p_aERn(va, val, buf, off, tsize): # jmp, jsr iflags = 0 op = ((val >> 3) & 0xfff0) | (val & 0xf) aERn = (val >> 4) & 0x7 opers = (h8_operands.H8RegIndirOper(aERn, tsize, va, 0), ) return (op, None, opers, iflags, 2)
def p_6c_6d_0100(va, val, buf, off, tsize): op = val >> 7 iflags = e_const.OSZ_FLAGS[tsize] isz = 2 mnem = None er0 = val & 0xf er1 = (val >> 4) & 7 if val & 0x80: # mov ERs, @-ERd if val & 0xf0 == 0xf0: # push mnem = 'push' opers = (h8_operands.H8RegDirOper(er0, tsize, va), ) else: # mov mnem = 'mov' opers = ( h8_operands.H8RegDirOper(er0, tsize, va), h8_operands.H8RegIndirOper(er1, tsize, va, 0, oflags=e_const.OF_PREDEC), ) else: # mov @ERs+,ERd if val & 0xf0 == 0x70: # pop mnem = 'pop' opers = (h8_operands.H8RegDirOper(er0, tsize, va), ) else: # mov mnem = 'mov' opers = ( h8_operands.H8RegIndirOper(er1, tsize, va, 0, oflags=e_const.OF_POSTINC), h8_operands.H8RegDirOper(er0, tsize, va), ) return (op, mnem, opers, iflags, isz)
def p_Mov_78(va, val, buf, off, tsize): val2, val3_4 = struct.unpack('>HI', buf[off + 2:off + 8]) op = (val3_4 >> 24) | ((val2 & 0xfff0) << 4) | ( (val & 0xff80) << (20 + 1)) | ((val & 0xf) << 20) # FIXME: complex and ugly. do we even need these in this impl? mnem = None disp = val3_4 & 0xffffffff # tsize is all over the map. must determine here. tsz_opt = (val2 >> 8) & 1 tsize = (1, 2)[tsz_opt] iflags = e_const.OSZ_FLAGS[tsize] if (val2 & 0x80): erd = (val >> 4) & 0x7 rs = val2 & 0xf opers = ( h8_operands.H8RegDirOper(rs, tsize), h8_operands.H8RegIndirOper(erd, tsize, va, disp=disp, dispsz=4, oflags=0), ) else: ers = (val >> 4) & 0x7 rd = val2 & 0xf opers = ( h8_operands.H8RegIndirOper(ers, tsize, va, disp=disp, dispsz=4, oflags=0), h8_operands.H8RegDirOper(rd, tsize), ) return (op, mnem, opers, iflags, 8)
def p_7c(va, val, buf, off, tsize): # btst, bor, bior, bxor, bixor, band, biand, bid, bild (erd) val2, = struct.unpack('>H', buf[off + 2:off + 4]) iflags = 0 op, mnem, flags = getBitDbl_OpMnem(val2) op |= ((val & 0xff80) << 9) telltale = (val2 >> 8) # FIXME: is any of this redundant with previous encodings? if telltale == 0x63: # btst (0x####63## mnem = 'btst' erd = (val >> 4) & 0x7 rn = (val2 >> 4) & 0xf opers = ( h8_operands.H8RegDirOper(rn, tsize=tsize), h8_operands.H8RegIndirOper(erd, tsize, va), ) elif telltale == 0x73: # btst (0x####73## mnem = 'btst' erd = (val >> 4) & 0x7 imm = (val2 >> 4) & 0x7 opers = ( h8_operands.H8ImmOper(imm, tsize), h8_operands.H8RegIndirOper(erd, tsize, va), ) elif 0x78 > telltale > 0x73: # other bit-halves: i3 = (val2 >> 4) & 0x7 erd = (val >> 4) & 0x7 opers = ( h8_operands.H8ImmOper(i3, tsize), h8_operands.H8RegIndirOper(erd, tsize, va), ) return op, mnem, opers, iflags, 4
def p_7d(va, val, buf, off, tsize): # bset, bnor, bclr, bst/bist val2, = struct.unpack('>H', buf[off + 2:off + 4]) op, mnem, iflags = getBitDbl_OpMnem(val2) op |= ((val & 0xff80) << 9) erd = (val >> 4) & 0x7 immreg = (val2 >> 4) & 0x7 if val2 & 0x1c00: opers = ( h8_operands.H8ImmOper(immreg, tsize), h8_operands.H8RegIndirOper(erd, tsize, va), ) else: opers = ( h8_operands.H8RegDirOper(immreg, tsize, va), h8_operands.H8RegIndirOper(erd, tsize, va), ) return op, mnem, opers, iflags, 4
def p_Rn_aERd(va, val, buf, off, tsize): # bclr, bset, btst val2, = struct.unpack('>H', buf[off + 2:off + 4]) iflags = 0 op = ((val >> 12) & 0xfff0) | (val & 0xf) | ( (val2 >> 4) & 0xfff0) | (val2 & 0xf) aERd = (val >> 4) & 0x7 Rn = (val2 >> 4) & 0xf opers = ( h8_operands.H8RegDirOper(Rn, tsize, va, 0), h8_operands.H8RegIndirOper(aERd, tsize, va, disp=0, oflags=0), ) return (op, None, opers, iflags, 4)
def p_68_69_6e_6f(va, val, buf, off, tsize): # mov 0x68, 0x69, 0x6e, 0x6f iflags = 0 op = (val >> 7) aERs = (val >> 4) & 0x7 Rd = (val) & 0xf if (val & 0x600): disp, = struct.unpack('>H', buf[off + 2:off + 4]) dispsz = 2 isz = 4 else: disp, dispsz = 0, 0 isz = 2 if val & 0x80: # reverse operand order opers = ( h8_operands.H8RegDirOper(Rd, tsize, va, 0), h8_operands.H8RegIndirOper(aERs, tsize, va, disp=disp, dispsz=dispsz, oflags=0), ) else: opers = ( h8_operands.H8RegIndirOper(aERs, tsize, va, disp=disp, dispsz=dispsz, oflags=0), h8_operands.H8RegDirOper(Rd, tsize, va, 0), ) return (op, None, opers, iflags, isz)
def p_i3_aERd(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 >> 3) & 0xfff0) | (val & 0xf)) << 13) | ((val2 >> 3) & 0xfff0) | (val & 0xf) i3 = (val2 >> 4) & 0x7 ERd = (val >> 4) & 0x7 opers = ( h8_operands.H8ImmOper(i3, tsize), h8_operands.H8RegIndirOper(ERd, tsize, va), ) 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)