i86half.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 456 行 · 第 1/2 页
C
456 行
extern instruction *rMAKEU2( instruction *ins ) {
/***************************************************/
instruction *new_ins;
instruction *ins2;
name *temp = NULL;
if( IndexOverlaps( ins, 0 ) || IndexOverlaps( ins, 1 ) ) {
ChangeType( ins, WORD );
if( ins->result != NULL ) {
new_ins = MakeMove( HighPart( ins->operands[ 0 ], WORD ),
AllocTemp( WORD ), WORD );
temp = HighPart( ins->result, WORD );
ins->result = LowPart( ins->result, WORD );
DupSegOp( ins, new_ins, 0 );
PrefixIns( ins, new_ins );
} else {
new_ins = ins;
}
ins->operands[ 0 ] = LowPart( ins->operands[ 0 ], WORD );
if( ins->operands[ 1 ]->n.name_class == LONG_WORD
|| ins->operands[ 1 ]->n.name_class == LONG_WORD_S ) {
ins->operands[ 1 ] = LowPart( ins->operands[ 1 ], WORD );
}
if( ins->result != NULL ) {
ins2 = MakeMove( new_ins->result, temp, WORD );
DupSegRes( ins, ins2 );
SuffixIns( ins, ins2 );
}
} else {
ChangeType( ins, WORD );
if( ins->result != NULL ) {
new_ins = MakeMove( HighPart( ins->operands[ 0 ], WORD ),
HighPart( ins->result, WORD ), WORD );
ins->result = LowPart( ins->result, WORD );
DupSegOp( ins, new_ins, 0 );
DupSegRes( ins, new_ins );
PrefixIns( ins, new_ins );
} else {
new_ins = ins;
}
ins->operands[ 0 ] = LowPart( ins->operands[ 0 ], WORD );
ins->operands[ 1 ] = LowPart( ins->operands[ 1 ], WORD );
}
return( new_ins );
}
#endif
extern instruction *rSPLITNEG( instruction *ins ) {
/******************************************************/
name *hi_res;
name *lo_res;
name *hi_src;
name *lo_src;
instruction *hi_ins;
instruction *lo_ins;
instruction *subtract;
HalfType( ins );
hi_res = HighPart( ins->result, ins->type_class );
hi_src = HighPart( ins->operands[ 0 ], ins->type_class );
lo_res = LowPart( ins->result, ins->type_class );
lo_src = LowPart( ins->operands[ 0 ], ins->type_class );
hi_ins = MakeUnary( OP_NEGATE, hi_src, hi_res, ins->type_class );
lo_ins = MakeUnary( OP_NEGATE, lo_src, lo_res, ins->type_class );
lo_ins->ins_flags |= INS_CC_USED;
subtract = MakeBinary( OP_EXT_SUB, hi_res, AllocIntConst( 0 ), hi_res,
ins->type_class );
DupSegRes( ins, subtract );
DupSeg( ins, hi_ins );
DupSeg( ins, lo_ins );
PrefixIns( ins, hi_ins );
ins->operands[ 0 ] = ins->result;
ins->operands[ 1 ] = AllocIntConst( 0 );
PrefixIns( ins, lo_ins );
ReplIns( ins, subtract );
UpdateLive( hi_ins, subtract );
return( hi_ins );
}
extern instruction *rSPLITCMP( instruction *ins ) {
/*********************************************************/
name *left;
name *right;
instruction *low = NULL;
instruction *high = NULL;
instruction *not_equal = NULL;
type_class_def high_class;
type_class_def low_class;
byte true_idx;
byte false_idx;
high_class = HalfClass[ ins->type_class ];
low_class = Unsigned[ high_class ];
left = ins->operands[ 0 ];
right = ins->operands[ 1 ];
true_idx = _TrueIndex( ins );
false_idx = _FalseIndex( ins );
switch( ins->head.opcode ) {
case OP_BIT_TEST_TRUE:
high = MakeCondition( ins->head.opcode,
HighPart( left, high_class ),
HighPart( right, high_class ),
true_idx, NO_JUMP,
WORD );
low = MakeCondition( ins->head.opcode,
LowPart( left, low_class ),
LowPart( right, low_class ),
true_idx, false_idx,
WORD );
not_equal = NULL;
break;
case OP_BIT_TEST_FALSE:
high = MakeCondition( OP_BIT_TEST_TRUE,
HighPart( left, high_class ),
HighPart( right, high_class ),
false_idx, NO_JUMP,
WORD );
low = MakeCondition( ins->head.opcode,
LowPart( left, low_class ),
LowPart( right, low_class ),
true_idx, false_idx,
WORD );
not_equal = NULL;
break;
case OP_CMP_EQUAL:
high = MakeCondition( OP_CMP_NOT_EQUAL,
HighPart( left, high_class ),
HighPart( right, high_class ),
false_idx, NO_JUMP,
WORD );
low = MakeCondition( ins->head.opcode,
LowPart( left, low_class ),
LowPart( right, low_class ),
true_idx, false_idx,
WORD );
not_equal = NULL;
break;
case OP_CMP_NOT_EQUAL:
high = MakeCondition( OP_CMP_NOT_EQUAL,
HighPart( left, high_class ),
HighPart( right, high_class ),
true_idx, NO_JUMP,
WORD );
low = MakeCondition( ins->head.opcode,
LowPart( left, low_class ),
LowPart( right, low_class ),
true_idx, false_idx,
WORD );
not_equal = NULL;
break;
case OP_CMP_LESS:
case OP_CMP_LESS_EQUAL:
not_equal = MakeCondition( OP_CMP_NOT_EQUAL,
HighPart( left, high_class ),
HighPart( right, high_class ),
false_idx, NO_JUMP,
high_class );
if( high_class == WORD
&& right->n.class == N_CONSTANT
&& right->c.const_type == CONS_ABSOLUTE
&& HIGH_WORD( right ) == 0 ) {
high = NULL;
} else {
high = MakeCondition( OP_CMP_LESS,
not_equal->operands[ 0 ], not_equal->operands[ 1 ],
true_idx, NO_JUMP,
high_class );
}
low = MakeCondition( ins->head.opcode,
LowPart( left, low_class ),
LowPart( right, low_class ),
true_idx, false_idx,
low_class );
break;
case OP_CMP_GREATER_EQUAL:
case OP_CMP_GREATER:
not_equal = MakeCondition( OP_CMP_NOT_EQUAL,
HighPart( left, high_class ),
HighPart( right, high_class ),
false_idx, NO_JUMP,
high_class );
if( high_class == WORD
&& right->n.class == N_CONSTANT
&& right->c.const_type == CONS_ABSOLUTE
&& HIGH_WORD( right ) == 0 ) {
_SetBlockIndex( not_equal, true_idx, NO_JUMP );
high = NULL;
} else {
high = MakeCondition( OP_CMP_GREATER,
not_equal->operands[ 0 ], not_equal->operands[ 1 ],
true_idx, NO_JUMP,
high_class );
}
low = MakeCondition( ins->head.opcode,
LowPart( left, low_class ),
LowPart( right, low_class ),
true_idx, false_idx,
low_class );
break;
default:
break;
}
if( high != NULL ) {
/*
* 2005-04-06 RomanT (bug #407)
* I removed calls do DoNothing(), it seems ok, extra jumps are perfectly
* optimized out in other places of compiler. Calling DoNothing() on chain
* of conditions to reuse existing CC flags is ugly and causes unpredictable
* logical faults in other places.
*/
DupSeg( ins, high );
PrefixIns( ins, high );
} else {
high = not_equal; /* for return value*/
}
if( not_equal != NULL ) {
DupSeg( ins, not_equal );
PrefixIns( ins, not_equal );
}
DupSeg( ins, low );
ReplIns( ins, low );
return( high );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?