i86index.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 519 行 · 第 1/2 页
C
519 行
index->i.index_flags | X_SEGMENTED );
if( ins->result == index ) {
ins->result = new_index;
}
i = ins->num_operands;
while( --i >= 0 ) {
if( ins->operands[ i ] == index ) {
ins->operands[ i ] = new_index;
}
}
*seg_ptr = SegmentPart( index->i.index );
MarkSegment( ins, *seg_ptr );
ins->num_operands++;
}
if( conf != NULL ) {
_SetTrue( conf, SEGMENT_SPLIT );
}
}
}
extern void FixMemRefs( void ) {
/*****************************
Make sure that no N_MEMORY names are used as indecies. This would
cause problems since we might need a segment override for the INDEX
as well as the memory which we're indexing to get to. This is no
good since each instruction can only have one segment override,
hence one memory reference.
*/
block *blk;
instruction *ins;
blk = HeadBlock;
while( blk != NULL ) {
ins = blk->ins.hd.next;
while( ins->head.opcode != OP_BLOCK ) {
#if _TARGET & _TARG_80386
ExpandThreadDataRef( ins );
#endif
NoMemIndex( ins );
ins = ins->head.next;
}
blk = blk->next_block;
}
}
extern void FixSegments( void ) {
/******************************
Add segment overrides to any instruction in the routine that needs
them.
*/
block *blk;
instruction *ins;
blk = HeadBlock;
while( blk != NULL ) {
ins = blk->ins.hd.next;
while( ins->head.opcode != OP_BLOCK ) {
AddSegment( ins );
/* Generate an error if segment override is requested and all segment
* registers are pegged. However we do NOT want to generate an error
* if this is a CS override in flat model - that particular case is not
* an error because the CS override is essentially a no-op. MN
*/
#define ANY_FLOATING (FLOATING_DS|FLOATING_ES|FLOATING_FS|FLOATING_GS)
if( _IsntTargetModel( ANY_FLOATING ) &&
ins->num_operands > NumOperands( ins )
#if _TARGET & _TARG_80386
&& !(_IsTargetModel( FLAT_MODEL ) &&
(ins->operands[ ins->num_operands-1 ]->n.class == N_REGISTER) &&
HW_CEqual( ins->operands[ ins->num_operands-1 ]->r.reg, HW_CS ))
#endif
) {
/* throw away override */
ins->num_operands--;
FEMessage( MSG_NO_SEG_REGS, AskForLblSym( CurrProc->label ) );
}
ins = ins->head.next;
}
blk = blk->next_block;
}
}
static type_class_def FltClass( instruction *ins ) {
/*****************************************************
return the floating point class (FD or FS) of "ins", or XX if it
does not involve floating point.
*/
if( _IsFloating( ins->type_class ) ) return( ins->type_class );
if( _IsFloating( _OpClass( ins ) ) ) return( _OpClass( ins ) );
return( XX );
}
extern void MergeIndex( void ) {
/*****************************
Merge segment overrides back into the index registers. This is
called just before scoreboarding to simplify matters. For example
MOV [DI], ES => AX becomes MOV [ES:DI] => AX.
*/
block *blk;
instruction *ins;
int i;
name **name;
bool dec;
blk = HeadBlock;
while( blk != NULL ) {
ins = blk->ins.hd.next;
while( ins->head.opcode != OP_BLOCK ) {
i = NumOperands( ins );
if( i < ins->num_operands ) {
dec = FALSE;
while( --i >= 0 ) {
name = &ins->operands[ i ];
if( (*name)->n.class == N_INDEXED ) {
Merge( name, ins );
dec = TRUE;
}
}
if( ins->result != NULL ) {
name = &ins->result;
if( (*name)->n.class == N_INDEXED ) {
Merge( name, ins );
dec = TRUE;
}
}
if( dec ) {
ins->num_operands--;
}
}
ins = ins->head.next;
}
blk = blk->next_block;
}
}
static void Merge( name **pname, instruction *ins ) {
/********************************************************
called by MergeIndex ^
*/
name *index;
name *reg;
hw_reg_set tmp;
index = *pname;
tmp = index->i.index->r.reg;
HW_TurnOn( tmp, ins->operands[ ins->num_operands-1 ]->r.reg );
reg = AllocRegName( tmp );
*pname = ScaleIndex( reg, index->i.base, index->i.constant,
index->n.name_class, index->n.size,
index->i.scale, index->i.index_flags );
}
extern void FixChoices( void ) {
/*****************************
Run through the conflict list and make sure that no conflict is
allowed to get cached in a segment register unless it was actually
used as a segment override somewhere in the program. This avoids
loads of bad selectors in protected mode.
*/
conflict_node *conf;
name *temp;
name *alias;
PropSegments();
conf = ConfList;
while( conf != NULL ) {
if( _Isnt( conf, VALID_SEGMENT ) ) {
conf->possible = NoSegments( conf->possible );
temp = conf->name;
if( temp->n.class == N_TEMP ) {
alias = temp;
for(;;) {
alias = alias->t.alias;
alias->t.possible = NoSegments( alias->t.possible );
if( alias == temp ) break;
}
}
}
conf = conf->next_conflict;
}
}
static void PropSegments( void ) {
/*******************************
For every instruction of the form MOV X => Y, mark the conflict node
for X as a valid segment if the conflict for Y is marked as a valid
segment.
*/
block *blk;
instruction *ins;
conflict_node *src;
conflict_node *dst;
bool change;
src = ConfList;
while( src != NULL ) {
if( _Is( src, VALID_SEGMENT ) ) {
_SetTrue( src, WAS_SEGMENT );
}
src = src->next_conflict;
}
for(;;) {
change = FALSE;
blk = HeadBlock;
while( blk != NULL ) {
ins = blk->ins.hd.prev;
while( ins->head.opcode != OP_BLOCK ) {
if( ins->head.opcode == OP_MOV ) {
dst = NameConflict( ins, ins->result );
if( dst != NULL && _Is( dst, WAS_SEGMENT ) ) {
src = NameConflict( ins, ins->operands[ 0 ] );
if( src != NULL && _Isnt( src, WAS_SEGMENT ) ) {
_SetTrue( src, WAS_SEGMENT );
change = TRUE;
}
}
}
ins = ins->head.prev;
}
blk = blk->next_block;
}
if( change == FALSE ) break;
}
}
extern void FixFPConsts( instruction *ins ) {
/************************************************
Fix floating point constants, by forcing them into memory if they
are not going to be segment register addressable. This is done so that
OneMemRef, the routine that ensures that we will have only one
memory reference, (therefore one segment override), will see it as a
memory reference and treat it accordingly.
*/
int i;
type_class_def class;
if( !FPCInCode() && (_IsTargetModel( FLOATING_SS ) && _IsTargetModel( FLOATING_DS )) ) {
class = FltClass( ins );
if( class != XX ) {
i = ins->num_operands;
while( --i >= 0 ) {
ins->operands[ i ] = Addressable( ins->operands[ i ], class );
}
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?