addrfold.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 681 行 · 第 1/2 页
C
681 行
static void AddIndex( an addr, name *index, name *addend ) {
/**************************************************************/
instruction *ins;
type_class_def class;
class = index->n.name_class;
if( class == XX ) class = addend->n.name_class; /* if index is a const ! */
ins = MakeBinary( OP_ADD, index, addend, AllocTemp( class ), class );
index = ins->result;
AddIns( ins );
addr->index = index;
}
extern bool CypAddrPlus( an l_addr, an r_addr, type_def *tipe ) {
/*******************************************************************/
mode_action action;
if( tipe->refno == T_HUGE_POINTER ) return( FALSE );
CheckPointer( l_addr );
if( l_addr->format == NF_NAME ) return( FALSE );
CheckPointer( r_addr );
if( r_addr->format == NF_NAME ) return( FALSE );
action = AddTable[ Idx[ r_addr->class ] ][ Idx[ l_addr->class ] ];
if( action == ADD_LA ) return( TRUE );
if( action == ADD_RA ) return( TRUE );
#if WORD_SIZE == 2
if( action == SHRNK_R ) return( TRUE );
if( action == SHRNK_L ) return( TRUE );
#else
if( action == XPAND_R ) return( TRUE );
if( action == XPAND_L ) return( TRUE );
#endif
return( FALSE );
}
static bool AddToTypeLength( type_length x, type_length y ) {
/*********************************************************************/
signed_32 lx,ly;
lx = x; ly = y;
x += y; lx += ly;
if( lx != x ) return( FALSE );
#if _TARGET & _TARG_370
if( lx < 0 || lx >= 4096 ) return( FALSE );
#endif
return( TRUE );
}
extern an AddrPlus( an l_addr, an r_addr, type_def *tipe ) {
/****************************************************************/
/* Returns NULL if code needs to be generated*/
mode_action action;
an addr;
CheckPointer( l_addr );
CheckPointer( r_addr );
if( !AddToTypeLength( l_addr->offset, r_addr->offset ) ) return( NULL );
if( l_addr->format == NF_NAME ) return( NULL );
if( r_addr->format == NF_NAME ) return( NULL );
if( tipe->refno == T_HUGE_POINTER ) return( NULL );
addr = NewAddrName();
for(;;) {
action = AddTable[ Idx[ r_addr->class ] ][ Idx[ l_addr->class ] ];
switch( action ) {
case UNEXPECTED:
AddrFree( addr );
return( NULL );
case TEMP_L:
LoadTempInt( l_addr );
break;
case TEMP_R:
LoadTempInt( r_addr );
break;
#if WORD_SIZE == 2
case SHRNK_L:
Convert( l_addr, I2 );
l_addr->class = CL_TEMP_OFFSET;
break;
case SHRNK_R:
Convert( r_addr, I2 );
r_addr->class = CL_TEMP_OFFSET;
break;
#endif
case XPAND_L:
Convert( l_addr, I4 );
l_addr->class = CL_VALUE4;
break;
case XPAND_R:
Convert( r_addr, I4 );
r_addr->class = CL_VALUE4;
break;
#if WORD_SIZE == 2
case XP_LC:
r_addr->offset += l_addr->offset;
l_addr->offset = 0;
Convert( l_addr, I4 );
l_addr->class = CL_VALUE4;
break;
case XP_RC:
l_addr->offset += r_addr->offset;
r_addr->offset = 0;
Convert( r_addr, I4 );
r_addr->class = CL_VALUE4;
break;
#endif
case IL:
MoveAddress( r_addr, addr );
addr->index = l_addr->u.name;
addr->offset += l_addr->offset;
FixIndexClass( addr );
break;
case IR:
MoveAddress( l_addr, addr );
addr->index = r_addr->u.name;
addr->offset += r_addr->offset;
FixIndexClass( addr );
break;
case ADD_LA:
MoveAddress( l_addr, addr );
addr->offset += r_addr->offset;
break;
case ADD_RA:
MoveAddress( r_addr, addr );
addr->offset += l_addr->offset;
break;
case ADD_LI:
if( PointLess( l_addr, r_addr ) ) {
AddrFree( addr );
return( NULL );
}
MoveAddress( l_addr, addr );
addr->offset += r_addr->offset;
AddIndex( addr, l_addr->index, r_addr->u.name );
break;
case ADD_RI:
if( PointLess( l_addr, r_addr ) ) {
AddrFree( addr );
return( NULL );
}
MoveAddress( r_addr, addr );
addr->offset += l_addr->offset;
AddIndex( addr, r_addr->index, l_addr->u.name );
break;
case ADD_I:
if( PointLess( l_addr, r_addr ) ) {
AddrFree( addr );
return( NULL );
}
addr->offset = l_addr->offset + r_addr->offset;
addr->class = CL_TEMP_OFFSET;
AddIndex( addr, l_addr->u.name, r_addr->u.name );
addr->u.name = addr->index;
addr->index = NULL;
break;
case CODE:
AddrFree( addr );
return( NULL );
}
if( _HaveMode( action ) ) break;
}
BGDone( l_addr );
BGDone( r_addr );
addr->tipe = tipe;
return( addr );
}
static bool ShiftConst( an r_addr ) {
/***************************************/
if( r_addr->format != NF_CONS ) return( FALSE );
if( r_addr->class != CL_CONS2 ) return( FALSE );
#if WORD_SIZE == 2
if( r_addr->offset < 0 || r_addr->offset > 16 ) return( FALSE );
if( _IsTargetModel( BIG_DATA ) && _IsntTargetModel( CHEAP_POINTER ) ) return( FALSE );
#else
if( r_addr->offset < 0 || r_addr->offset > 8 ) return( FALSE );
#endif
return( TRUE );
}
extern bool CypAddrShift( an l_addr, an r_addr, type_def *tipe ) {
/********************************************************************/
tipe = tipe;
CheckPointer( l_addr );
if( l_addr->format == NF_NAME ) return( FALSE );
if( l_addr->class != CL_TEMP_OFFSET ) return( FALSE );
if( l_addr->offset == 0 ) return( FALSE );
if( !ShiftConst( r_addr ) ) return( FALSE );
return( TRUE );
}
static bool ShiftToTypeLength( type_length x, unsigned_16 y ) {
/**********************************************/
signed_32 lx;
lx = x;
x <<= y; lx <<= y;
if( lx != x ) return( FALSE );
#if _TARGET & _TARG_370
if( lx < 0 || lx >= 4096 ) return( FALSE );
#endif
return( TRUE );
}
extern an AddrShift( an l_addr, an r_addr, type_def *tipe ) {
/*****************************************************************/
/* Returns NULL if code needs to be generated*/
instruction *ins;
signed_16 rv;
an addr;
type_class_def class;
addr = NULL;
if( !ShiftConst( r_addr ) ) return( NULL );
CheckPointer( l_addr );
if( l_addr->format == NF_NAME ) return( NULL );
if( l_addr->class != CL_TEMP_OFFSET ) return( NULL );
if( l_addr->offset == 0 ) return( NULL );
rv = r_addr->offset;
if( !ShiftToTypeLength( l_addr->offset, rv ) ) return( NULL );
addr = NewAddrName();
addr->offset = l_addr->offset << rv; /* new constant after shift*/
class = TypeClass( tipe );
ins = MakeBinary( OP_LSHIFT, l_addr->u.name,
AllocIntConst( rv ), AllocTemp( class ), class );
addr->u.name = ins->result;
AddIns( ins );
addr->class = CL_TEMP_OFFSET;
BGDone( l_addr );
BGDone( r_addr );
addr->tipe = tipe;
return( addr );
}
extern name *GetValue( an addr, name *suggest ) {
/***************************************************/
name *op;
instruction *ins;
InsToAddr( addr );
if( addr->format == NF_CONS || addr->format == NF_NAME ) {
op = addr->u.name;
} else if( addr->format == NF_ADDR ) {
switch( addr->class ) {
case CL_VALUE2:
case CL_VALUE4:
op = addr->u.name;
break;
case CL_TEMP_OFFSET:
if( addr->offset != 0 ) {
op = MaybeTemp( suggest, addr->u.name->n.name_class );
ins = MakeBinary( OP_ADD, addr->u.name,
AllocS32Const( addr->offset ),
op, TypeClass( addr->tipe ) );
if( addr->flags & ADDR_DEMOTED ) ins->ins_flags |= INS_DEMOTED;
AddIns( ins );
} else {
op = addr->u.name;
}
break;
case CL_ADDR_GLOBAL:
op = AllocMemory( addr->u.name->v.symbol,
addr->offset, addr->u.name->m.memory_type, XX );
op = LoadAddress( op, suggest, addr->tipe );
break;
case CL_ADDR_TEMP:
op = TempOffset( addr->u.name, addr->offset, XX );
op = LoadAddress( op, suggest, addr->tipe );
break;
case CL_GLOBAL_INDEX:
case CL_TEMP_INDEX:
op = AllocIndex( addr->index, addr->u.name,
addr->offset, XX );
op = LoadAddress( op, suggest, addr->tipe );
break;
case CL_POINTER:
op = AllocIndex( addr->index, addr->u.name,
addr->offset, XX );
op = LoadAddress( op, suggest, addr->tipe );
break;
default:
break;
}
} else if( addr->format == NF_BOOL ) {
_Zoiks( ZOIKS_025 );
}
if( op->n.class == N_TEMP
&& op->v.symbol == NULL
&& ( addr->flags & STACKABLE )
&& !( addr->flags & NEVER_STACK ) ) {
FPSetStack( op );
}
return( op );
}
extern name *AddrToName( an addr ) {
/**************************************/
name *op;
op = NULL;
if( addr->format == NF_CONS || addr->format == NF_NAME ) {
op = addr->u.name;
} else if( addr->format == NF_ADDR ) {
switch( addr->class ) {
case CL_VALUE2:
case CL_VALUE4:
op = addr->u.name;
break;
case CL_TEMP_OFFSET:
if( addr->offset == 0 ) {
op = addr->u.name;
}
break;
default:
break;
}
}
return( op );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?