i86enc32.c

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

C
1,002
字号
    OutRTImport( RT_Far32Func - BEG_RTNS, F_FAR16 );
    OutDataInt( 0 );
    OutDataInt( 0 );
    if( remove_parms ) {
        OutDataByte( 0xca );
        OutDataInt( parms_size );
    } else {
        OutDataByte( 0xcb );
        OutDataInt( 0 );                // padding
    }
    // emit "reloc for offset of code_32 label"
    SetUpObj( TRUE );
    TellKeepLabel( code_32 );
    OutReloc( AskCodeSeg(), F_OFFSET, FALSE );
    OutLblPatch( code_32, F_OFFSET, 0 );
    TellByPassOver();
    SetOP( old );
    return( code_32 );
}

void    GenProfilingCode( char *fe_name, label_handle *data, bool prolog )
/************************************************************************/
{
    if( _IsTargetModel( NEW_P5_PROFILING ) ) {
        doProfilingCode( fe_name, data, prolog );
    }
}

segment_id GenP5ProfileData( char *fe_name, label_handle *data, label_handle *stack )
/***********************************************************************************/
{
    seg_id              old;
    segment_id  data_seg = (segment_id)FEAuxInfo( NULL, P5_PROF_SEG );

    old = SetOP( data_seg );
    TellOptimizerByPassed();
    SetUpObj( TRUE );
    *data = AskForNewLabel();
    OutLabel( *data );
    OutDataByte( *fe_name );                    //flag
    OutDataByte( 0 );
    OutDataByte( 0 );
    OutDataByte( 0 );
    OutDataLong( 0 );                           //semaphore
    if( stack == NULL ) {
        OutDataLong( 0 );                       //stack
    } else {
        OutReloc( data_seg, F_OFFSET, FALSE );  //caller
        OutLblPatch( *stack, F_OFFSET, 0 );
    }
    OutDataLong( 0 );                           //esp
    OutDataLong( 0 );                           //dynamic
    OutDataLong( 0 );                           //lo_count
    OutDataLong( 0 );                           //hi_count
    OutDataLong( 0 );                           //lo_cycle
    OutDataLong( 0 );                           //hi_cycle
    OutDataLong( 0 );                           //lo_start_time
    OutDataLong( 0 );                           //hi_start_time
    OutReloc( AskCodeSeg(), F_OFFSET, FALSE );  //caller
    OutLblPatch( CurrProc->label, F_OFFSET, 0 );
    OutDataLong( 0 );                           //call_ins
    OutDataLong( 0 );                           //callee
    TellByPassOver();
    SetOP( old );
    return( data_seg );
}


void    doProfilingCode( char *fe_name, label_handle *data, bool prolog )
/***********************************************************************/
{
    if( prolog ) GenP5ProfileData( fe_name, data, NULL );
    _Code;
    LayOpbyte( 0x68 );
    ILen += 4;
    DoLblRef( *data, (segment_id)FEAuxInfo( NULL, P5_PROF_SEG ), 0, FE_FIX_OFF | OFST);
    _Emit;
    RTCall( prolog ? RT_PROFILE_ON : RT_PROFILE_OFF, ATTR_POP );
}

static  void    doProfilingPrologEpilog( label_handle label, bool prolog )
/************************************************************************/
{
    if( _IsTargetModel( NEW_P5_PROFILING ) ) {
        doProfilingCode( "", &CurrProc->targ.routine_profile_data, prolog );
    } else {
        bck_info                *bck;
        label_handle    data_lbl;
        segment_id              data_seg;

        bck = (bck_info *)FEAuxInfo( AskForLblSym( label ), P5_PROF_DATA );
        if( bck == NULL ) return;
        data_lbl = bck->lbl;
        data_seg = (segment_id)FEAuxInfo( NULL, P5_PROF_SEG );
        TellKeepLabel( data_lbl );
        _Code;
        if( prolog ) {
            LayOpword( 0x05ff );
            ILen += 4;
            DoLblRef( data_lbl, data_seg, offsetof( P5_timing_info, count ), FE_FIX_OFF | OFST);
            _Next;
        }
        LayOpword( prolog ? 0x05ff : 0x0dff );          // inc L1 / dec L1
        ILen += 4;
        DoLblRef( data_lbl, data_seg, offsetof( P5_timing_info, semaphore ), FE_FIX_OFF | OFST );
        _Next;
        if( _IsTargetModel( P5_PROFILING_CTR0 ) ) {
            LayOpword( prolog ? 0x1675 : 0x167d );              // jne skip / jge skip
            _Next;
            LayOpbyte( 0x51 );                                  // push ecx
            _Next;
        } else {
            LayOpword( prolog ? 0x1275 : 0x127d );              // jne skip / jge skip
            _Next;
        }
        LayOpbyte( 0x52 );                                      // push edx
        _Next;
        if( _IsTargetModel( P5_PROFILING_CTR0 ) ) {
            LayOpword( 0xc931 );                                // xor ecx,ecx
            _Next;
        }
        LayOpbyte( 0x50 );                                      // push eax
        _Next;
        if( _IsTargetModel( P5_PROFILING_CTR0 ) ) {
            LayOpword( 0x330f );                                // rdpmc
            _Next;
        } else {
            LayOpword( 0x310f );                                // rdtsc
            _Next;
        }
        LayOpword( prolog ? 0x0529 : 0x0501 );          // sub L1+4,eax / add L1+4,eax
        ILen += 4;
        DoLblRef( data_lbl, data_seg, offsetof( P5_timing_info, lo_cycle ), FE_FIX_OFF | OFST );
        _Next;
        LayOpbyte( 0x58 );                                      // pop eax
        _Next;
        LayOpword( prolog ? 0x1519 : 0x1511 );          // sbb L1+8,edx / adc L1+8,edx
        ILen += 4;
        DoLblRef( data_lbl, data_seg, offsetof( P5_timing_info, hi_cycle ), FE_FIX_OFF | OFST );
        _Next;
        LayOpbyte( 0x5a );                                      // pop edx
        _Next;
        if( _IsTargetModel( P5_PROFILING_CTR0 ) ) {
            LayOpbyte( 0x59 );                                  // pop ecx
            _Next;
        }
        _Emit;
    }
}


extern  void    GenP5ProfilingProlog( label_handle label )
/********************************************************/
{
    doProfilingPrologEpilog( label, TRUE );
}

extern  void    GenP5ProfilingEpilog( label_handle label )
/********************************************************/
{
    doProfilingPrologEpilog( label, FALSE );
}

extern  void    GFstp10( type_length where )
/******************************************/
{
    GCondFwait();
    CheckSize();
    LayOpword( 0x3ddb );
    EA( HW_EMPTY, HW_BP, 0, -where, NULL, FALSE );
    _Emit;
}


extern  void    GFld10( type_length where )
/*****************************************/
{
    GCondFwait();
    CheckSize();
    LayOpword( 0x2ddb );
    EA( HW_EMPTY, HW_BP, 0, -where, NULL, FALSE );
    _Emit;
}


extern  void    Do4Shift( instruction *ins ) {
/********************************************/
/* NOT NEEDED */ ins = ins;
}


extern  void    Do4RShift( instruction *ins )
/*******************************************/
/* NOT NEEDED ON 386 */
{
    ins = ins;
}


extern  void    Gen4RNeg( instruction *ins )
/******************************************/
/* NOT NEEDED ON 386 */
{
    ins = ins;
}


extern  void    Pow2Div( instruction *ins )
/*****************************************/
{
    int         log2;
    bool        if_32;

    if_32 = FALSE;
    log2 = GetLog2( ins->operands[1]->c.int_value );
    switch( ins->type_class ) {
    case I1:
    case U1:
        LayOpword( 0xe4c0 );    /* shl  ah,n */
        AddByte( log2 );
        _Next;
        LayOpword( 0xc41a );    /* sbb  al,ah */
        _Next;
        LayOpword( 0xf8c0 );    /* sar  al,n */
        AddByte( log2 );
        break;
    case I2:
    case U2:
        if_32 = TRUE;
    case I4:
    case U4:
        LayOpword( 0xe2c1 );    /* shl  edx,n */
        OpndSizeIf( if_32 );
        AddByte( log2 );
        _Next;
        LayOpword( 0xc21b );    /* sbb  eax,edx */
        OpndSizeIf( if_32 );
        _Next;
        LayOpword( 0xf8c1 );    /* sar  eax,n */
        OpndSizeIf( if_32 );
        AddByte( log2 );
        break;
    }
}

extern  void    By2Div( instruction *ins )
/****************************************/
{
    bool        if_32;

    if_32 = FALSE;
    switch( ins->type_class ) {
    case I1:
    case U1:
        LayOpword( 0xc42a );    /* sub  al,ah */
        _Next;
        LayOpword( 0xf8d0 );    /* sar  al,1 */
        break;
    case I2:
    case U2:
        if_32 = TRUE;
    case I4:
    case U4:
        LayOpword( 0xc22b );    /* sub  eax,edx */
        OpndSizeIf( if_32 );
        _Next;
        LayOpword( 0xf8d1 );    /* sar  eax,1 */
        OpndSizeIf( if_32 );
        break;
    }
}

extern  void    Gen4Neg( instruction *ins )
/*****************************************/
/* NOT NEEDED ON 386 */
{
    ins = ins;
}

extern  void    Do4CXShift( instruction *ins, void (*rtn)(instruction *) )
/************************************************************************/
/* NOT NEEDED ON 386 */
{
    ins = ins; rtn = rtn;
}

void StartBlockProfiling( block *blk )
/************************************/
{
    seg_id              old;
    segment_id          data_seg;
    label_handle        data;

    if( !_IsTargetModel( NEW_P5_PROFILING ) ) return;
    if( !_IsTargetModel( STATEMENT_COUNTING ) ) return;
    data_seg = (segment_id)FEAuxInfo( NULL, P5_PROF_SEG );
    if( blk->label == NULL ) return;
    TellKeepLabel( blk->label );
    old = SetOP( data_seg );
    TellOptimizerByPassed();
    SetUpObj( TRUE );
    data = AskForNewLabel();
    TellKeepLabel( data );
    OutLabel( data );
    OutDataByte( PROFILE_FLAG_BLOCK );          //flag
    OutDataByte( 0 );                           //...
    OutDataByte( 0 );                           //...
    OutDataByte( 0 );                           //...
    OutDataLong( 0 );                           //lo_count
    OutDataLong( 0 );                           //hi_count
    OutReloc( AskCodeSeg(), F_OFFSET, FALSE );  //block
    OutLblPatch( blk->label, F_OFFSET, 0 );
    OutReloc( AskCodeSeg(), F_OFFSET, FALSE );  //function
    OutLblPatch( CurrProc->label, F_OFFSET, 0 );
    TellByPassOver();
    SetOP( old );
    _Code;
    LayOpword( 0x0583 );                // sub L1+4,eax / add L1+4,eax
    ILen += 4;
    DoLblRef( data, data_seg, offsetof( block_count_info, lo_count ), FE_FIX_OFF | OFST );
    AddByte( 1 );
    _Next;
    LayOpword( 0x1583 );                // sub L1+4,eax / add L1+4,eax
    ILen += 4;
    DoLblRef( data, data_seg, offsetof( block_count_info, hi_count ), FE_FIX_OFF | OFST );
    AddByte( 0 );
    _Emit;
}

void EndBlockProfiling( void )
/****************************/
{
}

⌨️ 快捷键说明

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