axpdisas.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 472 行 · 第 1/2 页
C
472 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Alpha AXP instruction decoding.
*
****************************************************************************/
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#include "walloca.h"
#include "axp.h"
#include "axptypes.h"
#include "madregs.h"
static dis_handle DH;
mad_status DisasmInit()
{
if( DisInit( DISCPU_axp, &DH, FALSE ) != DR_OK ) {
return( MS_ERR | MS_FAIL );
}
return( MS_OK );
}
void DisasmFini()
{
DisFini( &DH );
}
dis_return DisCliGetData( void *d, unsigned off, unsigned int size, void *data )
{
mad_disasm_data *dd = d;
address addr;
addr = dd->addr;
addr.mach.offset += off;
if( MCReadMem( addr, size, data ) == 0 ) return( DR_FAIL );
return( DR_OK );
}
unsigned DisCliValueString( void *d, dis_dec_ins *ins, unsigned op, char *buff )
{
mad_disasm_data *dd = d;
char *p;
unsigned max;
mad_type_info mti;
address val;
p = buff;
p[0] = '\0';
val = dd->addr;
switch( ins->op[op].type & DO_MASK ) {
case DO_RELATIVE:
val.mach.offset += ins->op[op].value;
//NYI: 64 bit
MCAddrToString( val, AXPT_N32_PTR, MLK_CODE, 40, p );
break;
case DO_IMMED:
case DO_ABSOLUTE:
case DO_MEMORY_ABS:
MCTypeInfoForHost( MTK_INTEGER, -sizeof( ins->op[0].value ), &mti );
max = 40;
MCTypeToString( dd->radix, &mti, &ins->op[op].value, &max, p );
break;
}
return( strlen( buff ) );
}
unsigned DIGENTRY MIDisasmDataSize( void )
{
return( sizeof( mad_disasm_data ) );
}
unsigned DIGENTRY MIDisasmNameMax( void )
{
return( DisInsNameMax( &DH ) );
}
mad_status DisasmOne( mad_disasm_data *dd, address *a, int adj )
{
addr_off new;
dd->addr = *a;
new = dd->addr.mach.offset + adj * (int)sizeof( unsigned_32 );
if( (adj < 0 && new > dd->addr.mach.offset)
|| (adj > 0 && new < dd->addr.mach.offset) ) {
return( MS_FAIL );
}
dd->addr.mach.offset = new;
DisDecodeInit( &DH, &dd->ins );
if( DisDecode( &DH, dd, &dd->ins ) != DR_OK ) {
return( MS_ERR | MS_FAIL );
}
a->mach.offset = dd->addr.mach.offset + sizeof( unsigned_32 );
return( MS_OK );
}
mad_status DIGENTRY MIDisasm( mad_disasm_data *dd, address *a, int adj )
{
return( DisasmOne( dd, a, adj ) );
}
unsigned DIGENTRY MIDisasmFormat( mad_disasm_data *dd, mad_disasm_piece dp, unsigned radix, unsigned max, char *buff )
{
char nbuff[20];
char obuff[256];
char *np;
char *op;
unsigned nlen;
unsigned olen;
unsigned len;
dis_format_flags ff;
nbuff[0] = '\0';
obuff[0] = '\0';
np = (dp & MDP_INSTRUCTION) ? nbuff : NULL;
op = (dp & MDP_OPERANDS) ? obuff : NULL;
ff = DFF_NONE;
if( MADState->disasm_state & DT_PSEUDO_OPS ) ff |= DFF_PSEUDO;
if( MADState->disasm_state & DT_UPPER ) ff |= DFF_INS_UP | DFF_REG_UP;
if( MADState->reg_state[CPU_REG_SET] & CT_SYMBOLIC_NAMES ) {
ff |= DFF_SYMBOLIC_REG;
}
dd->radix = radix;
if( DisFormat( &DH, dd, &dd->ins, ff, np, op ) != DR_OK ) {
return( 0 );
}
olen = strlen( obuff );
nlen = strlen( nbuff );
if( dp == MDP_ALL ) nbuff[ nlen++ ] = ' ';
len = nlen + olen;
if( max > 0 ) {
--max;
if( max > len ) max = len;
if( nlen > max ) nlen = max;
memcpy( buff, nbuff, nlen );
buff += nlen;
max -= nlen;
if( olen > max ) olen = max;
memcpy( buff, obuff, olen );
buff[max] = '\0';
}
return( len );
}
unsigned DIGENTRY MIDisasmInsSize( mad_disasm_data *dd )
{
return( sizeof( unsigned_32 ) );
}
mad_status DIGENTRY MIDisasmInsUndoable( mad_disasm_data *dd )
{
switch( dd->ins.type ) {
case DI_AXP_CALL_PAL:
case DI_AXP_PAL19:
case DI_AXP_PAL1B:
case DI_AXP_PAL1D:
case DI_AXP_PAL1E:
case DI_AXP_PAL1F:
case DI_AXP_LDL_L:
case DI_AXP_LDQ_L:
case DI_AXP_STL_C:
case DI_AXP_STQ_C:
return( MS_FAIL );
}
return( MS_OK );
}
#define SKIP_ASM_REGS
const unsigned_8 RegTrans[] = {
#undef regpick
#define regpick( e, n ) AR_##e,
#include "regaxp.h"
};
static const mad_type_handle RefTrans[] = {
AXPT_BYTE,
AXPT_WORD,
AXPT_LWORD,
AXPT_QWORD,
AXPT_F_FLOAT,
AXPT_G_FLOAT,
AXPT_D_FLOAT,
AXPT_FLOAT,
AXPT_DOUBLE,
};
static int Cond( mad_disasm_data *dd, const mad_registers *mr, unsigned condition )
{
const axpreg *reg;
int cmp;
reg = &mr->axp.r[TRANS_REG(dd->ins.op[0].base)];
if( dd->ins.op[0].base >= DR_AXP_f0 && dd->ins.op[0].base <= DR_AXP_f31 ) {
/* floating point */
if( reg->t.r < 0 ) {
cmp = -1;
} else if( reg->t.r > 0 ) {
cmp = +1;
} else {
cmp = 0;
}
} else {
/* integer */
if( reg->s64.u.sign.v ) {
cmp = -1;
} else if( reg->u64.u._32[0] != 0 || reg->u64.u._32[1] != 0 ) {
cmp = +1;
} else {
cmp = 0;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?