madman.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,275 行 · 第 1/5 页
C
2,275 行
}
len = strlen( me->file );
if( max > 0 ) {
--max;
if( max > len ) max = len;
memcpy( name, me->file, max );
name[max] = '\0';
}
return( len );
}
unsigned MADNameDescription( mad_handle mh, unsigned max, char *name )
{
mad_entry *me;
unsigned len;
me = MADFind( mh );
if( me == NULL ) {
MADStatus( MS_ERR|MS_UNREGISTERED_MAD );
return( 0 );
}
len = strlen( me->desc );
if( max > 0 ) {
--max;
if( max > len ) max = len;
memcpy( name, me->desc, max );
name[max] = '\0';
}
return( len );
}
/*
* Address Arithmetic
*/
static void DIGREGISTER DummyAddrAdd( address *a, long b, mad_address_format af )
{
af = af;
a->mach.offset += b;
}
void MADAddrAdd( address *a, long b, mad_address_format af )
{
Active->rtns->MIAddrAdd( a, b, af );
}
static int DIGREGISTER DummyAddrComp( const address *a, const address *b, mad_address_format af )
{
af = af;
if( a->mach.offset == b->mach.offset ) return( 0 );
if( a->mach.offset > b->mach.offset ) return( +1 );
return( -1 );
}
int MADAddrComp( const address *a, const address *b, mad_address_format af )
{
return( Active->rtns->MIAddrComp( a, b, af ) );
}
static long DIGREGISTER DummyAddrDiff( const address *a, const address *b, mad_address_format af )
{
af = af;
return( a->mach.offset - b->mach.offset );
}
long MADAddrDiff( const address *a, const address *b, mad_address_format af )
{
return( Active->rtns->MIAddrDiff( a, b, af ) );
}
static mad_status DIGREGISTER DummyAddrMap( addr_ptr *a, const addr_ptr *map, const addr_ptr *real, const mad_registers *mr )
{
a = a;
map = map;
real = real;
mr = mr;
return( MS_FAIL );
}
mad_status MADAddrMap( addr_ptr *a, const addr_ptr *map, const addr_ptr *real, const mad_registers *mr )
{
return( Active->rtns->MIAddrMap( a, map, real, mr ) );
}
static mad_status DIGREGISTER DummyAddrFlat( const mad_registers *mr )
{
mr = mr;
return( MS_FAIL );
}
mad_status MADAddrFlat( const mad_registers *mr )
{
return( Active->rtns->MIAddrFlat( mr ) );
}
static mad_status DIGREGISTER DummyAddrInterrupt( const addr_ptr *a, unsigned size, const mad_registers *mr )
{
a = a;
size = size;
mr = mr;
return( MS_FAIL );
}
mad_status MADAddrInterrupt( const addr_ptr *a, unsigned size, const mad_registers *mr )
{
return( Active->rtns->MIAddrInterrupt( a, size, mr ) );
}
/*
* Machine Types
*/
static walk_result DIGREGISTER DummyTypeWalk( mad_type_kind tk, MI_TYPE_WALKER *wk, void *d )
{
tk = tk;
wk = wk;
d = d;
return( WR_CONTINUE );
}
struct type_glue {
MAD_TYPE_WALKER *wk;
void *d;
};
static walk_result DIGCLIENT TypeGlue( mad_type_handle th, void *d )
{
struct type_glue *gd = d;
return( gd->wk( th, gd->d ) );
}
walk_result MADTypeWalk( mad_type_kind tk, MAD_TYPE_WALKER *wk, void *d )
{
struct type_glue glue;
glue.wk = wk;
glue.d = d;
return( Active->rtns->MITypeWalk( tk, TypeGlue, &glue ) );
}
static mad_string DIGREGISTER DummyTypeName( mad_type_handle th )
{
th = th;
return( MSTR_NIL );
}
mad_string MADTypeName( mad_type_handle th )
{
return( Active->rtns->MITypeName( th ) );
}
static unsigned DIGREGISTER DummyTypePreferredRadix( mad_type_handle th )
{
th = th;
return( 0 );
}
unsigned MADTypePreferredRadix( mad_type_handle th )
{
return( Active->rtns->MITypePreferredRadix( th ) );
}
static mad_type_handle DIGREGISTER DummyTypeForDIPType( const type_info *ti )
{
ti = ti;
return( MAD_NIL_TYPE_HANDLE );
}
mad_type_handle MADTypeForDIPType( const type_info *ti )
{
return( Active->rtns->MITypeForDIPType( ti ) );
}
static void DIGREGISTER DummyTypeInfo( mad_type_handle th, mad_type_info *ti )
{
th = th;
ti->b.kind = MTK_CUSTOM;
ti->b.bits = 0;
}
void MADTypeInfo( mad_type_handle th, mad_type_info *ti )
{
Active->rtns->MITypeInfo( th, ti );
}
mad_status MADTypeInfoForHost( mad_type_kind tk, int size, mad_type_info *mti )
{
tk &= MTK_ALL;
mti->b.kind = tk;
mti->b.handler_code = MAD_DEFAULT_HANDLING;
mti->b.bits = size * BITS_PER_BYTE;
mti->i.endian = ME_HOST;
switch( tk ) {
case MTK_INTEGER:
mti->i.nr = MNR_UNSIGNED;
if( size < 0 ) {
mti->i.nr = MNR_HOST_SIGNED;
mti->b.bits = -mti->b.bits;
}
mti->i.sign_pos = mti->b.bits - 1;
break;
case MTK_ADDRESS:
if( size == sizeof( address ) ) {
size = sizeof( addr48_ptr );
mti->b.bits = sizeof( addr48_ptr ) * BITS_PER_BYTE;
}
mti->a.i.nr = MNR_UNSIGNED;
mti->a.seg.bits = sizeof( addr_seg )*BITS_PER_BYTE;
mti->a.seg.pos = (size - sizeof( addr_seg )) * BITS_PER_BYTE;
break;
case MTK_FLOAT:
mti->f.exp.base = FLT_RADIX;
#if defined(FLOAT_IEEE)
mti->f.mantissa.nr = MNR_SIGN_MAG;
mti->f.mantissa.sign_pos = mti->b.bits - 1;
switch( size ) {
case sizeof( sreal ):
mti->f.exp.hidden = 1;
mti->f.exp.bias = 127;
mti->f.exp.data.b.bits = 8;
break;
case sizeof( lreal ):
mti->f.exp.hidden = 1;
mti->f.exp.bias = 1023;
mti->f.exp.data.b.bits = 11;
break;
case sizeof( xreal ):
mti->f.exp.hidden = 0;
mti->f.exp.bias = 16383;
mti->f.exp.data.b.bits = 15;
break;
}
mti->f.exp.data.sign_pos = mti->f.exp.data.b.bits - 1;
mti->f.exp.data.nr = MNR_UNSIGNED;
mti->f.exp.data.endian = ME_HOST;
mti->f.exp.pos = mti->f.mantissa.sign_pos - mti->f.exp.data.b.bits;
#else
#error Host floating point info not configured
#endif
break;
case MTK_XMM:
break;
}
return( MS_UNSUPPORTED );
}
static mad_type_handle DIGREGISTER DummyTypeDefault( mad_type_kind tk, mad_address_format af, const mad_registers *mr, const address *a )
{
tk = tk;
af = af;
mr = mr;
a = a;
return( 0 );
}
mad_type_handle MADTypeDefault( mad_type_kind tk, mad_address_format af, const mad_registers *mr, const address *a )
{
return( Active->rtns->MITypeDefault( tk, af, mr, a ) );
}
static mad_status DIGREGISTER DummyTypeConvert( const mad_type_info *in_t, const void *in_d, const mad_type_info *out_t, void *out_d, addr_seg seg )
{
in_t = in_t; in_d = in_d; out_t = out_t; out_d = out_d; seg = seg;
return( MS_UNSUPPORTED );
}
typedef union {
unsigned_64 i;
addr_ptr a;
struct {
int exp;
int sign;
unsigned_64 mantissa;
unsigned_16 extra_slop; /* makes DecomposeFloat easier */
enum {
F_NORMAL,
F_ZERO,
F_DENORMAL,
F_SPECIAL /* nan, inf */
} type;
} f;
} decomposed_item;
/* size of decomposed int in bytes - corresponds to 'i' in decomposed_item */
#define DI_SIZE sizeof( unsigned_64 )
/* size of decomposed mantissa in bytes (f.mantissa) */
#define DF_SIZE sizeof( unsigned_64 )
/* Convert integer of specified type to native representation (64-bit) */
// NYI: non-two's complement support
static mad_status DecomposeInt( const mad_type_info *mti, const void *d,
decomposed_item *v )
{
unsigned bytes;
unsigned i;
unsigned sign_bit;
unsigned_8 *dst = &v->i.u._8[0];
bytes = mti->b.bits / BITS_PER_BYTE;
#if defined( __BIG_ENDIAN__ )
dst += DI_SIZE - bytes; /* low bytes are higher in memory */
#endif
/* copy significant (low) bytes */
if( mti->i.endian == ME_HOST ) {
memcpy( dst, d, bytes );
} else {
for( i = 0; i < bytes; i++ ) {
dst[i] = ((unsigned_8 *)d)[EndMap[ME_BIG][DI_SIZE - bytes + i]];
}
}
/* clear high bytes */
#if defined( __BIG_ENDIAN__ )
memset( &v->i.u._8[0], 0, DI_SIZE - bytes );
#else
memset( &v->i.u._8[bytes], 0, DI_SIZE - bytes );
#endif
/* sign extend if necessary */
if( mti->i.nr != MNR_UNSIGNED ) {
i = mti->i.sign_pos / BITS_PER_BYTE;
sign_bit = mti->i.sign_pos % BITS_PER_BYTE;
if( v->i.u._8[i] & (1 << sign_bit) ) {
v->i.u._8[i] |= 0xff << sign_bit;
++i;
#if defined( __BIG_ENDIAN__ )
memset( &v->i.u._8[0], 0xff, DI_SIZE - i );
#else
memset( &v->i.u._8[i], 0xff, DI_SIZE - i );
#endif
}
}
return( MS_OK );
}
static mad_status DecomposeAddr( const mad_type_info *mti, const void *d,
addr_seg seg, decomposed_item *v )
{
const void *valp;
valp = d;
if( mti->a.seg.pos == 0 ) {
/* segment is at the low end - offset above it */
if( (mti->a.seg.bits % BITS_PER_BYTE) != 0 )
return( MS_UNSUPPORTED );
valp = (const unsigned_8 *)d + mti->a.seg.bits / BITS_PER_BYTE;
}
// NYI - address endianness translation doesn't work yet
// if( mti->i.endian == ME_HOST ) {
switch( mti->b.bits - mti->a.seg.bits ) {
case 16:
v->a.offset = *(unsigned_16 *)valp;
break;
case 32:
v->a.offset = *(unsigned_32 *)valp;
break;
default:
return( MS_UNSUPPORTED );
}
#if 0
} else {
unsigned bytes;
unsigned i;
switch( mti->b.bits - mti->a.seg.bits ) {
case 16:
bytes = 2;
break;
case 32:
bytes = 4;
break;
default:
return( MS_UNSUPPORTED );
}
for( i = 0; i < bytes; i++ ) {
v->i.u._8[i] = ((unsigned_8 *)d)[EndMap[ME_BIG][DI_SIZE - bytes + i]];
}
}
#endif
if( mti->a.seg.bits == 0 ) {
v->a.segment = seg;
} else {
valp = d;
if( mti->a.seg.pos != 0 ) {
/* segment is at the high end - offset below it */
if( (mti->a.seg.pos % BITS_PER_BYTE) != 0 )
return( MS_UNSUPPORTED );
valp = (const unsigned_8 *)d + mti->a.seg.pos / BITS_PER_BYTE;
}
// TODO: byte swap segment also
switch( mti->a.seg.bits ) {
case 16:
v->a.segment = *(unsigned_16 *)valp;
break;
case 32:
v->a.segment = *(unsigned_32 *)valp;
break;
default:
return( MS_UNSUPPORTED );
}
}
return( MS_OK );
}
static const unsigned short BitMask[] = {
0x0000, 0x0001, 0x0003, 0x0007,
0x000f, 0x001f, 0x003f, 0x007f,
0x00ff, 0x01ff, 0x03ff, 0x07ff,
0x0fff, 0x1fff, 0x3fff, 0x7fff,
0xffff };
static void ShiftBits( unsigned bits, int amount, void *d )
{
unsigned_8 *b = d;
unsigned bytes;
unsigned byte_shift;
unsigned_8 tmp1;
unsigned_8 tmp2;
int i;
bytes = (bits + (BITS_PER_BYTE-1)) / BITS_PER_BYTE;
if( amount > 0 ) {
/* left shift */
byte_shift = amount / BITS_PER_BYTE;
if( byte_shift != 0 ) {
#if defined( __BIG_ENDIAN__ )
memmove( b, b + byte_shift, bytes - byte_shift );
memset( b + byte_shift, 0, byte_shift );
byte_shift = 0;
#else
memmove( b + byte_shift, b, bytes - byte_shift );
memset( b, 0, byte_shift );
#endif
amount %= BITS_PER_BYTE;
}
if( amount != 0 ) {
tmp1 = 0;
for( i = byte_shift; i < bytes; ++i ) {
tmp2 = b[i];
b[i] = (b[i] << amount) | (tmp1 >> (BITS_PER_BYTE - amount));
tmp1 = tmp2;
}
}
} else if( amount < 0 ) {
/* right shift */
amount = -amount;
byte_shift = amount / BITS_PER_BYTE;
if( byte_shift != 0 ) {
#if defined( __BIG_ENDIAN__ )
memmove( b + byte_shift, b, bytes - byte_shift );
memset( b, 0, byte_shift );
byte_shift = 0;
#else
memmove( b, b + byte_shift, bytes - byte_shift );
memset( b + bytes - byte_shift, 0, byte_shift );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?