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 + -
显示快捷键?