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 T* Ptr() { return ptr; }
00131 operator T() { return *ptr; }
00132 int operator==( T v ) { return *ptr == v; }
00133 int operator!=( T v ) { return *ptr != v; }
00134 int operator==( CNode_sp<T> p ) { return *ptr == *p.ptr; }
00135 int operator!=( CNode_sp<T> p ) { return *ptr != *p.ptr; }
00136 };
00137
00142 struct CNode_pr {
00143 CNode* head;
00144 CNode* tail;
00145 public:
00146 CNode* operator=( CNode* n ) { head = n; tail = n; return n; }
00147 CNode* operator->() { return head; }
00148 operator CNode*() { return head; }
00149 int operator==( CNode* v ) { return head == v; }
00150 int operator!=( CNode* v ) { return head != v; }
00151 int operator==( CNode_pr p ) { return head == p.head; }
00152 int operator!=( CNode_pr p ) { return head != p.head; }
00153 friend CNode_pr cLINK( CNode_pr pr1, CNode* n2 );
00154 };
00155
00160 struct CNode_triplet {
00161 CNode* first;
00162 CNode* second;
00163 CNode* third;
00164 };
00165
00166
00187 class CNode : public CObject
00188 {
00189 private:
00190 static list<CObstack*> stackList;
00191 static CObstack evalHeap;
00192 static INT32 evalCount;
00193 static CObstack* stack;
00194 static map<CNode*,int> labelCache;
00195 static int labelCacheEnabled;
00196 NodeOp_t op;
00197 void* left;
00198 void* right;
00199 Coord_t loc;
00200 Coord_t *locp;
00201 CNode* attributes;
00202
00203
00204
00205
00206 NodeType_t type;
00207 INT32 width;
00208 int fixedWidth;
00209 private:
00210 int LabelBits( int supressErrorMessages = FALSE );
00211 CNode* FixBits( INT32 newWidth, NodeType_t newType );
00212 void _EvalVector( CVector& v );
00213 double _EvalReal( void );
00214 void FixedWidth( int v ) { fixedWidth = v; }
00215 int FixedWidth() { return fixedWidth; }
00216 int ConditionalWiden();
00217 int WidthFixed();
00218 unsigned NodeMask();
00219 CNode* GetNLeft( void ) { return (CNode*)left; }
00220 CNode* GetNRight( void ) { return (CNode*)right; }
00221 static void _LabelBits( CNode* n, void* arg );
00222 public:
00227 static CObstack* CurrentHeap() { return stack; }
00237 static void UseEvalStack( void ) {
00238 stackList.push_front( stack );
00239 evalCount++;
00240 stack = &evalHeap;
00241 }
00246 static void SetBuildStack( CObstack* aStack ) {
00247 MASSERT( evalCount == 0 );
00248 stackList.push_front( stack );
00249 stack = aStack;
00250 }
00254 static void ResetBuildStack( void ) {
00255 if( stack == &evalHeap ) {
00256 evalCount--;
00257 if( evalCount == 0 ) {
00258 evalHeap.Free( NULL );
00259 }
00260 }
00261 if( stackList.empty() ) {
00262 stack = NULL;
00263 } else {
00264 stack = *stackList.begin();
00265 stackList.pop_front();
00266 }
00267 }
00277 static void EnableLabelCache()
00278 {
00279 labelCacheEnabled = 1;
00280 }
00285 static void DisableAndClearLabelCache()
00286 {
00287 labelCacheEnabled = 0;
00288 labelCache.erase( labelCache.begin(), labelCache.end() );
00289 }
00297 CNode( Coord_t* aLoc, NodeOp_t aOp );
00302 Coord_t* GetCoord() { return locp; }
00307 NodeOp_t GetOp() { return op; }
00314 void SetOp( NodeOp_t aOp ) {
00315 int oldCount = ArgCount();
00316 op = aOp;
00317 MASSERT( oldCount == ArgCount() );
00318 }
00324 unsigned Hash();
00330 template<class T> CNode_sp<T> Arg( int index );
00335 int ArgCount( void );
00343 CNode* Clone( CObstack* heap = stack );
00348 int Precedence();
00355 void PostVisit1( void (*callback)(CNode*,void*), void* data );
00364 CNode* PostSubVisit1( CNode* (*callback)(CNode*,void*),
00365 void* data );
00373 void PreVisit1( int (*callback)(CNode*,void*), void* data );
00382 CNode* Simplify( INT32 newWidth, NodeType_t newType );
00392 int IsNonX( int integerIsNonX = 0, char* exclude = NULL );
00398 int IsConstant();
00408 int IsEvaluateable();
00414 int IsVolatile( void );
00419 INT32 EvalINT32();
00426 void EvalVector( CVector& v );
00435 void EvalVector( CVector& v, INT32 newWidth, NodeType_t newType );
00441 double EvalReal( void );
00446 void Dump( FILE* f );
00452 int IsWidthConstant( void );
00458 int IsWidthVolatile( void );
00468 int IsWidthEvaluateable( void );
00473 CNode* GetWidthExp( void );
00479 INT32 GetWidth( void ) { LabelBits(TRUE); return width; }
00484 int IsScalar( void ) { LabelBits(TRUE); return width==1; }
00489 int IsVector( void ) { LabelBits(TRUE); return width>1; }
00494 int IsReal( void ) { LabelBits(TRUE); return type==eR; }
00499 CNode* GetAttributes() { return attributes; }
00504 void SetAttributes( CNode* attr ) { attributes = attr; }
00512 int HasAttribute( const char* name, CNode* n=NULL, int init = 1 );
00520 CAttr* GetAttribute( const char* name, CNode* n=NULL, int init = 1 );
00525 NodeType_t GetNodeType( void ) { LabelBits(TRUE); return type; }
00526 };
00527
00528
00529
00530
00531
00532
00533
00534 template<class T> CNode_sp<T> CNode::Arg(int index)
00535 {
00536 switch( ArgCount() ) {
00537 case 1:
00538 switch( index ) {
00539 case 0:
00540 return CNode_sp<T>(&left);
00541 default:
00542 MASSERT( FALSE );
00543 return NULL;
00544 }
00545 case 2:
00546 switch( index ) {
00547 case 0:
00548 return CNode_sp<T>(&left);
00549 case 1:
00550 return CNode_sp<T>(&right);
00551 default:
00552 MASSERT( FALSE );
00553 return NULL;
00554 }
00555 case 3:
00556 switch( index ) {
00557 case 0:
00558 return CNode_sp<T>(&GetNLeft()->left);
00559 case 1:
00560 return CNode_sp<T>(&GetNLeft()->right);
00561 case 2:
00562 return CNode_sp<T>(&right);
00563 default:
00564 MASSERT( FALSE );
00565 return NULL;
00566 }
00567 case 4:
00568 switch( index ) {
00569 case 0:
00570 return CNode_sp<T>(&GetNLeft()->left);
00571 case 1:
00572 return CNode_sp<T>(&GetNLeft()->right);
00573 case 2:
00574 return CNode_sp<T>(&GetNRight()->left);
00575 case 3:
00576 return CNode_sp<T>(&GetNRight()->right);
00577 default:
00578 MASSERT( FALSE );
00579 return NULL;
00580 }
00581 case 5:
00582 switch( index ) {
00583 case 0:
00584 return CNode_sp<T>(&GetNLeft()->GetNLeft()->left);
00585 case 1:
00586 return CNode_sp<T>(&GetNLeft()->GetNLeft()->right);
00587 case 2:
00588 return CNode_sp<T>(&GetNLeft()->right);
00589 case 3:
00590 return CNode_sp<T>(&GetNRight()->left);
00591 case 4:
00592 return CNode_sp<T>(&GetNRight()->right);
00593 default:
00594 MASSERT( FALSE );
00595 return NULL;
00596 }
00597 case 6:
00598 switch( index ) {
00599 case 0:
00600 return CNode_sp<T>(&GetNLeft()->GetNLeft()->left);
00601 case 1:
00602 return CNode_sp<T>(&GetNLeft()->GetNLeft()->right);
00603 case 2:
00604 return CNode_sp<T>(&GetNLeft()->GetNRight()->left);
00605 case 3:
00606 return CNode_sp<T>(&GetNLeft()->GetNRight()->right);
00607 case 4:
00608 return CNode_sp<T>(&GetNRight()->left);
00609 case 5:
00610 return CNode_sp<T>(&GetNRight()->right);
00611 default:
00612 MASSERT( FALSE );
00613 return NULL;
00614 }
00615 case 7:
00616 switch( index ) {
00617 case 0:
00618 return CNode_sp<T>(&GetNLeft()->GetNLeft()->left);
00619 case 1:
00620 return CNode_sp<T>(&GetNLeft()->GetNLeft()->right);
00621 case 2:
00622 return CNode_sp<T>(&GetNLeft()->GetNRight()->left);
00623 case 3:
00624 return CNode_sp<T>(&GetNLeft()->GetNRight()->right);
00625 case 4:
00626 return CNode_sp<T>(&GetNRight()->GetNLeft()->left);
00627 case 5:
00628 return CNode_sp<T>(&GetNRight()->GetNLeft()->right);
00629 case 6:
00630 return CNode_sp<T>(&GetNRight()->right);
00631 default:
00632 MASSERT( FALSE );
00633 return NULL;
00634 }
00635 case 8:
00636 switch( index ) {
00637 case 0:
00638 return CNode_sp<T>(&GetNLeft()->GetNLeft()->left);
00639 case 1:
00640 return CNode_sp<T>(&GetNLeft()->GetNLeft()->right);
00641 case 2:
00642 return CNode_sp<T>(&GetNLeft()->GetNRight()->left);
00643 case 3:
00644 return CNode_sp<T>(&GetNLeft()->GetNRight()->right);
00645 case 4:
00646 return CNode_sp<T>(&GetNRight()->GetNLeft()->left);
00647 case 5:
00648 return CNode_sp<T>(&GetNRight()->GetNLeft()->right);
00649 case 6:
00650 return CNode_sp<T>(&GetNRight()->GetNRight()->left);
00651 case 7:
00652 return CNode_sp<T>(&GetNRight()->GetNRight()->right);
00653 default:
00654 MASSERT( FALSE );
00655 return NULL;
00656 }
00657
00658 default:
00659 MASSERT( FALSE );
00660 }
00661 }
00662 int Equivalent( CNode* a, CNode* b );
00663
00664
00665
00666
00667 inline void Add( double* r, double* a, double* b )
00668 {
00669 *r = *a + *b;
00670 }
00671
00672 inline void Sub( double* r, double* a, double* b )
00673 {
00674 *r = *a - *b;
00675 }
00676
00677 inline void Mul( double* r, double* a, double* b )
00678 {
00679 *r = *a * *b;
00680 }
00681
00682 inline void Div( double* r, double* a, double* b )
00683 {
00684 *r = *a / *b;
00685 }
00686
00687 inline void Neg( double* r, double* a )
00688 {
00689 *r = - *a;
00690 }
00691
00692 inline void Plus( double* r, double* a )
00693 {
00694 *r = *a;
00695 }
00696
00697 inline void Pow( double* r, double* a, double* b )
00698 {
00699 *r = pow(*a,*b);
00700 }
00701
00702
00703
00704
00705
00706 #define ILLEGAL_OP2(op) \
00707 inline void op( double*, double*, double* )\
00708 { fatal( NULL, #op " is illegal for reals" ); }
00709
00710 #define ILLEGAL_OP1(op) \
00711 inline void op( double*, double* )\
00712 { fatal( NULL, #op " is illegal for reals" ); }
00713
00714 ILLEGAL_OP2(Rsh);
00715 ILLEGAL_OP2(Lsh);
00716
00717 ILLEGAL_OP2(Rep);
00718 ILLEGAL_OP2(Mod);
00719 ILLEGAL_OP2(And);
00720 ILLEGAL_OP2(Xor);
00721 ILLEGAL_OP2(Xnor);
00722 ILLEGAL_OP2(Or);
00723 ILLEGAL_OP2(Lor);
00724 ILLEGAL_OP2(Land);
00725 ILLEGAL_OP1(Com);
00726 ILLEGAL_OP1(Rand);
00727 ILLEGAL_OP1(Rnand);
00728 ILLEGAL_OP1(Ror);
00729 ILLEGAL_OP1(Rnor);
00730 ILLEGAL_OP1(Rxor);
00731 ILLEGAL_OP1(Rxnor);
00732
00733 #define DEFINE_CONSTRUCTOR
00734 #include "cnode_def.h"
00735 #undef DEFINE_CONSTRUCTOR
00736
00737
00738
00739
00740
00747 inline CNode* cVECTOR( CVector& vec )
00748 {
00749 CVector* v = CVector::AllocFromHeap( CNode::CurrentHeap(), vec.GetWidth() );
00750 CNode* n;
00751 *v = vec;
00752 v->SetPreferredBase( vec.GetPreferredBase() );
00753 n = new(CNode::CurrentHeap()) CNode( NULL, eVCONSTANT );
00754 n->Arg<CVector*>(0) = v;
00755 return n;
00756 }
00757
00764 inline CNode* cSTRING( const char* s )
00765 {
00766 int len = strlen( s );
00767 if( !len ) {
00768 len = 1;
00769 }
00770 CVector* v = CVector::AllocFromHeap( CNode::CurrentHeap(), len*8 );
00771 v->LoadString( s );
00772 CNode* n = new(CNode::CurrentHeap()) CNode( NULL, eVCONSTANT );
00773 n->Arg<CVector*>(0) = v;
00774 return n;
00775 }
00776
00783 inline CNode* cINT32( INT32 i )
00784 {
00785 CVector* v = CVector::AllocFromHeap( CNode::CurrentHeap(), 32 );
00786 CNode* n;
00787 *v = i;
00788 v->Sized(FALSE);
00789 v->Signed(TRUE);
00790 v->Based(FALSE);
00791 n = new(CNode::CurrentHeap()) CNode( NULL, eVCONSTANT );
00792 n->Arg<CVector*>(0) = v;
00793 return n;
00794 }
00795
00802 inline CNode* cREAL( double number )
00803 {
00804 CNode* node = new(CNode::CurrentHeap()) CNode( NULL, eRCONSTANT );
00805 node->Arg<char*>(0) = d2s(number,CNode::CurrentHeap());
00806 return node;
00807 }
00808
00816 inline CNode* cELINK( CNode* n1, CNode* n2 )
00817 {
00818 if( n1 == NULL ) {
00819 return n2;
00820 } else if( n2 == NULL ) {
00821 return n1;
00822 }
00823 return cELIST( n1, n2 );
00824 }
00825
00833 inline CNode* cABS( CNode* a )
00834 {
00835 CNode* a1 = a->Clone();
00836 CNode* a2 = a->Clone();
00837 CNode* c = cGE(a,cINT32(0));
00838 return cHOOK( c, a1, cNEG( a2) );
00839 }
00840
00849 inline CNode* cABSDIFF( CNode* a, CNode* b )
00850 {
00851 return cABS( cSUB( a, b ) );
00852 }
00853
00862 inline CNode* cLINK( CNode* n1, CNode* n2 )
00863 {
00864 if( n1 == NULL ) {
00865 return n2;
00866 } else if( n2 == NULL ) {
00867 return n1;
00868 }
00869 return cLIST( n1, n2 );
00870 }
00871
00880 inline CNode* cMAX( CNode* n1, CNode* n2 )
00881 {
00882 CNode* cond = cLT(n2->Clone(),n1->Clone());
00883 return cHOOK(cond,n1,n2);
00884 }
00885
00886
00887
00888
00889
00890
00903 template<class T> void ArgList2Vector(CNode* n, NodeOp_t op,
00904 int argNumber, vector<T>& v)
00905 {
00906 if( !n ) {
00907 return;
00908 }
00909 switch( n->GetOp() ) {
00910 case eLIST:
00911 ArgList2Vector<T>(n->Arg<CNode*>(0),op,argNumber,v);
00912 ArgList2Vector<T>(n->Arg<CNode*>(1),op,argNumber,v);
00913 break;
00914 default:
00915 if( n->GetOp() == op ) {
00916 v.push_back(n->Arg<T>(argNumber));
00917 }
00918 break;
00919 }
00920 }
00921
00930 inline void EList2VectorExclude(CNode* n, const set<NodeOp_t>& excludeOps, vector<CNode*>& v)
00931 {
00932 if( !n ) {
00933 return;
00934 }
00935 switch( n->GetOp() ) {
00936 case eELIST:
00937 EList2VectorExclude(n->Arg<CNode*>(0),excludeOps,v);
00938 EList2VectorExclude(n->Arg<CNode*>(1),excludeOps,v);
00939 break;
00940 default:
00941 if( excludeOps.find(n->GetOp()) == excludeOps.end() ) {
00942 v.push_back(n);
00943 }
00944 break;
00945 }
00946 }
00947
00956 inline void List2VectorExclude(CNode* n, const set<NodeOp_t>& excludeOps, vector<CNode*>& v)
00957 {
00958 if( !n ) {
00959 return;
00960 }
00961 switch( n->GetOp() ) {
00962 case eLIST:
00963 List2VectorExclude(n->Arg<CNode*>(0),excludeOps,v);
00964 List2VectorExclude(n->Arg<CNode*>(1),excludeOps,v);
00965 break;
00966 default:
00967 if( excludeOps.find(n->GetOp()) == excludeOps.end() ) {
00968 v.push_back(n);
00969 }
00970 break;
00971 }
00972 }
00973
00980 inline CNode* Vector2EList(const vector<CNode*>& v)
00981 {
00982 CNode* result = NULL;
00983 vector<CNode*>::const_reverse_iterator ptr;
00984 for( ptr = v.rbegin(); ptr != v.rend(); ++ptr ) {
00985 if( result ) {
00986 result = cELIST(*ptr, result);
00987 } else {
00988 result = *ptr;
00989 }
00990 }
00991 return result;
00992 }
00993
01000 inline CNode* List2EList(list<CNode*>& v)
01001 {
01002 CNode* result = NULL;
01003 list<CNode*>::reverse_iterator ptr;
01004 for( ptr = v.rbegin(); ptr != v.rend(); ++ptr ) {
01005 if( result ) {
01006 result = cELIST(*ptr, result);
01007 } else {
01008 result = *ptr;
01009 }
01010 }
01011 return result;
01012 }
01013
01022 inline int ListCount(CNode* n, NodeOp_t op)
01023 {
01024 int result = 0;
01025 if( !n ) {
01026 return result;
01027 }
01028 switch( n->GetOp() ) {
01029 case eLIST:
01030 case eELIST:
01031 result += ListCount(n->Arg<CNode*>(0),op);
01032 result += ListCount(n->Arg<CNode*>(1),op);
01033 break;
01034 default:
01035 if( n->GetOp() == op ) {
01036 result = 1;
01037 }
01038 break;
01039 }
01040 return result;
01041 }
01042
01049 inline int ListCount(CNode* n)
01050 {
01051 int result = 0;
01052 if( !n ) {
01053 return result;
01054 }
01055 switch( n->GetOp() ) {
01056 case eLIST:
01057 case eELIST:
01058 result += ListCount(n->Arg<CNode*>(0));
01059 result += ListCount(n->Arg<CNode*>(1));
01060 break;
01061 default:
01062 result = 1;
01063 break;
01064 }
01065 return result;
01066 }
01067
01078 inline double s2d( char* s ) {
01079 return atof(s);
01080 }
01081
01090 inline char* d2s( double d, CObstack* heap ) {
01091 char buffer[256];
01092
01093
01094 snprintf( buffer, sizeof(buffer), "%g", d );
01095 char* s = (char*)heap->Alloc(strlen(buffer)+1);
01096 strcpy( s, buffer );
01097 return s;
01098 }
01099
01100
01101
01102
01103
01104 inline CNode* RebalanceRight( CNode* n ) {
01105 if( n == NULL ) {
01106 return n;
01107 }
01108 if( n->GetOp() != eLIST ) {
01109 return n;
01110 }
01111 CNode* result = n;
01112 CNode* parent = NULL;
01113 while( 1 ) {
01114 while( n->Arg<CNode*>(0) && n->Arg<CNode*>(0)->GetOp() == eLIST ) {
01115 CNode* l = n->Arg<CNode*>(0);
01116 CNode* ll = l->Arg<CNode*>(0);
01117 CNode* lr = l->Arg<CNode*>(1);
01118 l->Arg<CNode*>(1) = n;
01119 n->Arg<CNode*>(0) = lr;
01120 n = l;
01121 if( parent ) {
01122 parent->Arg<CNode*>(1) = n;
01123 } else {
01124 result = n;
01125 }
01126 }
01127 if( n->Arg<CNode*>(1) && n->Arg<CNode*>(1)->GetOp() == eLIST ) {
01128 parent = n;
01129 n = n->Arg<CNode*>(1);
01130 } else {
01131 break;
01132 }
01133 }
01134 return result;
01135 }
01136
01137
01138
01139
01140
01141
01142 inline void MeasureDepth( CNode* n, int* count, int* depth )
01143 {
01144 *count = 0;
01145 *depth = 0;
01146 if( !n ) {
01147 return;
01148 }
01149 if( n->GetOp() == eLIST ) {
01150 int count0 = 0;
01151 int depth0 = 0;
01152 int count1 = 0;
01153 int depth1 = 0;
01154 if( n->Arg<CNode*>(0) ) {
01155 MeasureDepth( n->Arg<CNode*>(0), &count0, &depth0 );
01156 depth0++;
01157 }
01158 if( n->Arg<CNode*>(1) ) {
01159 MeasureDepth( n->Arg<CNode*>(1), &count1, &depth1 );
01160 }
01161 *count = count0+count1;
01162 *depth = depth0 > depth1 ? depth0 : depth1;
01163 }
01164 (*count)++;
01165 }
01166
01167
01168
01169
01170
01171
01172 inline CNode_pr cLINK( CNode_pr pr1, CNode* n2 )
01173 {
01174 if( !n2 ) {
01175 return pr1;
01176 } else if( !pr1.tail ) {
01177 CNode_pr pr;
01178 pr.head = n2;
01179 pr.tail = n2;
01180 return pr;
01181 } else if( pr1.tail->GetOp() != eLIST ) {
01182 CNode* t = cLINK( pr1.head, n2 );
01183 CNode_pr pr;
01184 pr.head = t;
01185 pr.tail = t;
01186 return pr;
01187 } else {
01188 pr1.tail->Arg<CNode*>(1) = cLINK(pr1.tail->Arg<CNode*>(1),n2);
01189 CNode_pr pr;
01190 pr.head = pr1.head;
01191 pr.tail = pr1.tail->Arg<CNode*>(1);
01192 return pr;
01193 }
01194 }
01195
01196
01197
01198
01199 inline string HierarchicalReference2String( CNode* ref )
01200 {
01201 string buffer;
01202 switch( ref->GetOp() ) {
01203 case eARRAY: {
01204 buffer = HierarchicalReference2String(ref->Arg<CNode*>(0)).c_str();
01205 vector<CNode*> indexes;
01206 EList2VectorExclude( ref->Arg<CNode*>(1),
01207 set<NodeOp_t>(), indexes );
01208 vector<CNode*>::iterator ptr;
01209 for( ptr = indexes.begin(); ptr != indexes.end(); ++ptr ) {
01210 switch( ref->Arg<CNode*>(0)->GetOp() ) {
01211 case eSLICE:
01212 case ePSLICE:
01213 case eMSLICE:
01214 break;
01215 default: {
01216 INT32 value = (*ptr)->EvalINT32();
01217 ostringstream subscript;
01218 subscript << '[' << value << ']';
01219 buffer += subscript.str();
01220 } break;
01221 }
01222 }
01223 } break;
01224 case eMEMBER:
01225 buffer = HierarchicalReference2String(ref->Arg<CNode*>(0)).c_str();
01226 buffer += ".";
01227 buffer += ref->Arg<CSymbol*>(1)->GetName();
01228 break;
01229 case eEXTERNAL_REF:
01230 buffer = ref->Arg<CSymbol*>(0)->GetName();
01231 ref = NULL;
01232 break;
01233 case eNET_REF:
01234 case eVAR_REF:
01235 case ePARAM_REF:
01236 case ePORT_REF:
01237 case eFWD_REF:
01238 case eGENVAR_REF:
01239 buffer = ref->Arg<CDecl*>(0)->GetName();
01240 ref = NULL;
01241 break;
01242 default:;
01243 MASSERT( FALSE );
01244 }
01245 return buffer;
01246 }
01247
01248
01249
01250
01251 inline CNode* cMAX_N( CNode* first, ... )
01252 {
01253 CNode* result = first;
01254 va_list ap;
01255 va_start( ap, first );
01256 while( 1 ) {
01257 CNode* arg = va_arg(ap,CNode*);
01258 if( !arg ) {
01259 break;
01260 }
01261 if( !Equivalent( result, arg ) ) {
01262 result = cMAX( result, arg );
01263 }
01264 }
01265 va_end( ap );
01266 return result;
01267 }
01268
01269 inline CNode* cADD_N( CNode* first, ... )
01270 {
01271 CNode* result = first;
01272 va_list ap;
01273 va_start( ap, first );
01274 while( 1 ) {
01275 CNode* arg = va_arg(ap,CNode*);
01276 if( !arg ) {
01277 break;
01278 }
01279 result = cADD( result, arg );
01280 }
01281 va_end( ap );
01282 return result;
01283 }
01284
01285 inline CNode* cMUL_N( CNode* first, ... )
01286 {
01287 CNode* result = first;
01288 va_list ap;
01289 va_start( ap, first );
01290 while( 1 ) {
01291 CNode* arg = va_arg(ap,CNode*);
01292 if( !arg ) {
01293 break;
01294 }
01295 result = cMUL( result, arg );
01296 }
01297 va_end( ap );
01298 return result;
01299 }
01300
01301 inline CNode* cABSDIFFPLUS1_N( CNode* first, ... )
01302 {
01303 va_list ap;
01304 va_start( ap, first );
01305 CNode* second = va_arg(ap,CNode*);
01306
01307
01308
01309 MASSERT( va_arg(ap,CNode*) == NULL );
01310 va_end( ap );
01311
01312 return cHOOK(
01313 cGE(first,second),
01314 cADD(cSUB(first->Clone(),second->Clone()),cINT32(1)),
01315 cADD(cSUB(second->Clone(),first->Clone()),cINT32(1)) );
01316
01317 }
01318
01319 inline int cMAX( int a1, int a2 )
01320 {
01321 return a1 < a2 ? a2 : a1;
01322 }
01323
01324 inline int cMAX( int a1, int a2, int a3 )
01325 {
01326 return cMAX(a1,cMAX(a2,a3));
01327 }
01328
01329 inline int cADD( int a1, int a2 )
01330 {
01331 return a1 + a2;
01332 }
01333
01334 inline int cMUL( int a1, int a2 )
01335 {
01336 return a1 * a2;
01337 }
01338
01339 inline int cABSDIFFPLUS1( int a1, int a2 )
01340 {
01341 int diff = a1-a2;
01342 return (diff < 0 ? -diff : diff)+1;
01343 }
01344
01345
01346 #endif // CNODE_HPP
01347