Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
0
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)
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
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)