i86proc.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,286 行 · 第 1/3 页
C
1,286 行
return;
if( SymIsExported( sym ) ) {
CurrProc->prolog_state |= GENERATE_EXPORT;
}
}
extern void RTCall( rt_class rtn, oc_class pop_bit ) {
/****************************************************/
DoCall( RTLabel( rtn - BEG_RTNS ), TRUE, _IsTargetModel( BIG_CODE ), pop_bit );
}
static bool NeedStackCheck( void )
/******************************/
{
return( FEStackChk( AskForLblSym( CurrProc->label ) ) );
}
static void DoStackCheck( void ) {
/**************************/
if( CurrProc->prolog_state & GENERATE_THUNK_PROLOG )
return;
#if _TARGET & _TARG_80386
if( CurrProc->prolog_state & GENERATE_GROW_STACK ) {
if( BlockByBlock || CurrProc->locals.size >= 4*1024 ) {
GenUnkPush( &CurrProc->targ.stack_check );
RTCall( RT_GROW, ATTR_POP );
}
return;
}
#endif
if( NeedStackCheck() ) {
#if _TARGET & _TARG_80386
GenUnkPush( &CurrProc->targ.stack_check );
RTCall( RT_CHK, ATTR_POP );
#else
if( HW_COvlap( CurrProc->state.parm.used, HW_AX ) ) {
QuickSave( HW_STACK_CHECK, OP_PUSH );
}
GenUnkMov( HW_STACK_CHECK, &CurrProc->targ.stack_check );
RTCall( RT_CHK, EMPTY );
if( HW_COvlap( CurrProc->state.parm.used, HW_AX ) ) {
QuickSave( HW_STACK_CHECK, OP_POP );
}
#endif
}
}
static void EmitNameInCode( void ) {
/********************************/
sym_handle sym;
char *name;
char *endname;
char b[128];
label_handle lbl;
sym = AskForLblSym( CurrProc->label );
if( sym == NULL )
return;
name = FEName( sym );
endname = CopyStr( name, b );
name = b;
*endname = endname - name;
lbl = AskForNewLabel();
TellKeepLabel( lbl );
CodeLabel( lbl, 0 );
GenKillLabel( lbl );
EyeCatchBytes( name, *endname+1 );
}
static int ProEpiDataSize( void )
/***************************
*/
{
return( ( (int)(pointer)FEAuxInfo( NULL, PROEPI_DATA_SIZE )
+ (WORD_SIZE-1) ) & ~(WORD_SIZE-1) );
}
static void PrologHook( void )
/***************************
*/
{
int size;
if( !( CurrProc->prolog_state & GENERATE_PROLOG_HOOKS ) )
return;
size = ProEpiDataSize();
if( size != 0 ) {
GenRegSub( HW_SP, size );
CurrProc->targ.base_adjust += size;
}
#if _TARGET & _TARG_80386
// GenPushC( CurrProc->parms.size );
RTCall( RT_PROHOOK, EMPTY );
#else
RTCall( RT_PROHOOK, EMPTY );
#endif
}
static void EpilogHook( void )
/***************************
*/
{
int size;
if( ( CurrProc->prolog_state & GENERATE_EPILOG_HOOKS ) ) {
RTCall( RT_EPIHOOK, EMPTY );
}
size = ProEpiDataSize();
if( size != 0 )
GenRegAdd( HW_SP, size );
}
static void DoLoadDS( void )
{
#if _TARGET & _TARG_80386
if( _IsntTargetModel( LOAD_DS_DIRECTLY ) ) {
RTCall( RT_GETDS, EMPTY );
} else
#endif
{
if( HW_COvlap( CurrProc->state.parm.used, HW_AX ) ) {
QuickSave( HW_STACK_CHECK, OP_PUSH );
}
GenLoadDS();
if( HW_COvlap( CurrProc->state.parm.used, HW_AX ) ) {
QuickSave( HW_STACK_CHECK, OP_POP );
}
}
}
static int LoadDS( void )
/**********************/
{
int size;
size = 0;
if( CurrProc->state.attr & ROUTINE_LOADS_DS ) {
if( HW_COvlap( CurrProc->state.unalterable, HW_DS ) ) {
QuickSave( HW_DS, OP_PUSH );
size = WORD_SIZE;
DoLoadDS();
}
}
return( size );
}
static void UnloadDS( void ) {
/**************************/
if( CurrProc->state.attr & ROUTINE_LOADS_DS ) {
if( HW_COvlap( CurrProc->state.unalterable, HW_DS ) ) {
QuickSave( HW_DS, OP_POP );
}
}
}
extern void GenProlog( void ) {
/***************************/
seg_id old;
hw_reg_set to_push;
unsigned ret_size;
pointer label;
pointer origlabel; // Original label for generated __far16 thunks
fe_attr attr;
ScanInstructions(); /* Do These 2 calls before using DO_WINDOWS_CRAP! */
FindIfExported();
old = SetOP( AskCodeSeg() );
if( CurrProc->prolog_state & GENERATE_FUNCTION_NAME ) {
EmitNameInCode();
}
if( _IsModel( NUMBERS ) ) {
CodeLineNum( HeadBlock->ins.hd.line_num, FALSE );
}
if( _IsModel( DBG_LOCALS ) ){ // d1+ or d2
EmitRtnBeg();
}
if( CurrProc->state.attr & ROUTINE_WANTS_DEBUGGING ) {
CurrProc->state.attr |= ROUTINE_NEEDS_PROLOG;
}
CurrProc->parms.base = 0;
CurrProc->parms.size = CurrProc->state.parm.offset;
origlabel = label = CurrProc->label;
#if _TARGET & _TARG_80386
if( _RoutineIsFar16( CurrProc->state.attr ) ) {
label = GenFar16Thunk( CurrProc->label, CurrProc->parms.size,
CurrProc->state.attr & ROUTINE_REMOVES_PARMS );
// CurrProc->label = label; - ugly mess if following are combined
}
#endif
CodeLabel( label, DepthAlign( PROC_ALIGN ) );
attr = FEAttr( AskForLblSym( origlabel ) );
#if _TARGET & _TARG_80386
if( ( attr & FE_NAKED ) == EMPTY ) {
if( _IsTargetModel( NEW_P5_PROFILING|P5_PROFILING ) ) {
GenP5ProfilingProlog( label );
}
if( CurrProc->prolog_state & GENERATE_THUNK_PROLOG ) {
QuickSave( HW_SP, OP_PUSH );
GenPushC( CurrProc->parms.size );
GenUnkPush( &CurrProc->targ.stack_check );
if( NeedStackCheck() ) {
RTCall( RT_THUNK_STK, ATTR_POP );
} else {
RTCall( RT_THUNK, ATTR_POP );
}
CurrProc->parms.base += WORD_SIZE;
}
}
#endif
if( _RoutineIsInterrupt( CurrProc->state.attr ) ||
( CurrProc->state.attr & ROUTINE_NEVER_RETURNS ) ) {
ret_size = 0;
} else if( _RoutineIsLong( CurrProc->state.attr ) ) {
ret_size = 2 * WORD_SIZE;
} else if( _RoutineIsFar16( CurrProc->state.attr ) ) {
ret_size = 2 * WORD_SIZE;
} else {
ret_size = WORD_SIZE;
}
CurrProc->parms.base += ret_size;
CalcUsedRegs();
to_push = SaveRegs();
HW_CTurnOff( to_push, HW_FLTS );
if( !CurrProc->targ.sp_frame || CurrProc->targ.sp_align ) {
HW_CTurnOff( to_push, HW_BP );
}
if( ( attr & FE_NAKED ) != EMPTY ) {
// don't do anything - empty prologue
} else if( _RoutineIsInterrupt( CurrProc->state.attr ) ) {
ret_size = -PushAll();
CurrProc->targ.base_adjust = 0;
MoveParms();
} else {
if( CHAIN_FRAME ) {
CurrProc->targ.base_adjust = 0;
if( NeedBPProlog() ) {
HW_CTurnOn( CurrProc->state.used, HW_BP );
CurrProc->parms.base += WORD_SIZE;
if( FAR_RET_ON_STACK ) {
if( CHEAP_FRAME ) {
GenCypWindowsProlog();
} else {
#if _TARGET & _TARG_IAPX86
// Windows prologs zap AX, so warn idiot user if we
// generate one for a routine in which AX is live
// upon entry to routine, or unalterable.
if( HW_COvlap( CurrProc->state.unalterable, HW_AX ) ||
HW_COvlap( CurrProc->state.parm.used, HW_AX ) ) {
FEMessage( MSG_ERROR,
"exported routine with AX live on entry" );
}
#endif
GenWindowsProlog();
CurrProc->targ.base_adjust += 2; /* the extra push DS */
}
} else {
QuickSave( HW_BP, OP_PUSH );
GenRegMove( HW_SP, HW_BP );
}
PrologHook();
}
DoStackCheck();
CurrProc->targ.base_adjust += LoadDS();
CurrProc->targ.base_adjust += Push( to_push );
CurrProc->parms.base += CurrProc->targ.base_adjust;
AllocStack();
AdjustPushLocals();
} else {
DoStackCheck();
CurrProc->parms.base += LoadDS();
if( (CurrProc->state.attr & ROUTINE_NEVER_RETURNS) == 0 ) {
CurrProc->parms.base += Push( to_push );
}
Enter();
AdjustPushLocals();
if( _IsModel( NO_OPTIMIZATION ) || CurrProc->targ.sp_frame ) {
CurrProc->targ.base_adjust = 0;
} else {
CurrProc->targ.base_adjust = AdjustBase();
if( CurrProc->targ.base_adjust != 0 ) {
GenRegSub( HW_BP, -CurrProc->targ.base_adjust );
}
}
}
RelocParms();
MoveParms();
}
CurrProc->prolog_state |= GENERATED_PROLOG;
if( _IsModel( DBG_LOCALS ) ){ // d1+ or d2
DbgRetOffset( CurrProc->parms.base - CurrProc->targ.base_adjust
- ret_size );
EmitProEnd();
}
SetOP( old );
if( CurrProc->prolog_state & GENERATE_EXPORT ) {
OutDLLExport( ( CurrProc->parms.size+WORD_SIZE-1 ) / WORD_SIZE,
AskForLblSym( CurrProc->label ) );
}
}
static void MoveParms( void ) {
/***************************/
int i;
i = 0;
while( Parm8087[ i ] != NULL ) {
GFstpM( Parm8087[ i ] );
++i;
}
}
extern void InitStackDepth( block *blk ) {
/********************************************/
if( blk->edge[0].flags & DOWN_ONE_CALL ) {
StackDepth = WORD_SIZE;
} else {
StackDepth = 0;
}
StackDepth += blk->stack_depth;
}
extern void AdjustStackDepth( instruction *ins ) {
/************************************************************/
name *op;
type_length adjust;
if( !DoesSomething( ins ) )
return;
switch( ins->head.opcode ) {
case OP_ADD:
case OP_SUB:
if( ins->operands[0] != ins->result )
return;
if( ins->result->n.class != N_REGISTER )
return;
if( !HW_CEqual( ins->result->r.reg, HW_SP ) )
return;
op = ins->operands[1];
if( op->n.class != N_CONSTANT ) {
_Zoiks( ZOIKS_077 );
return;
}
adjust = op->c.int_value;
if( ins->head.opcode == OP_SUB ) {
StackDepth += adjust;
} else {
StackDepth -= adjust;
}
break;
case OP_PUSH:
StackDepth += WORD_SIZE;
break;
case OP_POP:
StackDepth -= WORD_SIZE;
break;
case OP_CALL:
case OP_CALL_INDIRECT:
if( ins->flags.call_flags & CALL_POPS_PARMS ) {
op = ins->operands[ CALL_OP_POPS ];
if( op->n.class == N_CONSTANT ) {
StackDepth -= op->c.int_value;
}
}
default:
break;
}
}
extern void AdjustStackDepthDirect( int adjust ) {
/************************************************************/
StackDepth += adjust;
}
extern bool BaseIsSP( name *op ) {
/************************************/
if( !CurrProc->targ.sp_frame ) return( FALSE );
if( CurrProc->targ.sp_align && ( op->t.temp_flags & STACK_PARM ) ) {
return( FALSE );
}
return( TRUE );
}
extern type_length NewBase( name *op ) {
/*******************************************/
if( !BaseIsSP( op ) ) {
return( op->t.location - CurrProc->targ.base_adjust );
}
return( op->t.location + CurrProc->locals.size
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?