dbgexpr3.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 884 行 · 第 1/2 页
C
884 行
tmp = entry->v.real;
break;
case C8:
case C16:
case C20:
tmp = entry->v.cmplx.re;
break;
default:
return( FALSE );
}
entry->v.real = tmp;
return( TRUE );
}
OVL_EXTERN bool ConvR4( stack_entry *entry, conv_class from )
{
if( !ConvR10( entry, from ) ) return( FALSE );
DToLD( (float)LDToD( &entry->v.real ), &entry->v.real );
return( TRUE );
}
OVL_EXTERN bool ConvR8( stack_entry *entry, conv_class from )
{
if( !ConvR10( entry, from ) ) return( FALSE );
DToLD( (double)LDToD( &entry->v.real ), &entry->v.real );
return( TRUE );
}
OVL_EXTERN bool ConvC20( stack_entry *entry, conv_class from )
{
xcomplex tmp;
DToLD( 0.0, &tmp.im );
switch( from ) {
case U1:
case U2:
case U4:
case U8:
//NYI: 64 bit support
DToLD( U32FetchTrunc( entry->v.uint ), &tmp.re );
break;
case I1:
case I2:
case I4:
case I8:
DToLD( I32FetchTrunc( entry->v.sint ), &tmp.re );
break;
case F4:
case F8:
case F10:
tmp.re = entry->v.real;
break;
case C8:
case C16:
case C20:
tmp = entry->v.cmplx;
break;
default:
return( FALSE );
}
entry->v.cmplx = tmp;
return( TRUE );
}
OVL_EXTERN bool ConvC8( stack_entry *entry, conv_class from )
{
if( !ConvC20( entry, from ) ) return( FALSE );
DToLD( (float)LDToD( &entry->v.cmplx.re ), &entry->v.cmplx.re );
DToLD( (float)LDToD( &entry->v.cmplx.im ), &entry->v.cmplx.im );
return( TRUE );
}
OVL_EXTERN bool ConvC16( stack_entry *entry, conv_class from )
{
if( !ConvC20( entry, from ) ) return( FALSE );
DToLD( (double)LDToD( &entry->v.cmplx.re ), &entry->v.cmplx.re );
DToLD( (double)LDToD( &entry->v.cmplx.im ), &entry->v.cmplx.im );
return( TRUE );
}
OVL_EXTERN bool ConvNP4( stack_entry *entry, conv_class from )
{
addr48_off tmp;
switch( from ) {
case U1:
case U2:
case U4:
case U8:
//NYI: 64 bit offsets
tmp = U32FetchTrunc( entry->v.uint );
break;
case I1:
case I2:
case I4:
case I8:
//NYI: 64 bit offsets
tmp = I32FetchTrunc( entry->v.sint );
break;
case NP2:
case NP4:
case FP4:
case FP6:
tmp = entry->v.addr.mach.offset;
break;
default:
return( FALSE );
}
if( (entry->flags & SF_CONST) && tmp == 0 ) {
entry->v.addr = NilAddr;
} else {
entry->v.addr = DefAddrSpaceForAddr( Context.execution );
}
entry->v.addr.mach.offset = tmp;
return( TRUE );
}
OVL_EXTERN bool ConvNP2( stack_entry *entry, conv_class from )
{
if( !ConvNP4( entry, from ) ) return( FALSE );
entry->v.addr.mach.offset = (addr32_off)entry->v.addr.mach.offset;
return( TRUE );
}
OVL_EXTERN bool ConvFP6( stack_entry *entry, conv_class from )
{
address tmp;
tmp = DefAddrSpaceForAddr( Context.execution );
switch( from ) {
case U1:
case U2:
case U4:
case U8:
if( (entry->flags & SF_CONST) && U64Test( &entry->v.uint ) == 0 ) tmp = NilAddr;
//NYI: 64 bit offsets
tmp.mach.offset = U32FetchTrunc( entry->v.uint );
break;
case I1:
case I2:
case I4:
case I8:
if( (entry->flags & SF_CONST) && I64Test( &entry->v.sint ) == 0 ) tmp = NilAddr;
//NYI: 64 bit offsets
tmp.mach.offset = U32FetchTrunc( entry->v.sint );
break;
case NP2:
case NP4:
/* near pointers already have correct segment information filled in */
tmp = entry->v.addr;
break;
case FP4:
case FP6:
case HP4:
tmp = entry->v.addr;
break;
default:
return( FALSE );
}
entry->v.addr = tmp;
return( TRUE );
}
OVL_EXTERN bool ConvFP4( stack_entry *entry, conv_class from )
{
if( !ConvFP6( entry, from ) ) return( FALSE );
entry->v.addr.mach.offset = (addr32_off)entry->v.addr.mach.offset;
return( TRUE );
}
OVL_EXTERN bool ConvSTR( stack_entry *entry, conv_class from )
{
entry = entry;
from = from;
/* everything has already been taken care of */
return( TRUE );
}
OVL_EXTERN bool ConvERR( stack_entry *entry, conv_class from )
{
entry = entry;
from = from;
return( FALSE );
}
static bool (* const ConvFunc[])( stack_entry *, conv_class ) = {
ConvI1,
ConvU1,
ConvI2,
ConvU2,
ConvI4,
ConvU4,
ConvI8,
ConvU8,
ConvR4,
ConvR8,
ConvR10,
ConvC8,
ConvC16,
ConvC20,
ConvSTR,
ConvNP2,
ConvNP4,
ConvFP4,
ConvFP6,
ConvFP4, /* HP4 */
ConvERR
};
/*
* ConvertTo -- convert 'entry' to the given 'class'.
* 'entry' should be an rvalue.
*/
void ConvertTo( stack_entry *entry, type_kind k, type_modifier m, unsigned s )
{
conv_class from;
char *dest;
if( s == 0 && k == TK_INTEGER ) {
s = DefaultSize( DK_INT );
}
if( entry->info.kind == k
&& entry->info.modifier == m
&& entry->info.size == s ) return;
from = ConvIdx( &entry->info );
switch( from ) {
case U1:
U32ToU64( U8FetchTrunc( entry->v.uint ), &entry->v.uint );
break;
case U2:
U32ToU64( U16FetchTrunc( entry->v.uint ), &entry->v.uint );
break;
case U4:
U32ToU64( U32FetchTrunc( entry->v.uint ), &entry->v.uint );
break;
case I1:
I32ToI64( I8FetchTrunc( entry->v.uint ), &entry->v.uint );
break;
case I2:
I32ToI64( I16FetchTrunc( entry->v.uint ), &entry->v.uint );
break;
case I4:
I32ToI64( I32FetchTrunc( entry->v.uint ), &entry->v.uint );
break;
case F4:
DToLD( (float)LDToD( &entry->v.real ), &entry->v.real );
break;
case F8:
DToLD( (double)LDToD( &entry->v.real ), &entry->v.real );
break;
case C8:
DToLD( (float)LDToD( &entry->v.cmplx.re ), &entry->v.cmplx.re );
DToLD( (float)LDToD( &entry->v.cmplx.im ), &entry->v.cmplx.im );
break;
case C16:
DToLD( (double)LDToD( &entry->v.cmplx.re ), &entry->v.cmplx.re );
DToLD( (double)LDToD( &entry->v.cmplx.im ), &entry->v.cmplx.im );
break;
case NP2:
case FP4:
entry->v.addr.mach.offset &= 0xffff;
break;
case STR:
if( k != TK_STRING ) {
Error( ERR_NONE, LIT( ERR_TYPE_CONVERSION ) );
}
if( s > entry->info.size ) {
/* have to expand string */
_ChkAlloc( dest, s, LIT( ERR_NO_MEMORY_FOR_EXPR ) );
memcpy( dest, entry->v.string.loc.e[0].u.p, entry->info.size );
memset( &dest[entry->info.size], ' ', s - entry->info.size );
if( AllocatedString( entry ) ) {
_Free( entry->v.string.allocated );
}
entry->v.string.allocated = dest;
LocationCreate( &entry->v.string.loc, LT_INTERNAL, dest );
}
break;
default:
break;
}
entry->info.kind = k;
entry->info.modifier = m;
entry->info.size = s;
if( !ConvFunc[ ConvIdx( &entry->info ) ]( entry, from ) ) {
Error( ERR_NONE, LIT( ERR_TYPE_CONVERSION ) );
}
entry->th = NULL;
}
static conv_class BinResult[NUM_CLASSES][NUM_CLASSES] = {
/* I1 U1 I2 U2 I4 U4 I8 U8 F4 F8 F10 C8 C16 C20 STR NP2 NP4 FP4 FP6 HP4*/
/* I1 */ { I1, U1, I2, U2, I4, U4, I8, U8, F4, F8, F10,C8, C16,C20,ERR,NP2,NP4,FP4,FP6,HP4},
/* U1 */ { U1, U1, I2, U2, I4, U4, I8, U8, F4, F8, F10,C8, C16,C20,ERR,NP2,NP4,FP4,FP6,HP4},
/* I2 */ { I2, I2, I2, U2, I4, U4, I8, U8, F4, F8, F10,C8, C16,C20,ERR,NP2,NP4,FP4,FP6,HP4},
/* U2 */ { U2, U2, U2, U2, I4, U4, I8, U8, F4, F8, F10,C8, C16,C20,ERR,NP2,NP4,FP4,FP6,HP4},
/* I4 */ { I4, I4, I4, I4, I4, U4, I8, U8, F4, F8, F10,C8, C16,C20,ERR,NP2,NP4,FP4,FP6,HP4},
/* U4 */ { U4, U4, U4, U4, U4, U4, I8, U8, F4, F8, F10,C8, C16,C20,ERR,NP2,NP4,FP4,FP6,HP4},
/* I8 */ { I8, I8, I8, I8, I8, U8, I8, U8, F8, F8, F10,C8, C16,C20,ERR,NP2,NP4,FP4,FP6,HP4},
/* U8 */ { U8, U8, U8, U8, U8, U8, I8, U8, F8, F8, F10,C8, C16,C20,ERR,NP2,NP4,FP4,FP6,HP4},
/* F4 */ { F4, F4, F4, F4, F4, F4, F8, F8, F4, F8, F10,C8, C16,C20,ERR,ERR,ERR,ERR,ERR,ERR},
/* F8 */ { F8, F8, F8, F8, F8, F8, F8, F8, F8, F8, F10,C16,C16,C20,ERR,ERR,ERR,ERR,ERR,ERR},
/* F10*/ { F8, F8, F8, F8, F8, F8, F8, F8, F8, F8, F10,C20,C20,C20,ERR,ERR,ERR,ERR,ERR,ERR},
/* C8 */ { C8, C8, C8, C8, C8, C8, C16,C16,C8, C16,C20,C8, C16,C20,ERR,ERR,ERR,ERR,ERR,ERR},
/* C16*/ { C16,C16,C16,C16,C16,C16,C16,C16,C16,C16,C20,C16,C16,C20,ERR,ERR,ERR,ERR,ERR,ERR},
/* C20*/ { C20,C20,C20,C20,C20,C20,C20,C20,C20,C20,C20,C20,C20,C20,ERR,ERR,ERR,ERR,ERR,ERR},
/* STR*/ { ERR,ERR,ERR,ERR,ERR,ERR,ERR,ERR,ERR,ERR,ERR,ERR,ERR,STR,ERR,ERR,ERR,ERR,ERR,ERR},
/* NP2*/ { NP2,NP2,NP2,NP2,NP2,NP2,NP2,NP2,ERR,ERR,ERR,ERR,ERR,ERR,ERR,NP2,NP4,FP4,FP6,HP4},
/* NP4*/ { NP4,NP4,NP4,NP4,NP4,NP4,NP4,NP4,ERR,ERR,ERR,ERR,ERR,ERR,ERR,NP4,NP4,FP4,FP6,HP4},
/* FP4*/ { FP4,FP4,FP4,FP4,FP4,FP4,FP4,FP4,ERR,ERR,ERR,ERR,ERR,ERR,ERR,FP4,FP4,FP4,FP6,HP4},
/* FP6*/ { FP6,FP6,FP4,FP6,FP6,FP6,FP6,FP6,ERR,ERR,ERR,ERR,ERR,ERR,ERR,FP6,FP6,FP6,FP6,FP6},
/* HP4*/ { HP4,HP4,HP4,HP4,HP4,HP4,HP4,HP4,ERR,ERR,ERR,ERR,ERR,ERR,ERR,HP4,HP4,HP4,FP6,HP4}
};
static type_info ResultInfo[] = {
{ 1, TK_INTEGER, TM_SIGNED },
{ 1, TK_INTEGER, TM_UNSIGNED },
{ 2, TK_INTEGER, TM_SIGNED },
{ 2, TK_INTEGER, TM_UNSIGNED },
{ 4, TK_INTEGER, TM_SIGNED },
{ 4, TK_INTEGER, TM_UNSIGNED },
{ 8, TK_INTEGER, TM_SIGNED },
{ 8, TK_INTEGER, TM_UNSIGNED },
{ 4, TK_REAL, TM_NONE },
{ 8, TK_REAL, TM_NONE },
{ 10, TK_REAL, TM_NONE },
{ 8, TK_COMPLEX, TM_NONE },
{ 16, TK_COMPLEX, TM_NONE },
{ 20, TK_COMPLEX, TM_NONE },
{ 0, TK_STRING, TM_NONE },
{ 2, TK_POINTER, TM_NEAR },
{ 4, TK_POINTER, TM_NEAR },
{ 4, TK_POINTER, TM_FAR },
{ 6, TK_POINTER, TM_FAR },
{ 4, TK_POINTER, TM_HUGE },
};
static void DoBinOp( stack_entry *left, stack_entry *right )
{
conv_class lclass;
conv_class rclass;
conv_class result_class;
type_info *result_info;
bool promote_left;
lclass = ConvIdx( &left->info );
rclass = ConvIdx( &right->info );
if( lclass == ERR || rclass == ERR ) {
Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
}
result_class = BinResult[ lclass ][ rclass ];
if( result_class == ERR ) {
Error( ERR_NONE, LIT( ERR_TYPE_CONVERSION ) );
}
if( left->info.kind == TK_ENUM ) {
result_info = &left->info;
} else if( right->info.kind == TK_ENUM ) {
result_info = &right->info;
} else {
result_info = &ResultInfo[ result_class ];
}
promote_left = FALSE;
if( lclass != result_class ) {
promote_left = TRUE;
ConvertTo( left, result_info->kind,
result_info->modifier, result_info->size );
}
if( rclass != result_class ) {
ConvertTo( right, result_info->kind,
result_info->modifier, result_info->size );
}
/* set up result type in left operand */
if( left->th != NULL && right->th != NULL ) {
/* if left side was promoted, use right's type. otherwise use left's */
if( promote_left ) {
MoveTH( right, left );
}
} else if( right->th != NULL ) {
MoveTH( right, left );
/* else use left->type */
}
}
void BinOp( stack_entry *left, stack_entry *right )
{
RValue( left );
RValue( right );
DoBinOp( left, right );
}
void AddOp( stack_entry *left, stack_entry *right )
{
switch( left->info.kind ) {
case TK_POINTER:
case TK_ADDRESS:
break;
default:
DoBinOp( left, right );
}
}
void ToItemMAD( stack_entry *entry, item_mach *tmp, mad_type_info *mti )
{
unsigned bytes;
mad_type_info src;
bytes = mti->b.bits / BITS_PER_BYTE;
switch( mti->b.kind ) {
case MTK_INTEGER:
ConvertTo( entry, TK_INTEGER, TM_UNSIGNED, bytes );
MADTypeInfoForHost( MTK_INTEGER, sizeof( entry->v.uint ), &src );
break;
case MTK_ADDRESS:
if( mti->a.seg.bits == 0 ) {
ConvertTo( entry, TK_ADDRESS, TM_NEAR, bytes );
MADTypeInfoForHost( MTK_ADDRESS, sizeof( entry->v.addr.mach.offset ), &src );
} else {
ConvertTo( entry, TK_ADDRESS, TM_FAR, bytes );
MADTypeInfoForHost( MTK_ADDRESS, sizeof( entry->v.addr.mach ), &src );
}
break;
case MTK_FLOAT:
ConvertTo( entry, TK_REAL, TM_NONE, bytes );
MADTypeInfoForHost( MTK_FLOAT, sizeof( entry->v.real ), &src );
break;
case MTK_XMM:
//MAD: nyi
ToItem( entry, tmp );
return;
case MTK_CUSTOM:
//MAD: nyi
ToItem( entry, tmp );
return;
}
if( MADTypeConvert( &src, &entry->v, mti, tmp, 0 ) != MS_OK ) {
ToItem( entry, tmp );
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?