rscsplit.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,383 行 · 第 1/4 页
C
1,383 行
first_ins = ( ( prom_ins == NULL ) ? first_ins : prom_ins );
UpdateLive( first_ins, new_ins );
return( first_ins );
}
extern instruction *rPOPTOMOV( instruction *ins ) {
/******************************************************/
instruction *new_ins;
instruction *first_ins;
instruction *prom_ins;
name *stack_reg;
type_class_def push_class;
push_class = U8;
if( _IsFloating( ins->type_class ) ) {
push_class = FD;
}
prom_ins = PromoteOperand( ins );
stack_reg = AllocRegName( StackReg() );
first_ins = MakeMove( AllocIndex( stack_reg, NULL, 0, push_class ), ins->result, WD );
PrefixIns( ins, first_ins );
new_ins = MakeBinary( OP_ADD, stack_reg, AllocS32Const( TypeClassSize[ push_class ] ), stack_reg, push_class );
ReplIns( ins, new_ins );
first_ins = ( ( prom_ins == NULL ) ? first_ins : prom_ins );
UpdateLive( first_ins, new_ins );
return( first_ins );
}
static instruction *LoadFPConst( instruction *ins, name **constant ) {
/*************************************************************************/
name *temp_1;
name *temp_2;
name *mem;
instruction *first_ins;
instruction *last_ins;
temp_1 = AllocTemp( CP );
temp_2 = AllocTemp( ins->type_class );
mem = GenFloat( *constant, ins->type_class );
first_ins = MakeUnary( OP_LA, mem, temp_1, WD );
PrefixIns( ins, first_ins );
last_ins = MakeMove( AllocIndex( temp_1, NULL, 0, ins->type_class ), temp_2, ins->type_class );
PrefixIns( ins, last_ins );
*constant = temp_2;
UpdateLive( first_ins, ins );
return( first_ins );
}
extern instruction *rOP1CMEM( instruction *ins ) {
/*****************************************************/
ins = LoadFPConst( ins, &ins->operands[ 0 ] );
return( ins );
}
extern instruction *rOP2CMEM( instruction *ins ) {
/*****************************************************/
ins = LoadFPConst( ins, &ins->operands[ 1 ] );
return( ins );
}
extern instruction *rCHANGETYPE( instruction *ins ) {
/********************************************************/
type_class_def new;
assert( ins->type_class == XX );
switch( ins->operands[ 0 ]->n.size ) {
case 1:
new = U1;
break;
case 2:
new = U2;
break;
case 4:
new = U4;
break;
case 8:
new = U8;
break;
default:
new = U1;
_Zoiks( ZOIKS_120 );
}
ChangeType( ins, new );
return( ins );
}
static void UseAddress( name *op ) {
/**************************************/
name *next;
switch( op->n.class ) {
case N_TEMP:
next = op->t.alias;
for(;;) {
next->v.usage |= USE_ADDRESS;
if( next == op ) break;
next = next->t.alias;
}
break;
case N_MEMORY:
op->v.usage |= USE_ADDRESS;
break;
}
}
extern instruction *rMOVEXX( instruction *ins ) {
/****************************************************/
instruction *first_ins;
instruction *new_ins;
name *len;
name *reg_name;
label_handle lbl;
hw_reg_set all_regs;
hw_reg_set reg;
reg = FirstReg( RL_PARM_4 );
all_regs = reg;
reg_name = AllocRegName( reg );
first_ins = MakeUnary( OP_LA, ins->result, reg_name, CP );
PrefixIns( ins, first_ins );
UseAddress( ins->result );
reg = FirstReg( RL_PARM2_4 );
reg_name = AllocRegName( reg );
HW_TurnOn( all_regs, reg );
new_ins = MakeUnary( OP_LA, ins->operands[ 0 ], reg_name, CP );
PrefixIns( ins, new_ins );
UseAddress( ins->operands[ 0 ] );
len = AllocS32Const( ins->operands[ 0 ]->n.size );
reg = FirstReg( RL_PARM3_4 );
reg_name = AllocRegName( reg );
HW_TurnOn( all_regs, reg );
new_ins = MakeMove( len, reg_name, CP );
PrefixIns( ins, new_ins );
HW_TurnOn( all_regs, ReturnAddrReg() );
reg_name = AllocRegName( all_regs );
lbl = RTLabel( RT_MEMCPY );
new_ins = NewIns( 3 );
new_ins->head.opcode = OP_CALL;
new_ins->type_class = ins->type_class;
new_ins->operands[ CALL_OP_USED ] = reg_name;
new_ins->operands[ CALL_OP_USED2 ] = reg_name;
new_ins->operands[ CALL_OP_ADDR ]= AllocMemory( lbl, 0, CG_LBL,
ins->type_class );
HW_CTurnOn( all_regs, HW_FULL );
HW_TurnOff( all_regs, SavedRegs() );
HW_CTurnOff( all_regs, HW_UNUSED );
HW_TurnOn( all_regs, ReturnAddrReg() );
reg_name = AllocRegName( all_regs );
new_ins->result = NULL;
new_ins->num_operands = 2; /* special case for OP_CALL*/
HW_CTurnOn( all_regs, HW_FULL );
HW_TurnOff( all_regs, SavedRegs() );
HW_CTurnOff( all_regs, HW_UNUSED );
HW_TurnOn( all_regs, ReturnAddrReg() );
new_ins->zap = ®_name->r; /* all parm regs could be zapped*/
ReplIns( ins, new_ins );
UpdateLive( first_ins, new_ins );
return( first_ins );
}
extern name *TrimConst( name *c, type_class_def tipe ) {
/******************************************************************/
signed_32 value;
switch( tipe ) {
case U1:
value = (unsigned_8)c->c.int_value;
break;
case I1:
value = (signed_8)c->c.int_value;
break;
case U2:
value = (unsigned_16)c->c.int_value;
break;
case I2:
value = (signed_16)c->c.int_value;
break;
case U4:
case I4:
/* FIXME: int_value should be a 64-bit const for the Alpha
* and we should be doing the same thing here.
*/
default:
return( c );
}
if( value != c->c.int_value ) {
c = AllocS32Const( value );
}
return( c );
}
static instruction *doPromote( instruction *ins, type_class_def tipe ) {
/***************************************************************************/
instruction *op0_ins;
instruction *op1_ins;
instruction *last_ins;
name *t0;
name *t1;
t0 = AllocTemp( tipe );
if( ins->operands[ 0 ]->n.class == N_CONSTANT ) {
op0_ins = NULL;
ins->operands[ 0 ] = TrimConst( ins->operands[ 0 ], ins->type_class );
} else {
op0_ins = MakeConvert( ins->operands[ 0 ], t0, tipe, ins->type_class );
ins->operands[ 0 ] = t0;
PrefixIns( ins, op0_ins );
}
if( ins->operands[ 1 ]->n.class == N_CONSTANT ) {
op1_ins = NULL;
ins->operands[ 1 ] = TrimConst( ins->operands[ 1 ], ins->type_class );
} else {
t1 = AllocTemp( tipe );
op1_ins = MakeConvert( ins->operands[ 1 ], t1, tipe, ins->type_class );
ins->operands[ 1 ] = t1;
PrefixIns( ins, op1_ins );
}
last_ins = ins;
if( ins->result != NULL ) {
last_ins = MakeConvert( t0, ins->result, ins->type_class, tipe );
ins->result = t0;
SuffixIns( ins, last_ins );
}
ChangeType( ins, tipe );
if( op0_ins != NULL ) {
UpdateLive( op0_ins, last_ins );
return( op0_ins );
}
if( op1_ins != NULL ) {
UpdateLive( op1_ins, last_ins );
return( op1_ins );
}
return( ins );
}
extern instruction *rBIN2INT( instruction *ins ) {
/*****************************************************/
type_class_def new;
new = I4;
if( Unsigned[ ins->type_class ] == ins->type_class ) {
new = U4;
}
return( doPromote( ins, new ) );
}
extern instruction *rBIN2QUAD( instruction *ins ) {
/******************************************************/
type_class_def new;
new = I8;
if( Unsigned[ ins->type_class ] == ins->type_class ) {
new = U8;
}
return( doPromote( ins, new ) );
}
extern bool UnChangeable( instruction *ins ) {
/************************************************/
ins = ins;
return( FALSE );
}
extern name *Int64Equivalent( name *name )
/*********************************************
* Return a U64 equivalent of a double value
*/
{
constant_defn *defn;
unsigned_32 *low;
unsigned_32 *high;
defn = GetFloat( name, FD );
low = (unsigned_32 *)&defn->value[0];
high = (unsigned_32 *)&defn->value[2];
return( AllocU64Const( *low, *high ) );
}
extern name *LowPart( name *tosplit, type_class_def class )
/**************************************************************
* Return the low (of type 'class') part of name 'tosplit'
* Note: There may not be any need to support splitting to
* classes other than U4/I4 on RISC (assuming that registers are
* at least 32-bit).
*/
{
name *new;
signed_8 s8;
unsigned_8 u8;
signed_16 s16;
unsigned_16 u16;
unsigned_32 u32;
constant_defn *floatval;
switch( tosplit->n.class ) {
case N_CONSTANT:
if( tosplit->c.const_type == CONS_ABSOLUTE ) {
if( class == U1 ) {
u8 = tosplit->c.int_value & 0xff;
new = AllocUIntConst( u8 );
} else if( class == I1 ) {
s8 = tosplit->c.int_value & 0xff;
new = AllocIntConst( s8 );
} else if( class == U2 ) {
u16 = tosplit->c.int_value & 0xffff;
new = AllocUIntConst( u16 );
} else if( class == I2 ) {
s16 = tosplit->c.int_value & 0xffff;
new = AllocIntConst( s16 );
} else if( class == I4 ) {
new = AllocS32Const( tosplit->c.int_value );
} else if( class == U4 ) {
new = AllocUIntConst( tosplit->c.int_value );
} else if( class == FL ) {
_Zoiks( ZOIKS_129 );
} else { /* FD */
floatval = GetFloat( tosplit, FD );
u32 = (unsigned_32)floatval->value[1] << 16;
u32 += floatval->value[0];
new = AllocConst( CFCnvU32F( _TargetLongInt( u32 ) ) );
}
#if 0
} else if( tosplit->c.const_type == CONS_ADDRESS ) {
new = AddrConst( tosplit->c.value,
tosplit->c.int_value, CONS_OFFSET );
#endif
} else {
_Zoiks( ZOIKS_044 );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?