Пример #1
0
static
float_handle BFCnvU64F( unsigned_64 val )
{
    float_handle t0, t1, t2;

    t0 = TwoTo32();
    t1 = BFCnvUF( val.u._32[ I64HI32 ] );
    t2 = BFMul( t0, t1 );
    BFFree( t0 );
    BFFree( t1 );
    t0 = BFCnvUF( val.u._32[ I64LO32 ] );
    t1 = BFAdd( t0, t2 );
    BFFree( t0 );
    BFFree( t2 );
    return t1;
}
Пример #2
0
static
float_handle BFCnvI64F( signed_64 val )
{
    float_handle t0, t1, t2;

    t0 = TwoTo32();
    t1 = BFCnvIF( val.u._32[ I64HI32 ] );
    t2 = BFMul( t0, t1 );
    BFFree( t0 );
    BFFree( t1 );
    if( val.u.sign.v ) {
        t0 = BFCnvUF( ( val.u._32[ I64LO32 ] ^ ULONG_MAX ) + 1 );
        BFNegate( t0 );
    } else {
        t0 = BFCnvUF( val.u._32[ I64LO32 ] );
    }
    t1 = BFAdd( t0, t2 );
    BFFree( t0 );
    BFFree( t2 );
    return t1;
}
Пример #3
0
static
signed_64 BFCnvF64( float_handle flt )
{
    signed_64 result;
    float_handle absol, t0, t1, t2, t3;
    bool positive;

    int sign = BFSign( flt );
    if( 0 == sign ) {
        result.u._32[0] = 0;
        result.u._32[1] = 0;
        return result;
    }
    positive = true;
    absol = flt;
    if( sign < 0 ) {
        positive = false;
        absol = BFCopy( flt );
        BFNegate( absol );
    }
    t0 = TwoTo32();
    t1 = BFDiv( flt, t0 );
    t3 = BFTrunc( t1 );
    BFFree( t1 );
    result.u._32[ I64HI32 ] = BFCnvF32( t3 );
    BFFree( t3 );
    t1 = BFCnvUF( result.u._32[ I64HI32 ] );
    t2 = BFMul( t0, t1 );
    BFFree( t0 );
    BFFree( t1 );
    t0 = BFSub( flt, t2 );
    BFFree( t2 );
    t3 = BFTrunc( t0 );
    BFFree( t0 );
    result.u._32[ I64LO32 ] = BFCnvF32( t3 );
    BFFree( t3 );
    if( ! positive ) {
        signed_64 neg;
        BFFree( absol );
        neg = result;
        U64Neg( &neg, &result );
    }
    return result;
}
Пример #4
0
static PTREE foldInt64( CGOP op, PTREE left, signed_64 v2 )
{
    signed_64 test;
    signed_64 v1;
    float_handle t0, t1, t2;

    v1 = left->u.int64_constant;
    switch( op ) {
    case CO_PLUS:
        U64Add( &v1, &v2, &left->u.int64_constant );
        break;
    case CO_MINUS:
        U64Sub( &v1, &v2, &left->u.int64_constant );
        break;
    case CO_TIMES:
        t0 = BFCnvI64F( v1 );
        t1 = BFCnvI64F( v2 );
        t2 = BFMul( t0, t1 );
        test = BFCnvF64( t2 );
        BFFree( t0 );
        BFFree( t1 );
        BFFree( t2 );
        U64Mul( &v1, &v2, &left->u.int64_constant );
        if( 0 != I64Cmp( &test, &left->u.int64_constant ) ) {
            CErr1( ANSI_ARITHMETIC_OVERFLOW );
        }
        break;
    case CO_DIVIDE:
    {   signed_64 rem;
        idiv64( &v1, &v2, &left->u.int64_constant, &rem );
    }   break;
    case CO_PERCENT:
    {   signed_64 div;
        idiv64( &v1, &v2, &div, &left->u.int64_constant );
    }   break;
    case CO_AND:
        left->u.int64_constant.u._32[0] = v1.u._32[0] & v2.u._32[0];
        left->u.int64_constant.u._32[1] = v1.u._32[1] & v2.u._32[1];
        break;
    case CO_OR:
        left->u.int64_constant.u._32[0] = v1.u._32[0] | v2.u._32[0];
        left->u.int64_constant.u._32[1] = v1.u._32[1] | v2.u._32[1];
        break;
    case CO_XOR:
        left->u.int64_constant.u._32[0] = v1.u._32[0] ^ v2.u._32[0];
        left->u.int64_constant.u._32[1] = v1.u._32[1] ^ v2.u._32[1];
        break;
    case CO_RSHIFT:
        I64ShiftR( &v1, v2.u._32[ I64LO32 ], &left->u.int64_constant );
        break;
    case CO_LSHIFT:
        U64ShiftL( &v1, v2.u._32[ I64LO32 ], &left->u.int64_constant );
        break;
    case CO_EQ:
        left = makeBooleanConst( left, 0 == I64Cmp( &v1, &v2 ) );
        return( left );
    case CO_NE:
        left = makeBooleanConst( left, 0 != I64Cmp( &v1, &v2 ) );
        return( left );
    case CO_GT:
        left = makeBooleanConst( left, 0 < I64Cmp( &v1, &v2 )) ;
        return( left );
    case CO_LE:
        left = makeBooleanConst( left, 0 >= I64Cmp( &v1, &v2 ) );
        return( left );
    case CO_LT:
        left = makeBooleanConst( left, 0 > I64Cmp( &v1, &v2 )) ;
        return( left );
    case CO_GE:
        left = makeBooleanConst( left, 0 <= I64Cmp( &v1, &v2 ) );
        return( left );
    case CO_AND_AND:
        left = makeBooleanConst( left, !Zero64( &v1 ) && !Zero64( &v2 ) );
        return( left );
    case CO_OR_OR:
        left = makeBooleanConst( left, !Zero64( &v1) || !Zero64( &v2 ) );
        return( left );
    case CO_COMMA:
        left->u.int64_constant = v2;
        break;
    default:
        return( NULL );
    }
    left->op = PT_INT_CONSTANT;
    return( left );
}
Пример #5
0
static PTREE foldFloating( CGOP op, PTREE left, float_handle v2 )
{
    float_handle v1;
    float_handle tmp;

    v1 = left->u.floating_constant;
    switch( op ) {
    case CO_PLUS:
        tmp = BFAdd( v1, v2 );
        BFFree( v1 );
        v1 = tmp;
        break;
    case CO_MINUS:
        tmp = BFSub( v1, v2 );
        BFFree( v1 );
        v1 = tmp;
        break;
    case CO_TIMES:
        tmp = BFMul( v1, v2 );
        BFFree( v1 );
        v1 = tmp;
        break;
    case CO_DIVIDE:
        if( BFSign( v2 ) == 0 ) {
            CErr1( ERR_DIVISION_BY_ZERO );
        }
        tmp = BFDiv( v1, v2 );
        BFFree( v1 );
        v1 = tmp;
        break;
    case CO_EQ:
        left = makeBooleanConst( left, BFCmp( v1, v2 ) == 0 );
        BFFree( v1 );
        return( left );
    case CO_NE:
        left = makeBooleanConst( left, BFCmp( v1, v2 ) != 0 );
        BFFree( v1 );
        return( left );
    case CO_GT:
        left = makeBooleanConst( left, BFCmp( v1, v2 ) > 0 );
        BFFree( v1 );
        return( left );
    case CO_LE:
        left = makeBooleanConst( left, BFCmp( v1, v2 ) <= 0 );
        BFFree( v1 );
        return( left );
    case CO_LT:
        left = makeBooleanConst( left, BFCmp( v1, v2 ) < 0 );
        BFFree( v1 );
        return( left );
    case CO_GE:
        left = makeBooleanConst( left, BFCmp( v1, v2 ) >= 0 );
        BFFree( v1 );
        return( left );
    case CO_COMMA:
        BFFree( v1 );
        v1 = BFCopy( v2 );
        break;
    default:
        return( NULL );
    }

    left->u.floating_constant = v1;
    left->op = PT_FLOATING_CONSTANT;
    return( left );
}
Пример #6
0
static  void    DoDataInit( PTYPE var_type ) {
//==========================================

// Do data initialization.

    int         const_size;
    int         var_size;
    int         size;
    byte        *const_ptr;
    segment_id  seg;
    seg_offset  offset;
    byte        const_buff[sizeof(ftn_type)];

    if( ( DtConstType == PT_CHAR ) || ( DtConstType == PT_NOTYPE ) ) {
        const_size = DtConst->u.lt.length;
        const_ptr = &DtConst->u.lt.value;
    } else {
        const_size = DtConst->u.cn.size;
        const_ptr = (byte *)(&DtConst->u.cn.value);
    }
    var_size = DtItemSize;
    seg = GetDataSegId( InitVar );
    offset = GetDataOffset( InitVar );
    DtInit( seg, offset );
    if( DtConstType == PT_CHAR ) {
        if( const_size >= var_size ) {
            DtBytes( const_ptr, var_size );
        } else {
            DtBytes( const_ptr, const_size );
            DtIBytes( ' ', var_size - const_size );
        }
    } else if( ( var_type == PT_CHAR ) && IntType( DtConstType ) ) {
        DtBytes( const_ptr, sizeof( char ) );
        if( var_size > sizeof( char ) ) {
            DtIBytes( ' ', var_size - sizeof( char ) );
        }
    } else if( DtConstType == PT_NOTYPE ) {
        if( var_type != PT_CHAR ) {
            size = var_size;
            while( size > const_size ) {
                size--;
                const_buff[ size ] = 0;
            }
            while( size > 0 ) {
                size--;
                const_buff[ size ] = *const_ptr;
                const_ptr++;
            }
            const_ptr = const_buff;
            const_size = var_size;
        }
        if( const_size < var_size ) {
            DtIBytes( 0, var_size - const_size );
            var_size = const_size;
        } else {
            const_ptr += const_size - var_size;
        }
        DtBytes( const_ptr, var_size );
    } else if( DtConstType <= PT_LOG_4 ) {
        DtBytes( const_ptr, var_size );
    } else {        // numeric to numeric
        if( DtConstType != var_type ) {
            DataCnvTab[ ( var_type - PT_INT_1 ) * CONST_TYPES +
                        ( DtConstType - PT_INT_1 ) ]( (ftn_type *)const_ptr, (ftn_type *)&const_buff );
            const_ptr = const_buff;
        }

// Temporary fix for identical precision between front end and code generator.
        {
            char        fmt_buff[CONVERSION_BUFFER+1];
            float_handle cf;

            if( (var_type == PT_REAL_4) || (var_type == PT_CPLX_8) ) {
                CnvS2S( (single *)const_ptr, fmt_buff );
                cf = BFCnvSF( fmt_buff );
                BFCnvTarget( cf, const_buff, BETypeLength( TY_SINGLE ) );
                BFFree( cf );
            } else if( (var_type == PT_REAL_8) || (var_type == PT_CPLX_16) ) {
                CnvD2S( (double *)const_ptr, fmt_buff );
                cf = BFCnvSF( fmt_buff );
                BFCnvTarget( cf, const_buff, BETypeLength( TY_DOUBLE ) );
                BFFree( cf );
            } else if( (var_type == PT_REAL_16) || (var_type == PT_CPLX_32) ) {
                CnvX2S( (extended *)const_ptr, fmt_buff );
                cf = BFCnvSF( fmt_buff );
                BFCnvTarget( cf, const_buff, BETypeLength( TY_LONGDOUBLE ) );
                BFFree( cf );
            }
            if( var_type == PT_CPLX_8 ) {
                CnvS2S( (single *)(const_ptr + sizeof( single )), fmt_buff );
                cf = BFCnvSF( fmt_buff );
                BFCnvTarget( cf, const_buff + sizeof( single ), BETypeLength( TY_SINGLE ) );
                BFFree( cf );
            } else if( var_type == PT_CPLX_16 ) {
                CnvD2S( (double *)(const_ptr + sizeof( double )), fmt_buff );
                cf = BFCnvSF( fmt_buff );
                BFCnvTarget( cf, const_buff + sizeof( double ), BETypeLength( TY_DOUBLE ) );
                BFFree( cf );
            } else if( var_type == PT_CPLX_32 ) {
                CnvX2S( (extended *)(const_ptr + sizeof( extended )), fmt_buff );
                cf = BFCnvSF( fmt_buff );
                BFCnvTarget( cf, const_buff + sizeof( extended ), BETypeLength( TY_LONGDOUBLE ) );
                BFFree( cf );
            }
            if( (var_type >= PT_REAL_4) && (var_type <= PT_CPLX_32) ) {
                const_ptr = const_buff;
            }
        }
// End of temporary fix.

        DtBytes( const_ptr, var_size );
    }
    DtItemSize = 0;
}