i87opt.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 906 行 · 第 1/3 页
C
906 行
#endif
}
return( BackUpAndFree( ins, ins, next ) );
}
static instruction *Opt87Sequence( instruction *ins, bool *again ) {
/************************************************************************
Look for silly 8087 sequences and fix them up.
*/
instruction *next;
instruction *third;
instruction *ret;
type_class_def class;
int num_ops;
next = Next87Ins( ins );
ret = ins->head.next;
if( next == ins ) return( ret );
if( G( ins ) == G_RFLD && FPRegNum( ins->operands[ 0 ] ) == 0 ) {
if( G( next ) == G_MFST ) {
/* FLD ST, FSTP X ===> FST X */
FreeIns( ins );
if( FPResultNotNeeded( next ) ) {
ret = BackUpAndFree( ins, next, NULL );
} else {
ret = next;
NoPop( next );
}
*again = TRUE;
} else if( G( next ) == G_RFST ) {
/* FLD ST, FSTP ST(i) ===> FST ST(i-1) */
if( FPRegNum( next->result ) == 0 ) {
ret = BackUpAndFree( ins, ins, next );
} else {
AdjustST( &next->result, -1 );
FreeIns( ins );
ret = next;
NoPop( next );
}
*again = TRUE;
} else if( G( next ) == G_RNFBINP || G( next ) == G_RRFBINP ) {
/* FLD ST, FopP ST(i),ST ==> Fop ST(i-1),ST */
if( FPRegNum( next->operands[ 0 ] ) == 0 ) {
ret = BackUpAndFree( ins, ins, next );
} else {
AdjustST( &next->operands[ 0 ], -1 );
NoPopRBin( next );
FreeIns( ins );
ret = next;
}
*again = TRUE;
} else if( G( next ) == G_FXCH && FPRegNum( next->result ) == 1 ) {
FreeIns( next );
*again = TRUE;
ret = ins;
}
} else if( G( ins ) == G_RFLD || G( ins ) == G_MFLD ) {
if( ( G( next ) == G_RRFBINP || G( next ) == G_RNFBINP ) ) {
if( G( ins ) == G_MFLD ) {
class = ins->operands[ 0 ]->n.name_class;
if( !_IsFloating( class ) ) return( ret ); /* need convert! */
}
if( ( FPRegNum( next->operands[ 0 ] ) == 1 ) ) {
/* FLD X, FxxP ST(1) ==> Fxx X */
next->result = ST( 0 );
next->operands[ 0 ] = ins->operands[ 0 ];
num_ops = NumOperands( ins );
if( ins->num_operands > num_ops
&& next->num_operands <= NumOperands( next ) ) {
next->operands[ next->num_operands ]
= ins->operands[ num_ops ];
next->num_operands++;
}
FreeIns( ins );
NoPopBin( next );
*again = TRUE;
ret = next;
}
} else if( G( next ) == G_RFLD || G( next ) == G_MFLD ) {
if( G( ins ) == G_MFLD && G( next ) == G_MFLD &&
/* FLD X, FLD X ==> FLD X, FLD ST(0) */
ins->operands[0] == next->operands[0] ) {
next->operands[0] = ST( 0 );
ToRFld( next );
*again = TRUE;
ret = next;
} else {
/* FLD X, FLD Y, FXCH ST(1) ==> FLD Y, FLD X */
third = Next87Ins( next );
if( third == next ) return( ret );
if( G( third ) == G_FXCH && FPRegNum( third->result ) == 1 ) {
FreeIns( third );
if( FPRegNum( next->operands[0] ) != 0 ) {
ins->head.next->head.prev = ins->head.prev;
ins->head.prev->head.next = ins->head.next;
SuffixIns( next, ins );
if( G( ins ) == G_RFLD ) {
AdjustST( &ins->operands[0], +1 );
}
if( G( next ) == G_RFLD ) {
AdjustST( &next->operands[0], -1 );
}
ret = next;
} else {
ret = ins;
}
*again = TRUE;
}
}
} else if( G( ins ) == G_MFLD ) {
if( G( next ) == G_MFST ) {
if(ins->operands[0]->n.name_class==next->result->n.name_class) {
ret = To86Move( ins, next );
}
} else if( G( next ) == G_MRFBIN || G( next ) == G_MNFBIN ) {
if( ins->operands[0] == next->operands[ 0 ] ) {
/* FLD X, FOP X ==> FLD X, FOP ST */
next->operands[ 0 ] = ST( 0 );
DelSeg( next );
NoMemBin( next );
*again = TRUE;
ret = ins;
}
}
}
} else if( G( ins ) == G_MFST || G( ins ) == G_RFST ) {
if( G( next ) == G_MFLD
&& ( next->operands[ 0 ] == ins->result )
&& _IsFloating( ins->result->n.name_class )
&& !IsVolatile( ins->result ) ) {
/* FSTP X, FLD X ==> FST X */
FreeIns( next );
if( FPResultNotNeeded( ins ) ) {
ret = BackUpAndFree( ins, ins, NULL );
} else {
ret = ins;
NoPop( ins );
}
*again = TRUE;
} else if( G( next ) == G_RFLD
&& FPRegNum( next->operands[0] ) + 1 == FPRegNum( ins->result ) ) {
/* FSTP ST(i), FLD ST(i-1) ==> FST ST(i) */
FreeIns( next );
NoPop( ins );
*again = TRUE;
ret = ins;
}
} else if( G( ins ) == G_FXCH ) {
if( G( next ) == G_FXCH ) {
/* FXCH ST(i) FXCH ST(i) => nothing */
if( FPRegNum( ins->result ) == FPRegNum( next->result ) ) {
FreeIns( next );
next = BackUpAndFree( ins, ins, NULL );
*again = TRUE;
ret = next;
}
} else {
if( G( next ) == G_RRFBINP || G( next ) == G_RNFBINP ) {
if( FPRegNum( ins->result ) == FPRegNum( next->operands[0] ) ) {
/* FXCH ST(i), FopP ST(i),ST -> FopRP ST(i),ST */
FreeIns( ins );
ReverseFPGen( next );
*again = TRUE;
ret = next;
}
}
}
} else if( G( ins ) == G_MFSTNP ) {
if( G( next ) == G_MFLD && ins->result == next->operands[0] ) {
/* FST X, FLD X => FST X, FLD ST */
next->operands[0] = ST( 0 );
ToRFld( next );
*again = TRUE;
ret = ins;
} else if( RedundantStore( ins ) ) {
ret = BackUpAndFree( ins, ins, NULL );
*again = TRUE;
}
} else if( G( ins ) == G_RNFBIN || G( ins ) == G_RRFBIN ) {
if( G( next ) == G_RFST && next->result == ins->operands[0] ) {
ToPopBin( ins );
FreeIns( next );
*again = TRUE;
ret = ins;
}
}
return( ret );
}
static void MoveThrough( name *from, name *to, instruction *from_ins,
instruction *to_ins, name *reg,
type_class_def class ) {
/****************************************************
Move from "from" to "to" using register name "reg". Segments if
any should be taken from "from_ins" and "to_ins".
*/
bool dummy;
instruction *new;
new = MakeMove( from, reg, class );
new->u.gen_table = FindGenEntry( new, &dummy );
DupSeg( from_ins, new );
PrefixIns( to_ins, new );
new = MakeMove( reg, to, class );
DupSeg( to_ins, new );
new->u.gen_table = FindGenEntry( new, &dummy );
PrefixIns( to_ins, new );
}
extern bool DivIsADog( type_class_def class )
/***********************************************/
{
return( _FPULevel( FPU_87 ) && _IsFloating( class ) );
}
extern void Opt8087( void ) {
/**************************
Look for silly 8087 sequences and change them into better ones.
*/
block *blk;
instruction *ins;
int i;
bool again;
blk = HeadBlock;
while( blk != NULL ) {
i = 0;
for( ins = blk->ins.hd.next;
ins->head.opcode != OP_BLOCK; ins = ins->head.next ) {
ins->sequence = ++i;
}
ins = blk->ins.hd.next;
again = FALSE;
while( ins->head.opcode != OP_BLOCK ) {
if( _GenIs8087( ins->u.gen_table->generate ) ) {
if( !FSinCos( ins ) ) {
ins = Opt87Sequence( ins, &again );
} else {
ins = ins->head.next;
}
} else {
ins = ins->head.next;
}
}
if( !again ) {
for( ins = blk->ins.hd.next;
ins->head.opcode != OP_BLOCK; ins = ins->head.next ) {
if( FPResultNotNeeded( ins ) ) {
ins->result = ST( 0 );
ToRFstp( ins );
}
}
blk = blk->next_block;
}
}
}
extern void FixP5Divs( void ) {
/*********************************/
block *blk;
instruction *ins;
if( !_IsTargetModel( P5_DIVIDE_CHECK ) ) return;
if( !_FPULevel( FPU_87 ) ) return;
for( blk = HeadBlock; blk != NULL; blk = blk->next_block ) {
for( ins = blk->ins.hd.next; ins->head.opcode != OP_BLOCK; ins = ins->head.next ) {
if( ins->head.opcode != OP_DIV ) continue;
if( !_IsFloating( ins->type_class ) ) continue;
ins->head.opcode = OP_P5DIV;
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?