コード例 #1
0
ファイル: fold.c プロジェクト: Azarien/open-watcom-v2
static PTREE foldUInt64( 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 = BFCnvU64F( v1 );
        t1 = BFCnvU64F( v2 );
        t2 = BFMul( t0, t1 );
        test = BFCnvF64( t2 );
        BFFree( t0 );
        BFFree( t1 );
        BFFree( t2 );
        U64Mul( &v1, &v2, &left->u.int64_constant );
        if( 0 != U64Cmp( &test, &left->u.int64_constant ) ) {
            CErr1( ANSI_ARITHMETIC_OVERFLOW );
        }
        break;
    case CO_DIVIDE:
    {   signed_64 rem;
        udiv64( &v1, &v2, &left->u.int64_constant, &rem );
    }   break;
    case CO_PERCENT:
    {   signed_64 div;
        udiv64( &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:
        U64ShiftR( &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 == U64Cmp( &v1, &v2 ) );
        return( left );
    case CO_NE:
        left = makeBooleanConst( left, 0 != U64Cmp( &v1, &v2 ) );
        return( left );
    case CO_GT:
        left = makeBooleanConst( left, 0 < U64Cmp( &v1, &v2 )) ;
        return( left );
    case CO_LE:
        left = makeBooleanConst( left, 0 >= U64Cmp( &v1, &v2 ) );
        return( left );
    case CO_LT:
        left = makeBooleanConst( left, 0 > U64Cmp( &v1, &v2 )) ;
        return( left );
    case CO_GE:
        left = makeBooleanConst( left, 0 <= U64Cmp( &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 );
}
コード例 #2
0
TYPEPTR EnumDecl( int flags )
{
    TYPEPTR     typ;
    TAGPTR      tag;

    flags = flags;
    NextToken();
    if( CurToken == T_ID ) {
        /* could be: (1) "enum" <id> ";"
                     (2) "enum" <id> <variable_name> ";"
                     (3) "enum" <id> "{" <enum_const_decl> ... "}"
        */
        tag = TagLookup();
        NextToken();
        if( CurToken != T_LEFT_BRACE ) {
            typ = tag->sym_type;
            if( typ == NULL ) {
                CErr1( ERR_INCOMPLETE_ENUM_DECL );
                typ = TypeDefault();
            } else {
                if( typ->decl_type != TYPE_ENUM ) {         /* 18-jan-89 */
                    CErr2p( ERR_DUPLICATE_TAG, tag->name );
                }
                typ->u.tag = tag;
            }
            return( typ );
        }
        tag = VfyNewTag( tag, TYPE_ENUM );
    } else {
        tag = NullTag();
    }
    typ = TypeNode( TYPE_ENUM, GetType( TYPE_INT ) );
    typ->u.tag = tag;
    tag->sym_type = typ;
    tag->size = TARGET_INT;
    tag->u.enum_list = NULL;
    if( CurToken == T_LEFT_BRACE ) {
        const_val       val;
        enum enum_rng   index;
        enum enum_rng   const_index;
        enum enum_rng   start_index;
        enum enum_rng   step;
        enum enum_rng   error;
        uint64          n;
        uint64          Inc;
        bool            minus;
        bool            has_sign;
        ENUMPTR         *prev_lnk;
        ENUMPTR         esym;
        source_loc      error_loc;
        char            buff[50];

        if( CompFlags.make_enums_an_int ) {
            start_index = ENUM_INT;
        } else {
            start_index = ENUM_S8;
        }
        const_index = ENUM_UNDEF;
        NextToken();
        if( CurToken == T_RIGHT_BRACE ) {
            CErr1( ERR_EMPTY_ENUM_LIST );
        }
        U32ToU64( 1, &Inc );
        U64Clear( n );
        minus = FALSE;
        has_sign = FALSE;
        step = 1;
        prev_lnk = &esym;
        esym = NULL;
        while( CurToken == T_ID ) {
            esym = EnumLkAdd( tag );
            *prev_lnk = esym;
            prev_lnk = &esym->thread;
            error_loc = TokenLoc;
            NextToken();
            if( CurToken == T_EQUAL ) {
                NextToken();
                error_loc = TokenLoc;
                ConstExprAndType( &val );
                switch( val.type ){
                case TYPE_ULONG:
                case TYPE_UINT:
                case TYPE_ULONG64:
                    minus = FALSE;
                    break;
                default:
                    if( val.value.u.sign.v ) {
                        minus = TRUE;
                        step = 2;
                    } else {
                        minus = FALSE;
                    }
                    break;
                }
                n = val.value;
            } else if( has_sign ) {
                if( n.u.sign.v ) {
                    minus = TRUE;
                } else {
                    minus = FALSE;
                }
            }
            for( index = start_index; index < ENUM_SIZE; index += step ) {
                if( minus ) {
                    if( I64Cmp( &n, &( RangeTable[ index ][LOW] ) ) >= 0 ) break;
                } else {
                    if( U64Cmp( &n, &( RangeTable[ index ][HIGH]) ) <= 0 ) break;
                }
            }
            error = ENUM_UNDEF;
            if( !CompFlags.extensions_enabled && ( index > ENUM_INT )) {
                error = ENUM_INT;
            }
            if( index >= ENUM_SIZE ) {
                // overflow signed maximum range
                if( error == ENUM_UNDEF ) {
                    error = const_index;
                }
            } else if(( const_index == ENUM_SIZE - 1 ) && minus ) {
                // overflow unsigned maximum range by any negative signed value
                if( error == ENUM_UNDEF )
                    error = const_index;
                step = 1;
            } else {
                if( !has_sign && minus) {
                    has_sign = TRUE;
                    if( index < const_index ) {
                        // round up to signed
                        index = ( const_index + 1 ) & ~1;
                    }
                }
                if( index > const_index ) {
                    const_index = index;
                    typ->object = GetType( ItypeTable[const_index].decl_type );
                    tag->size   = ItypeTable[const_index].size;
                }
            }
            if( error != ENUM_UNDEF ) {
                SetErrLoc( &error_loc );
                get_msg_range( buff, error );
                CErr2p( ERR_ENUM_CONSTANT_OUT_OF_RANGE, buff );
                InitErrLoc();
            }
            esym->value = n;
            EnumTable[ esym->hash ] = esym;             /* 08-nov-94 */
            if( CurToken == T_RIGHT_BRACE )
                break;
            U64Add( &n, &Inc, &n );
            MustRecog( T_COMMA );
            if( !CompFlags.extensions_enabled
              && !CompFlags.c99_extensions
              && ( CurToken == T_RIGHT_BRACE )) {
                ExpectIdentifier();         /* 13-may-91 */
            }
        }
        MustRecog( T_RIGHT_BRACE );
    }
    return( typ );
}
コード例 #3
0
ファイル: 386setcc.c プロジェクト: ABratovic/open-watcom-v2
/* Take advantage of the SETcc instruction in cases such as
 * x = y ? 3 : 4;
 * by adding a constant to the result of SETcc to directly obtain
 * the result of the assignment.
 */
static  bool    FindFlowOut( block *blk ) {
/*****************************************/

    signed_64           false_cons;
    signed_64           true_cons;
    signed_64           one;
    signed_64           neg_one;
    signed_64           diff;
    instruction         *ins;
    instruction         *ins0;
    instruction         *ins1;
//    instruction         *prev;
    block               *true_blk;
    block               *false_blk;
    block               *join_blk;
    block_edge          *new_edge;
    bool                reverse;
    name                *u1temp;
    name                *temp;
    name                *result;
    name                *konst;
    type_class_def      class;

    for( ins = blk->ins.hd.prev; !_OpIsCondition( ins->head.opcode ); ) {
        ins = ins->head.prev;
    }
//    prev = ins->head.prev;
    if( TypeClassSize[ ins->type_class ] > WORD_SIZE ) return( FALSE );
    true_blk = blk->edge[ _TrueIndex( ins ) ].destination.u.blk;
    if( true_blk->inputs != 1 ) return( FALSE );
    if( true_blk->targets != 1 ) return( FALSE );

    false_blk = blk->edge[ _FalseIndex( ins ) ].destination.u.blk;
    if( false_blk->inputs != 1 ) return( FALSE );
    if( false_blk->targets != 1 ) return( FALSE );

    join_blk = false_blk->edge[ 0 ].destination.u.blk;
    if( join_blk != true_blk->edge[ 0 ].destination.u.blk ) return( FALSE );
    if( join_blk->inputs != 2 ) return( FALSE );
    if( join_blk->class & UNKNOWN_DESTINATION ) return( FALSE );

    ins0 = SetToConst( false_blk, &false_cons );
    if( ins0 == NULL ) return( FALSE );
    ins1 = SetToConst( true_blk, &true_cons );
    if( ins1 == NULL ) return( FALSE );

    I32ToI64( 1, &one );
    I32ToI64( -1, &neg_one );
    U64Sub( &true_cons, &false_cons, &diff );
    if( U64Cmp( &diff, &neg_one ) == 0 ) {
        U64IncDec( &false_cons, -1 );
        reverse = TRUE;
    } else {
        if( U64Cmp( &diff, &one ) != 0 ) return( FALSE );
        reverse = FALSE;
    }
    result = ins0->result;
    if( result != ins1->result ) return( FALSE );
    class = ins0->type_class;
    if( class != ins1->type_class ) return( FALSE );

    if( reverse ) FlipCond( ins );

    u1temp = AllocTemp( U1 );
    temp = AllocTemp( class );

    ins->result = u1temp;
    ins1 = MakeConvert( u1temp, temp, class, U1 );
    SuffixIns( ins, ins1 );
    ins = ins1;

    if( I64Test( &false_cons ) != 0 ) {
        konst = AllocS64Const( false_cons.u._32[I64LO32], false_cons.u._32[I64HI32] );
        ins1 = MakeBinary( OP_ADD, temp, konst, result, class );
    } else {