dbgexpr3.c

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

C
884
字号
        tmp = entry->v.real;
        break;
    case C8:
    case C16:
    case C20:
        tmp = entry->v.cmplx.re;
        break;
    default:
        return( FALSE );
    }
    entry->v.real = tmp;
    return( TRUE );
}

OVL_EXTERN bool ConvR4( stack_entry *entry, conv_class from )
{
    if( !ConvR10( entry, from ) ) return( FALSE );
    DToLD( (float)LDToD( &entry->v.real ), &entry->v.real );
    return( TRUE );
}

OVL_EXTERN bool ConvR8( stack_entry *entry, conv_class from )
{
    if( !ConvR10( entry, from ) ) return( FALSE );
    DToLD( (double)LDToD( &entry->v.real ), &entry->v.real );
    return( TRUE );
}

OVL_EXTERN bool ConvC20( stack_entry *entry, conv_class from )
{
    xcomplex tmp;

    DToLD( 0.0, &tmp.im );

    switch( from ) {
    case U1:
    case U2:
    case U4:
    case U8:
        //NYI: 64 bit support
        DToLD( U32FetchTrunc( entry->v.uint ), &tmp.re );
        break;
    case I1:
    case I2:
    case I4:
    case I8:
        DToLD( I32FetchTrunc( entry->v.sint ), &tmp.re );
        break;
    case F4:
    case F8:
    case F10:
        tmp.re = entry->v.real;
        break;
    case C8:
    case C16:
    case C20:
        tmp = entry->v.cmplx;
        break;
    default:
        return( FALSE );
    }
    entry->v.cmplx = tmp;
    return( TRUE );
}

OVL_EXTERN bool ConvC8( stack_entry *entry, conv_class from )
{
    if( !ConvC20( entry, from ) ) return( FALSE );
    DToLD( (float)LDToD( &entry->v.cmplx.re ), &entry->v.cmplx.re );
    DToLD( (float)LDToD( &entry->v.cmplx.im ), &entry->v.cmplx.im );
    return( TRUE );
}

OVL_EXTERN bool ConvC16( stack_entry *entry, conv_class from )
{
    if( !ConvC20( entry, from ) ) return( FALSE );
    DToLD( (double)LDToD( &entry->v.cmplx.re ), &entry->v.cmplx.re );
    DToLD( (double)LDToD( &entry->v.cmplx.im ), &entry->v.cmplx.im );
    return( TRUE );
}

OVL_EXTERN bool ConvNP4( stack_entry *entry, conv_class from )
{
    addr48_off  tmp;

    switch( from ) {
    case U1:
    case U2:
    case U4:
    case U8:
        //NYI: 64 bit offsets
        tmp = U32FetchTrunc( entry->v.uint );
        break;
    case I1:
    case I2:
    case I4:
    case I8:
        //NYI: 64 bit offsets
        tmp = I32FetchTrunc( entry->v.sint );
        break;
    case NP2:
    case NP4:
    case FP4:
    case FP6:
        tmp = entry->v.addr.mach.offset;
        break;
    default:
        return( FALSE );
    }
    if( (entry->flags & SF_CONST) && tmp == 0 ) {
        entry->v.addr = NilAddr;
    } else {
        entry->v.addr = DefAddrSpaceForAddr( Context.execution );
    }
    entry->v.addr.mach.offset = tmp;
    return( TRUE );
}

OVL_EXTERN bool ConvNP2( stack_entry *entry, conv_class from )
{
    if( !ConvNP4( entry, from ) ) return( FALSE );
    entry->v.addr.mach.offset = (addr32_off)entry->v.addr.mach.offset;
    return( TRUE );
}

OVL_EXTERN bool ConvFP6( stack_entry *entry, conv_class from )
{
    address     tmp;

    tmp = DefAddrSpaceForAddr( Context.execution );
    switch( from ) {
    case U1:
    case U2:
    case U4:
    case U8:
        if( (entry->flags & SF_CONST) && U64Test( &entry->v.uint ) == 0 ) tmp = NilAddr;
        //NYI: 64 bit offsets
        tmp.mach.offset = U32FetchTrunc( entry->v.uint );
        break;
    case I1:
    case I2:
    case I4:
    case I8:
        if( (entry->flags & SF_CONST) && I64Test( &entry->v.sint ) == 0 ) tmp = NilAddr;
        //NYI: 64 bit offsets
        tmp.mach.offset = U32FetchTrunc( entry->v.sint );
        break;
    case NP2:
    case NP4:
        /* near pointers already have correct segment information filled in */
        tmp = entry->v.addr;
        break;
    case FP4:
    case FP6:
    case HP4:
        tmp = entry->v.addr;
        break;
    default:
        return( FALSE );
    }
    entry->v.addr = tmp;
    return( TRUE );
}

OVL_EXTERN bool ConvFP4( stack_entry *entry, conv_class from )
{
    if( !ConvFP6( entry, from ) ) return( FALSE );
    entry->v.addr.mach.offset = (addr32_off)entry->v.addr.mach.offset;
    return( TRUE );
}

OVL_EXTERN bool ConvSTR( stack_entry *entry, conv_class from )
{
    entry = entry;
    from = from;
    /* everything has already been taken care of */
    return( TRUE );
}

OVL_EXTERN bool ConvERR( stack_entry *entry, conv_class from )
{
    entry = entry;
    from = from;
    return( FALSE );
}

static bool (* const ConvFunc[])( stack_entry *, conv_class ) = {
    ConvI1,
    ConvU1,
    ConvI2,
    ConvU2,
    ConvI4,
    ConvU4,
    ConvI8,
    ConvU8,
    ConvR4,
    ConvR8,
    ConvR10,
    ConvC8,
    ConvC16,
    ConvC20,
    ConvSTR,
    ConvNP2,
    ConvNP4,
    ConvFP4,
    ConvFP6,
    ConvFP4, /* HP4 */
    ConvERR
};


/*
 * ConvertTo -- convert 'entry' to the given 'class'.
 *      'entry' should be an rvalue.
 */
void ConvertTo( stack_entry *entry, type_kind k, type_modifier m, unsigned s )
{
    conv_class  from;
    char        *dest;

    if( s == 0 && k == TK_INTEGER ) {
        s = DefaultSize( DK_INT );
    }
    if( entry->info.kind == k
     && entry->info.modifier == m
     && entry->info.size == s ) return;
    from = ConvIdx( &entry->info );
    switch( from ) {
    case U1:
        U32ToU64( U8FetchTrunc( entry->v.uint ), &entry->v.uint );
        break;
    case U2:
        U32ToU64( U16FetchTrunc( entry->v.uint ), &entry->v.uint );
        break;
    case U4:
        U32ToU64( U32FetchTrunc( entry->v.uint ), &entry->v.uint );
        break;
    case I1:
        I32ToI64( I8FetchTrunc( entry->v.uint ), &entry->v.uint );
        break;
    case I2:
        I32ToI64( I16FetchTrunc( entry->v.uint ), &entry->v.uint );
        break;
    case I4:
        I32ToI64( I32FetchTrunc( entry->v.uint ), &entry->v.uint );
        break;
    case F4:
        DToLD( (float)LDToD( &entry->v.real ), &entry->v.real );
        break;
    case F8:
        DToLD( (double)LDToD( &entry->v.real ), &entry->v.real );
        break;
    case C8:
        DToLD( (float)LDToD( &entry->v.cmplx.re ), &entry->v.cmplx.re );
        DToLD( (float)LDToD( &entry->v.cmplx.im ), &entry->v.cmplx.im );
        break;
    case C16:
        DToLD( (double)LDToD( &entry->v.cmplx.re ), &entry->v.cmplx.re );
        DToLD( (double)LDToD( &entry->v.cmplx.im ), &entry->v.cmplx.im );
        break;
    case NP2:
    case FP4:
        entry->v.addr.mach.offset &= 0xffff;
        break;
    case STR:
        if( k != TK_STRING ) {
            Error( ERR_NONE, LIT( ERR_TYPE_CONVERSION ) );
        }
        if( s > entry->info.size ) {
            /* have to expand string */
            _ChkAlloc( dest, s, LIT( ERR_NO_MEMORY_FOR_EXPR ) );
            memcpy( dest, entry->v.string.loc.e[0].u.p, entry->info.size );
            memset( &dest[entry->info.size], ' ', s - entry->info.size );
            if( AllocatedString( entry ) ) {
                _Free( entry->v.string.allocated );
            }
            entry->v.string.allocated = dest;
            LocationCreate( &entry->v.string.loc, LT_INTERNAL, dest );
        }
        break;
    default:
        break;
    }
    entry->info.kind = k;
    entry->info.modifier = m;
    entry->info.size = s;
    if( !ConvFunc[ ConvIdx( &entry->info ) ]( entry, from ) ) {
        Error( ERR_NONE, LIT( ERR_TYPE_CONVERSION ) );
    }
    entry->th = NULL;
}


static conv_class BinResult[NUM_CLASSES][NUM_CLASSES] = {
        /* I1  U1  I2  U2  I4  U4  I8  U8  F4  F8  F10 C8  C16 C20 STR NP2 NP4 FP4 FP6 HP4*/
/* I1 */ { I1, U1, I2, U2, I4, U4, I8, U8, F4, F8, F10,C8, C16,C20,ERR,NP2,NP4,FP4,FP6,HP4},
/* U1 */ { U1, U1, I2, U2, I4, U4, I8, U8, F4, F8, F10,C8, C16,C20,ERR,NP2,NP4,FP4,FP6,HP4},
/* I2 */ { I2, I2, I2, U2, I4, U4, I8, U8, F4, F8, F10,C8, C16,C20,ERR,NP2,NP4,FP4,FP6,HP4},
/* U2 */ { U2, U2, U2, U2, I4, U4, I8, U8, F4, F8, F10,C8, C16,C20,ERR,NP2,NP4,FP4,FP6,HP4},
/* I4 */ { I4, I4, I4, I4, I4, U4, I8, U8, F4, F8, F10,C8, C16,C20,ERR,NP2,NP4,FP4,FP6,HP4},
/* U4 */ { U4, U4, U4, U4, U4, U4, I8, U8, F4, F8, F10,C8, C16,C20,ERR,NP2,NP4,FP4,FP6,HP4},
/* I8 */ { I8, I8, I8, I8, I8, U8, I8, U8, F8, F8, F10,C8, C16,C20,ERR,NP2,NP4,FP4,FP6,HP4},
/* U8 */ { U8, U8, U8, U8, U8, U8, I8, U8, F8, F8, F10,C8, C16,C20,ERR,NP2,NP4,FP4,FP6,HP4},
/* F4 */ { F4, F4, F4, F4, F4, F4, F8, F8, F4, F8, F10,C8, C16,C20,ERR,ERR,ERR,ERR,ERR,ERR},
/* F8 */ { F8, F8, F8, F8, F8, F8, F8, F8, F8, F8, F10,C16,C16,C20,ERR,ERR,ERR,ERR,ERR,ERR},
/* F10*/ { F8, F8, F8, F8, F8, F8, F8, F8, F8, F8, F10,C20,C20,C20,ERR,ERR,ERR,ERR,ERR,ERR},
/* C8 */ { C8, C8, C8, C8, C8, C8, C16,C16,C8, C16,C20,C8, C16,C20,ERR,ERR,ERR,ERR,ERR,ERR},
/* C16*/ { C16,C16,C16,C16,C16,C16,C16,C16,C16,C16,C20,C16,C16,C20,ERR,ERR,ERR,ERR,ERR,ERR},
/* C20*/ { C20,C20,C20,C20,C20,C20,C20,C20,C20,C20,C20,C20,C20,C20,ERR,ERR,ERR,ERR,ERR,ERR},
/* STR*/ { ERR,ERR,ERR,ERR,ERR,ERR,ERR,ERR,ERR,ERR,ERR,ERR,ERR,STR,ERR,ERR,ERR,ERR,ERR,ERR},
/* NP2*/ { NP2,NP2,NP2,NP2,NP2,NP2,NP2,NP2,ERR,ERR,ERR,ERR,ERR,ERR,ERR,NP2,NP4,FP4,FP6,HP4},
/* NP4*/ { NP4,NP4,NP4,NP4,NP4,NP4,NP4,NP4,ERR,ERR,ERR,ERR,ERR,ERR,ERR,NP4,NP4,FP4,FP6,HP4},
/* FP4*/ { FP4,FP4,FP4,FP4,FP4,FP4,FP4,FP4,ERR,ERR,ERR,ERR,ERR,ERR,ERR,FP4,FP4,FP4,FP6,HP4},
/* FP6*/ { FP6,FP6,FP4,FP6,FP6,FP6,FP6,FP6,ERR,ERR,ERR,ERR,ERR,ERR,ERR,FP6,FP6,FP6,FP6,FP6},
/* HP4*/ { HP4,HP4,HP4,HP4,HP4,HP4,HP4,HP4,ERR,ERR,ERR,ERR,ERR,ERR,ERR,HP4,HP4,HP4,FP6,HP4}
};

static type_info ResultInfo[] = {
        {  1, TK_INTEGER,       TM_SIGNED },
        {  1, TK_INTEGER,       TM_UNSIGNED },
        {  2, TK_INTEGER,       TM_SIGNED },
        {  2, TK_INTEGER,       TM_UNSIGNED },
        {  4, TK_INTEGER,       TM_SIGNED },
        {  4, TK_INTEGER,       TM_UNSIGNED },
        {  8, TK_INTEGER,       TM_SIGNED },
        {  8, TK_INTEGER,       TM_UNSIGNED },
        {  4, TK_REAL,          TM_NONE },
        {  8, TK_REAL,          TM_NONE },
        { 10, TK_REAL,          TM_NONE },
        {  8, TK_COMPLEX,       TM_NONE },
        { 16, TK_COMPLEX,       TM_NONE },
        { 20, TK_COMPLEX,       TM_NONE },
        {  0, TK_STRING,        TM_NONE },
        {  2, TK_POINTER,       TM_NEAR },
        {  4, TK_POINTER,       TM_NEAR },
        {  4, TK_POINTER,       TM_FAR },
        {  6, TK_POINTER,       TM_FAR },
        {  4, TK_POINTER,       TM_HUGE },
};

static void DoBinOp( stack_entry *left, stack_entry *right )
{
    conv_class  lclass;
    conv_class  rclass;
    conv_class  result_class;
    type_info   *result_info;
    bool        promote_left;

    lclass = ConvIdx( &left->info );
    rclass = ConvIdx( &right->info );
    if( lclass == ERR || rclass == ERR ) {
        Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
    }
    result_class = BinResult[ lclass ][ rclass ];
    if( result_class == ERR ) {
        Error( ERR_NONE, LIT( ERR_TYPE_CONVERSION ) );
    }
    if( left->info.kind == TK_ENUM ) {
        result_info = &left->info;
    } else if( right->info.kind == TK_ENUM ) {
        result_info = &right->info;
    } else {
        result_info = &ResultInfo[ result_class ];
    }
    promote_left = FALSE;
    if( lclass != result_class ) {
        promote_left = TRUE;
        ConvertTo( left, result_info->kind,
                result_info->modifier, result_info->size );
    }
    if( rclass != result_class ) {
        ConvertTo( right, result_info->kind,
                result_info->modifier, result_info->size );
    }
    /* set up result type in left operand */
    if( left->th != NULL && right->th != NULL ) {
        /* if left side was promoted, use right's type. otherwise use left's */
        if( promote_left ) {
            MoveTH( right, left );
        }
    } else if( right->th != NULL ) {
        MoveTH( right, left );
    /* else use left->type */
    }
}

void BinOp( stack_entry *left, stack_entry *right )
{
    RValue( left );
    RValue( right );
    DoBinOp( left, right );
}

void AddOp( stack_entry *left, stack_entry *right )
{
    switch( left->info.kind ) {
    case TK_POINTER:
    case TK_ADDRESS:
        break;
    default:
        DoBinOp( left, right );
    }
}

void ToItemMAD( stack_entry *entry, item_mach *tmp, mad_type_info *mti )
{
    unsigned            bytes;
    mad_type_info       src;

    bytes = mti->b.bits / BITS_PER_BYTE;
    switch( mti->b.kind ) {
    case MTK_INTEGER:
        ConvertTo( entry, TK_INTEGER, TM_UNSIGNED, bytes );
        MADTypeInfoForHost( MTK_INTEGER, sizeof( entry->v.uint ), &src );
        break;
    case MTK_ADDRESS:
        if( mti->a.seg.bits == 0 ) {
            ConvertTo( entry, TK_ADDRESS, TM_NEAR, bytes );
            MADTypeInfoForHost( MTK_ADDRESS, sizeof( entry->v.addr.mach.offset ), &src );
        } else {
            ConvertTo( entry, TK_ADDRESS, TM_FAR, bytes );
            MADTypeInfoForHost( MTK_ADDRESS, sizeof( entry->v.addr.mach ), &src );
        }
        break;
    case MTK_FLOAT:
        ConvertTo( entry, TK_REAL, TM_NONE, bytes );
        MADTypeInfoForHost( MTK_FLOAT, sizeof( entry->v.real ), &src );
        break;
    case MTK_XMM:
        //MAD: nyi
        ToItem( entry, tmp );
        return;
    case MTK_CUSTOM:
        //MAD: nyi
        ToItem( entry, tmp );
        return;
    }
    if( MADTypeConvert( &src, &entry->v, mti, tmp, 0 ) != MS_OK ) {
        ToItem( entry, tmp );
    }
}

⌨️ 快捷键说明

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