disx86.c

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

C
2,201
字号
/**********************************************************************
 *  Get ST  (Floating Point) Register  w - not used
 */
{
    switch( reg ) {
    case RM_0: return( DR_X86_st  );
    case RM_1: return( DR_X86_st1 );
    case RM_2: return( DR_X86_st2 );
    case RM_3: return( DR_X86_st3 );
    case RM_4: return( DR_X86_st4 );
    case RM_5: return( DR_X86_st5 );
    case RM_6: return( DR_X86_st6 );
    case RM_7: return( DR_X86_st7 );
    default:   return( DR_NONE );
    }
}

dis_register X86GetMMReg(WBIT w, RM reg, dis_dec_ins *ins )
/**********************************************************************
 *  Get MM  (Multimedia) Register  w - not used
 */
{
    switch( reg ) {
    case RM_0: return( DR_X86_mm0 );
    case RM_1: return( DR_X86_mm1 );
    case RM_2: return( DR_X86_mm2 );
    case RM_3: return( DR_X86_mm3 );
    case RM_4: return( DR_X86_mm4 );
    case RM_5: return( DR_X86_mm5 );
    case RM_6: return( DR_X86_mm6 );
    case RM_7: return( DR_X86_mm7 );
    default:   return( DR_NONE );
    }
}

dis_register X86GetXMMReg(WBIT w, RM reg, dis_dec_ins *ins )
/**********************************************************************
 *  Get SSE  (Streaming SIMD Extensions) Register  w - not used
 */
{
    switch( reg ) {
    case RM_0: return( DR_X86_xmm0 );
    case RM_1: return( DR_X86_xmm1 );
    case RM_2: return( DR_X86_xmm2 );
    case RM_3: return( DR_X86_xmm3 );
    case RM_4: return( DR_X86_xmm4 );
    case RM_5: return( DR_X86_xmm5 );
    case RM_6: return( DR_X86_xmm6 );
    case RM_7: return( DR_X86_xmm7 );
    default:   return( DR_NONE );
    }
}

dis_register X86GetCRegister( WBIT w, RM reg, dis_dec_ins *ins )
/**********************************************************************
 *  Get Control Register
 */
{
    switch( reg ) {
    case REG_CR0: return( DR_X86_cr0 );
    case REG_CR2: return( DR_X86_cr2 );
    case REG_CR3: return( DR_X86_cr3 );
    case REG_CR4: return( DR_X86_cr4 );
    default     : return( DR_NONE );
    }
}

dis_register X86GetDRegister( WBIT w, RM reg, dis_dec_ins *ins )
/**********************************************************************
 *  Get Debug Register
 */
{
    switch( reg ) {
    case REG_DR0: return( DR_X86_dr0 );
    case REG_DR1: return( DR_X86_dr1 );
    case REG_DR2: return( DR_X86_dr2 );
    case REG_DR3: return( DR_X86_dr3 );
    case REG_DR6: return( DR_X86_dr6 );
    case REG_DR7: return( DR_X86_dr7 );
    default     : return( DR_NONE );
    }
}

dis_register X86GetTRegister( WBIT w, RM reg, dis_dec_ins *ins )
/**********************************************************************
 *  Get Test Register 80486
 */
{
    switch( reg ) {
    case REG_TR3: return( DR_X86_tr3 );
    case REG_TR4: return( DR_X86_tr4 );
    case REG_TR5: return( DR_X86_tr5 );
    case REG_TR6: return( DR_X86_tr6 );
    case REG_TR7: return( DR_X86_tr7 );
    default     : return( DR_NONE );
    }
}

dis_register X86GetSRegister( WBIT w, RM reg, dis_dec_ins *ins )
/**********************************************************************
 *  Get Segment Register
 */
{
    switch( reg ) {
    case REG_ES: return( DR_X86_es );
    case REG_CS: return( DR_X86_cs );
    case REG_SS: return( DR_X86_ss );
    case REG_DS: return( DR_X86_ds );
    case REG_FS: return( DR_X86_fs );
    case REG_GS: return( DR_X86_gs );
    default     : return( DR_NONE );
    }
}

dis_register X86GetRegister( WBIT w, RM reg, dis_dec_ins *ins )
/**********************************************************************
 *  Get Register
 *                 w   =  1  (default) use full width of operand
 *                     =  0            use byte size operand
 */
{
    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_verr:
    case DI_X86_verw:
    case DI_X86_arpl:
        return( X86GetRegister_W( w, reg, ins ) );
    case DI_X86_bswap:
        return( X86GetRegister_D( w, reg, ins ) );
    default:
        if( w != W_FULL ) {
            return( X86GetRegister_B ( w, reg, ins ) );
        } else if( DIF_X86_OPND_LONG & ins->flags ) {
            return( X86GetRegister_D( w, reg, ins ) );
        } else {
            return( X86GetRegister_W( w, reg, ins ) );
        }
    }
}


dis_register X86GetRegisterAddr( WBIT w, RM reg, dis_dec_ins *ins )
/**********************************************************************
 *  Get Register
 *                 w   =  1  (default) use full width of operand
 *                     =  0            use byte size operand
 */
{
    switch(ins->type) {
    default:
        if( w != W_FULL ) {
            return( X86GetRegister_B ( w, reg, ins ) );
        } else if( DIF_X86_ADDR_LONG & ins->flags ) {
            return( X86GetRegister_D( w, reg, ins ) );
        } else {
            return( X86GetRegister_W( w, reg, ins ) );
        }
    }
}


static void X86GetModRM_S( WBIT w, MOD mod, RM rm, void * d,
                           dis_dec_ins *ins, dis_ref_type ref_type,
           dis_register (*func)( WBIT w,RM reg, dis_dec_ins* ins ) )
/**********************************************************************
 *  Get Mod RM  - 16-Bit Operand Version
 */
{
    int oper;

    oper = ins->num_ops;
    ++ins->num_ops;

    ins->op[oper].type = DO_MEMORY_ABS;
    ins->op[oper].ref_type = ref_type;
    ins->op[oper].value = 0;
    ins->op[oper].scale = 1;

    switch(rm)  {
    case RM_0:
        ins->op[oper].base  = DR_X86_bx;
        ins->op[oper].index = DR_X86_si;
        break;
    case RM_1:
        ins->op[oper].base  = DR_X86_bx;
        ins->op[oper].index = DR_X86_di;
        break;
    case RM_2:
        ins->op[oper].base  = DR_X86_bp;
        ins->op[oper].index = DR_X86_si;
        break;
    case RM_3:
        ins->op[oper].base  = DR_X86_bp;
        ins->op[oper].index = DR_X86_di;
        break;
    case RM_4:
        ins->op[oper].base  = DR_X86_si;
        ins->op[oper].index = DR_NONE;
        break;
    case RM_5:
        ins->op[oper].base  = DR_X86_di;
        ins->op[oper].index = DR_NONE;
        break;
    case RM_6:
        ins->op[oper].base  = DR_X86_bp;
        ins->op[oper].index = DR_NONE;
        break;
    case RM_7:
        ins->op[oper].base  = DR_X86_bx;
        ins->op[oper].index = DR_NONE;
        break;
    }

    switch( mod ) {
    case MOD_0:
        if(rm == RM_6) {
            ins->op[oper].base = DR_NONE;
            ins->op[oper].op_position = ins->size;
            ins->op[oper].value = GetUShort( d, ins->size );
            ins->size += 2;
        }
        break;
    case MOD_1:
        ins->op[oper].op_position = ins->size;
        ins->op[oper].value = GetSByte( d, ins->size );
        ins->size += 1;
        break;
    case MOD_2:
        ins->op[oper].op_position = ins->size;
        ins->op[oper].value = GetSShort( d,  ins->size);
        ins->size += 2;
        break;
    case MOD_3:
        ins->op[oper].type = DO_REG;
        ins->op[oper].base = func( w, rm, ins );
        ins->op[oper].index = DR_NONE;
        break;
    }
}


static void X86GetSIB( unsigned_8 scale, RM base, RM index,
                       dis_dec_ins *ins, unsigned oper )
/**********************************************************************
 * Get SIB - only used in 32-Bit Operand Mode
 */
{
    ins->op[oper].base = X86GetRegister_D( W_DEFAULT, base, ins );
    if( index == RM_4 ) {
        ins->op[oper].scale = 1;
        ins->op[oper].index = DR_NONE;
    } else {
        ins->op[oper].scale = 1 << scale;
        ins->op[oper].index = X86GetRegister_D( W_DEFAULT, index, ins );
    }
}

static void X86GetModRM_L( WBIT w, MOD mod, RM rm, void * d,
                           dis_dec_ins *ins, dis_ref_type ref_type,
           dis_register (*func)( WBIT w, RM reg, dis_dec_ins* ins ) ) {
/**********************************************************************
 *   Get MOD RM - 32-Bit Version
 */

    SIB sib;
    int oper;

    oper = ins->num_ops;
    ++ins->num_ops;

    ins->op[oper].type = DO_MEMORY_ABS;
    ins->op[oper].ref_type = ref_type;
    ins->op[oper].value = 0;
    ins->op[oper].scale = 1;
    ins->op[oper].index = DR_NONE;
    ins->op[oper].base  = DR_NONE;

    switch( rm )  {
    case RM_0:
        ins->op[oper].base  = DR_X86_eax;
        break;
    case RM_1:
        ins->op[oper].base  = DR_X86_ecx;
        break;
    case RM_2:
        ins->op[oper].base  = DR_X86_edx;
        break;
    case RM_3:
        ins->op[oper].base  = DR_X86_ebx;
        break;
    case RM_4:
        if( mod != MOD_3) {
            sib.full = GetUByte( d, ins->size );
            ins->size += 1;
            X86GetSIB( sib.split.scale,
                       sib.split.base,
                       sib.split.index,
                       ins,
                       oper );
            if( mod == MOD_0 ) {
                if( ins->op[oper].base == DR_X86_ebp ) {
                    ins->op[oper].base = DR_NONE;
                    ins->op[oper].op_position = ins->size;
                    ins->op[oper].value = GetULong( d, ins->size );
                    ins->size += 4;
                }
            }
        }
        break;
    case RM_5:
        ins->op[oper].base  = DR_X86_ebp;
        break;
    case RM_6:
        ins->op[oper].base  = DR_X86_esi;
        break;
    case RM_7:
        ins->op[oper].base  = DR_X86_edi;
        break;
    }

    switch( mod ) {
    case MOD_0:
        if( rm == RM_5 ) {
            ins->op[oper].base = DR_NONE;
            ins->op[oper].op_position = ins->size;
            ins->op[oper].value = GetULong( d, ins->size );
            ins->size += 4;
        }
        break;
    case MOD_1:
        ins->op[oper].op_position = ins->size;
        ins->op[oper].value = GetSByte( d, ins->size );
        ins->size += 1;
        break;
    case MOD_2:
        ins->op[oper].op_position = ins->size;
        ins->op[oper].value = GetULong( d, ins->size );
        ins->size += 4;
        break;
    case MOD_3:
        ins->op[oper].type = DO_REG;
        ins->op[oper].base = func( w, rm, ins );
        break;
    }
}

/*=====================================================================*/
/*               Get MOD/RM as Operand                                 */
/*=====================================================================*/
static void X86GetModRM( WBIT w, MOD mod, RM rm, void * d,
                         dis_dec_ins *ins, dis_ref_type ref_type )
/**********************************************************************
 */
{
    if( DIF_X86_ADDR_LONG & ins->flags ) {
        X86GetModRM_L( w, mod, rm, d ,ins, ref_type, X86GetRegister );
    } else {
        X86GetModRM_S( w, mod, rm, d ,ins, ref_type, X86GetRegister );
    }
}

static void X86GetModRM_D( WBIT w, MOD mod, RM rm, void * d,
                         dis_dec_ins *ins, dis_ref_type ref_type )
/**********************************************************************
 * 32-Bit Operand Version
 */
{
    if( DIF_X86_ADDR_LONG & ins->flags ) {
        X86GetModRM_L( w, mod, rm, d ,ins, ref_type, X86GetRegister_D );
    } else {
        X86GetModRM_S( w, mod, rm, d ,ins, ref_type, X86GetRegister_D );
    }
}

static void X86GetModRM_W( WBIT w, MOD mod, RM rm, void * d,
                         dis_dec_ins *ins, dis_ref_type ref_type )
/**********************************************************************
 * 16-Bit Operand Version
 */
{
    if( DIF_X86_ADDR_LONG & ins->flags ) {
        X86GetModRM_L( w, mod, rm, d ,ins, ref_type, X86GetRegister_W );
    } else {
        X86GetModRM_S( w, mod, rm, d ,ins, ref_type, X86GetRegister_W );
    }
}

static void X86GetModRM_B( WBIT w, MOD mod, RM rm, void * d,
                         dis_dec_ins *ins )
/**********************************************************************
 * 8-Bit Operand Version
 */
{
    if( DIF_X86_ADDR_LONG & ins->flags ) {
        X86GetModRM_L( w, mod, rm, d ,ins, DRT_X86_BYTE, X86GetRegister_B );
    } else {
        X86GetModRM_S( w, mod, rm, d ,ins, DRT_X86_BYTE, X86GetRegister_B );
    }
}

static void X86FGetModRM( WBIT w, MOD mod, RM rm, void * d,
                         dis_dec_ins *ins, dis_ref_type ref_type )
/**********************************************************************
 * Gets the Floating Point MOD/RM
 * NOT the same with X86GetModRM it returns ST instead of a register
 * if MOD = MOD_3
 */
{
    if( DIF_X86_ADDR_LONG & ins->flags ) {
        X86GetModRM_L( w, mod, rm, d ,ins, ref_type, X86FGetSTReg );
    } else {
        X86GetModRM_S( w, mod, rm, d ,ins, ref_type, X86FGetSTReg );
    }
}

static void X86MMGetModRM( WBIT w, MOD mod, RM rm, void * d,
                         dis_dec_ins *ins, dis_ref_type ref_type )
/**********************************************************************
 * Gets the Floating Point MOD/RM
 * NOT the same with X86GetModRM it returns MM instead of a register
 * if MOD = MOD_3
 */
{
    if( DIF_X86_ADDR_LONG & ins->flags ) {
        X86GetModRM_L( w, mod, rm, d ,ins, ref_type, X86GetMMReg );
    } else {
        X86GetModRM_S( w, mod, rm, d ,ins, ref_type, X86GetMMReg );
    }
}

static void X86XMMGetModRM( WBIT w, MOD mod, RM rm, void * d,
                         dis_dec_ins *ins, dis_ref_type ref_type )
/**********************************************************************
 * Gets the Floating Point MOD/RM
 * NOT the same with X86GetModRM it returns XMM instead of a register
 * if MOD = MOD_3

⌨️ 快捷键说明

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