x86reg.c

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

C
1,979
字号
    mad_string                  name;
    const x86_reg_info          * const *reglist;
    unsigned_8                  grouping;
};

static const mad_toggle_strings CPUToggleList[] =
{
    {MSTR_MHEX,MSTR_HEX,MSTR_DECIMAL},
    {MSTR_MEXTENDED,MSTR_REG_EXTENDED,MSTR_REG_NORMAL},
    {MSTR_MOS,MSTR_REG_OS,MSTR_REG_USER},
    {MSTR_NIL,MSTR_NIL,MSTR_NIL}
};
static const mad_toggle_strings FPUToggleList[] =
{
    {MSTR_MHEX,MSTR_HEX,MSTR_DECIMAL},
    {MSTR_NIL,MSTR_NIL,MSTR_NIL}
};
static const mad_toggle_strings MMXToggleList[] =
{
    {MSTR_MHEX,MSTR_HEX,MSTR_DECIMAL},
    {MSTR_SIGNED,MSTR_SIGNED,MSTR_UNSIGNED},
    {MSTR_BYTE,MSTR_BYTE,MSTR_NIL},
    {MSTR_WORD,MSTR_WORD,MSTR_NIL},
    {MSTR_DWORD,MSTR_DWORD,MSTR_NIL},
    {MSTR_QWORD,MSTR_QWORD,MSTR_NIL},
    {MSTR_FLOAT,MSTR_FLOAT,MSTR_NIL},
    {MSTR_NIL,MSTR_NIL,MSTR_NIL}
};
static const mad_toggle_strings XMMToggleList[] =
{
    {MSTR_MHEX,MSTR_HEX,MSTR_DECIMAL},
    {MSTR_SIGNED,MSTR_SIGNED,MSTR_UNSIGNED},
    {MSTR_BYTE,MSTR_BYTE,MSTR_NIL},
    {MSTR_WORD,MSTR_WORD,MSTR_NIL},
    {MSTR_DWORD,MSTR_DWORD,MSTR_NIL},
    {MSTR_QWORD,MSTR_QWORD,MSTR_NIL},
    {MSTR_FLOAT,MSTR_FLOAT,MSTR_NIL},
    {MSTR_DOUBLE,MSTR_DOUBLE,MSTR_NIL},
    {MSTR_NIL,MSTR_NIL,MSTR_NIL}
};

#define FPU_GROUPING    6

static mad_status CPUGetPiece( const mad_registers *, unsigned piece, char **, unsigned *, const mad_reg_info **, mad_type_handle *, unsigned * );
static mad_status FPUGetPiece( const mad_registers *, unsigned piece, char **, unsigned *, const mad_reg_info **, mad_type_handle *, unsigned * );
static mad_status MMXGetPiece( const mad_registers *, unsigned piece, char **, unsigned *, const mad_reg_info **, mad_type_handle *, unsigned * );
static mad_status XMMGetPiece( const mad_registers *, unsigned piece, char **, unsigned *, const mad_reg_info **, mad_type_handle *, unsigned * );

static const mad_reg_set_data RegSet[] = {
    { CPUGetPiece, CPUToggleList, MSTR_CPU, CPURegList, 0 },
    { FPUGetPiece, FPUToggleList, MSTR_FPU, FPURegList, FPU_GROUPING },
    { MMXGetPiece, MMXToggleList, MSTR_MMX, MMXRegList, 1 },
    { XMMGetPiece, XMMToggleList, MSTR_XMM, XMMRegList, 1 } };

unsigned DIGENTRY MIRegistersSize( void )
{
    return( sizeof( struct x86_mad_registers ) );
}


#define EXTRACT_ST( mr ) (((unsigned_16)(mr)->x86.fpu.sw >> SHIFT_st) & ((1<<LEN_st)-1))

mad_status DIGENTRY MIRegistersHost( mad_registers *mr )
{
    unsigned    st;
    unsigned_16 tag;

    /* normalize the tag bits to tag[0..1] refer to ST(0), etc */
    st = EXTRACT_ST(mr)*2;
    tag = mr->x86.fpu.tag;
    tag = (tag >> (st)) | (tag << (16-st));
    mr->x86.fpu.tag &= ~0xffffUL;
    mr->x86.fpu.tag |= tag;
    return( MS_MODIFIED );
}

mad_status DIGENTRY MIRegistersTarget( mad_registers *mr )
{
    unsigned    st;
    unsigned_16 tag;

    /* put the tag bits back the stupid way the x87 wants them */
    st = EXTRACT_ST(mr)*2;
    tag = mr->x86.fpu.tag;
    tag = (tag << (st)) | (tag >> (16-st));
    mr->x86.fpu.tag &= ~0xffffUL;
    mr->x86.fpu.tag |= tag;
    return( MS_MODIFIED );
}

walk_result DIGENTRY MIRegSetWalk( mad_type_kind tk, MI_REG_SET_WALKER *wk, void *d )
{
    walk_result wr;

    if( tk & (MTK_INTEGER|MTK_ADDRESS) ) {
        wr = wk( &RegSet[CPU_REG_SET], d );
        if( wr != WR_CONTINUE ) {
            return( wr );
        }
    }
    if( tk & MTK_FLOAT ) {
        wr = wk( &RegSet[FPU_REG_SET], d );
        if( wr != WR_CONTINUE ) {
            return( wr );
        }
    }
    if( (tk & MTK_CUSTOM) && (MCSystemConfig()->cpu & X86_MMX) ) {
        wr = wk( &RegSet[MMX_REG_SET], d );
        if( wr != WR_CONTINUE ) {
            return( wr );
        }
    }
    if( (tk & MTK_XMM) && (MCSystemConfig()->cpu & X86_XMM) ) {
        wr = wk( &RegSet[XMM_REG_SET], d );
        if( wr != WR_CONTINUE ) {
            return( wr );
        }
    }
    return( WR_CONTINUE );
}

mad_string DIGENTRY MIRegSetName( const mad_reg_set_data *rsd )
{
    return( rsd->name );
}

unsigned DIGENTRY MIRegSetLevel( const mad_reg_set_data *rsd, unsigned max, char *buff )
{
    char        str[80];
    unsigned    len;

    switch( rsd - RegSet ) {
    case CPU_REG_SET:
        switch( MCSystemConfig()->cpu & X86_CPU_MASK ) {
        case X86_86:
            strcpy( str, "8086" );
            break;
        case X86_586:
            strcpy( str, "Pentium" );
            break;
        case X86_686:
            strcpy( str, "Pentium Pro" );
            break;
        case X86_P4:
            strcpy( str, "Pentium 4/Xeon" );
            break;
        default:
            str[0] = MCSystemConfig()->cpu + '0';
            strcpy( &str[1], "86" );
            break;
        }
        break;
    case FPU_REG_SET:
        switch( MCSystemConfig()->fpu ) {
        case X86_NO:
            MCString( MSTR_NONE, sizeof( str ), str );
            break;
        case X86_EMU:
            MCString( MSTR_EMULATOR, sizeof( str ), str );
            break;
        case X86_87:
            strcpy( str, "8087" );
            break;
        case X86_587:
            strcpy( str, "Pentium" );
            break;
        case X86_687:
            strcpy( str, "Pentium Pro" );
            break;
        case X86_P47:
            strcpy( str, "Pentium 4/Xeon" );
            break;
        default:
            str[0] = MCSystemConfig()->fpu + '0';
            strcpy( &str[1], "87" );
            break;
        }
        break;
    default:
        str[0] = '\0';
        break;
    }
    len = strlen( str );
    if( max > 0 ) {
        --max;
        if( max > len )
            max = len;
        memcpy( buff, str, max );
        buff[max] = '\0';
    }
    return( len );
}

unsigned DIGENTRY MIRegSetDisplayGrouping( const mad_reg_set_data *rsd )
{
    switch( rsd - RegSet ) {
    case MMX_REG_SET:
        if( MADState->reg_state[MMX_REG_SET] & MT_BYTE ) {
            return( 8 );
        } else if( MADState->reg_state[MMX_REG_SET] & MT_WORD ) {
            return( 4 );
        } else if( MADState->reg_state[MMX_REG_SET] & MT_DWORD ) {
            return( 2 );
        } else if( MADState->reg_state[MMX_REG_SET] & MT_FLOAT ) {
            return( 2 );
        } else {
            return( 1 );
        }
    case XMM_REG_SET:
        if( MADState->reg_state[XMM_REG_SET] & XT_BYTE ) {
            return( 16 + 2 );
        } else if( MADState->reg_state[XMM_REG_SET] & XT_WORD ) {
            return( 8 + 2 );
        } else if( MADState->reg_state[XMM_REG_SET] & XT_DWORD ) {
            return( 4 + 2 );
        } else if( MADState->reg_state[XMM_REG_SET] & XT_QWORD ) {
            return( 2 + 2 );
        } else if( MADState->reg_state[XMM_REG_SET] & XT_FLOAT ) {
            return( 4 + 2 );
        } else {  // double
            return( 2 + 2 );
        }
    default:
        return( rsd->grouping );
    }
}

static char     DescriptBuff[40];

static mad_status CPUGetPiece(
    const mad_registers *mr,
    unsigned piece,
    char **descript_p,
    unsigned *max_descript_p,
    const mad_reg_info **reg_p,
    mad_type_handle *disp_type_p,
    unsigned *max_value_p )
{
    static const x86_reg_info *list16[] = {
        &CPU_ax, &CPU_bx, &CPU_cx, &CPU_dx,
        &CPU_si, &CPU_di, &CPU_bp, &CPU_sp, &CPU_ip,
        &CPU_ds, &CPU_es, &CPU_ss, &CPU_cs,
        &CPU_fl, &CPU_c, &CPU_p, &CPU_a, &CPU_z, &CPU_s, &CPU_i, &CPU_d, &CPU_o,
        };
    static const x86_reg_info *list32[] = {
        &CPU_eax, &CPU_ebx, &CPU_ecx, &CPU_edx,
        &CPU_esi, &CPU_edi, &CPU_ebp, &CPU_esp, &CPU_eip,
        &CPU_efl, &CPU_c, &CPU_p, &CPU_a, &CPU_z, &CPU_s, &CPU_i, &CPU_d, &CPU_o,
        &CPU_ds, &CPU_es, &CPU_fs, &CPU_gs, &CPU_ss, &CPU_cs,
        };
    static const x86_reg_info *listOS[] = {
        &CPU_iopl, &CPU_nt, &CPU_rf, &CPU_vm,
        };
    const x86_reg_info  *curr;
    const x86_reg_info  **list;
    unsigned            list_num;
    char                *p;
    static const void   **last_list;

    if( (MADState->reg_state[CPU_REG_SET] & CT_EXTENDED) || BIG_SEG( GetRegIP( mr ) ) ) {
        list = list32;
        list_num = NUM_ELTS( list32 );
    } else {
        list = list16;
        list_num = NUM_ELTS( list16 );
    }
    if( last_list == NULL )
        last_list = list;
    if( last_list != list ) {
        last_list = list;
        MCNotify( MNT_REDRAW_REG, (void *)&RegSet[CPU_REG_SET] );
    }
    if( MADState->reg_state[CPU_REG_SET] & CT_OS ) {
        *max_descript_p = 4;
        if( piece >= list_num ) {
            piece -= list_num;
            if( piece >= NUM_ELTS( listOS ) )
                return( MS_FAIL );
            list = listOS;
        }
    } else {
        *max_descript_p = 3;
        if( piece >= list_num ) {
            return( MS_FAIL );
        }
    }
    curr = list[ piece ];
    *max_value_p = 0;
    *reg_p = &curr->info;
    *descript_p = DescriptBuff;
    strcpy( DescriptBuff, curr->info.name );
    p = DescriptBuff;
    while( *p != '\0' ) {
        *p = toupper( *p );
        ++p;
    }
    *p = '\0';
    if( curr->info.bit_size <= 3 ) {
        *disp_type_p = X86T_BIT;
    } else if( curr->info.bit_size <= 16 ) {
        if( MADState->reg_state[CPU_REG_SET] & CT_HEX ) {
            *disp_type_p = X86T_WORD;
        } else {
            *disp_type_p = X86T_USHORT;
        }
    } else {
        if( MADState->reg_state[CPU_REG_SET] & CT_HEX ) {
            *disp_type_p = X86T_DWORD;
        } else {
            *disp_type_p = X86T_ULONG;
        }
    }
    return( MS_OK );
}

static const byte zero  = 0;
static const byte one   = 1;
static const byte two   = 2;
static const byte three = 3;
static const byte four  = 4;
static const byte five  = 5;
static const byte six   = 6;
static const byte seven = 7;

static const mad_modify_list ModBit[] = {
    { &zero, X86T_BYTE, MSTR_NIL },
    { &one,  X86T_BYTE, MSTR_NIL },
};
static const mad_modify_list ModByte[] = {
    { NULL, X86T_BYTE, MSTR_NIL },
};
static const mad_modify_list ModWord[] = {
    { NULL, X86T_WORD, MSTR_NIL },
};
static const mad_modify_list ModDWord[] = {
    { NULL, X86T_DWORD, MSTR_NIL },
};
static const mad_modify_list ModQWord[] = {
    { NULL, X86T_QWORD, MSTR_NIL },
};
static const mad_modify_list ModFPUTag[] = {
    { &zero,  X86T_BYTE, MSTR_VALID },
    { &one,   X86T_BYTE, MSTR_ZERO },
    { &two,   X86T_BYTE, MSTR_NAN },
    { &three, X86T_BYTE, MSTR_EMPTY },
};
static const mad_modify_list ModFPUStack[] = {
    { NULL, X86T_EXTENDED, MSTR_NIL },
};
static const mad_modify_list ModFPUSt[] = {
    { &zero, X86T_BIT, MSTR_NIL },
    { &one,  X86T_BIT, MSTR_NIL },
    { &two,  X86T_BIT, MSTR_NIL },
    { &three,X86T_BIT, MSTR_NIL },
    { &four, X86T_BIT, MSTR_NIL },
    { &five, X86T_BIT, MSTR_NIL },
    { &six,  X86T_BIT, MSTR_NIL },
    { &seven,X86T_BIT, MSTR_NIL },
};
static const mad_modify_list ModFPUPc[] = {
    { &zero,  X86T_BYTE, MSTR_PCSINGLE },
    { &one,   X86T_BYTE, MSTR_NIL },
    { &two,   X86T_BYTE, MSTR_PCDOUBLE },
    { &three, X86T_BYTE, MSTR_PCEXTENDED },
};
static const mad_modify_list ModFPURc[] = {
    { &zero,  X86T_BYTE, MSTR_NEAREST },
    { &one,   X86T_BYTE, MSTR_DOWN },
    { &two,   X86T_BYTE, MSTR_UP },
    { &three, X86T_BYTE, MSTR_CHOP },
};
static const mad_modify_list ModFPUIc[] = {
    { &zero,  X86T_BYTE, MSTR_PROJECTIVE },
    { &one,   X86T_BYTE, MSTR_AFFINE },
};

#define MODLEN( name ) MaxModLen( name, NUM_ELTS( name ) )

static unsigned MaxModLen( const mad_modify_list *list, unsigned num )
{
    unsigned    max;
    unsigned    len;

    max = 0;
    while( num != 0 ) {
        --num;
        len = MCString( list[num].name, 0, NULL );
        if( len > max ) {
            max = len;
        }
    }
    return( max );
}

#define LIST( num, r1, r2, r3, r4, r5, r6, r7, r8 )     \
    static const x86_reg_info * const list##num[]       \

⌨️ 快捷键说明

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