disx86.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,201 行 · 第 1/5 页

C
2,201
字号
 */
{
    if( DIF_X86_ADDR_LONG & ins->flags ) {
        X86GetModRM_L( w, mod, rm, d ,ins, ref_type, X86GetXMMReg );
    } else {
        X86GetModRM_S( w, mod, rm, d ,ins, ref_type, X86GetXMMReg );
    }
}

/*=====================================================================*/
/*               Get Register as Operands                              */
/*=====================================================================*/

static dis_ref_type X86RegRefType( dis_register reg )
{
    if( reg <= DR_X86_bl ) return( DRT_X86_BYTE );
    if( reg <= DR_X86_di ) return( DRT_X86_WORD );
    if( reg <= DR_X86_edi ) return( DRT_X86_DWORD );
    if( reg <= DR_X86_st7 ) return( DRT_X86_TBYTE );
    if( reg <= DR_X86_mm7 ) return( DRT_X86_MM64 );
    if( reg <= DR_X86_xmm7 ) return( DRT_X86_XMM128 );
    if( reg <= DR_X86_dr7 ) return( DRT_X86_DWORD );
    return( DRT_X86_WORD );
}

static void X86FGetST( RM reg, dis_dec_ins *ins )
/**********************************************************************
 *  Get ST - Floating Point Stack Register
 */
{
    int oper;

    oper = ins->num_ops;
    ins->op[oper].type = DO_REG;
    ins->op[oper].base = X86FGetSTReg( W_DEFAULT, reg, ins );
    ins->op[oper].ref_type = DRT_X86_TBYTE;
    ++ins->num_ops;
}

static void X86GetMM( RM reg, dis_dec_ins *ins )
/**********************************************************************
 *  Get MM  Register
 */
{
    int oper;

    oper = ins->num_ops;
    ins->op[oper].type = DO_REG;
    ins->op[oper].base = X86GetMMReg( W_DEFAULT, reg, ins );
    ins->op[oper].ref_type = DRT_X86_MM64;
    ++ins->num_ops;
}

static void X86GetXMM( RM reg, dis_dec_ins *ins )
/**********************************************************************
 *  Get XMM Register
 */
{
    int oper;

    oper = ins->num_ops;
    ins->op[oper].type = DO_REG;
    ins->op[oper].base = X86GetXMMReg( W_DEFAULT, reg, ins );
    ins->op[oper].ref_type = DRT_X86_XMM128;
    ++ins->num_ops;
}

static void X86GetReg( WBIT w, RM reg, dis_dec_ins *ins )
/**********************************************************************
 *  Get Register
 */
{
    int oper;

    oper = ins->num_ops;
    ins->op[oper].type = DO_REG;
    ins->op[oper].base = X86GetRegister( w, reg, ins );
    ins->op[oper].ref_type = X86RegRefType( ins->op[oper].base );
    ++ins->num_ops;
}

static void X86GetReg32( WBIT w, RM reg, dis_dec_ins *ins )
/**********************************************************************
 *  Get Register
 */
{
    int oper;

    oper = ins->num_ops;
    ins->op[oper].type = DO_REG;
    ins->op[oper].base = X86GetRegister_D( w, reg, ins );
    ins->op[oper].ref_type = DRT_X86_DWORD;
    ++ins->num_ops;
}

static void X86GetSReg( WBIT w, RM reg, dis_dec_ins *ins )
/**********************************************************************
 *  Get S Registers
 */
{
    int oper;

    oper = ins->num_ops;
    ins->op[oper].type = DO_REG;
    ins->op[oper].base = X86GetSRegister( w, reg, ins );
    ins->op[oper].ref_type = DRT_X86_WORD;
    ++ins->num_ops;
}

/*=====================================================================*/
/*               Get Immediate Value                                   */
/*=====================================================================*/


static void X86GetImmedVal( SBIT s, WBIT w, void *d, dis_dec_ins *ins )
/*********************************************************************
 * Get Immediate Value
 *                   s = 0  (S_FULL / S_DEFAULT)
 *                   s = 1  (S_BYTE)
 */
{
    int oper;

    oper                      = ins->num_ops;
    ins->op[oper].op_position = ins->size;
    ins->op[oper].type        = DO_IMMED;
    ++ins->num_ops;

    if( w == W_FULL && s == S_FULL ) {
        if( ins->flags & DIF_X86_OPND_LONG ) {
            ins->op[oper].value = GetULong( d, ins->size );
            ins->op[oper].ref_type = DRT_X86_DWORD;
            ins->size   += 4;
        } else {
            ins->op[oper].value = GetSShort( d, ins->size );
            ins->op[oper].ref_type = DRT_X86_WORD;
            ins->size   += 2;
        }
    } else {
        ins->op[oper].value = GetSByte( d, ins->size );
        if( w == W_BYTE ) {
            ins->op[oper].ref_type = DRT_X86_BYTE;
        } else if( ins->flags & DIF_X86_OPND_LONG ) {
            ins->op[oper].ref_type = DRT_X86_DWORD;
        } else {
            ins->op[oper].ref_type = DRT_X86_WORD;
        }
        ins->size   += 1;
    }
}

/*=====================================================================*/
/*               Get Absolute Value                                    */
/*=====================================================================*/

static void X86GetAbsVal( void *d, dis_dec_ins *ins )
/*********************************************************************
 * Get Absolute Value
 */
{
    int oper;

    oper = ins->num_ops;
    ins->op[oper].op_position = ins->size;
    ins->op[oper].type = DO_ABSOLUTE;
    ++ins->num_ops;
    if( ins->flags & DIF_X86_OPND_LONG ) {
        ins->op[oper].value = GetULong( d, ins->size );
        ins->size += 4;
    } else {
        ins->op[oper].value = GetUShort( d, ins->size );
        ins->size   += 2;
    }

    // Get Segment Value
    ins->op[oper].extra = GetUShort( d, ins->size );
    ins->size += 2;
    ins->op[oper].type |= DO_EXTRA;

}

/*=====================================================================*/
/*               Get Relative Value                                    */
/*=====================================================================*/

static void X86GetRelVal_8( void *d, dis_dec_ins *ins )
/*********************************************************************
 * Get Relative Value   - 1 byte
 */
{
    int oper;

    oper = ins->num_ops;
    ins->op[oper].op_position = ins->size;
    ins->op[oper].type = DO_RELATIVE;
    ++ins->num_ops;
    ins->op[oper].value = GetSByte( d, ins->size );
    ins->size += 1;
    ins->op[oper].value += ins->size;
}

static void X86GetRelVal( void *d, dis_dec_ins *ins )
/*********************************************************************
 * Get Relative Value
 */
{
    int oper;

    oper = ins->num_ops;
    ins->op[oper].op_position = ins->size;
    ins->op[oper].type = DO_RELATIVE;
    ++ins->num_ops;
    if( ins->flags & DIF_X86_ADDR_LONG ) {
        ins->op[oper].value = GetULong( d, ins->size );
        ins->size += 4;
    } else {
        ins->op[oper].value = GetSShort( d, ins->size );
        ins->size += 2;
    }
    ins->op[oper].value += ins->size;
}

/*=====================================================================*/
/*               Get Reference Type                                    */
/*=====================================================================*/

dis_ref_type  X86GetRefType( WBIT w, dis_dec_ins *ins )
/*********************************************************************
 * Get Reference Type
 */
{
    // Instructions that have default ref type
    switch( ins->type ) {
    case DI_X86_lldt:
    case DI_X86_sldt:
    case DI_X86_ltr:
    case DI_X86_lmsw:
    case DI_X86_smsw:
    case DI_X86_str:
    case DI_X86_invlpg:
    case DI_X86_verr:
    case DI_X86_verw:
    case DI_X86_arpl:
        return( DRT_X86_WORD );
    case DI_X86_cmpxchg8b:
        return( DRT_X86_QWORD );
    case DI_X86_fxsave00:
    case DI_X86_fxsave01:
    case DI_X86_fxsave10:
    case DI_X86_fxrstor00:
    case DI_X86_fxrstor01:
    case DI_X86_fxrstor10:
        return( DRT_X86_BYTE512 );
    case DI_X86_prefetch:
    case DI_X86_prefetchw:
    case DI_X86_prefetcht000:
    case DI_X86_prefetcht001:
    case DI_X86_prefetcht010:
    case DI_X86_prefetcht100:
    case DI_X86_prefetcht101:
    case DI_X86_prefetcht110:
    case DI_X86_prefetcht200:
    case DI_X86_prefetcht201:
    case DI_X86_prefetcht210:
    case DI_X86_prefetchnta00:
    case DI_X86_prefetchnta01:
    case DI_X86_prefetchnta10:
    case DI_X86_clflush00:
    case DI_X86_clflush01:
    case DI_X86_clflush10:
        return( DRT_X86_BYTEX );
    case DI_X86_ldmxcsr00:
    case DI_X86_ldmxcsr01:
    case DI_X86_ldmxcsr10:
    case DI_X86_stmxcsr00:
    case DI_X86_stmxcsr01:
    case DI_X86_stmxcsr10:
        return( DRT_X86_XMM32 );
    default:
        break;
    }

    if( w == W_FULL ) {
        if( ins->flags & DIF_X86_OPND_LONG ) {
            switch( ins->type ) {
            case DI_X86_lds:
            case DI_X86_les:
            case DI_X86_lfs:
            case DI_X86_lgs:
            case DI_X86_lss:
            case DI_X86_call4:
            case DI_X86_jmp4:
                return( DRT_X86_FARPTR48 );
#if 0
            case DI_X86_bound:
                return( DRT_X86_QWORD );
#endif
            case DI_X86_lgdt:
            case DI_X86_lidt:
            case DI_X86_sgdt:
            case DI_X86_sidt00:
            case DI_X86_sidt01:
            case DI_X86_sidt10:
                return( DRT_X86_MEM1632 );
            default:
                return( DRT_X86_DWORD );
            }
        } else {
            switch( ins->type ) {
            case DI_X86_lds:
            case DI_X86_les:
            case DI_X86_lfs:
            case DI_X86_lgs:
            case DI_X86_lss:
            case DI_X86_call4:
            case DI_X86_jmp4:
                return( DRT_X86_FARPTR32 );
#if 0
            case DI_X86_bound:
                return( DRT_X86_DWORD );
#endif
            case DI_X86_lgdt:
            case DI_X86_lidt:
            case DI_X86_sgdt:
            case DI_X86_sidt00:
            case DI_X86_sidt01:
            case DI_X86_sidt10:
                return( DRT_X86_MEM1624 );
            default:
                return( DRT_X86_WORD );
            }
        }
    }
    return( DRT_X86_BYTE );
}

dis_ref_type X86FGetRefType( MF_BITS mf, dis_dec_ins * ins )
/*********************************************************************
 * Get Reference Type - Floating Point Instructions
 */
{
    switch( mf ) {
    case MF_0: return( DRT_X86_DWORDF );
    case MF_1: return( DRT_X86_DWORD );
    case MF_2: return( DRT_X86_QWORDF );
    case MF_3: return( DRT_X86_WORD );
    default:   return( DRT_X86_WORD );
    }
}

dis_ref_type X86FGetRefTypeEnv( dis_dec_ins * ins )
/*********************************************************************
 * Get Reference Type - Floating Point Environment Instructions
 */
{
    if( ins->flags & DIF_X86_OPND_LONG ) {
        switch( ins->type ) {
        case DI_X86_fnsave00:
        case DI_X86_fnsave01:
        case DI_X86_fnsave10:
        case DI_X86_frstor00:
        case DI_X86_frstor01:
        case DI_X86_frstor10:
            return( DRT_X86_BYTE108 );
        case DI_X86_fnstenv00:
        case DI_X86_fnstenv01:
        case DI_X86_fldenv00:
        case DI_X86_fldenv01:
        case DI_X86_fldenv10:
            return( DRT_X86_BYTE28 );
        default:
            return( DRT_X86_DWORD );
        }
    } else {
        switch( ins->type ) {
        case DI_X86_fnsave00:
        case DI_X86_fnsave01:
        case DI_X86_fnsave10:
        case DI_X86_frstor00:
        case DI_X86_frstor01:
        case DI_X86_frstor10:
            return( DRT_X86_BYTE94 );
        case DI_X86_fnstenv00:
        case DI_X86_fnstenv01:
        case DI_X86_fnstenv10:
        case DI_X86_fldenv00:
        case DI_X86_fldenv01:
        case DI_X86_fldenv10:
            return( DRT_X86_BYTE14 );
        default:
            return( DRT_X86_WORD );
        }
    }
}


/*=====================================================================*/
/*               GET REGISTER AND MOD/RM FUNCTIONS                     */
/*=====================================================================*/


static void X86GetRegModRM( DBIT dir, WBIT w, MOD mod, RM rm, RM reg,
                     void * d, dis_dec_ins *ins )
/**********************************************************************/
//    dir                   1                 0
//   Destination           Reg              MODRM
//   Source               MODRM              Reg
{
    if( dir ) {
        X86GetReg( w, reg, ins );
        X86GetModRM( w, mod, rm, d, ins, X86GetRefType( w,ins ) );
    } else {
        X86GetModRM( w, mod, rm, d, ins, X86GetRefType( w,ins ) );
        X86GetReg( w, reg, ins );
    }
}

static void X86GetMMRegModRM( DBIT dir, WBIT w, MOD mod, RM rm, RM reg,
                     dis_ref_type ref_type, void * d, dis_dec_ins *ins )
/**********************************************************************/
//    dir                   1                 0
//   Destination           Reg              MODRM
//   Source               MODRM              Reg
{

    if( dir ) {
        X86GetMM( reg, ins );
        X86MMGetModRM( w, mod, rm, d, ins, ref_type );
    } else {
        X86MMGetModRM( w, mod, rm, d, ins, ref_type );
        X86GetMM( reg, ins );
    }
}

static void X86GetXMMRegModRM( DBIT dir, WBIT w, MOD mod, RM rm, RM reg,
                     dis_ref_type ref_type, void * d, dis_dec_ins *ins )
/**********************************************************************/
//    dir                   1                 0
//   Destination           Reg              MODRM
//   Source               MODRM              Reg
{

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?