bldins.c

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

C
818
字号
    AddIns( ins );
    GenBlock( CONDITIONAL, 2 );
    AddTarget( lt, FALSE );
    AddTarget( gt, FALSE );
    Generate( FALSE );
    HaveCurrBlock = FALSE;
}


extern  void    BGControl( cg_op op, bn expr, label_handle lbl ) {
/****************************************************************/

    BGGenCtrl( op, expr, lbl, FALSE );
}


extern  void    BGGenCtrl( cg_op op, bn expr, label_handle lbl, bool gen ) {
/**************************************************************************/

    switch( op ) {
    case O_LABEL:
        if( HaveCurrBlock ) {
            GenBlock( JUMP, 1 );  /* block with 1 target*/
            AddTarget( lbl, FALSE );
            if( gen ) {
                Generate( FALSE );
            }
        }
        EnLink( lbl, FALSE );
        HaveCurrBlock = TRUE;
        CurrBlock->unroll_count = UnrollValue;
        break;
    case O_GOTO:
        if( HaveCurrBlock ) {
            GenBlock( JUMP, 1 );
            AddTarget( lbl, FALSE );
            if( gen ) {
                Generate( FALSE );
            }
        }
        HaveCurrBlock = FALSE;
        break;
    case O_INVOKE_LABEL:
        if( HaveCurrBlock ) {
            GenBlock( CALL_LABEL, 1 );
            AddTarget( lbl, FALSE );
        #if 0
            Need to make sure that next_block != NULL when we generate the
            code for a CALL_LABEL block - see comments in GenObject

            if( gen ) {
                Generate( FALSE );
            }
        #endif
            EnLink( AskForNewLabel(), TRUE );
        }
        break;
    case O_LABEL_RETURN:
        if( HaveCurrBlock ) {
            AddIns( MakeNop() );
            GenBlock( LABEL_RETURN, 0 );
            if( gen ) {
                Generate( FALSE );
            }
        }
        HaveCurrBlock = FALSE;
        break;
    case O_IF_TRUE:
        *(expr->f) = CurrBlock->label;
        *(expr->t) = lbl;
        BoolFree( expr );
        if( gen ) {
            Generate( FALSE );
        }
        break;
    case O_IF_FALSE:
        *(expr->t) = CurrBlock->label;
        *(expr->f) = lbl;
        BoolFree( expr );
        if( gen ) {
            Generate( FALSE );
        }
        break;
    default:
        break;
    }
}


extern  void    BGBigLabel( bck_info *bck ) {
/******************************************/

    if( HaveCurrBlock ) {
        GenBlock( JUMP, 1 );  /* block with 1 target*/
        AddTarget( bck->lbl, FALSE );
        Generate( FALSE );
    }
    EnLink( bck->lbl, FALSE );
    HaveCurrBlock = TRUE;
    BigLabel();
    CurrBlock->class |= BIG_LABEL;
}


extern  void    BGBigGoto( label_handle lbl, int level ) {
/********************************************************/

    GenBlock( BIG_JUMP, 1 ); // No longer supported!
    AddTarget( lbl, FALSE );
    BigGoto( level );
    Generate( FALSE );
    EnLink( AskForNewLabel(), TRUE );
}


extern  unsigned_32 BGUnrollCount( unsigned_32 unroll_count ) {
/*************************************************************/

    unsigned_32         old_value;

    old_value = UnrollValue;
    UnrollValue = unroll_count;
    return( old_value );
}


extern  an      BGUnary( cg_op op, an left, type_def *tipe ) {
/*************************************************************/

    an          new;

    new = NULL;
    switch( op ) {
    case O_POINTS:
        new = MakePoints( left, tipe );
        break;
    case O_CONVERT:
        if( tipe == left->tipe || !NeedPtrConvert( left, tipe ) ) {
            new = left;
        } else {
            new = CnvRnd( left, tipe, O_CONVERT );
        }
        break;
    case O_ROUND:
        if( tipe == left->tipe ) {
            new = left;
        } else {
            new = CnvRnd( left, tipe, O_ROUND );
        }
        break;
#if _TARGET & _TARG_RISC
    case O_STACK_ALLOC:
        CurrProc->targ.base_is_fp = TRUE;
        break;
#endif
#if 0
    case O_PTR_TO_FOREIGN:
    case O_PTR_TO_NATIVE:
        // no large model runtime libraries
        if( left->tipe->length != WORD_SIZE ) {
            FEMessage( MSG_ERROR,
                "runtime call cannot be made when DS not pegged" );
            left = Unary( O_CONVERT, left, TypeAddress( T_NEAR_POINTER ) );
        }
#endif
    default:
        break;
    }
    if( new == NULL ) {
        new = Unary( op, left, tipe );
    }
    new->tipe = tipe;
    return( new );
}


static  an      CheckType( an op, type_def *tipe ) {
/**************************************************/

    if( op->format != NF_ADDR ) return( op );
    return( BGUnary( O_CONVERT, op, tipe ) );
}


extern  an      BGBinary( cg_op op, an left,
                          an rite, type_def *tipe, bool fold_addr ) {
/*******************************************************************/

    an          result;
    instruction *ins;

    result = NULL;
    if( op == O_PLUS || op == O_MINUS
       && ( tipe->attr & TYPE_POINTER )
       && ( left->tipe->attr & TYPE_POINTER )
       && !( rite->tipe->attr & ( TYPE_POINTER | TYPE_FLOAT ) ) ) {
        /* Special case for pointer +- int. Don't convert! */
    } else {
        left = CheckType( left, tipe );
        rite = CheckType( rite, tipe );
    }
    switch( op ) {
    case O_PLUS:
        if( fold_addr ) {
            if( TGIsAddress() || CypAddrPlus( left, rite, tipe ) ) {
                result = AddrPlus( left, rite, tipe );
            }
        }
        break;
    case O_LSHIFT:
        if( fold_addr ) {
            if( TGIsAddress() || CypAddrShift( left, rite, tipe ) ) {
                result = AddrShift( left, rite, tipe );
            }
        }
        break;
    default:
        break;
    }
    if( result == NULL ) {
        left = CheckType( left, tipe );
        ins = MakeBinary( op, GenIns( left ), GenIns( rite ),
                           NULL, TypeClass( tipe ) );
        result = InsName( ins, tipe );
        AddIns( ins );
        BGDone( left );
        BGDone( rite );
    }
    result->tipe = tipe;
    return( result );
}



extern  an      BGOpGets( cg_op op, an left, an rite,
                          type_def *tipe, type_def *optipe ) {
/************************************************************/

    an                  result;
    an                  leftp;
    name                *temp;
    type_class_def      opclass;
    type_class_def      class;
    name                *left_name;
    instruction         *ins;

    leftp = MakePoints( left, tipe );
    left_name = GenIns( leftp );
    class = TypeClass( tipe );
    opclass = TypeClass( optipe );
    if( NeedConvert( tipe, optipe ) ) {
        temp = AllocTemp( opclass );
        ins = MakeConvert( left_name, temp, opclass, class );
        AddIns( ins );
        AddIns( MakeBinary( op, temp, GenIns( rite ), temp, opclass ) );
        ins = MakeConvert( temp, left_name, class, opclass );
        AddIns( ins );
    } else {
        ins = MakeBinary( op, left_name, GenIns( rite ), left_name, opclass );
        if( tipe != optipe ) {
            ins->ins_flags |= INS_DEMOTED; /* its not quite the right type */
        }
        AddIns( ins );
    }
    result = AddrName( left_name, tipe );
    BGDone( rite );
    BGDone( leftp );
    return( result );
}


extern  an      BGConvert( an left, type_def *tipe ) {
/****************************************************/

    an          new;
    type_attr   left_attr;

    left_attr = left->tipe->attr;
    new = BGUnary( O_CONVERT, left, tipe );
    if( left_attr & TYPE_CODE ) {
        FixCodePtr( new ); /*% kludge for code pointer conversions*/
    }
    return( new );
}


extern  bn      BGFlow( cg_op op, bn left, bn rite ) {
/****************************************************/

    bn                  new;
    label_handle        temp;

    if( op == O_FLOW_NOT ) {
        temp = left->t;
        left->t = left->f;
        left->f = temp;
        new = left;
    } else {
        switch( op ) {
        case O_FLOW_AND:
            *(left->t) = rite->e;
            *(left->f) = CurrBlock->label;
            *(rite->f) = CurrBlock->label;
            GenBlock( JUMP, 1 );
            AddTarget( NULL, FALSE );
            left->f = &CurrBlock->edge[ 0 ].destination;
            left->t = rite->t;
            new = left;
            BoolFree( rite );
            EnLink( AskForNewLabel(), TRUE );
            break;
        case O_FLOW_OR:
            *(left->f) = rite->e;
            *(left->t) = CurrBlock->label;
            *(rite->t) = CurrBlock->label;
            GenBlock( JUMP, 1 );
            AddTarget( NULL, FALSE );
            left->t = &CurrBlock->edge[ 0 ].destination;
            left->f = rite->f;
            new = left;
            BoolFree( rite );
            EnLink( AskForNewLabel(), TRUE );
            break;
        default:
            break;
        }
    }
    return( new );
}


extern  an      BGAssign( an dst, an src, type_def *tipe ) {
/**********************************************************/

    an          res;

    res = MakeGets( dst, src, tipe );
    res->tipe = tipe;
    return( res );
}


extern  an      BGCopy( an node ) {
/**************************************/

    return( AddrCopy( node ) );
}


extern  an      BGDuplicate( an node ) {
/**************************************/

    return( AddrDuplicate( node ) );
}


extern  void    BGDone( an node ) {
/*********************************/

    if( node->format == NF_BOOL ) {
        FlowOff( (bn) node );
    } else {
        AddrFree( node );
    }
}


extern  void    BGTrash( an node ) {
/***************************/

    BGDone( node );
}


static  void    BoolFree( bn b ) {
/********************************/

    _Free( b, sizeof( bool_node ) );
}


extern  void    FlowOff( bn name ) {
/*****************************/

    *(name->t) = CurrBlock->label;
    *(name->f) = CurrBlock->label;
    NamesCrossBlocks();
    BoolFree( name );
}




extern  void    BGStartBlock( void ) {
/************************************/

    label_handle        lbl;

    if( _MemLow ) { /* break the block here and generate code*/
        lbl = AskForNewLabel();
        GenBlock( JUMP, 1 );
        AddTarget( lbl, FALSE );
        Generate( FALSE );
        EnLink( lbl, TRUE );
    } else { /* check if the block is getting too big*/
        BlkTooBig();
    }
}

⌨️ 快捷键说明

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