dbgexpr3.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 884 行 · 第 1/2 页
C
884 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Debugger expression handling, Part III (Type conversion).
*
****************************************************************************/
#include <string.h>
#include "dbgdefn.h"
#include "dbgstk.h"
#include "dbgerr.h"
#include "dbgtoggl.h"
#include "dbgitem.h"
#include "dbgmem.h"
#include "dbglit.h"
#include "ldsupp.h"
#include "mad.h"
#include "i64.h"
extern void RValue(stack_entry *);
extern void MoveTH( stack_entry *, stack_entry * );
extern bool AllocatedString( stack_entry * );
extern void LocationCreate( location_list *, location_type, void * );
extern address DefAddrSpaceForAddr( address );
extern unsigned DefaultSize( default_kind );
extern address NilAddr;
extern stack_entry *ExprSP;
typedef enum {
I1,
U1,
I2,
U2,
I4,
U4,
I8,
U8,
F4,
F8,
F10,
C8,
C16,
C20,
STR,
NP2,
NP4,
FP4,
FP6,
HP4,
ERR,
NUM_CLASSES
} conv_class;
conv_class ConvIdx( type_info *info )
{
unsigned size;
if( info->kind == TK_STRING ) return( STR );
if( info->size > sizeof( item_mach ) ) return( ERR );
size = info->size;
switch( info->kind ) {
case TK_BOOL:
case TK_ENUM:
case TK_CHAR:
case TK_INTEGER:
if( (info->modifier & TM_MOD_MASK) == TM_SIGNED ) {
switch( size ) {
case 1:
return( I1 );
case 2:
return( I2 );
case 4:
return( I4 );
case 8:
return( I8 );
}
} else {
switch( size ) {
case 1:
return( U1 );
case 2:
return( U2 );
case 4:
return( U4 );
case 8:
return( U8 );
}
}
break;
case TK_REAL:
switch( size ) {
case 4:
return( F4 );
case 8:
return( F8 );
case 10:
return( F10 );
}
break;
case TK_COMPLEX:
switch( size ) {
case 8:
return( C8 );
case 16:
return( C16 );
case 20:
return( C20 );
}
break;
case TK_POINTER:
case TK_ADDRESS:
switch( info->modifier & TM_MOD_MASK ) {
case TM_NEAR:
switch( size ) {
case 2:
return( NP2 );
case 4:
return( NP4 );
}
break;
case TM_FAR:
switch( size ) {
case 4:
return( FP4 );
case 6:
return( FP6 );
}
break;
case TM_HUGE:
switch( size ) {
case 4:
return( HP4 );
}
}
break;
}
return( ERR );
}
void FromItem( item_mach *tmp, stack_entry *entry )
{
unsigned size;
mad_type_info src_type;
mad_type_info dst_type;
type_info ti;
if( entry->info.size > sizeof( *tmp ) ) {
Error( ERR_NONE, LIT( ERR_TYPE_CONVERSION ) );
}
size = entry->info.size;
switch( entry->info.kind ) {
case TK_BOOL:
case TK_ENUM:
case TK_CHAR:
case TK_INTEGER:
MADTypeInfo( MADTypeForDIPType( &entry->info ), &src_type );
if( (entry->info.modifier & TM_MOD_MASK) == TM_SIGNED ) {
MADTypeInfoForHost( MTK_INTEGER, -sizeof( entry->v.sint ), &dst_type );
} else {
MADTypeInfoForHost( MTK_INTEGER, sizeof( entry->v.sint ), &dst_type );
}
MADTypeConvert( &src_type, tmp, &dst_type, &entry->v.uint, 0 );
return;
case TK_REAL:
MADTypeInfo( MADTypeForDIPType( &entry->info ), &src_type );
MADTypeInfoForHost( MTK_FLOAT, sizeof( entry->v.real ), &dst_type );
MADTypeConvert( &src_type, tmp, &dst_type, &entry->v.real, 0 );
return;
case TK_COMPLEX:
ti.kind = TK_REAL;
ti.size = entry->info.size / 2;
ti.modifier = entry->info.modifier;
MADTypeInfo( MADTypeForDIPType( &ti ), &src_type );
MADTypeInfoForHost( MTK_FLOAT, sizeof( entry->v.cmplx.re ), &dst_type );
MADTypeConvert( &src_type, tmp, &dst_type, &entry->v.cmplx.re, 0 );
MADTypeConvert( &src_type, (unsigned_8 *)tmp + ti.size, &dst_type, &entry->v.cmplx.im, 0 );
return;
case TK_POINTER:
case TK_ADDRESS:
//NYI: use MAD conversion routines....
switch( entry->info.modifier & TM_MOD_MASK ) {
case TM_NEAR:
switch( size ) {
case 2:
entry->v.addr.mach.offset = tmp->so;
return;
case 8:
//NYI: 64 bit offsets
entry->info.size = 4;
case 4:
entry->v.addr.mach.offset = tmp->lo;
return;
}
break;
case TM_FAR:
case TM_HUGE:
switch( size ) {
case 4:
entry->v.addr.sect_id = 0;
entry->v.addr.indirect = FALSE;
ConvAddr32ToAddr48( tmp->sa, entry->v.addr.mach );
return;
case 6:
entry->v.addr.sect_id = 0;
entry->v.addr.indirect = FALSE;
entry->v.addr.mach = tmp->la;
return;
case sizeof( address ):
/* it's an internal address symbol */
entry->v.addr = tmp->xa;
entry->info.size = 6;
return;
}
break;
}
break;
}
Error( ERR_NONE, LIT( ERR_TYPE_CONVERSION ) );
}
void ToItem( stack_entry *entry, item_mach *tmp )
{
unsigned size;
mad_type_info src_type;
mad_type_info dst_type;
if( entry->info.size > sizeof( *tmp ) ) {
Error( ERR_NONE, LIT( ERR_TYPE_CONVERSION ) );
}
//NYI: use MAD routines for all conversions
size = entry->info.size;
switch( entry->info.kind ) {
case TK_BOOL:
case TK_ENUM:
case TK_CHAR:
case TK_INTEGER:
MADTypeInfo( MADTypeForDIPType( &entry->info ), &dst_type );
if( (entry->info.modifier & TM_MOD_MASK) == TM_SIGNED ) {
MADTypeInfoForHost( MTK_INTEGER, -sizeof( entry->v.sint ), &src_type );
} else {
MADTypeInfoForHost( MTK_INTEGER, sizeof( entry->v.sint ), &src_type );
}
MADTypeConvert( &src_type, &entry->v.uint, &dst_type, tmp, 0 );
return;
case TK_REAL:
MADTypeInfo( MADTypeForDIPType( &entry->info ), &dst_type );
MADTypeInfoForHost( MTK_FLOAT, sizeof( entry->v.real ), &src_type );
MADTypeConvert( &src_type, &entry->v.real, &dst_type, tmp, 0 );
return;
case TK_COMPLEX:
switch( size ) {
case 8:
tmp->sc.re = LDToD( &entry->v.cmplx.re );
tmp->sc.im = LDToD( &entry->v.cmplx.im );
return;
case 16:
tmp->lc.re = LDToD( &entry->v.cmplx.re );
tmp->lc.im = LDToD( &entry->v.cmplx.im );
return;
case 20:
tmp->xc = entry->v.cmplx;
return;
}
break;
case TK_POINTER:
case TK_ADDRESS:
switch( entry->info.modifier & TM_MOD_MASK ) {
case TM_NEAR:
switch( size ) {
case 2:
tmp->so = entry->v.addr.mach.offset;
return;
case 4:
tmp->lo = entry->v.addr.mach.offset;
return;
case 8:
tmp->qo.u._32[I64LO32] = entry->v.addr.mach.offset;
tmp->qo.u._32[I64HI32] = 0;
}
break;
case TM_FAR:
case TM_HUGE:
switch( size ) {
case 4:
ConvAddr48ToAddr32( entry->v.addr.mach, tmp->sa );
return;
case 6:
tmp->la = entry->v.addr.mach;
return;
}
break;
}
break;
}
Error( ERR_NONE, LIT( ERR_TYPE_CONVERSION ) );
}
OVL_EXTERN bool ConvU8( stack_entry *entry, conv_class from )
{
unsigned_64 tmp;
switch( from ) {
case U1:
case U2:
case U4:
case U8:
tmp = entry->v.uint;
break;
case I1:
case I2:
case I4:
case I8:
tmp = entry->v.sint;
break;
case F4:
case F8:
case F10:
//NYI: 64-bit support
I32ToI64( LDToD( &entry->v.real ), &tmp );
break;
case C8:
case C16:
case C20:
I32ToI64( LDToD( &entry->v.cmplx.re ), &tmp );
break;
case NP2:
case NP4:
//NYI: 64-bit offsets
U32ToU64( entry->v.addr.mach.offset, &tmp );
break;
case FP4:
case HP4:
U32ToU64( entry->v.addr.mach.offset +
((long) entry->v.addr.mach.segment << 16), &tmp );
break;
case FP6:
U32ToU64( entry->v.addr.mach.offset, &tmp );
break;
default:
return( FALSE );
}
entry->v.uint = tmp;
return( TRUE );
}
OVL_EXTERN bool ConvU1( stack_entry *entry, conv_class from )
{
if( !ConvU8( entry, from ) ) return( FALSE );
U32ToU64( (unsigned_8)U32FetchTrunc( entry->v.uint ), &entry->v.uint );
return( TRUE );
}
OVL_EXTERN bool ConvU2( stack_entry *entry, conv_class from )
{
if( !ConvU8( entry, from ) ) return( FALSE );
U32ToU64( (unsigned_16)U32FetchTrunc( entry->v.uint ), &entry->v.uint );
return( TRUE );
}
OVL_EXTERN bool ConvU4( stack_entry *entry, conv_class from )
{
if( !ConvU8( entry, from ) ) return( FALSE );
U32ToU64( (unsigned_32)U32FetchTrunc( entry->v.uint ), &entry->v.uint );
return( TRUE );
}
OVL_EXTERN bool ConvI1( stack_entry *entry, conv_class from )
{
if( !ConvU8( entry, from ) ) return( FALSE );
I32ToI64( (signed_8)U32FetchTrunc( entry->v.uint ), &entry->v.sint );
return( TRUE );
}
OVL_EXTERN bool ConvI2( stack_entry *entry, conv_class from )
{
if( !ConvU8( entry, from ) ) return( FALSE );
I32ToI64( (signed_16)U32FetchTrunc( entry->v.uint ), &entry->v.sint );
return( TRUE );
}
OVL_EXTERN bool ConvI4( stack_entry *entry, conv_class from )
{
if( !ConvU8( entry, from ) ) return( FALSE );
I32ToI64( (signed_32)U32FetchTrunc( entry->v.uint ), &entry->v.sint );
return( TRUE );
}
OVL_EXTERN bool ConvI8( stack_entry *entry, conv_class from )
{
return( ConvU8( entry, from ) );
}
OVL_EXTERN bool ConvR10( stack_entry *entry, conv_class from )
{
xreal tmp;
switch( from ) {
case U1:
case U2:
case U4:
case U8:
//NYI: 64 bit support
DToLD( U32FetchTrunc( entry->v.uint ), &tmp );
break;
case I1:
case I2:
case I4:
case I8:
//NYI: 64 bit support
DToLD( I32FetchTrunc( entry->v.sint ), &tmp );
break;
case F4:
case F8:
case F10:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?