dbgexpr4.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,355 行 · 第 1/3 页
C
1,355 行
/****************************************************************************
*
* 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 IV (Arithmetic).
*
****************************************************************************/
#include <string.h>
#include "dbglit.h"
#include "dbgdefn.h"
#include "dbgtoken.h"
#include "dbgstk.h"
#include "dbgerr.h"
#include "dbgmem.h"
#include "dbgtoggl.h"
#include "dbgitem.h"
#include "dbgtback.h"
#include "dbgri.h"
#include "ldsupp.h"
#include "mad.h"
#include "i64.h"
extern void BinOp( stack_entry *, stack_entry * );
extern void AddOp( stack_entry *, stack_entry * );
extern address AddrAdd( address, long );
extern int AddrComp( address, address );
extern long AddrDiff( address, address );
extern bool NameResolve( stack_entry *, bool );
extern void SymResolve( stack_entry *entry );
extern void RValue( stack_entry * );
extern void LRValue( stack_entry * );
extern void LValue( stack_entry * );
extern void ExprResolve( stack_entry * );
extern void ConvertTo( stack_entry *, type_kind, type_modifier, unsigned );
extern void ClassifyEntry( stack_entry *, type_info * );
extern bool ClassifyType( location_context *, type_handle *, type_info * );
extern void LclLValue( stack_entry * );
extern void FreezeRegs( void );
extern bool PerformCall( address, bool, unsigned int );
extern void UnFreezeRegs( void );
extern void SetRegSP( address );
extern void CreateEntry( void );
extern void DeleteEntry( stack_entry * );
extern stack_entry *StkEntry( int );
extern void MoveSP( int );
extern void SwapStack( int );
extern char *DupStringEntry( char *, unsigned long );
extern void PushType( type_handle * );
extern void FreePgmStack( bool );
extern void RtnRetValSetup( sym_handle *, unsigned long, address * );
extern void RtnRetValGet( sym_handle *, unsigned long, address * );
extern unsigned ToItem( stack_entry *, item_mach * );
extern void CombineEntries( stack_entry *, stack_entry *, stack_entry * );
extern void PushAddr( address );
extern void MoveTH( stack_entry *, stack_entry * );
extern bool CreateSym( lookup_item *, type_info * );
extern dip_status LocationAssign( location_list *, location_list *, unsigned long, bool );
extern void LocationCreate( location_list *, location_type, void * );
extern void LocationAdd( location_list *, unsigned long );
extern void ExprSymbol( stack_entry *, sym_handle * );
extern void CreateLC( stack_entry * );
extern void MoveLC( stack_entry *, stack_entry * );
extern address DefAddrSpaceForAddr( address );
extern address GetRegSP( void );
extern void SetRegSP( address );
extern void ExprSetAddrInfo( stack_entry *, bool );
extern void AddrFix( address * );
extern void PushLocation( location_list *, type_info * );
extern unsigned DefaultSize( default_kind );
extern void GetMADTypeDefaultAt( address, mad_type_kind, mad_type_info * );
extern stack_entry *ExprSP;
extern unsigned NestedCallLevel;
extern int PgmStackUsage[ MAX_NESTED_CALL ];
extern address NilAddr;
/*
* DoPlus - add two stack entries
*/
void DoPlus( void )
{
stack_entry *left;
left = StkEntry( 1 );
LRValue( left );
RValue( ExprSP );
switch( ExprSP->info.kind ) {
case TK_POINTER:
case TK_ADDRESS:
/* get the pointer as the left operand */
left = ExprSP;
SwapStack( 1 );
}
AddOp( left, ExprSP );
switch( left->info.kind ) {
case TK_BOOL:
case TK_ENUM:
case TK_CHAR:
case TK_INTEGER:
U64Add( &left->v.uint, &ExprSP->v.uint, &left->v.uint );
break;
case TK_POINTER:
case TK_ADDRESS:
switch( ExprSP->info.kind ) {
case TK_BOOL:
case TK_ENUM:
case TK_CHAR:
case TK_INTEGER:
break;
default:
Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
}
if( (left->info.modifier & TM_MOD_MASK) == TM_NEAR ) {
//NYI: 64 bit offsets
left->v.addr.mach.offset += U32FetchTrunc( ExprSP->v.uint );
} else {
//NYI: 64 bit offsets
left->v.addr = AddrAdd( left->v.addr, U32FetchTrunc( ExprSP->v.uint ) );
}
break;
case TK_REAL:
LDAdd( &left->v.real, &ExprSP->v.real, &left->v.real );
break;
case TK_COMPLEX:
LDAdd( &left->v.cmplx.re, &ExprSP->v.cmplx.re, &left->v.cmplx.re );
LDAdd( &left->v.cmplx.im, &ExprSP->v.cmplx.im, &left->v.cmplx.im );
break;
default:
Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
break;
}
CombineEntries( left, left, ExprSP );
}
/*
* DoMinus - subtract two stack entries
*/
void DoMinus( void )
{
stack_entry *left;
left = StkEntry( 1 );
LRValue( left );
RValue( ExprSP );
AddOp( left, ExprSP );
switch( left->info.kind ) {
case TK_BOOL:
case TK_ENUM:
case TK_CHAR:
case TK_INTEGER:
U64Sub( &left->v.uint, &ExprSP->v.uint, &left->v.uint );
left->info.modifier = TM_SIGNED;
break;
case TK_POINTER:
case TK_ADDRESS:
switch( ExprSP->info.kind ) {
case TK_BOOL:
case TK_CHAR:
case TK_ENUM:
case TK_INTEGER:
//NYI: 64 bit offsets
left->v.addr = AddrAdd( left->v.addr, -U32FetchTrunc( ExprSP->v.uint ) );
break;
case TK_POINTER:
case TK_ADDRESS:
I32ToI64( AddrDiff( left->v.addr, ExprSP->v.addr ), &left->v.sint );
left->info.kind = TK_INTEGER;
left->info.modifier = TM_SIGNED;
left->info.size = sizeof( signed_64 );
left->th = NULL;
break;
default:
Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
}
break;
case TK_REAL:
LDSub( &left->v.real, &ExprSP->v.real, &left->v.real );
break;
case TK_COMPLEX:
LDSub( &left->v.cmplx.re, &ExprSP->v.cmplx.re, &left->v.cmplx.re );
LDSub( &left->v.cmplx.im, &ExprSP->v.cmplx.im, &left->v.cmplx.im );
break;
default:
Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
break;
}
CombineEntries( left, left, ExprSP );
}
/*
* DoMul - multiply two stack entries
*/
void DoMul( void )
{
stack_entry *left;
xreal re, im, t1, t2;
left = StkEntry( 1 );
BinOp( left, ExprSP );
switch( left->info.kind ) {
case TK_BOOL:
case TK_ENUM:
case TK_CHAR:
case TK_INTEGER:
U64Mul( &left->v.uint, &ExprSP->v.uint, &left->v.uint );
break;
case TK_REAL:
LDMul( &left->v.real, &ExprSP->v.real, &left->v.real );
break;
case TK_COMPLEX:
/* (a,b) * (c,d) = (ac-bd,ad+bc) */
LDMul( &left->v.cmplx.re, &ExprSP->v.cmplx.re, &t1 );
LDMul( &left->v.cmplx.im, &ExprSP->v.cmplx.im, &t2 );
LDSub( &t1, &t2, &re );
LDMul( &left->v.cmplx.re, &ExprSP->v.cmplx.im, &t1 );
LDMul( &left->v.cmplx.im, &ExprSP->v.cmplx.re, &t2 );
LDAdd( &t1, &t2, &im );
left->v.cmplx.re = re;
left->v.cmplx.im = im;
break;
default:
Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
break;
}
CombineEntries( left, left, ExprSP );
}
/*
* DoDiv - divide two stack entries
*/
void DoDiv( void )
{
stack_entry *left;
xreal re, im, mag, t1, t2;
left = StkEntry( 1 );
BinOp( left, ExprSP );
switch( left->info.kind ) {
case TK_BOOL:
case TK_ENUM:
case TK_CHAR:
case TK_INTEGER:
if( U64Test( &ExprSP->v.uint ) == 0 ) {
Error( ERR_NONE, LIT( ERR_ZERO_DIV ) );
}
if( (left->info.modifier & TM_MOD_MASK) == TM_UNSIGNED ) {
U64Div( &left->v.uint, &ExprSP->v.uint, &left->v.uint, NULL );
} else {
I64Div( &left->v.sint, &ExprSP->v.sint, &left->v.sint, NULL );
}
break;
case TK_REAL:
DToLD( 0.0, &t1 );
if( LDCmp( &ExprSP->v.real, &t1 ) == 0 ) {
Error( ERR_NONE, LIT( ERR_ZERO_DIV ) );
}
LDDiv( &left->v.real, &ExprSP->v.real, &left->v.real );
break;
case TK_COMPLEX:
DToLD( 0.0, &t1 );
if( LDCmp( &ExprSP->v.cmplx.re, &t1 ) == 0
&& LDCmp( &ExprSP->v.cmplx.im, &t1 ) == 0 ) {
Error( ERR_NONE, LIT( ERR_ZERO_DIV ) );
}
/* (a,b)/(c,d) = (ac+bd,bc-ad) / (c^2+d^2) */
LDMul( &ExprSP->v.cmplx.re, &ExprSP->v.cmplx.re, &t1 );
LDMul( &ExprSP->v.cmplx.im, &ExprSP->v.cmplx.im, &t2 );
LDAdd( &t1, &t2, &mag );
LDMul( &left->v.cmplx.re, &ExprSP->v.cmplx.re, &t1 );
LDMul( &left->v.cmplx.im, &ExprSP->v.cmplx.im, &t2 );
LDAdd( &t1, &t2, &re );
LDMul( &left->v.cmplx.im, &ExprSP->v.cmplx.re, &t1 );
LDMul( &left->v.cmplx.re, &ExprSP->v.cmplx.im, &t2 );
LDSub( &t1, &t2, &im );
LDDiv( &re, &mag, &left->v.cmplx.re );
LDDiv( &im, &mag, &left->v.cmplx.im );
break;
default:
Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
break;
}
CombineEntries( left, left, ExprSP );
}
/*
* DoMod - calculate modulus of two stack entries
*/
void DoMod( void )
{
stack_entry *left;
union {
signed_64 s;
unsigned_64 u;
} dummy;
left = StkEntry( 1 );
BinOp( left, ExprSP );
switch( left->info.kind ) {
case TK_BOOL:
case TK_ENUM:
case TK_CHAR:
case TK_INTEGER:
if( U64Test( &ExprSP->v.uint ) == 0 ) {
Error( ERR_NONE, LIT( ERR_ZERO_MOD ) );
}
if( (left->info.modifier & TM_MOD_MASK) == TM_UNSIGNED ) {
U64Div( &left->v.uint, &ExprSP->v.uint, &dummy.u, &left->v.uint );
} else {
I64Div( &left->v.sint, &ExprSP->v.sint, &dummy.s, &left->v.sint );
}
break;
default:
Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
break;
}
CombineEntries( left, left, ExprSP );
}
/*
* DoAnd - AND two stack entries
*/
void DoAnd( void )
{
stack_entry *left;
left = StkEntry( 1 );
BinOp( left, ExprSP );
switch( left->info.kind ) {
case TK_BOOL:
case TK_ENUM:
case TK_CHAR:
case TK_INTEGER:
U64And( &left->v.uint, &ExprSP->v.uint, &left->v.uint );
break;
default:
Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
break;
}
CombineEntries( left, left, ExprSP );
}
/*
* DoOr - OR two stack entries
*/
void DoOr( void )
{
stack_entry *left;
left = StkEntry( 1 );
BinOp( left, ExprSP );
switch( left->info.kind ) {
case TK_BOOL:
case TK_ENUM:
case TK_CHAR:
case TK_INTEGER:
U64Or( &left->v.uint, &ExprSP->v.uint, &left->v.uint );
break;
default:
Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
break;
}
CombineEntries( left, left, ExprSP );
}
/*
* DoXor - XOR two stack entries
*/
void DoXor( void )
{
stack_entry *left;
left = StkEntry( 1 );
BinOp( left, ExprSP );
switch( left->info.kind ) {
case TK_BOOL:
case TK_ENUM:
case TK_CHAR:
case TK_INTEGER:
U64Xor( &left->v.uint, &ExprSP->v.uint, &left->v.uint );
break;
default:
Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
break;
}
CombineEntries( left, left, ExprSP );
}
/*
* DoShift - shift a stack entry left or right
*/
void DoShift( void )
{
stack_entry *left;
int shift;
left = StkEntry( 1 );
RValue( ExprSP );
ConvertTo( ExprSP, TK_INTEGER, TM_SIGNED, 0 );
shift = I32FetchTrunc( ExprSP->v.sint );
RValue( left );
switch( left->info.kind ) {
case TK_BOOL:
case TK_ENUM:
case TK_CHAR:
case TK_INTEGER:
if( shift >= 0 ) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?