i86split.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,100 行 · 第 1/3 页
C
1,100 行
name_int = name_flt;
} else {
name_int = TempOffset( name_flt, 0, U4 );
}
name_flt->v.usage |= USE_MEMORY | NEEDS_MEMORY;
new_ins = MakeMove( ins->operands[ 0 ], name_int, name_int->n.name_class);
ins->operands[ 0 ] = name_flt;
MoveSegOp( ins, new_ins, 0 );
PrefixIns( ins, new_ins );
return( new_ins );
}
extern instruction *rOP1CMEM( instruction *ins ) {
/*********************************************************/
ins->operands[ 0 ] = Addressable( ins->operands[ 0 ], ins->type_class );
return( ins );
}
extern instruction *rOP2CMEM( instruction *ins ) {
/*********************************************************/
ins->operands[ 1 ] = Addressable( ins->operands[ 1 ], ins->type_class );
return( ins );
}
extern instruction *rU_TEST( instruction *ins ) {
/***************************************************/
instruction *new_ins;
instruction *ins2;
name *name1;
name *name2;
ChangeType( ins, U2 );
name1 = ins->operands[ 0 ];
name2 = AllocTemp( U2 );
new_ins = MakeMove( HighPart( name1, U2 ), name2, U2 );
ins2 = MakeBinary( OP_OR, name2, LowPart( name1, U2 ), name2, U2 );
ins->operands[ 0 ] = name2;
DupSeg( ins, new_ins );
DupSeg( ins, ins2 );
DelSeg( ins );
PrefixIns( ins, new_ins );
PrefixIns( ins, ins2 );
return( new_ins );
}
extern instruction *rCPSUB( instruction *ins ) {
/**************************************************/
instruction *new_ins;
new_ins = MakeBinary( OP_SUB, OffsetPart( ins->operands[ 0 ] ),
OffsetPart( ins->operands[ 1 ] ),
ins->result, SW );
DupSeg( ins, new_ins );
ReplIns( ins, new_ins );
return( new_ins );
}
extern instruction *rPTSUB( instruction *ins ) {
/**************************************************/
instruction *new_ins;
ChangeType( ins, PT );
new_ins = rMAKECALL( ins );
return( new_ins );
}
extern instruction *rEXTPT( instruction *ins ) {
/**************************************************/
instruction *new_ins;
name *name1;
if( ins->ins_flags & INS_CODE_POINTER ) {
name1 = AllocRegName( HW_CS );
} else {
name1 = NearSegment();
}
new_ins = MakeMove( name1, SegmentPart( ins->result ), U2 );
ins->head.opcode = OP_MOV;
ins->type_class = WD;
ins->result = OffsetPart( ins->result );
ins->table = NULL;
DupSegRes( ins, new_ins );
PrefixIns( ins, new_ins );
return( new_ins );
}
extern instruction *rMAKEU4CONS( instruction *ins ) {
/*******************************************************/
ChangeType( ins, U4 );
ins->operands[ 0 ] = IntEquivalent( ins->operands[ 0 ] );
return( ins );
}
extern instruction *rCHPPT( instruction *ins ) {
/**************************************************/
ins->head.opcode = OP_MOV;
ChangeType( ins, WD );
ins->operands[ 0 ] = OffsetPart( ins->operands[ 0 ] );
return( ins );
}
/* NB: The following two routines are intended for 386 only */
extern instruction *rMOVPTI8( instruction *ins )
/***************************************************/
{
instruction *new_ins;
instruction *ins2;
new_ins = MakeMove( OffsetPart( ins->operands[0] ), LowPart( ins->result, U4 ), U4 );
ins2 = MakeConvert( SegmentPart( ins->operands[0] ), HighPart( ins->result, U4 ), U4, U2 );
DupSegRes( ins, ins2 );
SuffixIns( ins, ins2 );
ReplIns( ins, new_ins );
return( new_ins );
}
extern instruction *rMOVI8PT( instruction *ins )
/***************************************************/
{
instruction *new_ins;
instruction *ins2;
new_ins = MakeMove( LowPart( ins->operands[0], U4 ), OffsetPart( ins->result ), U4 );
ins2 = MakeMove( HighPart( ins->operands[0], U2 ), SegmentPart( ins->result ), U2 );
DupSegRes( ins, ins2 );
SuffixIns( ins, ins2 );
ReplIns( ins, new_ins );
return( new_ins );
}
extern void CheckCC( instruction *ins, instruction *new_ins ) {
/*****************************************************************/
if( ins->head.opcode == OP_EXT_ADD || ins->head.opcode == OP_EXT_SUB ) {
#if _TARGET & _TARG_80386
new_ins->table = Move4; /* ensure it doesn't set the condition codes */
#else
new_ins->table = Move2; /* ensure it doesn't set the condition codes */
#endif
new_ins->ins_flags |= INS_CC_USED;
}
}
static instruction *SplitPush( instruction *ins, type_length size ) {
/************************************************************************/
instruction *new_ins;
instruction *first_ins;
name *op;
name *new_op = NULL;
size = (size + (WORD_SIZE-1)) &~(WORD_SIZE-1);
op = ins->operands[ 0 ];
first_ins = NULL;
for( ;; ) {
size -= WORD_SIZE;
switch( op->n.class ) {
case N_MEMORY:
new_op = AllocMemory( op->v.symbol, op->v.offset + size,
op->m.memory_type, WD );
break;
case N_TEMP:
new_op = TempOffset( op, size, WD );
new_op->t.temp_flags |= CG_INTRODUCED;
break;
case N_INDEXED:
new_op = ScaleIndex( op->i.index, op->i.base,
op->i.constant + size, WD, 0,
op->i.scale, op->i.index_flags );
break;
default:
Zoiks( ZOIKS_051 );
break;
}
new_ins = MakeUnary( OP_PUSH, new_op, NULL, WD );
if( size == 0 ) break;
if( first_ins == NULL ) {
first_ins = new_ins;
}
DupSeg( ins, new_ins );
PrefixIns( ins, new_ins );
}
DupSeg( ins, new_ins );
ReplIns( ins, new_ins );
if( first_ins == NULL ) return( new_ins );
return( first_ins );
}
extern instruction *rDOLONGPUSH( instruction *ins ) {
/*****************************************************/
name *sp;
name *at_sp;
name *temp;
type_length size;
instruction *move;
instruction *sub_sp;
instruction *temp_ins;
hw_reg_set hw_ss_sp;
size = ins->operands[ 0 ]->n.size;
if( size <= 4*WORD_SIZE ) {
return( SplitPush( ins, size ) );
} else {
HW_CAsgn( hw_ss_sp, HW_SS );
HW_CTurnOn( hw_ss_sp, HW_SP );
sp = AllocRegName( HW_SP );
if( _IsTargetModel( FLOATING_SS ) ) {
temp = AllocTemp( CP );
temp_ins = MakeMove( AllocRegName( hw_ss_sp ), temp, CP );
} else {
temp = AllocTemp( WD );
temp_ins = MakeMove( sp, temp, WD );
}
at_sp = AllocIndex( temp, NULL, 0, XX );
at_sp->n.size = size;
move = MakeMove( ins->operands[ 0 ], at_sp, XX );
ReplIns( ins, move );
ins = LoadStringOps( move, &move->operands[ 0 ], &move->result );
/*% mov CX,const will be the first if it's there so try for SUB SP,CX*/
sub_sp = MakeBinary( OP_SUB, sp, AllocIntConst(
(size+(WORD_SIZE-1)) & ~(WORD_SIZE-1) ), sp, WD );
if( ins->result != NULL && HW_CEqual( ins->result->r.reg, hw( CX ) ) ) {
SuffixIns( ins, sub_sp );
} else {
PrefixIns( ins, sub_sp );
ins = sub_sp;
}
SuffixIns( sub_sp, temp_ins );
}
return( ins );
}
extern name *OpAdjusted( name *op, int bias, type_class_def type ) {
/*********************************************************************
Return a new op of type 'type' which is offset from the old op by the
amount specified by 'bias'.
*/
name *new_op = NULL;
switch( op->n.class ) {
case N_MEMORY:
new_op = AllocMemory( op->v.symbol, op->v.offset + bias,
op->m.memory_type, type );
break;
case N_TEMP:
new_op = TempOffset( op, bias, type );
new_op->t.temp_flags |= CG_INTRODUCED;
break;
case N_INDEXED:
new_op = ScaleIndex( op->i.index, op->i.base,
op->i.constant + bias, SW, 0,
op->i.scale, op->i.index_flags );
break;
default:
Zoiks( ZOIKS_051 );
break;
}
return( new_op );
}
extern instruction *rFLIPSIGN( instruction *ins ) {
/******************************************************/
instruction *new;
name *new_op;
new_op = OpAdjusted( ins->operands[0], ins->operands[0]->n.size - 1, U1 );
new = MakeBinary( OP_XOR, new_op, AllocIntConst( 0x80 ), new_op, U1 );
DupSegRes( ins, new );
ReplIns( ins, new );
return( new );
}
extern instruction *rTEMP2CONST( instruction *ins ) {
/********************************************************/
int i;
name *op;
for( i = ins->num_operands-1; i >= 0; --i ) {
op = ins->operands[i];
if( op->n.class != N_TEMP ) continue;
if( !(op->t.temp_flags & CONST_TEMP) ) continue;
ins->operands[i] = op->v.symbol;
}
return( ins );
}
extern void CnvOpToInt( instruction * ins, int op ) {
/***************************************************************/
name *name1;
switch( ins->type_class ) {
case FS:
name1 = ins->operands[ op ];
if( name1->n.class == N_CONSTANT ) {
ins->operands[ op ] = IntEquivalent( name1 );
}
break;
#if _TARGET & _TARG_80386
// this is for the I8 stuff - can't tell what to do in
// HighPart and LowPart if we don't get rid on constant
// here
case FD:
name1 = ins->operands[ op ];
if( name1->n.class == N_CONSTANT ) {
ins->operands[ op ] = Int64Equivalent( name1 );
}
break;
#endif
default:
break;
}
}
extern instruction *rCMPCP( instruction *ins ) {
/***************************************************/
assert( ins->type_class == CP );
assert( ins->operands[ 1 ]->n.class == N_CONSTANT );
assert( ins->operands[ 1 ]->c.int_value == 0 );
if( ins->head.opcode == OP_CMP_EQUAL ||
ins->head.opcode == OP_CMP_NOT_EQUAL ) {
if( _IsTargetModel( NULL_SELECTOR_BAD ) ) {
ins->operands[ 0 ] = HighPart( ins->operands[ 0 ], U2 );
ChangeType( ins, U2 );
return( ins );
}
}
return( rMAKEU4( ins ) );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?