Exemplo n.º 1
0
static bool zeroConstant(       // TEST IF NODE IS ZERO CONSTANT
    PTREE expr )                // - the expression
{
    PTREE orig;

    switch( expr->op ) {
    case PT_INT_CONSTANT:
        if( NULL == Integral64Type( expr->type ) ) {
            return( expr->u.int_constant == 0 );
        } else {
            return( Zero64( &expr->u.int64_constant ) );
        }
    case PT_FLOATING_CONSTANT:
    {   target_ulong ul_val = BFCnvF32( expr->u.floating_constant );
        return 0 == ul_val;
    }
    case PT_BINARY:
        orig = expr;
        expr = NodeRemoveCasts( expr );
        if( expr == orig ) break;
        return( zeroConstant( expr ) );
    }
    return( false );
}
Exemplo n.º 2
0
static void dumpPTreeNode(      // DUMP A PARSE TREE NODE
    PTREE node )                // - node in parse tree
{
    static char buffer[128];    // - debugging buffer
    char *node_name;            // - name of node
    VSTK_CTL ctl;               // - VSTK control information (nodes)
    VSTK_CTL dup;               // - VSTK control information (duplicates)
    int dup_out;                // - last duplicate printed

    VstkOpen( &ctl, sizeof( PTREE ), 32 );
    VstkOpen( &dup, sizeof( PTREE ), 8 );
    dup_out = -1;
    for( ; ; ) {
        switch( node->op ) {
          case PT_ERROR :
            printf( "PT_ERROR"      F_BADDR
                    " ***** ERROR TREE *****" F_EOL
                  , node
                  );
            break;
          case PT_INT_CONSTANT :
            node_name = "PT_INT_CONSTANT";
            printf( F_NAME          F_BADDR
                    " flags"        F_HEX_4
                    " type"         F_PTR
                  , node_name
                  , node
                  , node->flags
                  , node->type
                  );
            if( NULL == Integral64Type( node->type ) ) {
                printf( " integer"      F_HEX_4
                      , node->u.int_constant
                      );
            } else {
                printf( " integer-64" F_S64
                      , VAL64( node->u.int64_constant )
                      );
            }
            dumpNodeType( node );
            dumpLocation( &node->locn );
            dumpPtreeFlags( node );
            break;
          case PT_FLOATING_CONSTANT : {
            char buffer[256];

            BFCnvFS( node->u.floating_constant, buffer, 256 );
            printf( "PT_FLOATING_CONSTANT" F_BADDR
                    " flags"        F_HEX_4
                    " float"        F_CPP_FLOAT
                  , node
                  , node->flags
                  , buffer
                  );
            dumpNodeType( node );
            dumpLocation( &node->locn );
            dumpPtreeFlags( node );
          }
            break;
          case PT_STRING_CONSTANT :
            stvcpy( buffer, node->u.string->string, node->u.string->len );
            printf( "PT_STRING_CONSTANT" F_BADDR
                    " flags"        F_HEX_4
                    " string"       F_STRING
                  , node
                  , node->flags
                  , buffer
                  );
            dumpNodeType( node );
            dumpLocation( &node->locn );
            dumpPtreeFlags( node );
            break;
          case PT_ID :
            printf( "PT_ID"         F_BADDR
                    " flags"        F_HEX_4
                    " cgop"         F_STRING F_NL
                    " id"           F_PTR
                    "="             F_STRING
                    " id_cgop"      F_STRING
                    " u.id.scope"   F_PTR
                  , node
                  , node->flags
                  , DbgOperator( node->cgop )
                  , node->u.id.name
                  , NameStr( node->u.id.name )
                  , DbgOperator( node->id_cgop )
                  , node->u.id.scope
                  );
            dumpNodeType( node );
            dumpLocation( &node->locn );
            dumpPtreeFlags( node );
            break;
          case PT_TYPE :
            printf( "PT_TYPE"       F_BADDR
                    " cgop"         F_STRING
                    " flags"        F_HEX_4
                    " next"         F_PTR
                    " scope"        F_PTR
                  , node
                  , DbgOperator( node->cgop )
                  , node->flags
                  , node->u.type.next
                  , node->u.type.scope
                  );
            dumpNodeType( node );
            dumpLocation( &node->locn );
            dumpPtreeFlags( node );
            break;
          case PT_SYMBOL :
            if( node->cgop == CO_NAME_THIS ) {
                printf( "PT_SYMBOL"     F_BADDR
                        " flags"        F_HEX_4
                        " this "
                      , node
                      , node->flags
                      );
                dumpNodeType( node );
                dumpLocation( &node->locn );
                dumpPtreeFlags( node );
            } else if( node->cgop == CO_NAME_CDTOR_EXTRA ) {
                printf( "PT_SYMBOL"     F_BADDR
                        " flags"        F_HEX_4
                        " cdtor_extra_parm "
                      , node
                      , node->flags
                      );
                dumpNodeType( node );
                dumpLocation( &node->locn );
                dumpPtreeFlags( node );
            } else {
                printf( "PT_SYMBOL"     F_BADDR
                        " flags"        F_HEX_4
                        " cgop"         F_STRING F_NL
                        " symbol"       F_PTR
                        " result"       F_PTR
                      , node
                      , node->flags
                      , DbgOperator( node->cgop )
                      , node->u.symcg.symbol
                      , node->u.symcg.result
                      );
                dumpNodeType( node );
                dumpLocation( &node->locn );
                dumpPtreeFlags( node );
                DumpSymbol( node->u.symcg.symbol );
            }
            break;
          case PT_UNARY :
            printf( "PT_UNARY"      F_BADDR
                    F_POINTS        F_ADDR
                    " flags"        F_HEX_4
                    " cgop"         F_STRING
                  , node
                  , node->u.subtree[0]
                  , node->flags
                  , DbgOperator( node->cgop )
                  );
            dumpNodeType( node );
            dumpLocation( &node->locn );
            dumpPtreeFlags( node );
            PUSH_NODE( ctl, node->u.subtree[0] );
            break;
          case PT_BINARY :
            printf( "PT_BINARY"     F_BADDR
                    F_POINTS        F_ADDR
                    ","             F_ADDR
                    " flags"        F_HEX_4
                    " cgop"         F_STRING
                  , node
                  , node->u.subtree[0]
                  , node->u.subtree[1]
                  , node->flags
                  , DbgOperator( node->cgop )
                  );
            dumpNodeType( node );
            dumpLocation( &node->locn );
            dumpPtreeFlags( node );
            PUSH_NODE( ctl, node->u.subtree[1] );
            PUSH_NODE( ctl, node->u.subtree[0] );
            break;
          case PT_DUP_EXPR :
          { PTREE *duped;       // - duplicated expression
            printf( "PT_DUP_EXPR"   F_BADDR
                    F_POINTS        F_ADDR
                    " flags"        F_HEX_4
                    " node"         F_ADDR
                  , node
                  , node->u.dup.subtree[0]
                  , node->flags
                  , node->u.dup.node
                  );
            dumpNodeType( node );
            dumpLocation( &node->locn );
            dumpPtreeFlags( node );
            if( node->u.subtree[0] != NULL ) {
                for( duped = VstkTop( &dup )
                   ;
                   ; duped = VstkNext( &dup, duped ) ) {
                    if( duped == NULL ) {
                        PUSH_NODE( dup, node->u.subtree[0] );
                    } else if( *duped == node->u.subtree[0] ) {
                        break;
                    }
                }
            }
          } break;
          case PT_IC :
            printf( "PT_IC"         F_BADDR
                    " "             F_NAME
                    " value"        F_ADDR
                  , node
                  , DbgIcOpcode( node->u.ic.opcode )
                  , node->u.ic.value.pvalue
                  );
            dumpNodeType( node );
            dumpLocation( &node->locn );
            dumpPtreeFlags( node );
            break;
          default :
            printf( "***INVALID***" F_BADDR
                    " flags"        F_HEX_4
                    " op"           F_HEX_1
                  , node
                  , node->flags
                  , node->op
                  );
            dumpNodeType( node );
            dumpLocation( &node->locn );
            dumpPtreeFlags( node );
            break;
        }
        {
            PTREE *next;            // - addr[next node]
            next = VstkPop( &ctl );
            if( next != NULL ) {
                node = *next;
            } else {
                ++dup_out;
                if( dup_out > VstkDimension( &dup ) ) break;
                next = VstkIndex( &dup, dup_out );
                printf( "--------------- duplicate ------------\n" );
                node = *next;
            }
        }
    }
    VstkClose( &ctl );
    VstkClose( &dup );
}
Exemplo n.º 3
0
PTREE CastIntConstant( PTREE expr, TYPE type, bool *happened )
{
    PTREE new_expr;
    target_ulong ul_val;
    float_handle dbl_val;
    type_id id;
    bool signed_type;


    signed_type = SignedIntType( expr->type );
    id = TypedefModifierRemove( type )->id;
    ul_val = expr->u.uint_constant;
    if( NULL == Integral64Type( expr->type ) ) {
        switch( id ) {
        case TYP_SCHAR:
            ul_val = (target_schar) ul_val;
            /* fall through */
        case TYP_SSHORT:
            ul_val = (target_short) ul_val;
            /* fall through */
        case TYP_SINT:
            ul_val = (target_int) ul_val;
            /* fall through */
        case TYP_SLONG:
            ul_val = (target_long) ul_val;
            new_expr = PTreeIntConstant( ul_val, id );
            break;
        case TYP_UCHAR:
            ul_val = (target_uchar) ul_val;
            /* fall through */
        case TYP_USHORT:
            ul_val = (target_ushort) ul_val;
            /* fall through */
        case TYP_UINT:
            ul_val = (target_uint) ul_val;
            /* fall through */
        case TYP_ULONG:
            ul_val = (target_ulong) ul_val;
            new_expr = PTreeIntConstant( ul_val, id );
            break;
        case TYP_ULONG64:
        case TYP_SLONG64:
            if( PT_FLOATING_CONSTANT == expr->op ) {
                new_expr = PTreeInt64Constant
                                ( BFCnvF64( expr->u.floating_constant )
                                , id );
            } else {
                new_expr = PTreeInt64Constant( expr->u.int64_constant, id );
            }
            break;
        case TYP_POINTER:
        case TYP_MEMBER_POINTER:
            ul_val = (target_ulong) ul_val;
            new_expr = PTreeIntConstant( ul_val, TYP_ULONG );
            new_expr->type = type;
            break;
        case TYP_FLOAT:
#if 0
// these are now identical, with canonical floating point
            if( signed_type ) {
                flt_val = BFCnvIF( expr->u.int_constant );
            } else {
                flt_val = BFCnvUF( expr->u.uint_constant );
            }
            new_expr = PTreeFloatingConstant( flt_val, id );
            break;
#endif
        case TYP_LONG_DOUBLE:
        case TYP_DOUBLE:
            if( signed_type ) {
                dbl_val = BFCnvIF( expr->u.int_constant );
            } else {
                dbl_val = BFCnvUF( expr->u.uint_constant );
            }
            new_expr = PTreeFloatingConstant( dbl_val, id );
            break;
        case TYP_WCHAR:
            ul_val = (target_wchar) ul_val;
            new_expr = PTreeIntConstant( ul_val, id );
            break;
        default:
            return( expr );
        }
    } else {
        ul_val = expr->u.int_constant;
        switch( id ) {
        case TYP_SCHAR:
            ul_val = (target_schar) ul_val;
            /* fall through */
        case TYP_SSHORT:
            ul_val = (target_short) ul_val;
            /* fall through */
        case TYP_SINT:
            ul_val = (target_int) ul_val;
            /* fall through */
        case TYP_SLONG:
            ul_val = (target_long) ul_val;
            new_expr = PTreeIntConstant( ul_val, id );
            break;
        case TYP_SLONG64:
        case TYP_ULONG64:
            new_expr = PTreeInt64Constant( expr->u.int64_constant, id );
            break;
        case TYP_UCHAR:
            ul_val = (target_uchar) ul_val;
            /* fall through */
        case TYP_USHORT:
            ul_val = (target_ushort) ul_val;
            /* fall through */
        case TYP_UINT:
            ul_val = (target_uint) ul_val;
            /* fall through */
        case TYP_ULONG:
            ul_val = (target_ulong) ul_val;
            new_expr = PTreeIntConstant( ul_val, id );
            break;
        case TYP_POINTER:
        case TYP_MEMBER_POINTER:
            ul_val = (target_ulong) ul_val;
            new_expr = PTreeIntConstant( ul_val, TYP_ULONG );
            new_expr->type = type;
            break;
        case TYP_FLOAT:
#if 0
// these are now identical, with canonical floating point
            if( signed_type ) {
                flt_val = BFCnvI64F( expr->u.int64_constant );
            } else {
                flt_val = BFCnvU64F( expr->u.uint64_constant );
            }
            new_expr = PTreeFloatingConstant( flt_val, id );
            break;
#endif
        case TYP_LONG_DOUBLE:
        case TYP_DOUBLE:
            if( signed_type ) {
                dbl_val = BFCnvI64F( expr->u.int64_constant );
            } else {
                dbl_val = BFCnvU64F( expr->u.int64_constant );
            }
            new_expr = PTreeFloatingConstant( dbl_val, id );
            break;
        case TYP_WCHAR:
            ul_val = (target_wchar) ul_val;
            new_expr = PTreeIntConstant( ul_val, id );
            break;
        default:
            return( expr );
        }
    }
    *happened = true;
    new_expr->flags = expr->flags;
    new_expr = PTreeCopySrcLocation( new_expr, expr );
    PTreeFree( expr );
    return( new_expr );
}
Exemplo n.º 4
0
PTREE FoldBinary( PTREE expr )
/****************************/
{
    PTREE orig1;
    PTREE orig2;
    PTREE op1;
    PTREE op2;
    PTREE op_t;
    PTREE op_f;
    PTREE op_test;
    TYPE type;
    unsigned typ1;
    unsigned typ2;
    bool cast_happened;
    bool has_decoration_left;
    bool has_decoration_right;
    bool has_decoration;

    type = expr->type;
    orig1 = expr->u.subtree[0];
    orig2 = expr->u.subtree[1];
    type = expr->type;
    op1 = overCondDecor( orig1 );
    has_decoration_left = op1 != orig1;
    op2 = overCondDecor( orig2 );
    has_decoration_right = op2 != orig2;
    has_decoration = has_decoration_left | has_decoration_left;
    if( notFoldable( op1 ) ) {
        if( notFoldable( op2 ) ) {
            return( expr );
        }
        switch( expr->cgop ) {
        case CO_EQ:
            DbgVerify( ! has_decoration, "FoldBinary -- bad ==" );
            if( zeroConstant( op2 ) ) {
                if( zeroConstant( op1 ) ) {
                    expr = makeTrueFalse( expr, op1, 1 );
                } else if( nonZeroExpr( op1 ) ) {
                    expr = makeTrueFalse( expr, op1, 0 );
                }
            }
            break;
        case CO_NE:
            DbgVerify( ! has_decoration, "FoldBinary -- bad !=" );
            if( zeroConstant( op2 ) ) {
                if( zeroConstant( op1 ) ) {
                    expr = makeTrueFalse( expr, op1, 0 );
                } else if( nonZeroExpr( op1 ) ) {
                    expr = makeTrueFalse( expr, op1, 1 );
                }
            }
            break;
        case CO_PLUS_EQUAL :
        case CO_MINUS_EQUAL :
        case CO_AND_EQUAL :
        case CO_OR_EQUAL :
        case CO_XOR_EQUAL :
        case CO_EQUAL:
            /* have to be careful with pointer scaling of numbers */
            DbgVerify( ! has_decoration, "FoldBinary -- bad equals" );
            if( ArithType( type ) != NULL ) {
                expr->u.subtree[1] = castConstant( op2, type, &cast_happened );
            }
            break;
        case CO_CONVERT:
            DbgVerify( ! has_decoration, "FoldBinary -- bad convert" );
            op_test = castConstant( op2, type, &cast_happened );
            if( cast_happened ) {
                /* op2 was freed */
                op_test = PTreeCopySrcLocation( op_test, expr );
                NodeFreeDupedExpr( op1 );
                PTreeFree( expr );
                return( op_test );
            }
            break;
        case CO_COMMA :
            //
            // X, c -- can be optimized when X is PT_IC( IC_COND_TRUE )
            // and comma node has PTF_COND_END set
            //
            if( (expr->flags & PTF_COND_END)
             && op1->op == PT_IC
             && op1->u.ic.opcode == IC_COND_TRUE ) {
                expr = pruneExpr( expr, &expr->u.subtree[1], op2 );
            }
            break;
        }
        return( expr );
    }
    if( notFoldable( op2 ) ) {
        switch( expr->cgop ) {
        case CO_EQ:
            DbgVerify( ! has_decoration, "FoldBinary -- bad ==" );
            if( zeroConstant( op1 ) ) {
                if( zeroConstant( op2 ) ) {
                    expr = makeTrueFalse( expr, op2, 1 );
                } else if( nonZeroExpr( op2 ) ) {
                    expr = makeTrueFalse( expr, op2, 0 );
                }
            }
            break;
        case CO_NE:
            DbgVerify( ! has_decoration, "FoldBinary -- bad !=" );
            if( zeroConstant( op1 ) ) {
                if( zeroConstant( op2 ) ) {
                    expr = makeTrueFalse( expr, op2, 0 );
                } else if( nonZeroExpr( op2 ) ) {
                    expr = makeTrueFalse( expr, op2, 1 );
                }
            }
            break;
        case CO_AND_AND:
//          DbgVerify( has_decoration, "FoldBinary -- bad &&" );
            if( ! zeroConstant( op1 ) ) {
                /* 1 && X => X (X is already boolean) */
                expr = pruneExpr( expr, &expr->u.subtree[1], op2 );
            } else {
                /* 0 && X => 0 */
                return pruneExpr( expr, &expr->u.subtree[0], op1 );
            }
            break;
        case CO_OR_OR:
//          DbgVerify( has_decoration, "FoldBinary -- bad ||" );
            if( zeroConstant( op1 ) ) {
                /* 0 || X => X (X is already boolean) */
                return pruneExpr( expr, &expr->u.subtree[1], op2 );
            } else {
                /* 1 || X => 1 */
                return pruneExpr( expr, &expr->u.subtree[0], op1 );
            }
            break;
        case CO_COMMA:
            /* c , X => X */
//          DbgVerify( ! has_decoration, "FoldBinary -- bad comma" );
            expr->u.subtree[1] = NULL;
            op2 = PTreeCopySrcLocation( op2, expr );
            NodeFreeDupedExpr( expr );
            return( op2 );
        case CO_QUESTION:
            DbgVerify( ! has_decoration, "FoldBinary -- bad ?" );
            op_t = op2->u.subtree[0];
            op_f = op2->u.subtree[1];
            has_decoration = isCondDecor( op_t );
            DbgVerify( has_decoration == isCondDecor( op_f )
                     , "FoldBinary -- bad ?:" );
            if( has_decoration ) {
                op_t = op_t->u.subtree[1];
                op_f = op_f->u.subtree[1];
            }
            if( ! zeroConstant( op1 ) ) {
                /* 1 ? T : F => T */
                if( has_decoration ) {
                    op2->u.subtree[0]->u.subtree[1] = NULL;
                } else {
                    op2->u.subtree[0] = NULL;
                }
                op2 = op_t;
            } else {
                /* 0 ? T : F => F */
                if( has_decoration ) {
                    op2->u.subtree[1]->u.subtree[1] = NULL;
                } else {
                    op2->u.subtree[1] = NULL;
                }
                op2 = op_f;
            }
            op2 = PTreeCopySrcLocation( op2, expr );
            NodeFreeDupedExpr( expr );
            return( op2 );
        }
    } else {
        typ1 = op1->op;
        typ2 = op2->op;
        if( ! isIntFloatOp( typ1 ) || ! isIntFloatOp( typ2 ) ) {
            // (void)0 can make it here
            return expr;
        }
        if( typ1 != typ2 ) {
            if( PT_FLOATING_CONSTANT == typ1 ) {
                if( NULL == Integral64Type( op2->type ) ) {
                    if( SignedIntType( op2->type ) ) {
                        op2->u.floating_constant
                            = BFCnvIF( op2->u.int_constant );
                    } else {
                        op2->u.floating_constant
                            = BFCnvUF( op2->u.uint_constant );
                    }
                } else {
                    if( SignedIntType( op2->type ) ) {
                        op2->u.floating_constant
                            = BFCnvI64F( op2->u.int64_constant );
                    } else {
                        op2->u.floating_constant
                            = BFCnvU64F( op2->u.int64_constant );
                    }
                }
                typ2 = PT_FLOATING_CONSTANT;
                op2->op = typ2;
            } else {
                if( NULL == Integral64Type( op1->type ) ) {
                    if( SignedIntType( op1->type ) ) {
                        op1->u.floating_constant
                            = BFCnvIF( op1->u.int_constant );
                    } else {
                        op1->u.floating_constant
                            = BFCnvUF( op1->u.uint_constant );
                    }
                } else {
                    if( SignedIntType( op1->type ) ) {
                        op1->u.floating_constant
                            = BFCnvI64F( op1->u.int64_constant );
                    } else {
                        op1->u.floating_constant
                            = BFCnvU64F( op1->u.int64_constant );
                    }
                }
                typ1 = PT_FLOATING_CONSTANT;
                op1->op = typ2;
            }
        }
        if( PT_FLOATING_CONSTANT == typ1 ) {
            op1 = foldFloating( expr->cgop, op1, op2->u.floating_constant );
        } else if( SignedIntType( op1->type ) ) {
            if( NULL == Integral64Type( op1->type )
             && NULL == Integral64Type( op2->type ) ) {
                op1 = foldInt( expr->cgop, op1, op2->u.int_constant );
            } else {
                op1 = foldInt64( expr->cgop, op1, op2->u.int64_constant );
            }
        } else {
            if( NULL == Integral64Type( op1->type )
             && NULL == Integral64Type( op2->type ) ) {
                op1 = foldUInt( expr->cgop, op1, op2->u.uint_constant );
            } else {
                op1 = foldUInt64( expr->cgop, op1, op2->u.int64_constant );
            }
        }
        if( op1 != NULL ) {
            /* binary op was folded! */
            if( has_decoration ) {
                orig1->u.subtree[1] = NULL;
                orig2->u.subtree[1] = NULL;
            } else {
                expr->u.subtree[0] = NULL;
            }
            op1 = castConstant( op1, type, &cast_happened );
            op1 = PTreeCopySrcLocation( op1, expr );
            NodeFreeDupedExpr( expr );
            return op1;
        }
    }
    return( expr );
}