ppcproc.c

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

C
582
字号
        }
        index++;
        reg_set >>= 1;
    }
}

static  void    emitSavedRegsProlog( stack_record *saved_regs )
/*************************************************************/
{
    type_length         offset;

    offset = saved_regs->start + saved_regs->size - regSize( FALSE );
    saveRegSet( CurrProc->targ.gpr_mask, offset, FALSE );
    if( CurrProc->targ.gpr_mask == 0 ) {
        offset -= regSize( TRUE ) - regSize( FALSE );   // make it sp-8 for first double
    }
    offset -= CountBits( CurrProc->targ.gpr_mask ) * regSize( FALSE );
    saveRegSet( CurrProc->targ.fpr_mask, offset, TRUE );
}

static  void    emitSavedRegsEpilog( stack_record *saved_regs )
/*************************************************************/
{
    type_length         offset;

    offset = saved_regs->start - regSize( TRUE );
    loadRegSet( CurrProc->targ.fpr_mask, offset, TRUE );
    if( CurrProc->targ.fpr_mask == 0 ) {
        offset += regSize( TRUE ) - regSize( FALSE );
    }
    offset += CountBits( CurrProc->targ.fpr_mask ) * regSize( TRUE );
    loadRegSet( CurrProc->targ.gpr_mask, offset, FALSE );
}

static  void    initVarargs( stack_record *varargs, type_length *offset )
/***********************************************************************/
{
    varargs->start = *offset;
    varargs->size = 0;
}

static  void    emitVarargsProlog( stack_record *varargs )
/********************************************************/
{
    type_length         offset;
    int                 i;

    _unused( varargs );
    if( CurrProc->state.attr & ROUTINE_HAS_VARARGS ) {
        // save our registers in our caller's context - uhg!
        offset = CurrProc->targ.frame_size + STACK_HEADER_SIZE;
        for( i = CurrProc->state.parm.gr; i <= LAST_SCALAR_PARM_REG; i++ ) {
            saveReg( i, offset + ( i - FIRST_SCALAR_PARM_REG ) * 4, FALSE );
        }
    }
}

static  void    emitVarargsEpilog( stack_record *varargs )
/********************************************************/
{
    // NB see FrameSaveEpilog below
    _unused( varargs );
}

static  void    initSlop( stack_record *slop, type_length *offset )
/*****************************************************************/
{
    type_length         off;

    off = *offset;
    slop->start = off;
    slop->size = 0;
    if( off & ( STACK_ALIGNMENT - 1 ) ) {
        slop->size = STACK_ALIGNMENT - ( off & ( STACK_ALIGNMENT - 1 ) );
        *offset += slop->size;
    }
}

static  void    emitSlopProlog( stack_record *fs )
/************************************************/
{
    _unused( fs );
}

static  void    emitSlopEpilog( stack_record *fs )
/************************************************/
{
    _unused( fs );
}

static  void    initStackHeader( stack_record *stk, type_length *offset )
/***********************************************************************/
{
    stk->start = *offset;
    stk->size = STACK_HEADER_SIZE;
    *offset += stk->size;
}

static  void    emitStackHeaderProlog( stack_record *stk )
/********************************************************/
{
    _unused( stk );
}

static  void    emitStackHeaderEpilog( stack_record *stk )
/********************************************************/
{
    _unused( stk );
}


static  signed_32 frameSize( stack_map *map )
/*******************************************/
{
    signed_32           size;

    size = map->varargs.size + map->slop.size + map->saved_regs.size +
                map->locals.size + map->parm_cache.size + map->stack_header.size;
    if( size == ( map->slop.size + map->stack_header.size ) &&
        CurrProc->targ.leaf ) {
        // we are a leaf function whose stack frame consists only of a
        // stack header and some slop to make it 16-byte aligned, so instead
        // don't use any stack frame
        size = 0;
    }
    assert( ( size & ( STACK_ALIGNMENT - 1 ) ) == 0 );
    return( size );
}

static  void    initStackLayout( stack_map *map )
/***********************************************/
{
    type_length         offset;

    offset = 0;
    initStackHeader( &map->stack_header, &offset );
    initParmCache( &map->parm_cache, &offset );
    initLocals( &map->locals, &offset );
    initSavedRegs( &map->saved_regs, &offset );
    initSlop( &map->slop, &offset );
    initVarargs( &map->varargs, &offset );
}

static  void    emitProlog( stack_map *map )
/******************************************/
{
    type_length         frame_size;

    frame_size = frameSize( map );
    if( !CurrProc->targ.leaf ) {
        // mflr r0
        GenMTSPR( 0, SPR_LR, TRUE );
    }
    if( frame_size != 0 ) {
        // stwu sp,-frame_size(sp)
        GenMEMINS( 37, STACK_REG, STACK_REG, -frame_size );
        emitVarargsProlog( &map->varargs );
        emitSlopProlog( &map->varargs );
        emitSavedRegsProlog( &map->saved_regs );
        emitLocalProlog( &map->locals );
        emitParmCacheProlog( &map->parm_cache );
        emitStackHeaderProlog( &map->stack_header );
        if( CurrProc->targ.base_is_fp ) {
            genMove( STACK_REG, FRAME_REG );
        }
    }
}

static  void    emitEpilog( stack_map *map )
/******************************************/
{
    type_length         frame_size;
    uint_8              frame_reg;

    frame_size = frameSize( map );
    if( frame_size != 0 ) {
        emitStackHeaderEpilog( &map->stack_header );
        emitParmCacheEpilog( &map->parm_cache );
        emitLocalEpilog( &map->locals );
        emitSavedRegsEpilog( &map->saved_regs );
        emitSlopEpilog( &map->slop );
        emitVarargsEpilog( &map->varargs );
        if( !CurrProc->targ.leaf ) {
            GenMTSPR( 0, SPR_LR, FALSE );
        }
        frame_reg = STACK_REG;
        if( CurrProc->targ.base_is_fp ) {
            frame_reg = FRAME_REG;
        }
        genAdd( frame_reg, frame_size, STACK_REG );
    }
}

extern  void    GenProlog( void )
/*******************************/
{
    seg_id              old;
    label_handle        label;
    offset              lc;

    old = SetOP( AskCodeSeg() );
    lc = AskLocation();
    CurrProc->targ.proc_start = lc;
    label = CurrProc->label;
    if( _IsModel( NUMBERS ) ) {
        OutFileStart( HeadBlock->ins.hd.line_num );
    }
    OutTOCRec( label );
    CodeLabel( label, DepthAlign( PROC_ALIGN ) );
    if( _IsModel( NUMBERS ) ) {
        OutFuncStart( label, lc, HeadBlock->ins.hd.line_num );
    }
    if( _IsModel( DBG_LOCALS ) ) {  // d1+ or d2
        DbgRtnBeg( CurrProc->targ.debug, lc );
    }
    // keep stack aligned
    CurrProc->locals.size = _RoundUp( CurrProc->locals.size, 16 );
    CurrProc->parms.base = 0;
    CurrProc->parms.size = CurrProc->state.parm.offset;
    CalcUsedRegs();
    initStackLayout( &CurrProc->targ.stack_map );
    CurrProc->targ.frame_size = frameSize( &CurrProc->targ.stack_map );
    emitProlog( &CurrProc->targ.stack_map );
    lc = AskLocation();
    CurrProc->targ.pro_size = lc;
    if( _IsModel( DBG_LOCALS ) ) {  // d1+ or d2
  //    DbgRetOffset( CurrProc->parms.base - CurrProc->targ.base_adjust
  //                    - ret_size );
        DbgProEnd( CurrProc->targ.debug, lc );
    }
    SetOP( old );
}


extern  void    GenEpilog( void )
/*******************************/
{
    seg_id              old;
    offset              lc;

    old = SetOP( AskCodeSeg() );
    if( _IsModel( DBG_LOCALS ) ){  // d1+ or d2
        lc = AskLocation();
        DbgEpiBeg( CurrProc->targ.debug, lc );
    }
    // Pop();
    emitEpilog( &CurrProc->targ.stack_map );
    GenRET();
    CurrProc->prolog_state |= GENERATED_EPILOG;
    lc = AskLocation();
    if( _IsModel( DBG_LOCALS ) ){  // d1+ or d2
        DbgRtnEnd( CurrProc->targ.debug, lc );
    }
    if( _IsModel( NUMBERS ) ) {
        OutFuncEnd( lc );
    }
    OutPDataRec( CurrProc->label, CurrProc->targ.pro_size, lc );
    SetOP( old );
}


extern  int     AskDisplaySize( int level )
/*****************************************/
{
    return( 0 );
}

extern  void    InitStackDepth( block *blk )
/******************************************/
{
}

extern  type_length     PushSize( type_length len )
/*************************************************/
{
    if( len < REG_SIZE ) return( REG_SIZE );
    return( len );
}

extern  type_length     NewBase( name *op )
/*****************************************/
{
    return( TempLocation( op ) );
}

extern  int     ParmsAtPrologue( void )
/*************************************/
{
    return( 0 );
}

⌨️ 快捷键说明

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