i86call.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 505 行 · 第 1/2 页
C
505 行
if( state->attr & ROUTINE_ALLOCS_RETURN ) {
call_ins->result = reg_name;
AddCall( call_ins, call );
if( use_return ) {
temp = AllocTemp( WD ); /* assume near pointer*/
AddIns( MakeMove( reg_name, temp, WD ) );
temp = SAllocIndex( temp, NULL, 0,
result->n.name_class, call->tipe->length );
AddIns( MakeMove( temp, result, result->n.name_class ) );
}
} else {
call_ins->result = result;
AddIns( ret_ins );
if( HW_CEqual( state->return_reg, HW_EMPTY ) ) {
AddIns( MakeUnary( OP_PUSH, ret_ptr, NULL, WD ) );
state->parm.offset += TypeClassSize[ WD ];
call_ins->operands[ CALL_OP_POPS ] =
AllocS32Const( call_ins->operands[ CALL_OP_POPS ]->c.int_value + TypeClassSize[ WD ] );
if( state->attr & ROUTINE_REMOVES_PARMS ) {
call_ins->flags.call_flags |= CALL_POPS_PARMS;
}
}
AddCall( call_ins, call );
}
} else {
return_reg = state->return_reg;
zap_reg = call_ins->zap->reg;
HW_CTurnOn( zap_reg, HW_FLTS );
HW_OnlyOn( return_reg, zap_reg );
call_ins->result = AllocRegName( return_reg );
reg_name = AllocRegName( state->return_reg );
AddCall( call_ins, call );
if( use_return ) {
ret_ins = MakeMove( reg_name, result, result->n.name_class );
if( HW_COvlap( reg_name->r.reg, HW_FLTS ) ) {
ret_ins->stk_entry = 1;
ret_ins->stk_exit = 0;
}
AddIns( ret_ins );
}
}
if( state->parm.offset != 0 && ( state->attr & ROUTINE_REMOVES_PARMS ) == 0 ) {
reg_name = AllocRegName( HW_SP );
AddIns( MakeBinary( OP_ADD, reg_name,
AllocS32Const( state->parm.offset ), reg_name, WD ) );
}
FreeCallNode( call );
return( MakeTempAddr( result, call->tipe ) );
}
extern void BGProcDecl( sym_handle sym, type_def *tipe ) {
/************************************************************/
hw_reg_set reg;
name *temp;
type_class_def class;
seg_id old;
label_handle lbl;
SaveModel = TargetModel;
class = AddCallBlock( sym, tipe );
if( tipe != TypeNone ) {
if( class == XX ) {
if( CurrProc->state.attr & ROUTINE_ALLOCS_RETURN ) {
old = SetOP( AskBackSeg() );
lbl = AskForNewLabel();
DataLabel( lbl );
DGUBytes( tipe->length );
CurrProc->targ.return_points = SAllocMemory( lbl, 0, CG_LBL,
TypeClass( tipe ),
tipe->length );
SetOP( old );
} else {
reg = CurrProc->state.return_reg;
if( HW_CEqual( reg, HW_EMPTY ) ) {
temp = DoParmDecl( NULL, TypeInteger, HW_EMPTY );
} else {
temp = AllocTemp( WD );
temp->v.usage |= USE_IN_ANOTHER_BLOCK;
AddIns( MakeMove( AllocRegName( reg ), temp, WD ) );
HW_TurnOn( CurrProc->state.parm.used, reg );
}
CurrProc->targ.return_points = temp;
}
}
}
if( _RoutineIsInterrupt( CurrProc->state.attr ) ) {
TargetModel |= FLOATING_SS;
}
}
extern name *StReturn( an retval, type_def *tipe, instruction **pins ) {
/**************************************************************************/
name *retp;
name *ptr;
name *off;
name *seg;
hw_reg_set reg;
if( CurrProc->state.attr & ROUTINE_ALLOCS_RETURN ) {
retp = CurrProc->targ.return_points;
AddIns( MakeUnary( OP_LA, retp,
AllocRegName( CurrProc->state.return_reg ), WD ) );
*pins = NULL;
} else {
if( _IsTargetModel( FLOATING_SS ) || _IsTargetModel( FLOATING_DS ) ) {
ptr = AllocTemp( CP );
off = OffsetPart( ptr );
seg = SegmentPart( ptr );
AddIns( MakeMove( AllocRegName( HW_SS ), seg, U2 ) );
} else {
ptr = AllocTemp( WD );
off = ptr;
}
AddIns( MakeMove( CurrProc->targ.return_points, off, WD ) );
retp = SAllocIndex( ptr, NULL,
0, TypeClass( retval->tipe ), tipe->length );
reg = ReturnReg( WD, FALSE );
*pins = MakeMove( CurrProc->targ.return_points,
AllocRegName( reg ), WD );
CurrProc->state.return_reg = reg;
}
return( retp );
}
static void AddCall( instruction *ins, cn call ) {
/****************************************************/
name *proc_name;
if( _IsTargetModel(FLOATING_DS) && (call->state->attr&ROUTINE_NEEDS_DS_LOADED) ) {
AddIns( MakeMove( NearSegment(), AllocRegName( HW_DS ), U2 ) );
}
if( call->name->tipe == TypeProcParm ) {
proc_name = AllocTemp( ClassPointer );
/* what to do? proc_name->usage |= USE_REGISTER;*/
AddIns( MakeMove( ins->operands[CALL_OP_ADDR],
proc_name, ClassPointer ));
ins->operands[CALL_OP_ADDR] = proc_name;
SetDisplay( GenIns( call->name ) );
AddIns( ins );
SaveDisplay( OP_POP );
} else {
AddCallIns( ins, call );
}
}
extern reg_set_index CallIPossible( instruction *ins ) {
/*********************************************************/
if( ins->operands[ CALL_OP_ADDR ]->n.name_class == CP ) return( RL_ );
if( ins->operands[ CALL_OP_ADDR ]->n.name_class == PT ) return( RL_ );
#if _TARGET & _TARG_80386
return( RL_DOUBLE );
#else
return( RL_WORD );
#endif
}
extern void InitTargProc( void ) {
/******************************/
CurrProc->targ.stack_check = NULL;
CurrProc->targ.push_local_size = 0;
CurrProc->targ.debug = NULL;
CurrProc->targ.return_points = NULL;
CurrProc->targ.sp_frame = FALSE;
CurrProc->targ.sp_align = FALSE;
CurrProc->targ.has_fd_temps = FALSE;
CurrProc->targ.never_sp_frame = FALSE;
CurrProc->targ.tls_index = NULL;
}
extern void SaveToTargProc( void ) {
/********************************/
CurrProc->targ.max_stack = MaxStack;
}
extern void RestoreFromTargProc( void ) {
/*************************************/
MaxStack = CurrProc->targ.max_stack;
}
extern void PushInSameBlock( instruction *ins ) {
/***************************************************/
ins = ins;
#if ( _TARGET & _TARG_80386 )
while( ins->head.opcode != OP_BLOCK ) {
ins = ins->head.next;
}
if( _BLOCK( ins ) != CurrBlock ) {
CurrProc->targ.never_sp_frame = TRUE;
}
#endif
}
extern instruction * PushOneParm( instruction *ins, name *curr,
type_class_def class,
type_length offset,
call_state *state ) {
/**************************************************************/
instruction *new;
int size;
state = state;
offset = offset;
new = MakeUnary( OP_PUSH, curr, NULL, class );
SuffixIns( ins, new );
if( curr->n.class == N_CONSTANT ) {
size = TypeClassSize[ class ];
} else {
size = curr->n.size;
}
return( new );
}
extern void PreCall( cn call ) {
/**********************************/
call = call;
}
extern void PostCall( cn call ) {
/***********************************/
call = call;
}
extern type_def *PassParmType( sym_handle func, type_def* tipe, call_class class ) {
/******************************************************************************************/
if( class & FAR16_CALL ) return( tipe );
return( QParmType( func, NULL, tipe ) );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?