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