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