i87sched.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,092 行 · 第 1/3 页
C
1,092 行
ins->operands[ 0 ] = ST( temp->actual_locn );
ins->result = ins->operands[ 0 ];
ins->operands[ 1 ] = ST( 0 );
InsLoc( ins, VIRTUAL_0 ) = temp->actual_locn;
DecrementAll();
break;
}
temp->actual_locn = ACTUAL_NONE;
} else {
if( ( ins == temp->first ) && !temp->defined && !temp->whole_block ) {
PrefFLDOp( ins, OP_MEM, temp->actual_op );
IncrementAll();
temp->actual_locn = ACTUAL_0;
if( ins->u.gen_table->generate == G_MFLD ) {
// PushStack( ins );
ins->operands[ 0 ] = ST( ACTUAL_0 );
} else {
GetToTopOfStack( ins, VIRTUAL_0 );
ins->operands[ 0 ] = ST( temp->actual_locn );
}
} else {
ins->operands[ 0 ] = ST( temp->actual_locn );
// if( attr & PUSHES ) {
// PushStack( ins );
// }
}
if( attr & PUSHES ) {
PushStack( ins );
} else if( attr & POPS2 ) {
PopStack( ins );
PopStack( ins );
} else if( attr & POPS ) {
PopStack( ins );
}
ins->u.gen_table = RegAction( ins );
}
return( ins );
}
static void SetResultReg( instruction *ins, int virtual_reg ) {
/**********************************************************/
ins->result = ST( InsLoc( ins, virtual_reg ) );
ins->operands[ 0 ] = ins->result;
}
static void GetToTopOfStack( instruction *ins, int virtual_reg ) {
/*************************************************************/
byte actual_locn;
byte *actual_top_owner;
actual_locn = InsLoc( ins, virtual_reg );
if( actual_locn == ACTUAL_0 ) return;
actual_top_owner = ActualStackOwner( ACTUAL_0 );
if( actual_top_owner != NULL ) {
PrefixExchange( ins, actual_locn );
InsLoc( ins, virtual_reg ) = ACTUAL_0;
*actual_top_owner = actual_locn;
return;
}
_Zoiks( ZOIKS_076 );
}
static instruction *FComppKluge( instruction *ins ) {
/********************************************************/
byte actual_0,actual_1;
byte *owner_0,*owner_1;
actual_0 = InsLoc( ins, VIRTUAL_0 );
actual_1 = InsLoc( ins, VIRTUAL_1 );
owner_0 = ActualStackOwner( ACTUAL_0 );
owner_1 = ActualStackOwner( ACTUAL_1 );
if( actual_0 == ACTUAL_0 ) {
if( actual_1 == ACTUAL_1 ) { // actual_0=0 actual_1=1
return( ins );
} else { // actual_0=0 actual_1=n
PrefFXCH( ins, ACTUAL_1 );
PrefFXCH( ins, actual_1 );
PrefFXCH( ins, ACTUAL_1 );
*owner_1 = actual_1;
}
} else if( actual_1 == ACTUAL_0 ) {
if( actual_0 == ACTUAL_1 ) { // actual_0=1 actual_1=0
PrefFXCH( ins, ACTUAL_1 );
} else { // actual_0=n actual_1=0
PrefFXCH( ins, ACTUAL_1 );
PrefFXCH( ins, actual_0 );
*owner_1 = actual_0;
}
} else if( actual_1 == ACTUAL_1 ) { // actual_1=1 actual_0=n
PrefFXCH( ins, actual_0 );
*owner_0 = actual_0;
} else { // actual_0=1,n actual_1=n
PrefFXCH( ins, actual_1 );
PrefFXCH( ins, ACTUAL_1 );
PrefFXCH( ins, actual_0 );
*owner_0 = actual_1;
*owner_1 = actual_0;
}
InsLoc( ins, VIRTUAL_0 ) = ACTUAL_0;
InsLoc( ins, VIRTUAL_1 ) = ACTUAL_1;
return( ins );
}
static instruction *GetST0andST1( instruction *ins ) {
/*********************************************************/
byte actual_0,actual_1;
actual_0 = InsLoc( ins, VIRTUAL_0 );
actual_1 = InsLoc( ins, VIRTUAL_1 );
if( actual_0 == ACTUAL_0 ) {
if( actual_1 == ACTUAL_1 ) { // actual_0=0 actual_1=1
return( ins );
} else { // actual_0=0 actual_1=n
PrefFLDOp( ins, OP_STKI, ST( actual_1 ) );
PrefFXCH( ins, ACTUAL_1 );
return( SuffFSTPRes( ins, ST( actual_1 ), RES_STKI ) );
}
} else if( actual_1 == ACTUAL_0 ) {
if( actual_0 == ACTUAL_1 ) { // actual_0=1 actual_1=0
GetToTopOfStack( ins, VIRTUAL_0 );
return( ins );
} else { // actual_0=n actual_1=0
InsLoc( ins, VIRTUAL_1 ) = actual_0;
PrefFLDOp( ins, OP_STKI, ST( actual_0 ) );
return( SuffFSTPRes( ins, ST( actual_0 ), RES_STKI ) );
}
} else if( actual_1 == ACTUAL_1 ) { // actual_1=1 actual_0=n
GetToTopOfStack( ins, VIRTUAL_0 );
return( ins );
} else { // actual_0=1,n actual_1=n
GetToTopOfStack( ins, VIRTUAL_1 );
InsLoc( ins, VIRTUAL_1 ) = actual_0;
PrefFLDOp( ins, OP_STKI, ST( actual_0 ) );
return( SuffFSTPRes( ins, ST( actual_0 ), RES_STKI ) );
}
}
static void IncrementAll( void ) {
/*************************/
int i,j;
temp_entry *temp;
for( i = 0; i < MaxSeq; ++i ) {
for( j = VIRTUAL_0; j < VIRTUAL_NONE-1; ++j ) {
if( RegLoc( i, j ) != ACTUAL_NONE ) {
++RegLoc( i, j );
}
}
}
for( temp = TempList; temp != NULL; temp = temp->next ) {
if( temp->actual_locn != ACTUAL_NONE ) {
temp->actual_locn++;
}
}
}
static void PushVirtualStack( instruction *ins ) {
/****************************************************/
int i;
for( i = VIRTUAL_NONE-1; i > VIRTUAL_0; --i ) {
InsLoc( ins, i ) = InsLoc( ins, i-1 );
}
InsLoc( ins, VIRTUAL_0 ) = ACTUAL_0;
}
static void PushStack( instruction *ins ) {
/*******************************************/
IncrementAll();
PushVirtualStack( ins );
}
static void DecrementAll( void ) {
/************************/
int i,j;
temp_entry *temp;
for( i = 0; i < MaxSeq; ++i ) {
for( j = VIRTUAL_0; j < VIRTUAL_NONE-1; ++j ) {
if( RegLoc( i, j ) != ACTUAL_NONE ) {
--RegLoc( i, j );
}
}
}
for( temp = TempList; temp != NULL; temp = temp->next ) {
if( temp->actual_locn != ACTUAL_NONE ) {
temp->actual_locn--;
}
}
}
static void PopVirtualStack( instruction *ins ) {
/*******************************************************/
int i;
for( i = VIRTUAL_0; i < VIRTUAL_NONE-1; ++i ) {
InsLoc( ins, i ) = InsLoc( ins, i+1 );
}
InsLoc( ins, VIRTUAL_7 ) = VIRTUAL_NONE;
}
static void PopStack( instruction *ins ) {
/******************************************/
PopVirtualStack( ins );
DecrementAll();
}
static void InitStackLocations( void ) {
/**************************************/
temp_entry *temp;
int i,j;
_Alloc( STLocations, MaxSeq * sizeof( *STLocations ) );
for( i = 0; i < MaxSeq; ++i ) {
for( j = VIRTUAL_0; j < VIRTUAL_NONE; ++j ) {
RegLoc( i, j ) = ACTUAL_NONE;
}
}
for( temp = TempList; temp != NULL; temp = temp->next ) {
temp->actual_locn = ACTUAL_NONE;
}
}
static void FiniStackLocations( void ) {
/**************************/
_Free( STLocations, MaxSeq * sizeof( st_seq ) );
STLocations = NULL;
}
static temp_entry *LookupTempEntry( name *op ) {
/***********************************************/
temp_entry *temp;
if( op == NULL ) return( NULL );
if( op->n.class == N_TEMP ) op = DeAlias( op );
for( temp = TempList; temp != NULL; temp = temp->next ) {
if( temp->op == op ) return( temp );
}
return( NULL );
}
static temp_entry *AddTempEntry( name *op ) {
/********************************************/
temp_entry *temp;
temp = LookupTempEntry( op );
if( temp == NULL ) {
_Alloc( temp, sizeof( *temp ) );
temp->next = TempList;
TempList = temp;
temp->actual_op = op;
if( op->n.class == N_TEMP ) op = DeAlias( op );
temp->op = op;
temp->first = NULL;
temp->last = NULL;
temp->savings = 0;
temp->actual_locn = ACTUAL_NONE;
temp->savings = 0;
temp->cached = FALSE;
temp->defined = FALSE;
temp->killed = FALSE;
temp->global = FALSE;
temp->whole_block = FALSE;
}
return( temp );
}
static void DefUseTemp( name *op,
instruction *ins, bool defined ) {
/********************************************************************/
temp_entry *temp;
temp = AddTempEntry( op );
if( op->v.offset != temp->actual_op->v.offset ||
op->n.size != temp->actual_op->n.size ) {
temp->killed = TRUE;
return;
}
if( temp->first == NULL ) temp->first = ins;
temp->last = ins;
temp->savings++;
if( defined ) temp->defined = TRUE;
}
static void KillTempEntry( name *op ) {
/*************************************************/
temp_entry *temp;
temp = AddTempEntry( op );
temp->killed = TRUE;
}
static void CheckTemp( instruction *ins, name *op, bool defined ) {
/*********************************************************************/
if( op->n.class == N_MEMORY ) {
if( _IsntModel( RELAX_ALIAS ) ) return;
} else if( op->n.class != N_TEMP ) {
return;
}
if( op->v.usage & USE_ADDRESS ) return;
if( !_GenIs8087( ins->u.gen_table->generate ) ) {
KillTempEntry( op );
} else {
DefUseTemp( op, ins, defined );
}
}
static bool Better( void *t1, void *t2 ) {
/*****************************************************/
return( ((temp_entry *)t1)->savings > ((temp_entry *)t2)->savings );
}
extern void InitTempEntries( block *blk ) {
/***************************************/
instruction *ins;
int i;
TempList = NULL;
for( ins = blk->ins.hd.next;
ins->head.opcode != OP_BLOCK; ins = ins->head.next ) {
if( ins->ins_flags & FP_INS_INTRODUCED ) continue;
for( i = 0; i < ins->num_operands; ++i ) {
CheckTemp( ins, ins->operands[i], FALSE );
}
if( ins->result != NULL ) {
CheckTemp( ins, ins->result, TRUE );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?