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