00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef CNODE_HPP
00032 #define CNODE_HPP
00033
00034 #include <stdio.h>
00035 #include <iostream>
00036 #include <sstream>
00037 #include <math.h>
00038 #include <list>
00039 #include <set>
00040 #include "glue.h"
00041 #include "csymbol.h"
00042 #include "cdecl.h"
00043 #include "cvector.h"
00044 #include "cobstack.h"
00045 #include "cattr.h"
00046
00047 class CGenvar;
00048 class CParam;
00049 class CFref;
00050 class CVar;
00051 class CNet;
00052 class CPort;
00053 class CPortDir;
00054 class CInstance;
00055 class CFunction;
00056 class CModule;
00057 class CGate;
00058 class CEvent;
00059 class CAttr;
00060 class CBlock;
00061 class CSpecify;
00062 class CNode;
00063 class CTypedef;
00064 class CEnum;
00065 typedef CBlock CScope;
00066 inline char* d2s( double d, CObstack* stack );
00067
00071 enum Edge_t {
00072 eEDGE01 = 0x1,
00073 eEDGE10 = 0x2,
00074 eEDGE0x = 0x4,
00075 eEDGEx1 = 0x8,
00076 eEDGE1x = 0x10,
00077 eEDGEx0 = 0x20,
00078 };
00079
00083 enum DelayMode_t {
00084 eMIN_DELAY,
00085 eTYP_DELAY,
00086 eMAX_DELAY
00087 };
00088
00092 enum Strength_t {
00093 eUNDEFINED = 0,
00094 eSUPPLY,
00095 eSTRONG,
00096 ePULL,
00097 eLARGE,
00098 eWEAK,
00099 eMEDIUM,
00100 eSMALL,
00101 eHIGHZ,
00102 };
00103
00107 struct StrengthPair_t {
00108 Strength_t s0;
00109 Strength_t s1;
00110 };
00111
00112 #define DEFINE_ENUM
00113 #include "cnode_def.h"
00114 #undef DEFINE_ENUM
00115
00116
00123 template<class T>
00124 class CNode_sp {
00125 T* ptr;
00126 public:
00127 CNode_sp( void** np ) { ptr = (T*)np; }
00128 T operator=( T n ) { *ptr = n; return n; }
00129 T operator->() { return *ptr; }
00130 operator T() { return *ptr; }
00131 int operator==( T v ) { return *ptr == v; }
00132 int operator!=( T v ) { return *ptr != v; }
00133 int operator==( CNode_sp<T> p ) { return *ptr == *p.ptr; }
00134 int operator!=( CNode_sp<T> p ) { return *ptr != *p.ptr; }
00135 };
00136
00141 struct CNode_pr {
00142 CNode* head;
00143 CNode* tail;
00144 public:
00145 CNode* operator=( CNode* n ) { head = n; tail = n; return n; }
00146 CNode* operator->() { return head; }
00147 operator CNode*() { return head; }
00148 int operator==( CNode* v ) { return head == v; }
00149 int operator!=( CNode* v ) { return head != v; }
00150 int operator==( CNode_pr p ) { return head == p.head; }
00151 int operator!=( CNode_pr p ) { return head != p.head; }
00152 friend CNode_pr cLINK( CNode_pr pr1, CNode* n2 );
00153 };
00154
00159 struct CNode_triplet {
00160 CNode* first;
00161 CNode* second;
00162 CNode* third;
00163 };
00164
00165
00186 class CNode : public CObject
00187 {
00188 private:
00189 static list<CObstack*> stackList;
00190 static CObstack evalHeap;
00191 static INT32 evalCount;
00192 static CObstack* stack;
00193 static map<CNode*,int> labelCache;
00194 static int labelCacheEnabled;
00195 NodeOp_t op;
00196 void* left;
00197 void* right;
00198 Coord_t loc;
00199 Coord_t *locp;
00200 CNode* attributes;
00201
00202
00203
00204
00205 NodeType_t type;
00206 INT32 width;
00207 int fixedWidth;
00208 private:
00209 int LabelBits( int supressErrorMessages = FALSE );
00210 CNode* FixBits( INT32 newWidth, NodeType_t newType );
00211 void _EvalVector( CVector& v );
00212 double _EvalReal( void );
00213 void FixedWidth( int v ) { fixedWidth = v; }
00214 int FixedWidth() { return fixedWidth; }
00215 int ConditionalWiden();
00216 int WidthFixed();
00217 unsigned NodeMask();
00218 CNode* GetNLeft( void ) { return (CNode*)left; }
00219 CNode* GetNRight( void ) { return (CNode*)right; }
00220 static void _LabelBits( CNode* n, void* arg );
00221 public:
00226 static CObstack* CurrentHeap() { return stack; }
00236 static void UseEvalStack( void ) {
00237 stackList.push_front( stack );
00238 evalCount++;
00239 stack = &evalHeap;
00240 }
00245 static void SetBuildStack( CObstack* aStack ) {
00246 MASSERT( evalCount == 0 );
00247 stackList.push_front( stack );
00248 stack = aStack;
00249 }
00253 static void ResetBuildStack( void ) {
00254 if( stack == &evalHeap ) {
00255 evalCount--;
00256 if( evalCount == 0 ) {
00257 evalHeap.Free( NULL );
00258 }
00259 }
00260 if( stackList.empty() ) {
00261 stack = NULL;
00262 } else {
00263 stack = *stackList.begin();
00264 stackList.pop_front();
00265 }
00266 }
00276 static void EnableLabelCache()
00277 {
00278 labelCacheEnabled = 1;
00279 }
00284 static void DisableAndClearLabelCache()
00285 {
00286 labelCacheEnabled = 0;
00287 labelCache.erase( labelCache.begin(), labelCache.end() );
00288 }
00296 CNode( Coord_t* aLoc, NodeOp_t aOp );
00301 Coord_t* GetCoord() { return locp; }
00306 NodeOp_t GetOp() { return op; }
00313 void SetOp( NodeOp_t aOp ) {
00314 int oldCount = ArgCount();
00315 op = aOp;
00316 MASSERT( oldCount == ArgCount() );
00317 }
00323 unsigned Hash();
00329 template<class T> CNode_sp<T> Arg( int index );
00334 int ArgCount( void );
00342 CNode* Clone( CObstack* heap = stack );
00347 int Precedence();
00354 void PostVisit1( void (*callback)(CNode*,void*), void* data );
00363 CNode* PostSubVisit1( CNode* (*callback)(CNode*,void*),
00364 void* data );
00372 void PreVisit1( int (*callback)(CNode*,void*), void* data );
00381 CNode* Simplify( INT32 newWidth, NodeType_t newType );
00391 int IsNonX( int integerIsNonX = 0, char* exclude = NULL );
00397 int IsConstant();
00407 int IsEvaluateable();
00413 int IsVolatile( void );
00418 INT32 EvalINT32();
00425 void EvalVector( CVector& v );
00434 void EvalVector( CVector& v, INT32 newWidth, NodeType_t newType );
00440 double EvalReal( void );
00445 void Dump( FILE* f );
00451 int IsWidthConstant( void );
00457 int IsWidthVolatile( void );
00467 int IsWidthEvaluateable( void );
00472 CNode* GetWidthExp( void );
00478 INT32 GetWidth( void ) { LabelBits(TRUE); return width; }
00483 int IsScalar( void ) { LabelBits(TRUE); return width==1; }
00488 int IsVector( void ) { LabelBits(TRUE); return width>1; }
00493 int IsReal( void ) { LabelBits(TRUE); return type==eR; }
00498 CNode* GetAttributes() { return attributes; }
00503 void SetAttributes( CNode* attr ) { attributes = attr; }
00511 int HasAttribute( const char* name, CNode* n=NULL, int init = 1 );
00519 CAttr* GetAttribute( const char* name, CNode* n=NULL, int init = 1 );
00524 NodeType_t GetNodeType( void ) { LabelBits(TRUE); return type; }
00525 };
00526
00527
00528
00529
00530
00531
00532
00533 template<class T> CNode_sp<T> CNode::Arg(int index)
00534 {
00535 switch( ArgCount() ) {
00536 case 1:
00537 switch( index ) {
00538 case 0:
00539 return CNode_sp<T>(&left);
00540 default:
00541 MASSERT( FALSE );
00542 return NULL;
00543 }
00544 case 2:
00545 switch( index ) {
00546 case 0:
00547 return CNode_sp<T>(&left);
00548 case 1:
00549 return CNode_sp<T>(&right);
00550 default:
00551 MASSERT( FALSE );
00552 return NULL;
00553 }
00554 case 3:
00555 switch( index ) {
00556 case 0:
00557 return CNode_sp<T>(&GetNLeft()->left);
00558 case 1:
00559 return CNode_sp<T>(&GetNLeft()->right);
00560 case 2:
00561 return CNode_sp<T>(&right);
00562 default:
00563 MASSERT( FALSE );
00564 return NULL;
00565 }
00566 case 4:
00567 switch( index ) {
00568 case 0:
00569 return CNode_sp<T>(&GetNLeft()->left);
00570 case 1:
00571 return CNode_sp<T>(&GetNLeft()->right);
00572 case 2:
00573 return CNode_sp<T>(&GetNRight()->left);
00574 case 3:
00575 return CNode_sp<T>(&GetNRight()->right);
00576 default:
00577 MASSERT( FALSE );
00578 return NULL;
00579 }
00580 case 5:
00581 switch( index ) {
00582 case 0:
00583 return CNode_sp<T>(&GetNLeft()->GetNLeft()->left);
00584 case 1:
00585 return CNode_sp<T>(&GetNLeft()->GetNLeft()->right);
00586 case 2:
00587 return CNode_sp<T>(&GetNLeft()->right);
00588 case 3:
00589 return CNode_sp<T>(&GetNRight()->left);
00590 case 4:
00591 return CNode_sp<T>(&GetNRight()->right);
00592 default:
00593 MASSERT( FALSE );
00594 return NULL;
00595 }
00596 case 6:
00597 switch( index ) {
00598 case 0:
00599 return CNode_sp<T>(&GetNLeft()->GetNLeft()->left);
00600 case 1:
00601 return CNode_sp<T>(&GetNLeft()->GetNLeft()->right);
00602 case 2:
00603 return CNode_sp<T>(&GetNLeft()->GetNRight()->left);
00604 case 3:
00605 return CNode_sp<T>(&GetNLeft()->GetNRight()->right);
00606 case 4:
00607 return CNode_sp<T>(&GetNRight()->left);
00608 case 5:
00609 return CNode_sp<T>(&GetNRight()->right);
00610 default:
00611 MASSERT( FALSE );
00612 return NULL;
00613 }
00614 case 7:
00615 switch( index ) {
00616 case 0:
00617 return CNode_sp<T>(&GetNLeft()->GetNLeft()->left);
00618 case 1:
00619 return CNode_sp<T>(&GetNLeft()->GetNLeft()->right);
00620 case 2:
00621 return CNode_sp<T>(&GetNLeft()->GetNRight()->left);
00622 case 3:
00623 return CNode_sp<T>(&GetNLeft()->GetNRight()->right);
00624 case 4:
00625 return CNode_sp<T>(&GetNRight()->GetNLeft()->left);
00626 case 5:
00627 return CNode_sp<T>(&GetNRight()->GetNLeft()->right);
00628 case 6:
00629 return CNode_sp<T>(&GetNRight()->right);
00630 default:
00631 MASSERT( FALSE );
00632 return NULL;
00633 }
00634 case 8:
00635 switch( index ) {
00636 case 0:
00637 return CNode_sp<T>(&GetNLeft()->GetNLeft()->left);
00638 case 1:
00639 return CNode_sp<T>(&GetNLeft()->GetNLeft()->right);
00640 case 2:
00641 return CNode_sp<T>(&GetNLeft()->GetNRight()->left);
00642 case 3:
00643 return CNode_sp<T>(&GetNLeft()->GetNRight()->right);
00644 case 4:
00645 return CNode_sp<T>(&GetNRight()->GetNLeft()->left);
00646 case 5:
00647 return CNode_sp<T>(&GetNRight()->GetNLeft()->right);
00648 case 6:
00649 return CNode_sp<T>(&GetNRight()->GetNRight()->left);
00650 case 7:
00651 return CNode_sp<T>(&GetNRight()->GetNRight()->right);
00652 default:
00653 MASSERT( FALSE );
00654 return NULL;
00655 }
00656
00657 default:
00658 MASSERT( FALSE );
00659 }
00660 }
00661 int Equivalent( CNode* a, CNode* b );
00662
00663
00664
00665
00666 inline void Add( double* r, double* a, double* b )
00667 {
00668 *r = *a + *b;
00669 }
00670
00671 inline void Sub( double* r, double* a, double* b )
00672 {
00673 *r = *a - *b;
00674 }
00675
00676 inline void Mul( double* r, double* a, double* b )
00677 {
00678 *r = *a * *b;
00679 }
00680
00681 inline void Div( double* r, double* a, double* b )
00682 {
00683 *r = *a / *b;
00684 }
00685
00686 inline void Neg( double* r, double* a )
00687 {
00688 *r = - *a;
00689 }
00690
00691 inline void Plus( double* r, double* a )
00692 {
00693 *r = *a;
00694 }
00695
00696 inline void Pow( double* r, double* a, double* b )
00697 {
00698 *r = pow(*a,*b);
00699 }
00700
00701
00702
00703
00704
00705 #define ILLEGAL_OP2(op) \
00706 inline void op( double*, double*, double* )\
00707 { fatal( NULL, #op " is illegal for reals" ); }
00708
00709 #define ILLEGAL_OP1(op) \
00710 inline void op( double*, double* )\
00711 { fatal( NULL, #op " is illegal for reals" ); }
00712
00713 ILLEGAL_OP2(Rsh);
00714 ILLEGAL_OP2(Lsh);
00715
00716 ILLEGAL_OP2(Rep);
00717 ILLEGAL_OP2(Mod);
00718 ILLEGAL_OP2(And);
00719 ILLEGAL_OP2(Xor);
00720 ILLEGAL_OP2(Xnor);
00721 ILLEGAL_OP2(Or);
00722 ILLEGAL_OP2(Lor);
00723 ILLEGAL_OP2(Land);
00724 ILLEGAL_OP1(Com);
00725 ILLEGAL_OP1(Rand);
00726 ILLEGAL_OP1(Rnand);
00727 ILLEGAL_OP1(Ror);
00728 ILLEGAL_OP1(Rnor);
00729 ILLEGAL_OP1(Rxor);
00730 ILLEGAL_OP1(Rxnor);
00731
00732 #define DEFINE_CONSTRUCTOR
00733 #include "cnode_def.h"
00734 #undef DEFINE_CONSTRUCTOR
00735
00736
00737
00738
00739
00746 inline CNode* cVECTOR( CVector& vec )
00747 {
00748 CVector* v = CVector::AllocFromHeap( CNode::CurrentHeap(), vec.GetWidth() );
00749 CNode* n;
00750 *v = vec;
00751 v->SetPreferredBase( vec.GetPreferredBase() );
00752 n = new(CNode::CurrentHeap()) CNode( NULL, eVCONSTANT );
00753 n->Arg<CVector*>(0) = v;
00754 return n;
00755 }
00756
00763 inline CNode* cSTRING( const char* s )
00764 {
00765 int len = strlen( s );
00766 if( !len ) {
00767 len = 1;
00768 }
00769 CVector* v = CVector::AllocFromHeap( CNode::CurrentHeap(), len*8 );
00770 v->LoadString( s );
00771 CNode* n = new(CNode::CurrentHeap()) CNode( NULL, eVCONSTANT );
00772 n->Arg<CVector*>(0) = v;
00773 return n;
00774 }
00775
00782 inline CNode* cINT32( INT32 i )
00783 {
00784 CVector* v = CVector::AllocFromHeap( CNode::CurrentHeap(), 32 );
00785 CNode* n;
00786 *v = i;
00787 v->Sized(FALSE);
00788 v->Signed(TRUE);
00789 v->Based(FALSE);
00790 n = new(CNode::CurrentHeap()) CNode( NULL, eVCONSTANT );
00791 n->Arg<CVector*>(0) = v;
00792 return n;
00793 }
00794
00801 inline CNode* cREAL( double number )
00802 {
00803 CNode* node = new(CNode::CurrentHeap()) CNode( NULL, eRCONSTANT );
00804 node->Arg<char*>(0) = d2s(number,CNode::CurrentHeap());
00805 return node;
00806 }
00807
00815 inline CNode* cELINK( CNode* n1, CNode* n2 )
00816 {
00817 if( n1 == NULL ) {
00818 return n2;
00819 } else if( n2 == NULL ) {
00820 return n1;
00821 }
00822 return cELIST( n1, n2 );
00823 }
00824
00832 inline CNode* cABS( CNode* a )
00833 {
00834 CNode* a1 = a->Clone();
00835 CNode* a2 = a->Clone();
00836 CNode* c = cGE(a,cINT32(0));
00837 return cHOOK( c, a1, cNEG( a2) );
00838 }
00839
00848 inline CNode* cABSDIFF( CNode* a, CNode* b )
00849 {
00850 return cABS( cSUB( a, b ) );
00851 }
00852
00861 inline CNode* cLINK( CNode* n1, CNode* n2 )
00862 {
00863 if( n1 == NULL ) {
00864 return n2;
00865 } else if( n2 == NULL ) {
00866 return n1;
00867 }
00868 return cLIST( n1, n2 );
00869 }
00870
00879 inline CNode* cMAX( CNode* n1, CNode* n2 )
00880 {
00881 CNode* cond = cLT(n2->Clone(),n1->Clone());
00882 return cHOOK(cond,n1,n2);
00883 }
00884
00885
00886
00887
00888
00889
00902 template<class T> void ArgList2Vector(CNode* n, NodeOp_t op,
00903 int argNumber, vector<T>& v)
00904 {
00905 if( !n ) {
00906 return;
00907 }
00908 switch( n->GetOp() ) {
00909 case eLIST:
00910 ArgList2Vector<T>(n->Arg<CNode*>(0),op,argNumber,v);
00911 ArgList2Vector<T>(n->Arg<CNode*>(1),op,argNumber,v);
00912 break;
00913 default:
00914 if( n->GetOp() == op ) {
00915 v.push_back(n->Arg<T>(argNumber));
00916 }
00917 break;
00918 }
00919 }
00920
00929 inline void EList2VectorExclude(CNode* n, const set<NodeOp_t>& excludeOps, vector<CNode*>& v)
00930 {
00931 if( !n ) {
00932 return;
00933 }
00934 switch( n->GetOp() ) {
00935 case eELIST:
00936 EList2VectorExclude(n->Arg<CNode*>(0),excludeOps,v);
00937 EList2VectorExclude(n->Arg<CNode*>(1),excludeOps,v);
00938 break;
00939 default:
00940 if( excludeOps.find(n->GetOp()) == excludeOps.end() ) {
00941 v.push_back(n);
00942 }
00943 break;
00944 }
00945 }
00946
00955 inline void List2VectorExclude(CNode* n, const set<NodeOp_t>& excludeOps, vector<CNode*>& v)
00956 {
00957 if( !n ) {
00958 return;
00959 }
00960 switch( n->GetOp() ) {
00961 case eLIST:
00962 List2VectorExclude(n->Arg<CNode*>(0),excludeOps,v);
00963 List2VectorExclude(n->Arg<CNode*>(1),excludeOps,v);
00964 break;
00965 default:
00966 if( excludeOps.find(n->GetOp()) == excludeOps.end() ) {
00967 v.push_back(n);
00968 }
00969 break;
00970 }
00971 }
00972
00979 inline CNode* Vector2EList(const vector<CNode*>& v)
00980 {
00981 CNode* result = NULL;
00982 vector<CNode*>::const_reverse_iterator ptr;
00983 for( ptr = v.rbegin(); ptr != v.rend(); ++ptr ) {
00984 if( result ) {
00985 result = cELIST(*ptr, result);
00986 } else {
00987 result = *ptr;
00988 }
00989 }
00990 return result;
00991 }
00992
00999 inline CNode* List2EList(list<CNode*>& v)
01000 {
01001 CNode* result = NULL;
01002 list<CNode*>::reverse_iterator ptr;
01003 for( ptr = v.rbegin(); ptr != v.rend(); ++ptr ) {
01004 if( result ) {
01005 result = cELIST(*ptr, result);
01006 } else {
01007 result = *ptr;
01008 }
01009 }
01010 return result;
01011 }
01012
01021 inline int ListCount(CNode* n, NodeOp_t op)
01022 {
01023 int result = 0;
01024 if( !n ) {
01025 return result;
01026 }
01027 switch( n->GetOp() ) {
01028 case eLIST:
01029 case eELIST:
01030 result += ListCount(n->Arg<CNode*>(0),op);
01031 result += ListCount(n->Arg<CNode*>(1),op);
01032 break;
01033 default:
01034 if( n->GetOp() == op ) {
01035 result = 1;
01036 }
01037 break;
01038 }
01039 return result;
01040 }
01041
01048 inline int ListCount(CNode* n)
01049 {
01050 int result = 0;
01051 if( !n ) {
01052 return result;
01053 }
01054 switch( n->GetOp() ) {
01055 case eLIST:
01056 case eELIST:
01057 result += ListCount(n->Arg<CNode*>(0));
01058 result += ListCount(n->Arg<CNode*>(1));
01059 break;
01060 default:
01061 result = 1;
01062 break;
01063 }
01064 return result;
01065 }
01066
01077 inline double s2d( char* s ) {
01078 return atof(s);
01079 }
01080
01089 inline char* d2s( double d, CObstack* heap ) {
01090 char buffer[256];
01091
01092
01093 snprintf( buffer, sizeof(buffer), "%g", d );
01094 char* s = (char*)heap->Alloc(strlen(buffer)+1);
01095 strcpy( s, buffer );
01096 return s;
01097 }
01098
01099
01100
01101
01102
01103 inline CNode* RebalanceRight( CNode* n ) {
01104 if( n == NULL ) {
01105 return n;
01106 }
01107 if( n->GetOp() != eLIST ) {
01108 return n;
01109 }
01110 CNode* result = n;
01111 CNode* parent = NULL;
01112 while( 1 ) {
01113 while( n->Arg<CNode*>(0) && n->Arg<CNode*>(0)->GetOp() == eLIST ) {
01114 CNode* l = n->Arg<CNode*>(0);
01115 CNode* ll = l->Arg<CNode*>(0);
01116 CNode* lr = l->Arg<CNode*>(1);
01117 l->Arg<CNode*>(1) = n;
01118 n->Arg<CNode*>(0) = lr;
01119 n = l;
01120 if( parent ) {
01121 parent->Arg<CNode*>(1) = n;
01122 } else {
01123 result = n;
01124 }
01125 }
01126 if( n->Arg<CNode*>(1) && n->Arg<CNode*>(1)->GetOp() == eLIST ) {
01127 parent = n;
01128 n = n->Arg<CNode*>(1);
01129 } else {
01130 break;
01131 }
01132 }
01133 return result;
01134 }
01135
01136
01137
01138
01139
01140
01141 inline void MeasureDepth( CNode* n, int* count, int* depth )
01142 {
01143 *count = 0;
01144 *depth = 0;
01145 if( !n ) {
01146 return;
01147 }
01148 if( n->GetOp() == eLIST ) {
01149 int count0 = 0;
01150 int depth0 = 0;
01151 int count1 = 0;
01152 int depth1 = 0;
01153 if( n->Arg<CNode*>(0) ) {
01154 MeasureDepth( n->Arg<CNode*>(0), &count0, &depth0 );
01155 depth0++;
01156 }
01157 if( n->Arg<CNode*>(1) ) {
01158 MeasureDepth( n->Arg<CNode*>(1), &count1, &depth1 );
01159 }
01160 *count = count0+count1;
01161 *depth = depth0 > depth1 ? depth0 : depth1;
01162 }
01163 (*count)++;
01164 }
01165
01166
01167
01168
01169
01170
01171 inline CNode_pr cLINK( CNode_pr pr1, CNode* n2 )
01172 {
01173 if( !n2 ) {
01174 return pr1;
01175 } else if( !pr1.tail ) {
01176 CNode_pr pr;
01177 pr.head = n2;
01178 pr.tail = n2;
01179 return pr;
01180 } else if( pr1.tail->GetOp() != eLIST ) {
01181 CNode* t = cLINK( pr1.head, n2 );
01182 CNode_pr pr;
01183 pr.head = t;
01184 pr.tail = t;
01185 return pr;
01186 } else {
01187 pr1.tail->Arg<CNode*>(1) = cLINK(pr1.tail->Arg<CNode*>(1),n2);
01188 CNode_pr pr;
01189 pr.head = pr1.head;
01190 pr.tail = pr1.tail->Arg<CNode*>(1);
01191 return pr;
01192 }
01193 }
01194
01195
01196
01197
01198 inline string HierarchicalReference2String( CNode* ref )
01199 {
01200 string buffer;
01201 switch( ref->GetOp() ) {
01202 case eARRAY: {
01203 buffer = HierarchicalReference2String(ref->Arg<CNode*>(0)).c_str();
01204 vector<CNode*> indexes;
01205 EList2VectorExclude( ref->Arg<CNode*>(1),
01206 set<NodeOp_t>(), indexes );
01207 vector<CNode*>::iterator ptr;
01208 for( ptr = indexes.begin(); ptr != indexes.end(); ++ptr ) {
01209 switch( ref->Arg<CNode*>(0)->GetOp() ) {
01210 case eSLICE:
01211 case ePSLICE:
01212 case eMSLICE:
01213 break;
01214 default: {
01215 INT32 value = (*ptr)->EvalINT32();
01216 ostringstream subscript;
01217 subscript << '[' << value << ']';
01218 buffer += subscript.str();
01219 } break;
01220 }
01221 }
01222 } break;
01223 case eMEMBER:
01224 buffer = HierarchicalReference2String(ref->Arg<CNode*>(0)).c_str();
01225 buffer += ".";
01226 buffer += ref->Arg<CSymbol*>(1)->GetName();
01227 break;
01228 case eEXTERNAL_REF:
01229 buffer = ref->Arg<CSymbol*>(0)->GetName();
01230 ref = NULL;
01231 break;
01232 case eNET_REF:
01233 case eVAR_REF:
01234 case ePARAM_REF:
01235 case ePORT_REF:
01236 case eFWD_REF:
01237 case eGENVAR_REF:
01238 buffer = ref->Arg<CDecl*>(0)->GetName();
01239 ref = NULL;
01240 break;
01241 default:;
01242 MASSERT( FALSE );
01243 }
01244 return buffer;
01245 }
01246
01247
01248
01249
01250 inline CNode* cMAX_N( CNode* first, ... )
01251 {
01252 CNode* result = first;
01253 va_list ap;
01254 va_start( ap, first );
01255 while( 1 ) {
01256 CNode* arg = va_arg(ap,CNode*);
01257 if( !arg ) {
01258 break;
01259 }
01260 result = cMAX( result, arg );
01261 }
01262 va_end( ap );
01263 return result;
01264 }
01265
01266 inline CNode* cADD_N( CNode* first, ... )
01267 {
01268 CNode* result = first;
01269 va_list ap;
01270 va_start( ap, first );
01271 while( 1 ) {
01272 CNode* arg = va_arg(ap,CNode*);
01273 if( !arg ) {
01274 break;
01275 }
01276 result = cADD( result, arg );
01277 }
01278 va_end( ap );
01279 return result;
01280 }
01281
01282 inline CNode* cMUL_N( CNode* first, ... )
01283 {
01284 CNode* result = first;
01285 va_list ap;
01286 va_start( ap, first );
01287 while( 1 ) {
01288 CNode* arg = va_arg(ap,CNode*);
01289 if( !arg ) {
01290 break;
01291 }
01292 result = cMUL( result, arg );
01293 }
01294 va_end( ap );
01295 return result;
01296 }
01297
01298 inline CNode* cABSDIFFPLUS1_N( CNode* first, ... )
01299 {
01300 va_list ap;
01301 va_start( ap, first );
01302 CNode* second = va_arg(ap,CNode*);
01303
01304
01305
01306 MASSERT( va_arg(ap,CNode*) == NULL );
01307 va_end( ap );
01308
01309 return cHOOK(
01310 cGE(first,second),
01311 cADD(cSUB(first->Clone(),second->Clone()),cINT32(1)),
01312 cADD(cSUB(second->Clone(),first->Clone()),cINT32(1)) );
01313
01314 }
01315
01316 inline int cMAX( int a1, int a2 )
01317 {
01318 return a1 < a2 ? a2 : a1;
01319 }
01320
01321 inline int cMAX( int a1, int a2, int a3 )
01322 {
01323 return cMAX(a1,cMAX(a2,a3));
01324 }
01325
01326 inline int cADD( int a1, int a2 )
01327 {
01328 return a1 + a2;
01329 }
01330
01331 inline int cMUL( int a1, int a2 )
01332 {
01333 return a1 * a2;
01334 }
01335
01336 inline int cABSDIFFPLUS1( int a1, int a2 )
01337 {
01338 int diff = a1-a2;
01339 return (diff < 0 ? -diff : diff)+1;
01340 }
01341
01342
01343 #endif // CNODE_HPP
01344