axpreg.c

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

C
829
字号
    return( MS_OK );
}

static const reg_display_entry FPUList[] = {
    { IDX_f0,           31, AXPT_DOUBLE },
    { IDX_fpcr,          1, RT_INT },
    { IDX_nt_softfpcr,   1, RT_INT },
    { 0,                 0, 0 }
};

static mad_status       FPUGetPiece( unsigned piece,
                                char **descript,
                                unsigned *max_descript,
                                const mad_reg_info **reg,
                                mad_type_handle *disp_type,
                                unsigned *max_value )
{
    unsigned    idx;

    if( !FindEntry( FPUList, piece, &idx, disp_type ) ) return( MS_FAIL );
    if( MADState->reg_state[FPU_REG_SET] & FT_HEX ) {
        switch( *disp_type ) {
        case AXPT_DOUBLE:
            *disp_type = AXPT_HDOUBLE;
            break;
        }
    }
    if( MADState->reg_state[FPU_REG_SET] & FT_G_FLOAT ) {
        switch( *disp_type ) {
        case AXPT_DOUBLE:
            *disp_type = AXPT_RG_FLOAT;
            break;
        }
    }
    *descript = DescriptBuff;
    *max_descript = 0;
    *max_value = 0;
    *reg = &RegList[idx].info;
    strcpy( DescriptBuff, (*reg)->name );
    return( MS_OK );
}

mad_status      DIGENTRY MIRegSetDisplayGetPiece( const mad_reg_set_data *rsd,
                                const mad_registers *mr,
                                unsigned piece,
                                char **descript,
                                unsigned *max_descript,
                                const mad_reg_info **reg,
                                mad_type_handle *disp_type,
                                unsigned *max_value )
{
    return( rsd->get_piece( piece, descript, max_descript, reg,
                        disp_type, max_value ) );
}

static const mad_modify_list    IntReg = { NULL, REG_TYPE( REG_BITS_INT ), MSTR_NIL };
static const mad_modify_list    FltReg = { NULL, AXPT_DOUBLE, MSTR_NIL };

mad_status      DIGENTRY MIRegSetDisplayModify( const mad_reg_set_data *rsd, const mad_reg_info *ri, const mad_modify_list **possible_p, unsigned *num_possible_p )
{
    switch( ri->bit_start ) {
    case BIT_OFF( r[AR_r31] ):
    case BIT_OFF( r[AR_f31] ):
        *possible_p = NULL;
        *num_possible_p = 0;
        return( MS_FAIL );
    }
    *num_possible_p = 1;
    if( ri->type == AXPT_DOUBLE ) {
        *possible_p = &FltReg;
    } else {
        *possible_p = &IntReg;
    }
    return( MS_OK );
}

mad_status DIGENTRY MIRegModified( const mad_reg_set_data *rsd, const mad_reg_info *ri, const mad_registers *old, const mad_registers *cur )
{
    unsigned_64 new_ip;
    unsigned_8  *p_old;
    unsigned_8  *p_cur;
    unsigned    mask;
    unsigned    size;

    if( ri->bit_start == BIT_OFF( pal.nt.fir ) ) {
        new_ip = old->axp.pal.nt.fir;
        //NYI: 64 bit
        new_ip.u._32[0] += sizeof( unsigned_32 );
        if( new_ip.u._32[0] != cur->axp.pal.nt.fir.u._32[0] ) {
            return( MS_MODIFIED_SIGNIFICANTLY );
        } else if( old->axp.pal.nt.fir.u._32[0] != cur->axp.pal.nt.fir.u._32[0] ) {
            return( MS_MODIFIED );
        }
    } else {
        p_old = (unsigned_8 *)old + (ri->bit_start / BITS_PER_BYTE);
        p_cur = (unsigned_8 *)cur + (ri->bit_start / BITS_PER_BYTE);
        size = ri->bit_size;
        if( size >= BITS_PER_BYTE ) {
            /* it's going to be byte aligned */
            return( memcmp( p_old, p_cur, size / BITS_PER_BYTE ) != 0 ? MS_MODIFIED_SIGNIFICANTLY : MS_OK );
        } else {
            mask = (1 << size) - 1;
            #define GET_VAL( w ) (((*p_##w >> (ri->bit_start % BITS_PER_BYTE))) & mask)
            return( GET_VAL( old ) != GET_VAL( cur ) ? MS_MODIFIED_SIGNIFICANTLY : MS_OK );
        }
    }
    return( MS_OK );
}

mad_status      DIGENTRY MIRegInspectAddr( const mad_reg_info *ri, const mad_registers *mr, address *a )
{
    unsigned    bit_start;
    unsigned_32 *p;

    memset( a, 0, sizeof( *a ) );
    bit_start = ri->bit_start;
    if( bit_start == offsetof( mad_registers, axp.pal.nt.fir )*8 ) {
        a->mach.offset = mr->axp.pal.nt.fir.u._32[0];
        return( MS_OK );
    }
    #pragma disable_message(124)
    #pragma disable_message(111)
    if( bit_start >= offsetof( mad_registers, axp.r[AR_f0] ) * 8
     && bit_start <  offsetof( mad_registers, axp.r[AR_f31] )*8 + 64 ) {
        return( MS_FAIL );
    }
    #pragma enable_message(111)
    #pragma enable_message(124)
    if( bit_start >= offsetof( mad_registers, axp.pal ) * 8 ) {
        return( MS_FAIL );
    }
    p = (unsigned_32 *)((unsigned_8 *)mr + (bit_start / BITS_PER_BYTE));
    a->mach.offset = *p;
    return( MS_OK );
}

const mad_toggle_strings *DIGENTRY MIRegSetDisplayToggleList( const mad_reg_set_data *rsd )
{
    return( rsd->togglelist );
}

unsigned        DIGENTRY MIRegSetDisplayToggle( const mad_reg_set_data *rsd, unsigned on, unsigned off )
{
    unsigned    toggle;
    unsigned    *bits;
    unsigned    index;
    unsigned    old;

    toggle = on & off;
    index = rsd - &RegSet[CPU_REG_SET];
    bits = &MADState->reg_state[index];
    old = *bits;
    *bits ^= toggle;
    *bits |= on & ~toggle;
    *bits &= ~off | toggle;
    if( index == CPU_REG_SET && ((old ^ *bits) & CT_SYMBOLIC_NAMES) ) {
        /*
           We've changed from numeric regs to symbolic or vis-versa.
           Have to force a redraw of the disassembly window.
        */
        MCNotify( MNT_REDRAW_DISASM, NULL );
    }
    return( *bits );
}

walk_result     DIGENTRY MIRegWalk( const mad_reg_set_data *rsd, const mad_reg_info *ri, MI_REG_WALKER *wk, void *d )
{
    const axp_reg_info  *curr;
    walk_result         wr;
    unsigned            reg_set;

    if( ri != NULL ) {
        switch( ((axp_reg_info *)ri)->sublist_code ) {
        case RS_INT:
        case RS_FLT:
           curr = RegSubList[ ri->bit_start / (sizeof( axpreg )*BITS_PER_BYTE) ];
           break;
        default:
            curr = SubList[((axp_reg_info *)ri)->sublist_code];
            break;
        }
        if( curr != NULL ) {
            while( curr->info.name != NULL ) {
                wr = wk( &curr->info, 0, d );
                if( wr != WR_CONTINUE ) return( wr );
                ++curr;
            }
        }
    } else {
        reg_set = rsd - RegSet;
        curr = RegList;
        while( curr < &RegList[ IDX_LAST_ONE ] ) {
            if( curr->reg_set == reg_set
             && (curr->pal == PAL_all || curr->pal == CurrPAL) ) {
                wr = wk( &curr->info, curr->sublist_code != 0, d );
                if( wr != WR_CONTINUE ) return( wr );
            }
            ++curr;
        }
    }
    return( WR_CONTINUE );
}

void            DIGENTRY MIRegSpecialGet( mad_special_reg sr, const mad_registers *mr, addr_ptr *ma )
{
    ma->segment = 0;
    switch( sr ) {
    case MSR_IP:
        /* doesn't matter what PAL is in control since always first field */
        ma->offset = mr->axp.pal.nt.fir.u._32[0];
        break;
    case MSR_SP:
        ma->offset = mr->axp.r[AR_sp].u64.u._32[0];
        break;
    case MSR_FP:
        if( VariableFrame( mr->axp.pal.nt.fir.u._32[0] ) ) {
            ma->offset = mr->axp.r[AR_fp].u64.u._32[0];
        } else {
            ma->offset = mr->axp.r[AR_sp].u64.u._32[0];
        }
        break;
    }
}

void            DIGENTRY MIRegSpecialSet( mad_special_reg sr, mad_registers *mr, const addr_ptr *ma )
{
    switch( sr ) {
    case MSR_IP:
        /* doesn't matter what PAL is in control since always first field */
        mr->axp.pal.nt.fir.u._32[0] = ma->offset;
        break;
    case MSR_SP:
        mr->axp.r[AR_sp].u64.u._32[0] = ma->offset;
        break;
    case MSR_FP:
        if( VariableFrame( mr->axp.pal.nt.fir.u._32[0] ) ) {
            mr->axp.r[AR_fp].u64.u._32[0] = ma->offset;
        } else {
            mr->axp.r[AR_sp].u64.u._32[0] = ma->offset;
        }
        break;
    }
}

unsigned        DIGENTRY MIRegSpecialName( mad_special_reg sr, const mad_registers *mr, mad_address_format af, unsigned max, char *buff )
{
    unsigned    idx;
    unsigned    len;
    const char  *p;

    switch( sr ) {
    case MSR_IP:
        switch( mr->axp.active_pal ) {
        case PAL_nt:
            idx = IDX_nt_fir;
            break;
        case PAL_unix:
        case PAL_vms:
            //NYI: later
            //break;
        default:
            /* 'cause we gotta have one */
            idx = IDX_nt_fir;
            break;
        }
        break;
    case MSR_SP:
        idx = IDX_sp;
        break;
    case MSR_FP:
        if( VariableFrame( mr->axp.pal.nt.fir.u._32[0] ) ) {
            idx = IDX_fp;
        } else {
            idx = IDX_sp;
        }
        break;
    }
    p = RegList[idx].info.name;
    len = strlen( p );
    if( max > 0 ) {
        --max;
        if( max > len ) max = len;
        memcpy( buff, p, max );
        buff[max] = '\0';
    }
    return( len );
}


const mad_reg_info *DIGENTRY MIRegFromContextItem( context_item ci )
{
    const mad_reg_info  *reg;

    reg = NULL;
    if( ci == CI_AXP_fir ) {
        reg = &RegList[IDX_nt_fir].info;
    } else if( ci >= CI_AXP_r0 && ci <= CI_AXP_r31 ) {
        reg = &RegList[ci - CI_AXP_r0 + IDX_r0].info;
    } else if( ci >= CI_AXP_f0 && ci <= CI_AXP_f31 ) {
        reg = &RegList[ci - CI_AXP_f0 + IDX_f0].info;
    }
    return( reg );
}

void            DIGENTRY MIRegUpdateStart( mad_registers *mr, unsigned flags, unsigned bit_start, unsigned bit_size )
{
}

void            DIGENTRY MIRegUpdateEnd( mad_registers *mr, unsigned flags, unsigned bit_start, unsigned bit_size )
{
    unsigned    i;
    unsigned    bit_end;

    memset( &mr->axp.r[AR_r31], 0, sizeof( mr->axp.r[AR_r31] ) );
    memset( &mr->axp.r[AR_f31], 0, sizeof( mr->axp.r[AR_f31] ) );
    bit_end = bit_start + bit_size;
    #define IN_RANGE( i, bit )  \
      ((bit) >= RegList[i].info.bit_start && (bit) < RegList[i].info.bit_start+RegList[i].info.bit_size)
    for( i = 0; i < IDX_LAST_ONE; ++i ) {
        if( (IN_RANGE(i, bit_start) || IN_RANGE( i, bit_end ))
         && (RegList[i].pal == PAL_all || RegList[i].pal == mr->axp.active_pal) ) {
            MCNotify( MNT_MODIFY_REG, (void *)&RegSet[RegList[i].reg_set] );
            break;
        }
    }
    switch( bit_start ) {
    case BIT_OFF( pal.nt.fir ):
        MCNotify( MNT_MODIFY_IP, NULL );
        break;
    case BIT_OFF( r[AR_sp] ):
        MCNotify( MNT_MODIFY_SP, NULL );
        break;
    case BIT_OFF( r[AR_fp] ):
        MCNotify( MNT_MODIFY_FP, NULL );
        break;
    }
}

static mad_status AddSubList( unsigned idx, const sublist_data *sub, unsigned num )
{
    unsigned    i;
    unsigned    j;

    i = RegList[idx].info.bit_start / (sizeof( axpreg )*BITS_PER_BYTE);
    if( RegSubList[i] != NULL ) return( MS_OK );
    RegSubList[i] = MCAlloc( sizeof( axp_reg_info ) * (num+1) );
    if( RegSubList[i] == NULL ) return( MS_ERR|MS_NO_MEM );
    memset( RegSubList[i], 0, sizeof( axp_reg_info ) * (num+1) );
    for( j = 0; j < num; ++j ) {
        RegSubList[i][j] = RegList[idx];
        RegSubList[i][j].info.name       = sub[j].name;
        RegSubList[i][j].info.type       = sub[j].mth;
        RegSubList[i][j].info.bit_start += sub[j].start;
        RegSubList[i][j].info.bit_size   = TypeArray[ sub[j].mth ].u.b->bits;
        RegSubList[i][j].sublist_code    = RS_NONE;
    }
    return( MS_OK );
}

mad_status RegInit()
{
    unsigned    i;
    unsigned    max;
    unsigned    curr;
    mad_status  ms;

    max = 0;
    for( i = 0; i < NUM_ELTS( RegList ); ++i ) {
        switch( RegList[i].sublist_code ) {
        case RS_INT:
        case RS_FLT:
            curr = RegList[i].info.bit_start / (sizeof(axpreg)*BITS_PER_BYTE);
            if( curr > max ) max = curr;
            break;
        }
    }
    RegSubList = MCAlloc( (max+1) * sizeof( *RegSubList ) );
    if( RegSubList == NULL ) return( MS_ERR | MS_NO_MEM );
    memset( RegSubList, 0, (max+1) * sizeof( *RegSubList ) );
    for( i = 0; i < NUM_ELTS( RegList ); ++i ) {
        switch( RegList[i].sublist_code ) {
        case RS_INT:
            ms = AddSubList( i, IntRegSubData, NUM_ELTS( IntRegSubData ) );
            if( ms != MS_OK ) return( ms );
            break;
        case RS_FLT:
            ms = AddSubList( i, FltRegSubData, NUM_ELTS( FltRegSubData ) );
            if( ms != MS_OK ) return( ms );
        }
    }
    return( MS_OK );
}

void RegFini()
{
    unsigned    i;
    unsigned    max;
    unsigned    curr;

    max = 0;
    for( i = 0; i < NUM_ELTS( RegList ); ++i ) {
        switch( RegList[i].sublist_code ) {
        case RS_INT:
        case RS_FLT:
            curr = RegList[i].info.bit_start / (sizeof(axpreg)*BITS_PER_BYTE);
            if( curr > max ) max = curr;
            break;
        }
    }
    for( i = 0; i <= max; ++i ) MCFree( RegSubList[i] );
    MCFree( RegSubList );
    RegSubList = NULL;
}

⌨️ 快捷键说明

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