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 + -
显示快捷键?