vrq
cnode.h
Go to the documentation of this file.
1 /*****************************************************************************
2  * Copyright (C) 1997-2007, Mark Hummel
3  * This file is part of Vrq.
4  *
5  * Vrq is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * Vrq is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301 USA
19  *****************************************************************************
20  */
21 /******************************************************************************
22  *
23  *
24  * cnode.hpp
25  * - abstract class for declaration
26  *
27  *
28  ******************************************************************************
29  */
30 
31 #ifndef CNODE_HPP
32 #define CNODE_HPP
33 
34 #include <stdio.h>
35 #include <iostream>
36 #include <sstream>
37 #include <math.h>
38 #include <list>
39 #include <set>
40 #include "glue.h"
41 #include "csymbol.h"
42 #include "cdecl.h"
43 #include "cvector.h"
44 #include "cobstack.h"
45 #include "cattr.h"
46 
47 class CGenvar;
48 class CParam;
49 class CFref;
50 class CVar;
51 class CNet;
52 class CPort;
53 class CPortDir;
54 class CInstance;
55 class CFunction;
56 class CModule;
57 class CGate;
58 class CEvent;
59 class CAttr;
60 class CBlock;
61 class CSpecify;
62 class CNode;
63 class CTypedef;
64 class CEnum;
65 class CPackage;
66 typedef CBlock CScope;
67 inline char* d2s( double d, CObstack* stack );
68 
72 enum Edge_t {
73  eEDGE01 = 0x1,
74  eEDGE10 = 0x2,
75  eEDGE0x = 0x4,
76  eEDGEx1 = 0x8,
77  eEDGE1x = 0x10,
78  eEDGEx0 = 0x20,
79 };
80 
88 };
89 
93 enum Strength_t {
103 };
104 
111 };
112 
120 };
121 
122 #define DEFINE_ENUM
123 #include "cnode_def.h"
124 #undef DEFINE_ENUM
125 
126 
133 template<class T>
134 class CNode_sp {
135  T* ptr;
136 public:
137  CNode_sp( void** np ) { ptr = (T*)np; }
138  T operator=( T n ) { *ptr = n; return n; }
139  T operator->() { return *ptr; }
140  T* Ptr() { return ptr; }
141  operator T() { return *ptr; }
142  int operator==( T v ) { return *ptr == v; }
143  int operator!=( T v ) { return *ptr != v; }
144  int operator==( CNode_sp<T> p ) { return *ptr == *p.ptr; }
145  int operator!=( CNode_sp<T> p ) { return *ptr != *p.ptr; }
146 };
147 
152 struct CNode_pr {
155 public:
156  CNode* operator=( CNode* n ) { head = n; tail = n; return n; }
157  CNode* operator->() { return head; }
158  operator CNode*() { return head; }
159  int operator==( CNode* v ) { return head == v; }
160  int operator!=( CNode* v ) { return head != v; }
161  int operator==( CNode_pr p ) { return head == p.head; }
162  int operator!=( CNode_pr p ) { return head != p.head; }
163  friend CNode_pr cLINK( CNode_pr pr1, CNode* n2 );
164 };
165 
174 };
175 
176 
197 class CNode : public CObject
198 {
199 private:
200  static list<CObstack*> stackList;
201  static CObstack evalHeap;
202  static INT32 evalCount;
203  static CObstack* stack;
204  static map<CNode*,int> labelCache;
205  static int labelCacheEnabled;
206  NodeOp_t op;
207  void* left;
208  void* right;
209  Coord_t loc;
210  Coord_t *locp;
211  CNode* attributes;
212  /*
213  * These decorations are temporary and used
214  * by the expression evaluation routines
215  */
216  NodeType_t type;
217  INT32 width;
218  int fixedWidth;
219 private:
220  int LabelBits( int supressErrorMessages = FALSE );
221  CNode* FixBits( INT32 newWidth, NodeType_t newType );
222  void _EvalVector( CVector& v );
223  double _EvalReal( void );
224  void FixedWidth( int v ) { fixedWidth = v; }
225  int FixedWidth() { return fixedWidth; }
226  int ConditionalWiden();
227  int WidthFixed();
228  unsigned NodeMask();
229  CNode* GetNLeft( void ) { return (CNode*)left; }
230  CNode* GetNRight( void ) { return (CNode*)right; }
231  static void _LabelBits( CNode* n, void* arg );
232 public:
237  static CObstack* CurrentHeap() { return stack; }
247  static void UseEvalStack( void ) {
248  stackList.push_front( stack );
249  evalCount++;
250  stack = &evalHeap;
251  }
256  static void SetBuildStack( CObstack* aStack ) {
257  MASSERT( evalCount == 0 );
258  stackList.push_front( stack );
259  stack = aStack;
260  }
264  static void ResetBuildStack( void ) {
265  if( stack == &evalHeap ) {
266  evalCount--;
267  if( evalCount == 0 ) {
268  evalHeap.Free( NULL );
269  }
270  }
271  if( stackList.empty() ) {
272  stack = NULL;
273  } else {
274  stack = *stackList.begin();
275  stackList.pop_front();
276  }
277  }
287  static void EnableLabelCache()
288  {
289  labelCacheEnabled = 1;
290  }
296  {
297  labelCacheEnabled = 0;
298  labelCache.erase( labelCache.begin(), labelCache.end() );
299  }
307  CNode( Coord_t* aLoc, NodeOp_t aOp );
312  Coord_t* GetCoord() { return locp; }
317  NodeOp_t GetOp() { return op; }
322  const char* GetOpName() { return nodeOpName[op]; }
329  void SetOp( NodeOp_t aOp ) {
330  int oldCount = ArgCount();
331  op = aOp;
332  MASSERT( oldCount == ArgCount() );
333  }
339  unsigned Hash();
345  template<class T> CNode_sp<T> Arg( int index );
350  int ArgCount( void );
358  CNode* Clone( CObstack* heap = stack );
363  int Precedence();
370  void PostVisit1( void (*callback)(CNode*,void*), void* data );
379  CNode* PostSubVisit1( CNode* (*callback)(CNode*,void*),
380  void* data );
388  void PreVisit1( int (*callback)(CNode*,void*), void* data );
397  CNode* Simplify( INT32 newWidth, NodeType_t newType );
407  int IsNonX( int integerIsNonX = 0, char* exclude = NULL );
413  int IsConstant();
423  int IsEvaluateable();
429  int IsVolatile( void );
434  INT32 EvalINT32();
441  void EvalVector( CVector& v );
450  void EvalVector( CVector& v, INT32 newWidth, NodeType_t newType );
456  double EvalReal( void );
461  void Dump( FILE* f );
467  int IsWidthConstant( void );
473  int IsWidthVolatile( void );
483  int IsWidthEvaluateable( void );
488  CNode* GetWidthExp( void );
494  INT32 GetWidth( void ) { LabelBits(TRUE); return width; }
499  int IsScalar( void ) { LabelBits(TRUE); return width==1; }
504  int IsVector( void ) { LabelBits(TRUE); return width>1; }
509  int IsReal( void ) { LabelBits(TRUE); return type==eR; }
514  CNode* GetAttributes() { return attributes; }
519  void SetAttributes( CNode* attr ) { attributes = attr; }
527  int HasAttribute( const char* name, CNode* n=NULL, int init = 1 );
535  CAttr* GetAttribute( const char* name, CNode* n=NULL, int init = 1 );
540  NodeType_t GetNodeType( void ) { LabelBits(TRUE); return type; }
541 };
542 
543 
544 /************************************************
545  Arg<CNode*>
546  - returns CNode smart pointer to arg by index
547  ***********************************************/
548 
549 template<class T> CNode_sp<T> CNode::Arg(int index)
550 {
551  switch( ArgCount() ) {
552  case 1:
553  switch( index ) {
554  case 0:
555  return CNode_sp<T>(&left);
556  default:
557  MASSERT( FALSE );
558  return NULL;
559  }
560  case 2:
561  switch( index ) {
562  case 0:
563  return CNode_sp<T>(&left);
564  case 1:
565  return CNode_sp<T>(&right);
566  default:
567  MASSERT( FALSE );
568  return NULL;
569  }
570  case 3:
571  switch( index ) {
572  case 0:
573  return CNode_sp<T>(&GetNLeft()->left);
574  case 1:
575  return CNode_sp<T>(&GetNLeft()->right);
576  case 2:
577  return CNode_sp<T>(&right);
578  default:
579  MASSERT( FALSE );
580  return NULL;
581  }
582  case 4:
583  switch( index ) {
584  case 0:
585  return CNode_sp<T>(&GetNLeft()->left);
586  case 1:
587  return CNode_sp<T>(&GetNLeft()->right);
588  case 2:
589  return CNode_sp<T>(&GetNRight()->left);
590  case 3:
591  return CNode_sp<T>(&GetNRight()->right);
592  default:
593  MASSERT( FALSE );
594  return NULL;
595  }
596  case 5:
597  switch( index ) {
598  case 0:
599  return CNode_sp<T>(&GetNLeft()->GetNLeft()->left);
600  case 1:
601  return CNode_sp<T>(&GetNLeft()->GetNLeft()->right);
602  case 2:
603  return CNode_sp<T>(&GetNLeft()->right);
604  case 3:
605  return CNode_sp<T>(&GetNRight()->left);
606  case 4:
607  return CNode_sp<T>(&GetNRight()->right);
608  default:
609  MASSERT( FALSE );
610  return NULL;
611  }
612  case 6:
613  switch( index ) {
614  case 0:
615  return CNode_sp<T>(&GetNLeft()->GetNLeft()->left);
616  case 1:
617  return CNode_sp<T>(&GetNLeft()->GetNLeft()->right);
618  case 2:
619  return CNode_sp<T>(&GetNLeft()->GetNRight()->left);
620  case 3:
621  return CNode_sp<T>(&GetNLeft()->GetNRight()->right);
622  case 4:
623  return CNode_sp<T>(&GetNRight()->left);
624  case 5:
625  return CNode_sp<T>(&GetNRight()->right);
626  default:
627  MASSERT( FALSE );
628  return NULL;
629  }
630  case 7:
631  switch( index ) {
632  case 0:
633  return CNode_sp<T>(&GetNLeft()->GetNLeft()->left);
634  case 1:
635  return CNode_sp<T>(&GetNLeft()->GetNLeft()->right);
636  case 2:
637  return CNode_sp<T>(&GetNLeft()->GetNRight()->left);
638  case 3:
639  return CNode_sp<T>(&GetNLeft()->GetNRight()->right);
640  case 4:
641  return CNode_sp<T>(&GetNRight()->GetNLeft()->left);
642  case 5:
643  return CNode_sp<T>(&GetNRight()->GetNLeft()->right);
644  case 6:
645  return CNode_sp<T>(&GetNRight()->right);
646  default:
647  MASSERT( FALSE );
648  return NULL;
649  }
650  case 8:
651  switch( index ) {
652  case 0:
653  return CNode_sp<T>(&GetNLeft()->GetNLeft()->left);
654  case 1:
655  return CNode_sp<T>(&GetNLeft()->GetNLeft()->right);
656  case 2:
657  return CNode_sp<T>(&GetNLeft()->GetNRight()->left);
658  case 3:
659  return CNode_sp<T>(&GetNLeft()->GetNRight()->right);
660  case 4:
661  return CNode_sp<T>(&GetNRight()->GetNLeft()->left);
662  case 5:
663  return CNode_sp<T>(&GetNRight()->GetNLeft()->right);
664  case 6:
665  return CNode_sp<T>(&GetNRight()->GetNRight()->left);
666  case 7:
667  return CNode_sp<T>(&GetNRight()->GetNRight()->right);
668  default:
669  MASSERT( FALSE );
670  return NULL;
671  }
672 
673  default:
674  MASSERT( FALSE );
675  }
676 }
677 int Equivalent( CNode* a, CNode* b );
678 /******************************************************
679  real operation routines
680  ******************************************************/
681 
682 inline void Add( double* r, double* a, double* b )
683 {
684  *r = *a + *b;
685 }
686 
687 inline void Sub( double* r, double* a, double* b )
688 {
689  *r = *a - *b;
690 }
691 
692 inline void Mul( double* r, double* a, double* b )
693 {
694  *r = *a * *b;
695 }
696 
697 inline void Div( double* r, double* a, double* b )
698 {
699  *r = *a / *b;
700 }
701 
702 inline void Neg( double* r, double* a )
703 {
704  *r = - *a;
705 }
706 
707 inline void Plus( double* r, double* a )
708 {
709  *r = *a;
710 }
711 
712 inline void Pow( double* r, double* a, double* b )
713 {
714  *r = pow(*a,*b);
715 }
716 
717 
718 /*****************************************************
719  * Create stubs for illegal operations
720  ****************************************************/
721 #define ILLEGAL_OP2(op) \
722 inline void op( double*, double*, double* )\
723 { fatal( NULL, #op " is illegal for reals" ); }
724 
725 #define ILLEGAL_OP1(op) \
726 inline void op( double*, double* )\
727 { fatal( NULL, #op " is illegal for reals" ); }
728 
729 ILLEGAL_OP2(Rsh);
730 ILLEGAL_OP2(Lsh);
731 
732 ILLEGAL_OP2(Rep);
733 ILLEGAL_OP2(Mod);
734 ILLEGAL_OP2(And);
735 ILLEGAL_OP2(Xor);
736 ILLEGAL_OP2(Xnor);
737 ILLEGAL_OP2(Or);
738 ILLEGAL_OP2(Lor);
739 ILLEGAL_OP2(Land);
740 ILLEGAL_OP1(Com);
741 ILLEGAL_OP1(Rand);
742 ILLEGAL_OP1(Rnand);
743 ILLEGAL_OP1(Ror);
744 ILLEGAL_OP1(Rnor);
745 ILLEGAL_OP1(Rxor);
746 ILLEGAL_OP1(Rxnor);
747 
748 #define DEFINE_CONSTRUCTOR
749 #include "cnode_def.h"
750 #undef DEFINE_CONSTRUCTOR
751 
752 /****************************************************
753  Node building helper routines
754 *****************************************************/
755 
762 inline CNode* cVECTOR( CVector& vec )
763 {
765  CNode* n;
766  *v = vec;
768  n = new(CNode::CurrentHeap()) CNode( NULL, eVCONSTANT );
769  n->Arg<CVector*>(0) = v;
770  return n;
771 }
772 
779 inline CNode* cSTRING( const char* s )
780 {
781  int len = strlen( s );
782  if( !len ) {
783  len = 1;
784  }
786  v->LoadString( s );
787  CNode* n = new(CNode::CurrentHeap()) CNode( NULL, eVCONSTANT );
788  n->Arg<CVector*>(0) = v;
789  return n;
790 }
791 
798 inline CNode* cINT32( INT32 i )
799 {
801  CNode* n;
802  *v = i;
803  v->Sized(FALSE);
804  v->Signed(TRUE);
805  v->Based(FALSE);
806  n = new(CNode::CurrentHeap()) CNode( NULL, eVCONSTANT );
807  n->Arg<CVector*>(0) = v;
808  return n;
809 }
810 
817 inline CNode* cREAL( double number )
818 {
819  CNode* node = new(CNode::CurrentHeap()) CNode( NULL, eRCONSTANT );
820  node->Arg<char*>(0) = d2s(number,CNode::CurrentHeap());
821  return node;
822 }
823 
831 inline CNode* cELINK( CNode* n1, CNode* n2 )
832 {
833  if( n1 == NULL ) {
834  return n2;
835  } else if( n2 == NULL ) {
836  return n1;
837  }
838  return cELIST( n1, n2 );
839 }
840 
848 inline CNode* cABS( CNode* a )
849 {
850  CNode* a1 = a->Clone();
851  CNode* a2 = a->Clone();
852  CNode* c = cGE(a,cINT32(0));
853  return cHOOK( c, a1, cNEG( a2) );
854 }
855 
864 inline CNode* cABSDIFF( CNode* a, CNode* b )
865 {
866  return cABS( cSUB( a, b ) );
867 }
868 
877 inline CNode* cLINK( CNode* n1, CNode* n2 )
878 {
879  if( n1 == NULL ) {
880  return n2;
881  } else if( n2 == NULL ) {
882  return n1;
883  }
884  return cLIST( n1, n2 );
885 }
886 
895 inline CNode* cMAX( CNode* n1, CNode* n2 )
896 {
897  CNode* cond = cLT(n2->Clone(),n1->Clone());
898  return cHOOK(cond,n1,n2);
899 }
900 
901 
902 /****************************************************
903  utility routines
904 *****************************************************/
905 
918 template<class T> void ArgList2Vector(CNode* n, NodeOp_t op,
919  int argNumber, vector<T>& v)
920 {
921  if( !n ) {
922  return;
923  }
924  switch( n->GetOp() ) {
925  case eLIST:
926  ArgList2Vector<T>(n->Arg<CNode*>(0),op,argNumber,v);
927  ArgList2Vector<T>(n->Arg<CNode*>(1),op,argNumber,v);
928  break;
929  default:
930  if( n->GetOp() == op ) {
931  v.push_back(n->Arg<T>(argNumber));
932  }
933  break;
934  }
935 }
936 
945 inline void EList2VectorExclude(CNode* n, const set<NodeOp_t>& excludeOps, vector<CNode*>& v)
946 {
947  if( !n ) {
948  return;
949  }
950  switch( n->GetOp() ) {
951  case eELIST:
952  EList2VectorExclude(n->Arg<CNode*>(0),excludeOps,v);
953  EList2VectorExclude(n->Arg<CNode*>(1),excludeOps,v);
954  break;
955  default:
956  if( excludeOps.find(n->GetOp()) == excludeOps.end() ) {
957  v.push_back(n);
958  }
959  break;
960  }
961 }
962 
971 inline void List2VectorExclude(CNode* n, const set<NodeOp_t>& excludeOps, vector<CNode*>& v)
972 {
973  if( !n ) {
974  return;
975  }
976  switch( n->GetOp() ) {
977  case eLIST:
978  List2VectorExclude(n->Arg<CNode*>(0),excludeOps,v);
979  List2VectorExclude(n->Arg<CNode*>(1),excludeOps,v);
980  break;
981  default:
982  if( excludeOps.find(n->GetOp()) == excludeOps.end() ) {
983  v.push_back(n);
984  }
985  break;
986  }
987 }
988 
995 inline CNode* Vector2EList(const vector<CNode*>& v)
996 {
997  CNode* result = NULL;
998  vector<CNode*>::const_reverse_iterator ptr;
999  for( ptr = v.rbegin(); ptr != v.rend(); ++ptr ) {
1000  if( result ) {
1001  result = cELIST(*ptr, result);
1002  } else {
1003  result = *ptr;
1004  }
1005  }
1006  return result;
1007 }
1008 
1015 inline CNode* List2EList(list<CNode*>& v)
1016 {
1017  CNode* result = NULL;
1018  list<CNode*>::reverse_iterator ptr;
1019  for( ptr = v.rbegin(); ptr != v.rend(); ++ptr ) {
1020  if( result ) {
1021  result = cELIST(*ptr, result);
1022  } else {
1023  result = *ptr;
1024  }
1025  }
1026  return result;
1027 }
1028 
1037 inline int ListCount(CNode* n, NodeOp_t op)
1038 {
1039  int result = 0;
1040  if( !n ) {
1041  return result;
1042  }
1043  switch( n->GetOp() ) {
1044  case eLIST:
1045  case eELIST:
1046  result += ListCount(n->Arg<CNode*>(0),op);
1047  result += ListCount(n->Arg<CNode*>(1),op);
1048  break;
1049  default:
1050  if( n->GetOp() == op ) {
1051  result = 1;
1052  }
1053  break;
1054  }
1055  return result;
1056 }
1057 
1064 inline int ListCount(CNode* n)
1065 {
1066  int result = 0;
1067  if( !n ) {
1068  return result;
1069  }
1070  switch( n->GetOp() ) {
1071  case eLIST:
1072  case eELIST:
1073  result += ListCount(n->Arg<CNode*>(0));
1074  result += ListCount(n->Arg<CNode*>(1));
1075  break;
1076  default:
1077  result = 1;
1078  break;
1079  }
1080  return result;
1081 }
1082 
1093 inline double s2d( char* s ) {
1094  return atof(s);
1095 }
1096 
1105 inline char* d2s( double d, CObstack* heap ) {
1106  char buffer[256];
1107  // note this isn't quite correct as it will turn
1108  // reals into ints, ie 2.0 => 2
1109  snprintf( buffer, sizeof(buffer), "%g", d );
1110  char* s = (char*)heap->Alloc(strlen(buffer)+1);
1111  strcpy( s, buffer );
1112  return s;
1113 }
1114 
1115 /*********************************************
1116  * Adjust nodes structure to be efficient for
1117  * tail recursion
1118  *********************************************/
1119 inline CNode* RebalanceRight( CNode* n ) {
1120  if( n == NULL ) {
1121  return n;
1122  }
1123  if( n->GetOp() != eLIST ) {
1124  return n;
1125  }
1126  CNode* result = n;
1127  CNode* parent = NULL;
1128  while( 1 ) {
1129  while( n->Arg<CNode*>(0) && n->Arg<CNode*>(0)->GetOp() == eLIST ) {
1130  CNode* l = n->Arg<CNode*>(0);
1131  CNode* ll = l->Arg<CNode*>(0);
1132  CNode* lr = l->Arg<CNode*>(1);
1133  l->Arg<CNode*>(1) = n;
1134  n->Arg<CNode*>(0) = lr;
1135  n = l;
1136  if( parent ) {
1137  parent->Arg<CNode*>(1) = n;
1138  } else {
1139  result = n;
1140  }
1141  }
1142  if( n->Arg<CNode*>(1) && n->Arg<CNode*>(1)->GetOp() == eLIST ) {
1143  parent = n;
1144  n = n->Arg<CNode*>(1);
1145  } else {
1146  break;
1147  }
1148  }
1149  return result;
1150 }
1151 /*********************************************
1152  * Analyse tree struct.
1153  * - depth is worst case stack depth right side
1154  * optimization.
1155  * count is number nodes.
1156  *********************************************/
1157 inline void MeasureDepth( CNode* n, int* count, int* depth )
1158 {
1159  *count = 0;
1160  *depth = 0;
1161  if( !n ) {
1162  return;
1163  }
1164  if( n->GetOp() == eLIST ) {
1165  int count0 = 0;
1166  int depth0 = 0;
1167  int count1 = 0;
1168  int depth1 = 0;
1169  if( n->Arg<CNode*>(0) ) {
1170  MeasureDepth( n->Arg<CNode*>(0), &count0, &depth0 );
1171  depth0++;
1172  }
1173  if( n->Arg<CNode*>(1) ) {
1174  MeasureDepth( n->Arg<CNode*>(1), &count1, &depth1 );
1175  }
1176  *count = count0+count1;
1177  *depth = depth0 > depth1 ? depth0 : depth1;
1178  }
1179  (*count)++;
1180 }
1181 
1182 
1183 /**************************************************
1184  * Helper routine for parser to build trees that
1185  * are effient for tail recursion.
1186  *************************************************/
1187 inline CNode_pr cLINK( CNode_pr pr1, CNode* n2 )
1188 {
1189  if( !n2 ) {
1190  return pr1;
1191  } else if( !pr1.tail ) {
1192  CNode_pr pr;
1193  pr.head = n2;
1194  pr.tail = n2;
1195  return pr;
1196  } else if( pr1.tail->GetOp() != eLIST ) {
1197  CNode* t = cLINK( pr1.head, n2 );
1198  CNode_pr pr;
1199  pr.head = t;
1200  pr.tail = t;
1201  return pr;
1202  } else {
1203  pr1.tail->Arg<CNode*>(1) = cLINK(pr1.tail->Arg<CNode*>(1),n2);
1204  CNode_pr pr;
1205  pr.head = pr1.head;
1206  pr.tail = pr1.tail->Arg<CNode*>(1);
1207  return pr;
1208  }
1209 }
1210 
1211 /**************************************************
1212  * convert hierarchical reference tree to string
1213  *************************************************/
1215 {
1216  string buffer;
1217  switch( ref->GetOp() ) {
1218  case eARRAY: {
1219  buffer = HierarchicalReference2String(ref->Arg<CNode*>(0)).c_str();
1220  vector<CNode*> indexes;
1221  EList2VectorExclude( ref->Arg<CNode*>(1),
1222  set<NodeOp_t>(), indexes );
1223  vector<CNode*>::iterator ptr;
1224  for( ptr = indexes.begin(); ptr != indexes.end(); ++ptr ) {
1225  switch( ref->Arg<CNode*>(0)->GetOp() ) {
1226  case eSLICE:
1227  case ePSLICE:
1228  case eMSLICE:
1229  break;
1230  default: {
1231  INT32 value = (*ptr)->EvalINT32();
1232  ostringstream subscript;
1233  subscript << '[' << value << ']';
1234  buffer += subscript.str();
1235  } break;
1236  }
1237  }
1238  } break;
1239  case eMEMBER:
1240  buffer = HierarchicalReference2String(ref->Arg<CNode*>(0)).c_str();
1241  buffer += ".";
1242  buffer += ref->Arg<CSymbol*>(1)->GetName();
1243  break;
1244  case eEXTERNAL_REF:
1245  buffer = ref->Arg<CSymbol*>(0)->GetName();
1246  ref = NULL;
1247  break;
1248  case eNET_REF:
1249  case eVAR_REF:
1250  case ePARAM_REF:
1251  case ePORT_REF:
1252  case eFWD_REF:
1253  case eGENVAR_REF:
1254  buffer = ref->Arg<CDecl*>(0)->GetName();
1255  ref = NULL;
1256  break;
1257  default:;
1258  MASSERT( FALSE );
1259  }
1260  return buffer;
1261 }
1262 
1263 /*****************************************************
1264  * Support routines for cnode_def.h constructs
1265  *****************************************************/
1266 inline CNode* cMAX_N( CNode* first, ... )
1267 {
1268  CNode* result = first;
1269  va_list ap;
1270  va_start( ap, first );
1271  while( 1 ) {
1272  CNode* arg = va_arg(ap,CNode*);
1273  if( !arg ) {
1274  break;
1275  }
1276  if( !Equivalent( result, arg ) ) {
1277  result = cMAX( result, arg );
1278  }
1279  }
1280  va_end( ap );
1281  return result;
1282 }
1283 
1284 inline CNode* cADD_N( CNode* first, ... )
1285 {
1286  CNode* result = first;
1287  va_list ap;
1288  va_start( ap, first );
1289  while( 1 ) {
1290  CNode* arg = va_arg(ap,CNode*);
1291  if( !arg ) {
1292  break;
1293  }
1294  result = cADD( result, arg );
1295  }
1296  va_end( ap );
1297  return result;
1298 }
1299 
1300 inline CNode* cMUL_N( CNode* first, ... )
1301 {
1302  CNode* result = first;
1303  va_list ap;
1304  va_start( ap, first );
1305  while( 1 ) {
1306  CNode* arg = va_arg(ap,CNode*);
1307  if( !arg ) {
1308  break;
1309  }
1310  result = cMUL( result, arg );
1311  }
1312  va_end( ap );
1313  return result;
1314 }
1315 
1316 inline CNode* cABSDIFFPLUS1_N( CNode* first, ... )
1317 {
1318  va_list ap;
1319  va_start( ap, first );
1320  CNode* second = va_arg(ap,CNode*);
1321  /*
1322  * only make sense for 2 args
1323  */
1324  MASSERT( va_arg(ap,CNode*) == NULL );
1325  va_end( ap );
1326 // return cADD(cABSDIFF(first,second),cINT32(1));
1327  return cHOOK(
1328  cGE(first,second),
1329  cADD(cSUB(first->Clone(),second->Clone()),cINT32(1)),
1330  cADD(cSUB(second->Clone(),first->Clone()),cINT32(1)) );
1331 
1332 }
1333 
1334 inline int cMAX( int a1, int a2 )
1335 {
1336  return a1 < a2 ? a2 : a1;
1337 }
1338 
1339 inline int cMAX( int a1, int a2, int a3 )
1340 {
1341  return cMAX(a1,cMAX(a2,a3));
1342 }
1343 
1344 inline int cADD( int a1, int a2 )
1345 {
1346  return a1 + a2;
1347 }
1348 
1349 inline int cMUL( int a1, int a2 )
1350 {
1351  return a1 * a2;
1352 }
1353 
1354 inline int cABSDIFFPLUS1( int a1, int a2 )
1355 {
1356  int diff = a1-a2;
1357  return (diff < 0 ? -diff : diff)+1;
1358 }
1359 
1360 
1361 #endif // CNODE_HPP
1362 
Declaration object for nets.
Definition: cnet.h:46
Definition: cnode.h:94
CNode * cSUB(CNode *a0, CNode *a1, Coord_t *loc=NULL)
Node construction shortcut for SUB subtract.
Definition: cnode_def.h:2923
int HasAttribute(const char *name, CNode *n=NULL, int init=1)
Determine if node has the given attribute.
Definition: cnode.cc:412
static void DisableAndClearLabelCache()
Disable caching of label info (width and type) and clear all accumulated data.
Definition: cnode.h:295
real constant
Definition: cnode_def.h:665
vector subrange with ascending index select
Definition: cnode_def.h:1164
CNode * Simplify(INT32 newWidth, NodeType_t newType)
Create simplified expression tree with given width and type.
Definition: cnode.cc:337
int cMUL(int a1, int a2)
Definition: cnode.h:1349
static void UseEvalStack(void)
Use evaluation stack.
Definition: cnode.h:247
int Equivalent(CNode *a, CNode *b)
Definition: cnode_def.h:12282
Definition: cnode.h:77
Smart pointer for CNode class Creates safe references to CNode arguments Supports assignment...
Definition: cnode.h:134
CNode * operator->()
Definition: cnode.h:157
Declaration object for genvars.
Definition: cgenvar.h:46
CNode * cELIST(CNode *a0, CNode *a1, Coord_t *loc=NULL)
Node construction shortcut for ELIST expression list.
Definition: cnode_def.h:2832
CNode * RebalanceRight(CNode *n)
Definition: cnode.h:1119
Gate declaration object.
Definition: cgate.h:42
Definition: cnode.h:100
T * Ptr()
Definition: cnode.h:140
int IsScalar(void)
Determine if expression is a 1 bit signed or unsigned value.
Definition: cnode.h:499
CNode * cREAL(double number)
Short cut for creating RCONSTANT node with a given double value.
Definition: cnode.h:817
Definition: cnode.h:96
Definition: cnode.h:117
static void EnableLabelCache()
Enable cache of labeled nodes to be tracked.
Definition: cnode.h:287
int IsEvaluateable()
Checks to see if expression tree can be evaluated.
Definition: cnode_def.h:12842
int ListCount(CNode *n, NodeOp_t op)
Walks a list/elist of nodes and counts the number of node with the specified operation.
Definition: cnode.h:1037
void Add(double *r, double *a, double *b)
Definition: cnode.h:682
int cADD(int a1, int a2)
Definition: cnode.h:1344
Declaration object for specify blocks.
Definition: cspecify.h:47
CNode * cMAX_N(CNode *first,...)
Definition: cnode.h:1266
void SetPreferredBase(int base)
Set preferred base for printing value.
Definition: cvector.h:132
char * d2s(double d, CObstack *stack)
Convert double to char string allocating storage on given heap.
Definition: cnode.h:1105
CNode * second
Definition: cnode.h:172
void Neg(double *r, double *a)
Definition: cnode.h:702
Definition: cnode.h:76
list of nodes
Definition: cnode_def.h:1131
vector constant
Definition: cnode_def.h:655
CNode * cSTRING(const char *s)
Short cut for creating VCONSTANT node with a given string value.
Definition: cnode.h:779
Coord_t * GetCoord()
Get node's file coordinates.
Definition: cnode.h:312
CNode * List2EList(list< CNode * > &v)
Converts a list of CNode* into a linked ELIST of the elements.
Definition: cnode.h:1015
Definition: cnode.h:95
CNode * cMUL_N(CNode *first,...)
Definition: cnode.h:1300
static CObstack * CurrentHeap()
Gets pointer to current heap allocator.
Definition: cnode.h:237
int IsConstant()
Checks expression tree to see if it is constant.
Definition: cnode_def.h:8183
CNode * GetWidthExp(void)
Create expression representing width of expression.
Definition: cnode_def.h:8837
CBlock CScope
Definition: cnode.h:65
CNode * cNEG(CNode *a0, Coord_t *loc=NULL)
Node construction shortcut for NEG negation.
Definition: cnode_def.h:4434
Strength_t s1
Definition: cnode.h:110
void ArgList2Vector(CNode *n, NodeOp_t op, int argNumber, vector< T > &v)
Walks a list of nodes and collects the specified augments of a given node type.
Definition: cnode.h:918
void MeasureDepth(CNode *n, int *count, int *depth)
Definition: cnode.h:1157
void PostVisit1(void(*callback)(CNode *, void *), void *data)
Walk tree invoking callback on each node after children have been visited.
Definition: cnode_def.h:10654
long INT32
Short cut for signed 32 bit integer.
Definition: glue.h:38
int IsReal(void)
Determine if expression is real.
Definition: cnode.h:509
int IsVolatile(void)
Checks to see if expression tree is volatile.
Definition: cnode_def.h:8349
int Precedence()
Get the precedence of the operator represented by the node.
Definition: cnode_def.h:8011
CNode_sp< T > Arg(int index)
Get a node's operand.
Definition: cnode.h:549
Edge_t
Edge values.
Definition: cnode.h:72
reference to port
Definition: cnode_def.h:1008
void * Alloc(INT32 size)
Allocate block of storage with given size.
reference to a forward declared variable
Definition: cnode_def.h:1018
static CVector * AllocFromHeap(CObstack *aHeap, int width)
Create vector allocating all storage from given heap.
Definition: cvector.h:85
int operator!=(CNode_pr p)
Definition: cnode.h:162
int operator!=(CNode_sp< T > p)
Definition: cnode.h:145
void List2VectorExclude(CNode *n, const set< NodeOp_t > &excludeOps, vector< CNode * > &v)
Walks an expression list of nodes and collects the subtrees that don't match the given node types...
Definition: cnode.h:971
CNode * operator=(CNode *n)
Definition: cnode.h:156
INT32 EvalINT32()
Evaluates expression tree and returns value as a 32 bit integer.
Definition: cnode.cc:308
CNode * cHOOK(CNode *a0, CNode *a1, CNode *a2, Coord_t *loc=NULL)
Node construction shortcut for HOOK condition expression operator.
Definition: cnode_def.h:5027
T operator=(T n)
Definition: cnode.h:138
static void ResetBuildStack(void)
Restore previous heap.
Definition: cnode.h:264
reference to a genvar
Definition: cnode_def.h:1028
CNode * third
Definition: cnode.h:173
int ArgCount(void)
Get the number of operands for the node.
Definition: cnode_def.h:7685
Helper class for building tail recursive binary CNode trees Used by parser.
Definition: cnode.h:152
int Based()
Get based attribute.
Definition: cvector.h:155
Pair of strengths.
Definition: cnode.h:108
Structure to hold file coordinates.
Definition: cdecl.h:47
Holder for character strings.
Definition: csymbol.h:44
ILLEGAL_OP2(Rsh)
Declaration object for module/function/task ports.
Definition: cport.h:44
CNode * first
Definition: cnode.h:171
Forward reference declaration.
Definition: cfref.h:51
Bulk object allocation object.
Definition: cobstack.h:46
CNode * cABSDIFFPLUS1_N(CNode *first,...)
Definition: cnode.h:1316
Definition: cnode.h:119
Definition: cnode.h:99
reference to net
Definition: cnode_def.h:978
Strength_t
Strength values.
Definition: cnode.h:93
Primary data structure representing parse tree nodes.
Definition: cnode.h:197
int operator==(CNode_sp< T > p)
Definition: cnode.h:144
NodeOp_t
Parse tree opcodes.
Definition: cnode_def.h:636
CNode * cLINK(CNode *n1, CNode *n2)
Short cut for linking together to nodes with a LIST operator.
Definition: cnode.h:877
CNode * cELINK(CNode *n1, CNode *n2)
Link together two nodes with an ELIST operator.
Definition: cnode.h:831
int IsNonX(int integerIsNonX=0, char *exclude=NULL)
Checks expression tree to see if expression can result in an X or Z.
Definition: cnode_def.h:9451
Declaration object for module and gate instances.
Definition: cinstance.h:45
expression list
Definition: cnode_def.h:707
void EvalVector(CVector &v)
Evaluates expression tree evaluated in unconstrainted context.
Definition: cnode.cc:360
Definition: cnode.h:74
CNode * head
Definition: cnode.h:153
void Pow(double *r, double *a, double *b)
Definition: cnode.h:712
CNode * Vector2EList(const vector< CNode * > &v)
Converts a vector array of CNode* into a linked ELIST of the elements.
Definition: cnode.h:995
CNode(Coord_t *aLoc, NodeOp_t aOp)
Constructor for parse node.
Definition: cnode.cc:240
member reference (structure, class or external
Definition: cnode_def.h:2240
Definition: cmodule.h:54
CAttr * GetAttribute(const char *name, CNode *n=NULL, int init=1)
Get attribute attached to node with the given attribute.
Definition: cnode.cc:445
void SetAttributes(CNode *attr)
Attach attributes to operation.
Definition: cnode.h:519
CNode_sp(void **np)
Pointer to untyped argument.
Definition: cnode.h:137
static void SetBuildStack(CObstack *aStack)
Set heap to a specific heap.
Definition: cnode.h:256
int operator!=(T v)
Definition: cnode.h:143
CNode * cVECTOR(CVector &vec)
Short cut for creating VCONSTANT node with a given vector value.
Definition: cnode.h:762
CNode * PostSubVisit1(CNode *(*callback)(CNode *, void *), void *data)
Walk tree invoking callback on each node after children have been visited.
Definition: cnode_def.h:11193
Definition: cnode.h:75
void Div(double *r, double *a, double *b)
Definition: cnode.h:697
Definitions for parse tree nodes.
void SetOp(NodeOp_t aOp)
Set node's operation type.
Definition: cnode.h:329
Base class for describing declaration objects.
Definition: cdecl.h:164
CNode * tail
Definition: cnode.h:154
int IsVector(void)
Determine if expression is a multi-bit signed or unsigned value.
Definition: cnode.h:504
void Sub(double *r, double *a, double *b)
Definition: cnode.h:687
int operator==(CNode_pr p)
Definition: cnode.h:161
int Sized()
Get sized attribute.
Definition: cvector.h:143
Declaration object for variables.
Definition: cvar.h:50
external reference
Definition: cnode_def.h:2020
Declaration object for parameters.
Definition: cparam.h:46
Declaration object for holding lists of verilog attributes and their corresponding expressions...
Definition: cattr.h:50
CNode * cINT32(INT32 i)
Short cut for creating VCONSTANT node with a given integer value.
Definition: cnode.h:798
Definition: cnode.h:118
int IsWidthEvaluateable(void)
Evaluates if expression width can be evaluated.
Definition: cnode_def.h:9289
Bit vector class for implementing 4 state verilog signed and unsigned arithmetic. ...
Definition: cvector.h:58
CNode * cGE(CNode *a0, CNode *a1, Coord_t *loc=NULL)
Node construction shortcut for GE greater than or equal.
Definition: cnode_def.h:4555
void PreVisit1(int(*callback)(CNode *, void *), void *data)
Walk tree invoking callback on each node before children have been visited.
Definition: cnode_def.h:10128
Definition: cnode.h:78
INT32 GetWidth(void)
Evaluate width of expression.
Definition: cnode.h:494
Base class for vrq objects.
Definition: cobject.h:41
CNode * cLT(CNode *a0, CNode *a1, Coord_t *loc=NULL)
Node construction shortcut for LT less than.
Definition: cnode_def.h:4588
void Mul(double *r, double *a, double *b)
Definition: cnode.h:692
int IsWidthConstant(void)
Evaluates if expression width is constant.
Definition: cnode_def.h:8515
void EList2VectorExclude(CNode *n, const set< NodeOp_t > &excludeOps, vector< CNode * > &v)
Walks an expression elist of nodes and collects the subtrees that don't match the given node types...
Definition: cnode.h:945
NodeType_t GetNodeType(void)
Get node expression type.
Definition: cnode.h:540
int GetPreferredBase()
Get preferred base for printing value.
Definition: cvector.h:137
void Plus(double *r, double *a)
Definition: cnode.h:707
int operator!=(CNode *v)
Definition: cnode.h:160
INT32 GetWidth(void)
Get vector bit width.
int Signed() const
Get signed attribute.
Definition: cvector.h:178
vector subrange
Definition: cnode_def.h:1153
real - have width 0
Definition: cdatatype.h:103
Declaration object for functions and tasks.
Definition: cfunction.h:50
Definition: cnode.h:73
int operator==(CNode *v)
Definition: cnode.h:159
CNode * cLIST(CNode *a0, CNode *a1, Coord_t *loc=NULL)
Node construction shortcut for LIST list of nodes.
Definition: cnode_def.h:4088
Definition: cnode.h:86
unsigned Hash()
Calculate hash of tree.
Definition: cnode_def.h:11734
int LoadString(const char *string)
Load string value from string.
Declaration object for input/output/inout statements.
Definition: cportdir.h:45
CNode * cMAX(CNode *n1, CNode *n2)
Short cut for creating a expression tree that calculates the maximum of two expressions.
Definition: cnode.h:895
T operator->()
Definition: cnode.h:139
CNode * cADD_N(CNode *first,...)
Definition: cnode.h:1284
CNode * cABS(CNode *a)
Short cut for creating an subtree that calculates the absolute value of an expression.
Definition: cnode.h:848
Strength_t s0
Definition: cnode.h:109
NodeType_t
Expression node type.
Definition: cdatatype.h:101
Definition: cnode.h:87
friend CNode_pr cLINK(CNode_pr pr1, CNode *n2)
Definition: cnode.h:1187
const char * GetOpName()
Return node's operation type as a string.
Definition: cnode.h:322
void Free(void *object)
Free all storage including and after object.
CNode * GetAttributes()
Get attributes attached to operation.
Definition: cnode.h:514
Definition: cnode.h:85
const char * nodeOpName[]
Definition: cnode_def.h:2326
dimensioned reference (array/bit select)
Definition: cnode_def.h:968
NodeOp_t GetOp()
Return node's operation type.
Definition: cnode.h:317
int IsWidthVolatile(void)
Evaluates if expression width is volatile.
Definition: cnode_def.h:8675
Definition: cnode.h:102
void Dump(FILE *f)
Print a compact representation of the parse tree.
Definition: cnode_def.h:15479
Declaration class for block constructs.
Definition: cblock.h:52
int cABSDIFFPLUS1(int a1, int a2)
Definition: cnode.h:1354
ILLEGAL_OP1(Com)
DelayMode_t
Timing mode values.
Definition: cnode.h:84
vector subrange with descending index select
Definition: cnode_def.h:1175
Helper class for building tail recursive binary CNode trees Used by parser.
Definition: cnode.h:170
reference to parameter
Definition: cnode_def.h:998
Definition: cnode.h:98
double EvalReal(void)
Evaluates expression tree evaluated in a real context.
Definition: cnode.cc:391
Definition: cnode.h:101
Definition: cnode.h:97
CNode * cABSDIFF(CNode *a, CNode *b)
Short cut for creating an subtree that calculates the absolute difference between two expressions...
Definition: cnode.h:864
ConditionalType
Case/If type.
Definition: cnode.h:116
int operator==(T v)
Definition: cnode.h:142
string HierarchicalReference2String(CNode *ref)
Definition: cnode.h:1214
double s2d(char *s)
Convert char string to double.
Definition: cnode.h:1093
reference to variable
Definition: cnode_def.h:988
CNode * Clone(CObstack *heap=stack)
Replicate tree.
Definition: cnode_def.h:9626