axpdisas.c

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

C
472
字号
    }
    switch( condition ) {
    case DI_AXP_BLBC:
        if( (reg->u64.u._8[0] & 1) == 0 ) break;
        return( 0 );
    case DI_AXP_BEQ:
        if( cmp == 0 ) break;
        return( 0 );
    case DI_AXP_BLT:
        if( cmp < 0 ) break;
        return( 0 );
    case DI_AXP_BLE:
        if( cmp <= 0 ) break;
        return( 0 );
    case DI_AXP_BLBS:
        if( reg->u64.u._8[0] & 1 ) break;
        return( 0 );
    case DI_AXP_BNE:
        if( cmp != 0 ) break;
        return( 0 );
    case DI_AXP_BGE:
        if( cmp >= 0 ) break;
        return( 0 );
    case DI_AXP_BGT:
        if( cmp > 0 ) break;
        return( 0 );
    }
    return( 1 );
}

mad_disasm_control DisasmControl( mad_disasm_data *dd, const mad_registers *mr )
{
    switch( dd->ins.type ) {
    case DI_AXP_CALL_PAL:
        return( MDC_SYSCALL | MDC_TAKEN );
    case DI_AXP_JMP:
        return( MDC_JUMP | MDC_TAKEN );
    case DI_AXP_JSR:
    case DI_AXP_JSR_CORTN:
    case DI_AXP_BSR:
        return( MDC_CALL | MDC_TAKEN );
    case DI_AXP_RET:
        return( MDC_RET | MDC_TAKEN );
    case DI_AXP_BR:
        return( dd->ins.op[1].value < 0
                        ? (MDC_JUMP | MDC_TAKEN_BACK)
                        : (MDC_JUMP | MDC_TAKEN_FORWARD) );
    case DI_AXP_FBEQ:
        if( !Cond( dd, mr, DI_AXP_BEQ ) ) return( MDC_JUMP | MDC_CONDITIONAL | MDC_TAKEN_NOT );
        return( dd->ins.op[1].value < 0
                        ? (MDC_JUMP | MDC_CONDITIONAL | MDC_TAKEN_BACK)
                        : (MDC_JUMP | MDC_CONDITIONAL | MDC_TAKEN_FORWARD) );
    case DI_AXP_FBLE:
        if( !Cond( dd, mr, DI_AXP_BLE ) ) return( MDC_JUMP | MDC_CONDITIONAL | MDC_TAKEN_NOT );
        return( dd->ins.op[1].value < 0
                        ? (MDC_JUMP | MDC_CONDITIONAL | MDC_TAKEN_BACK)
                        : (MDC_JUMP | MDC_CONDITIONAL | MDC_TAKEN_FORWARD) );
    case DI_AXP_FBNE:
        if( !Cond( dd, mr, DI_AXP_BNE ) ) return( MDC_JUMP | MDC_CONDITIONAL | MDC_TAKEN_NOT );
        return( dd->ins.op[1].value < 0
                        ? (MDC_JUMP | MDC_CONDITIONAL | MDC_TAKEN_BACK)
                        : (MDC_JUMP | MDC_CONDITIONAL | MDC_TAKEN_FORWARD) );
    case DI_AXP_FBGE:
        if( !Cond( dd, mr, DI_AXP_BGE ) ) return( MDC_JUMP | MDC_CONDITIONAL | MDC_TAKEN_NOT );
        return( dd->ins.op[1].value < 0
                        ? (MDC_JUMP | MDC_CONDITIONAL | MDC_TAKEN_BACK)
                        : (MDC_JUMP | MDC_CONDITIONAL | MDC_TAKEN_FORWARD) );
    case DI_AXP_FBGT:
        if( !Cond( dd, mr, DI_AXP_BGT ) ) return( MDC_JUMP | MDC_CONDITIONAL | MDC_TAKEN_NOT );
        return( dd->ins.op[1].value < 0
                        ? (MDC_JUMP | MDC_CONDITIONAL | MDC_TAKEN_BACK)
                        : (MDC_JUMP | MDC_CONDITIONAL | MDC_TAKEN_FORWARD) );
    case DI_AXP_BLBC:
    case DI_AXP_BEQ:
    case DI_AXP_BLT:
    case DI_AXP_BLE:
    case DI_AXP_BLBS:
    case DI_AXP_BNE:
    case DI_AXP_BGE:
    case DI_AXP_BGT:
        if( !Cond( dd, mr, dd->ins.type ) ) return( MDC_JUMP | MDC_CONDITIONAL | MDC_TAKEN_NOT );
        return( dd->ins.op[1].value < 0
                        ? (MDC_JUMP | MDC_CONDITIONAL | MDC_TAKEN_BACK)
                        : (MDC_JUMP | MDC_CONDITIONAL | MDC_TAKEN_FORWARD) );
    case DI_AXP_CMOVEQ:
        if( !Cond( dd, mr, DI_AXP_BEQ ) ) return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN_NOT );
        return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN );
    case DI_AXP_CMOVLBC:
        if( !Cond( dd, mr, DI_AXP_BLBC ) ) return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN_NOT );
        return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN );
    case DI_AXP_CMOVLBS:
        if( !Cond( dd, mr, DI_AXP_BLBS ) ) return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN_NOT );
        return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN );
    case DI_AXP_CMOVGE:
        if( !Cond( dd, mr, DI_AXP_BGE ) ) return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN_NOT );
        return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN );
    case DI_AXP_CMOVGT:
        if( !Cond( dd, mr, DI_AXP_BGT ) ) return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN_NOT );
        return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN );
    case DI_AXP_CMOVLE:
        if( !Cond( dd, mr, DI_AXP_BLE ) ) return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN_NOT );
        return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN );
    case DI_AXP_CMOVLT:
        if( !Cond( dd, mr, DI_AXP_BLT ) ) return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN_NOT );
        return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN );
    case DI_AXP_CMOVNE:
        if( !Cond( dd, mr, DI_AXP_BNE ) ) return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN_NOT );
        return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN );
    case DI_AXP_FCMOVEQ:
        if( !Cond( dd, mr, DI_AXP_BEQ ) ) return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN_NOT );
        return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN );
    case DI_AXP_FCMOVGE:
        if( !Cond( dd, mr, DI_AXP_BGE ) ) return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN_NOT );
        return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN );
    case DI_AXP_FCMOVGT:
        if( !Cond( dd, mr, DI_AXP_BGT ) ) return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN_NOT );
        return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN );
    case DI_AXP_FCMOVLE:
        if( !Cond( dd, mr, DI_AXP_BLE ) ) return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN_NOT );
        return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN );
    case DI_AXP_FCMOVLT:
        if( !Cond( dd, mr, DI_AXP_BLT ) ) return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN_NOT );
        return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN );
    case DI_AXP_FCMOVNE:
        if( !Cond( dd, mr, DI_AXP_BNE ) ) return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN_NOT );
        return( MDC_OPER | MDC_CONDITIONAL | MDC_TAKEN );
    }
    return( MDC_OPER | MDC_TAKEN );
}

mad_disasm_control      DIGENTRY MIDisasmControl( mad_disasm_data *dd, const mad_registers *mr )
{
    return( DisasmControl( dd, mr ) );
}

mad_status      DIGENTRY MIDisasmInsNext( mad_disasm_data *dd, const mad_registers *mr, address *next )
{
    mad_disasm_control  dc;
    addr_off            new;
    const axpreg        *reg;

    memset( next, 0, sizeof( *next ) );
    next->mach.offset = mr->axp.pal.nt.fir.u._32[0] + sizeof( unsigned_32 );
    dc = DisasmControl( dd, mr );
    if( (dc & MDC_TAKEN_MASK) == MDC_TAKEN_NOT ) {
        return( MS_OK );
    }
    switch( dc & MDC_TYPE_MASK ) {
    case MDC_JUMP:
    case MDC_CALL:
    case MDC_RET:
        new = dd->ins.op[1].value;
        if( dd->ins.op[1].type == DO_RELATIVE ) {
            new += mr->axp.pal.nt.fir.u._32[0];
        }
        if( dd->ins.op[1].base != DR_NONE ) {
            reg = &mr->axp.r[TRANS_REG(dd->ins.op[1].base)];
            new += reg->u64.u._32[0];
        }
        next->mach.offset = new;
    }
    return( MS_OK );
}

walk_result             DIGENTRY MIDisasmMemRefWalk( mad_disasm_data *dd, MI_MEMREF_WALKER *wk, const mad_registers *mr, void *d )
{
    address             a;
    unsigned            i;
    walk_result         wr;
    mad_memref_kind     mmk;

    if( dd->ins.type >= DI_AXP_LDL && dd->ins.type <= DI_AXP_LDT ) {
        mmk = MMK_READ;
    } else if( dd->ins.type >= DI_AXP_STL && dd->ins.type <= DI_AXP_STT ) {
        mmk = MMK_WRITE;
    } else {
        return( WR_CONTINUE );
    }
    a = dd->addr;
    for( i = 0; i < dd->ins.num_ops; ++i ) {
        a.mach.offset = dd->ins.op[i].value;
        switch( dd->ins.op[i].type ) {
        case DO_MEMORY_REL:
            a.mach.offset += dd->addr.mach.offset;
            /* fall through */
        case DO_MEMORY_ABS:
            a.mach.offset +=
             mr->axp.r[TRANS_REG(dd->ins.op[i].base)].u64.u._32[0];
            mmk &= (MMK_READ|MMK_WRITE);
            if( TRANS_REG(dd->ins.op[i].base) == AR_sp ) {
                mmk |= MMK_VOLATILE;
            }
            wr = wk( a, RefTrans[dd->ins.op[i].ref_type-DRT_AXP_FIRST], mmk, d );
            if( wr != WR_CONTINUE ) return( wr );
            break;
        }
    }
    return( WR_CONTINUE );
}

const mad_toggle_strings        *DIGENTRY MIDisasmToggleList( void )
{
    static const mad_toggle_strings list[] = {
        { MSTR_MPSEUDOINS, MSTR_PSEUDOINS, MSTR_RAWINS },
        { MSTR_MUPPER, MSTR_UPPER, MSTR_LOWER },
        { MSTR_NIL, MSTR_NIL, MSTR_NIL }
    };
    return( list );
}

unsigned                DIGENTRY MIDisasmToggle( unsigned on, unsigned off )
{
    unsigned    toggle;

    toggle = (on & off);
    MADState->disasm_state ^= toggle;
    MADState->disasm_state |= on & ~toggle;
    MADState->disasm_state &= ~off | toggle;
    return( MADState->disasm_state );
}

mad_status              DIGENTRY MIDisasmInspectAddr( char *from, unsigned len, unsigned radix, const mad_registers *mr, address *a )
{
    char        *buff = __alloca( len * 2 );
    char        *to;

    mr = mr;
    to = buff;
    while( len != 0 ) {
        if( *from == '(' ) *to++ = '+';
        *to++ = *from++;
        --len;
    }
    return( MCMemExpr( buff, to - buff, radix, a ) );
}

⌨️ 快捷键说明

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