rscsplit.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,383 行 · 第 1/4 页
C
1,383 行
}
ins2->table = CodeTable( ins2 );
new_ins->table = ins2->table;
ins->operands[0] = temp;
ins->operands[1] = temp;
PrefixIns( ins, new_ins );
PrefixIns( ins, ins2 );
ins2 = MakeMove( LowPart( temp, WORD ), LowPart( ins->result, WORD ), WORD );
PrefixIns( ins, ins2 );
ins2 = MakeMove( HighPart( temp, WORD ),
HighPart( ins->result, WORD ), WORD );
ReplIns( ins, ins2 );
} else {
HalfType( ins );
new_ins = MakeBinary( ins->head.opcode,
LowPart( ins->operands[0], ins->type_class ),
LowPart( ins->operands[1], ins->type_class ),
LowPart( ins->result, ins->type_class ),
ins->type_class );
ins->operands[0] = HighPart( ins->operands[0], ins->type_class );
ins->operands[1] = HighPart( ins->operands[1], ins->type_class );
ins->result = HighPart( ins->result, ins->type_class );
if( ins->head.opcode == OP_ADD ) {
ins->head.opcode = OP_EXT_ADD;
} else if( ins->head.opcode == OP_SUB ) {
ins->head.opcode = OP_EXT_SUB;
}
ins->table = CodeTable( ins );
new_ins->table = ins->table;
PrefixIns( ins, new_ins );
}
new_ins->ins_flags |= INS_CC_USED;
return( new_ins );
}
extern instruction *rSPLITMOVE( instruction *ins )
/*************************************************
* Split a multi-word move instruction.
*/
{
instruction *new_ins;
instruction *ins2;
name *temp;
CnvOpToInt( ins, 0 );
if( IndexOverlaps( ins, 0 ) ) {
temp = AllocTemp( LONG_WORD );
new_ins = MakeMove( LowPart( ins->operands[0], WORD ),
LowPart( temp, WORD ), WORD );
ins2 = MakeMove( HighPart( ins->operands[0], WORD ),
HighPart( temp, WORD ), WORD );
ins->operands[0] = temp;
PrefixIns( ins, new_ins );
PrefixIns( ins, ins2 );
ins2 = MakeMove( LowPart( temp, WORD ), LowPart( ins->result, WORD ), WORD );
PrefixIns( ins, ins2 );
ins2 = MakeMove( HighPart( temp, WORD ),
HighPart( ins->result, WORD ), WORD );
ReplIns( ins, ins2 );
} else {
HalfType( ins );
new_ins = MakeMove( LowPart( ins->operands[0], ins->type_class ),
LowPart( ins->result, ins->type_class ),
ins->type_class );
ins->operands[0] = HighPart( ins->operands[0], ins->type_class );
ins->result = HighPart( ins->result, ins->type_class );
if( new_ins->result->n.class == N_REGISTER
&& ins->operands[0]->n.class == N_REGISTER
&& HW_Ovlap( new_ins->result->r.reg, ins->operands[0]->r.reg ) ) {
SuffixIns( ins, new_ins );
new_ins = ins;
} else {
PrefixIns( ins, new_ins );
}
}
return( new_ins );
}
extern instruction *rSPLITNEG( instruction *ins )
/*****************************************************
* Split a multi-word negate instruction.
*/
{
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 );
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 *rSPLITUNARY( instruction *ins )
/*******************************************************
* Split a multi-word unary operation. Only valid for ops
* which can be split into two independent operations on
* constituent types (e.g. bitwise complement).
*/
{
instruction *new_ins;
name *high_res;
name *low_res;
CnvOpToInt( ins, 0 );
HalfType( ins );
if( ins->result == NULL ) {
high_res = NULL;
low_res = NULL;
} else {
high_res = HighPart( ins->result, ins->type_class );
low_res = LowPart( ins->result, ins->type_class );
}
new_ins = MakeUnary( ins->head.opcode,
LowPart( ins->operands[0], ins->type_class ),
low_res, ins->type_class );
ins->operands[0] = HighPart( ins->operands[0],ins->type_class );
ins->result = high_res;
if( ins->head.opcode == OP_PUSH ) {
SuffixIns( ins, new_ins );
new_ins = ins;
} else {
PrefixIns( ins, new_ins );
}
return( new_ins );
}
extern instruction *rCLRHI_4( instruction *ins )
/****************************************************
* Clear the high 32 bits of a 64-bit name
*/
{
name *high;
name *low;
instruction *new_ins;
type_class_def tipe;
tipe = HalfClass[ins->type_class];
low = LowPart( ins->result, tipe );
high = HighPart( ins->result, tipe );
ChangeType( ins, tipe );
ins->head.opcode = OP_MOV;
ins->result = low;
new_ins = MakeMove( AllocS32Const( 0 ), high, tipe );
PrefixIns( ins, new_ins );
return( new_ins );
}
extern instruction *rSEX_4TO8( instruction *ins )
/*****************************************************
* Sign-extend a 32-bit name to 64-bit
*/
{
instruction *ins1;
instruction *ins2;
name *high;
high = HighPart( ins->result, WD );
ins->result = LowPart( ins->result, WD );
ins->head.opcode = OP_MOV;
ins->type_class = WD;
ins->base_type_class = WD;
ins->table = NULL;
ins1 = MakeMove( ins->operands[0], high, WD );
SuffixIns( ins, ins1 );
ins2 = MakeBinary( OP_RSHIFT, high, AllocIntConst( 31 ), high, SW );
SuffixIns( ins1, ins2 );
return( ins );
}
extern instruction *rSPLITCMP( instruction *ins )
/*****************************************************
* Split a multi-word comparison instruction
*/
{
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 ) {
PrefixIns( ins, high );
} else {
high = not_equal; /* for return value */
}
if( not_equal != NULL ) {
PrefixIns( ins, not_equal );
}
ReplIns( ins, low );
return( high );
}
extern instruction *rMOVELOW( instruction *ins )
/****************************************************
* Move low part of a name, in other words chop off the
* high part (e.g. convert U8==>U4)
*/
{
ins->head.opcode = OP_MOV;
ins->operands[0] = LowPart( ins->operands[0], ins->type_class );
ins->table = NULL;
return( ins );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?