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 
113 #define DEFINE_ENUM
114 #include "cnode_def.h"
115 #undef DEFINE_ENUM
116 
117 
124 template<class T>
125 class CNode_sp {
126  T* ptr;
127 public:
128  CNode_sp( void** np ) { ptr = (T*)np; }
129  T operator=( T n ) { *ptr = n; return n; }
130  T operator->() { return *ptr; }
131  T* Ptr() { return ptr; }
132  operator T() { return *ptr; }
133  int operator==( T v ) { return *ptr == v; }
134  int operator!=( T v ) { return *ptr != v; }
135  int operator==( CNode_sp<T> p ) { return *ptr == *p.ptr; }
136  int operator!=( CNode_sp<T> p ) { return *ptr != *p.ptr; }
137 };
138 
143 struct CNode_pr {
146 public:
147  CNode* operator=( CNode* n ) { head = n; tail = n; return n; }
148  CNode* operator->() { return head; }
149  operator CNode*() { return head; }
150  int operator==( CNode* v ) { return head == v; }
151  int operator!=( CNode* v ) { return head != v; }
152  int operator==( CNode_pr p ) { return head == p.head; }
153  int operator!=( CNode_pr p ) { return head != p.head; }
154  friend CNode_pr cLINK( CNode_pr pr1, CNode* n2 );
155 };
156 
165 };
166 
167 
188 class CNode : public CObject
189 {
190 private:
191  static list<CObstack*> stackList;
192  static CObstack evalHeap;
193  static INT32 evalCount;
194  static CObstack* stack;
195  static map<CNode*,int> labelCache;
196  static int labelCacheEnabled;
197  NodeOp_t op;
198  void* left;
199  void* right;
200  Coord_t loc;
201  Coord_t *locp;
202  CNode* attributes;
203  /*
204  * These decorations are temporary and used
205  * by the expression evaluation routines
206  */
207  NodeType_t type;
208  INT32 width;
209  int fixedWidth;
210 private:
211  int LabelBits( int supressErrorMessages = FALSE );
212  CNode* FixBits( INT32 newWidth, NodeType_t newType );
213  void _EvalVector( CVector& v );
214  double _EvalReal( void );
215  void FixedWidth( int v ) { fixedWidth = v; }
216  int FixedWidth() { return fixedWidth; }
217  int ConditionalWiden();
218  int WidthFixed();
219  unsigned NodeMask();
220  CNode* GetNLeft( void ) { return (CNode*)left; }
221  CNode* GetNRight( void ) { return (CNode*)right; }
222  static void _LabelBits( CNode* n, void* arg );
223 public:
228  static CObstack* CurrentHeap() { return stack; }
238  static void UseEvalStack( void ) {
239  stackList.push_front( stack );
240  evalCount++;
241  stack = &evalHeap;
242  }
247  static void SetBuildStack( CObstack* aStack ) {
248  MASSERT( evalCount == 0 );
249  stackList.push_front( stack );
250  stack = aStack;
251  }
255  static void ResetBuildStack( void ) {
256  if( stack == &evalHeap ) {
257  evalCount--;
258  if( evalCount == 0 ) {
259  evalHeap.Free( NULL );
260  }
261  }
262  if( stackList.empty() ) {
263  stack = NULL;
264  } else {
265  stack = *stackList.begin();
266  stackList.pop_front();
267  }
268  }
278  static void EnableLabelCache()
279  {
280  labelCacheEnabled = 1;
281  }
287  {
288  labelCacheEnabled = 0;
289  labelCache.erase( labelCache.begin(), labelCache.end() );
290  }
298  CNode( Coord_t* aLoc, NodeOp_t aOp );
303  Coord_t* GetCoord() { return locp; }
308  NodeOp_t GetOp() { return op; }
313  const char* GetOpName() { return nodeOpName[op]; }
320  void SetOp( NodeOp_t aOp ) {
321  int oldCount = ArgCount();
322  op = aOp;
323  MASSERT( oldCount == ArgCount() );
324  }
330  unsigned Hash();
336  template<class T> CNode_sp<T> Arg( int index );
341  int ArgCount( void );
349  CNode* Clone( CObstack* heap = stack );
354  int Precedence();
361  void PostVisit1( void (*callback)(CNode*,void*), void* data );
370  CNode* PostSubVisit1( CNode* (*callback)(CNode*,void*),
371  void* data );
379  void PreVisit1( int (*callback)(CNode*,void*), void* data );
388  CNode* Simplify( INT32 newWidth, NodeType_t newType );
398  int IsNonX( int integerIsNonX = 0, char* exclude = NULL );
404  int IsConstant();
414  int IsEvaluateable();
420  int IsVolatile( void );
425  INT32 EvalINT32();
432  void EvalVector( CVector& v );
441  void EvalVector( CVector& v, INT32 newWidth, NodeType_t newType );
447  double EvalReal( void );
452  void Dump( FILE* f );
458  int IsWidthConstant( void );
464  int IsWidthVolatile( void );
474  int IsWidthEvaluateable( void );
479  CNode* GetWidthExp( void );
485  INT32 GetWidth( void ) { LabelBits(TRUE); return width; }
490  int IsScalar( void ) { LabelBits(TRUE); return width==1; }
495  int IsVector( void ) { LabelBits(TRUE); return width>1; }
500  int IsReal( void ) { LabelBits(TRUE); return type==eR; }
505  CNode* GetAttributes() { return attributes; }
510  void SetAttributes( CNode* attr ) { attributes = attr; }
518  int HasAttribute( const char* name, CNode* n=NULL, int init = 1 );
526  CAttr* GetAttribute( const char* name, CNode* n=NULL, int init = 1 );
531  NodeType_t GetNodeType( void ) { LabelBits(TRUE); return type; }
532 };
533 
534 
535 /************************************************
536  Arg<CNode*>
537  - returns CNode smart pointer to arg by index
538  ***********************************************/
539 
540 template<class T> CNode_sp<T> CNode::Arg(int index)
541 {
542  switch( ArgCount() ) {
543  case 1:
544  switch( index ) {
545  case 0:
546  return CNode_sp<T>(&left);
547  default:
548  MASSERT( FALSE );
549  return NULL;
550  }
551  case 2:
552  switch( index ) {
553  case 0:
554  return CNode_sp<T>(&left);
555  case 1:
556  return CNode_sp<T>(&right);
557  default:
558  MASSERT( FALSE );
559  return NULL;
560  }
561  case 3:
562  switch( index ) {
563  case 0:
564  return CNode_sp<T>(&GetNLeft()->left);
565  case 1:
566  return CNode_sp<T>(&GetNLeft()->right);
567  case 2:
568  return CNode_sp<T>(&right);
569  default:
570  MASSERT( FALSE );
571  return NULL;
572  }
573  case 4:
574  switch( index ) {
575  case 0:
576  return CNode_sp<T>(&GetNLeft()->left);
577  case 1:
578  return CNode_sp<T>(&GetNLeft()->right);
579  case 2:
580  return CNode_sp<T>(&GetNRight()->left);
581  case 3:
582  return CNode_sp<T>(&GetNRight()->right);
583  default:
584  MASSERT( FALSE );
585  return NULL;
586  }
587  case 5:
588  switch( index ) {
589  case 0:
590  return CNode_sp<T>(&GetNLeft()->GetNLeft()->left);
591  case 1:
592  return CNode_sp<T>(&GetNLeft()->GetNLeft()->right);
593  case 2:
594  return CNode_sp<T>(&GetNLeft()->right);
595  case 3:
596  return CNode_sp<T>(&GetNRight()->left);
597  case 4:
598  return CNode_sp<T>(&GetNRight()->right);
599  default:
600  MASSERT( FALSE );
601  return NULL;
602  }
603  case 6:
604  switch( index ) {
605  case 0:
606  return CNode_sp<T>(&GetNLeft()->GetNLeft()->left);
607  case 1:
608  return CNode_sp<T>(&GetNLeft()->GetNLeft()->right);
609  case 2:
610  return CNode_sp<T>(&GetNLeft()->GetNRight()->left);
611  case 3:
612  return CNode_sp<T>(&GetNLeft()->GetNRight()->right);
613  case 4:
614  return CNode_sp<T>(&GetNRight()->left);
615  case 5:
616  return CNode_sp<T>(&GetNRight()->right);
617  default:
618  MASSERT( FALSE );
619  return NULL;
620  }
621  case 7:
622  switch( index ) {
623  case 0:
624  return CNode_sp<T>(&GetNLeft()->GetNLeft()->left);
625  case 1:
626  return CNode_sp<T>(&GetNLeft()->GetNLeft()->right);
627  case 2:
628  return CNode_sp<T>(&GetNLeft()->GetNRight()->left);
629  case 3:
630  return CNode_sp<T>(&GetNLeft()->GetNRight()->right);
631  case 4:
632  return CNode_sp<T>(&GetNRight()->GetNLeft()->left);
633  case 5:
634  return CNode_sp<T>(&GetNRight()->GetNLeft()->right);
635  case 6:
636  return CNode_sp<T>(&GetNRight()->right);
637  default:
638  MASSERT( FALSE );
639  return NULL;
640  }
641  case 8:
642  switch( index ) {
643  case 0:
644  return CNode_sp<T>(&GetNLeft()->GetNLeft()->left);
645  case 1:
646  return CNode_sp<T>(&GetNLeft()->GetNLeft()->right);
647  case 2:
648  return CNode_sp<T>(&GetNLeft()->GetNRight()->left);
649  case 3:
650  return CNode_sp<T>(&GetNLeft()->GetNRight()->right);
651  case 4:
652  return CNode_sp<T>(&GetNRight()->GetNLeft()->left);
653  case 5:
654  return CNode_sp<T>(&GetNRight()->GetNLeft()->right);
655  case 6:
656  return CNode_sp<T>(&GetNRight()->GetNRight()->left);
657  case 7:
658  return CNode_sp<T>(&GetNRight()->GetNRight()->right);
659  default:
660  MASSERT( FALSE );
661  return NULL;
662  }
663 
664  default:
665  MASSERT( FALSE );
666  }
667 }
668 int Equivalent( CNode* a, CNode* b );
669 /******************************************************
670  real operation routines
671  ******************************************************/
672 
673 inline void Add( double* r, double* a, double* b )
674 {
675  *r = *a + *b;
676 }
677 
678 inline void Sub( double* r, double* a, double* b )
679 {
680  *r = *a - *b;
681 }
682 
683 inline void Mul( double* r, double* a, double* b )
684 {
685  *r = *a * *b;
686 }
687 
688 inline void Div( double* r, double* a, double* b )
689 {
690  *r = *a / *b;
691 }
692 
693 inline void Neg( double* r, double* a )
694 {
695  *r = - *a;
696 }
697 
698 inline void Plus( double* r, double* a )
699 {
700  *r = *a;
701 }
702 
703 inline void Pow( double* r, double* a, double* b )
704 {
705  *r = pow(*a,*b);
706 }
707 
708 
709 /*****************************************************
710  * Create stubs for illegal operations
711  ****************************************************/
712 #define ILLEGAL_OP2(op) \
713 inline void op( double*, double*, double* )\
714 { fatal( NULL, #op " is illegal for reals" ); }
715 
716 #define ILLEGAL_OP1(op) \
717 inline void op( double*, double* )\
718 { fatal( NULL, #op " is illegal for reals" ); }
719 
720 ILLEGAL_OP2(Rsh);
721 ILLEGAL_OP2(Lsh);
722 
723 ILLEGAL_OP2(Rep);
724 ILLEGAL_OP2(Mod);
725 ILLEGAL_OP2(And);
726 ILLEGAL_OP2(Xor);
727 ILLEGAL_OP2(Xnor);
728 ILLEGAL_OP2(Or);
729 ILLEGAL_OP2(Lor);
730 ILLEGAL_OP2(Land);
731 ILLEGAL_OP1(Com);
732 ILLEGAL_OP1(Rand);
733 ILLEGAL_OP1(Rnand);
734 ILLEGAL_OP1(Ror);
735 ILLEGAL_OP1(Rnor);
736 ILLEGAL_OP1(Rxor);
737 ILLEGAL_OP1(Rxnor);
738 
739 #define DEFINE_CONSTRUCTOR
740 #include "cnode_def.h"
741 #undef DEFINE_CONSTRUCTOR
742 
743 /****************************************************
744  Node building helper routines
745 *****************************************************/
746 
753 inline CNode* cVECTOR( CVector& vec )
754 {
756  CNode* n;
757  *v = vec;
759  n = new(CNode::CurrentHeap()) CNode( NULL, eVCONSTANT );
760  n->Arg<CVector*>(0) = v;
761  return n;
762 }
763 
770 inline CNode* cSTRING( const char* s )
771 {
772  int len = strlen( s );
773  if( !len ) {
774  len = 1;
775  }
777  v->LoadString( s );
778  CNode* n = new(CNode::CurrentHeap()) CNode( NULL, eVCONSTANT );
779  n->Arg<CVector*>(0) = v;
780  return n;
781 }
782 
789 inline CNode* cINT32( INT32 i )
790 {
792  CNode* n;
793  *v = i;
794  v->Sized(FALSE);
795  v->Signed(TRUE);
796  v->Based(FALSE);
797  n = new(CNode::CurrentHeap()) CNode( NULL, eVCONSTANT );
798  n->Arg<CVector*>(0) = v;
799  return n;
800 }
801 
808 inline CNode* cREAL( double number )
809 {
810  CNode* node = new(CNode::CurrentHeap()) CNode( NULL, eRCONSTANT );
811  node->Arg<char*>(0) = d2s(number,CNode::CurrentHeap());
812  return node;
813 }
814 
822 inline CNode* cELINK( CNode* n1, CNode* n2 )
823 {
824  if( n1 == NULL ) {
825  return n2;
826  } else if( n2 == NULL ) {
827  return n1;
828  }
829  return cELIST( n1, n2 );
830 }
831 
839 inline CNode* cABS( CNode* a )
840 {
841  CNode* a1 = a->Clone();
842  CNode* a2 = a->Clone();
843  CNode* c = cGE(a,cINT32(0));
844  return cHOOK( c, a1, cNEG( a2) );
845 }
846 
855 inline CNode* cABSDIFF( CNode* a, CNode* b )
856 {
857  return cABS( cSUB( a, b ) );
858 }
859 
868 inline CNode* cLINK( CNode* n1, CNode* n2 )
869 {
870  if( n1 == NULL ) {
871  return n2;
872  } else if( n2 == NULL ) {
873  return n1;
874  }
875  return cLIST( n1, n2 );
876 }
877 
886 inline CNode* cMAX( CNode* n1, CNode* n2 )
887 {
888  CNode* cond = cLT(n2->Clone(),n1->Clone());
889  return cHOOK(cond,n1,n2);
890 }
891 
892 
893 /****************************************************
894  utility routines
895 *****************************************************/
896 
909 template<class T> void ArgList2Vector(CNode* n, NodeOp_t op,
910  int argNumber, vector<T>& v)
911 {
912  if( !n ) {
913  return;
914  }
915  switch( n->GetOp() ) {
916  case eLIST:
917  ArgList2Vector<T>(n->Arg<CNode*>(0),op,argNumber,v);
918  ArgList2Vector<T>(n->Arg<CNode*>(1),op,argNumber,v);
919  break;
920  default:
921  if( n->GetOp() == op ) {
922  v.push_back(n->Arg<T>(argNumber));
923  }
924  break;
925  }
926 }
927 
936 inline void EList2VectorExclude(CNode* n, const set<NodeOp_t>& excludeOps, vector<CNode*>& v)
937 {
938  if( !n ) {
939  return;
940  }
941  switch( n->GetOp() ) {
942  case eELIST:
943  EList2VectorExclude(n->Arg<CNode*>(0),excludeOps,v);
944  EList2VectorExclude(n->Arg<CNode*>(1),excludeOps,v);
945  break;
946  default:
947  if( excludeOps.find(n->GetOp()) == excludeOps.end() ) {
948  v.push_back(n);
949  }
950  break;
951  }
952 }
953 
962 inline void List2VectorExclude(CNode* n, const set<NodeOp_t>& excludeOps, vector<CNode*>& v)
963 {
964  if( !n ) {
965  return;
966  }
967  switch( n->GetOp() ) {
968  case eLIST:
969  List2VectorExclude(n->Arg<CNode*>(0),excludeOps,v);
970  List2VectorExclude(n->Arg<CNode*>(1),excludeOps,v);
971  break;
972  default:
973  if( excludeOps.find(n->GetOp()) == excludeOps.end() ) {
974  v.push_back(n);
975  }
976  break;
977  }
978 }
979 
986 inline CNode* Vector2EList(const vector<CNode*>& v)
987 {
988  CNode* result = NULL;
989  vector<CNode*>::const_reverse_iterator ptr;
990  for( ptr = v.rbegin(); ptr != v.rend(); ++ptr ) {
991  if( result ) {
992  result = cELIST(*ptr, result);
993  } else {
994  result = *ptr;
995  }
996  }
997  return result;
998 }
999 
1006 inline CNode* List2EList(list<CNode*>& v)
1007 {
1008  CNode* result = NULL;
1009  list<CNode*>::reverse_iterator ptr;
1010  for( ptr = v.rbegin(); ptr != v.rend(); ++ptr ) {
1011  if( result ) {
1012  result = cELIST(*ptr, result);
1013  } else {
1014  result = *ptr;
1015  }
1016  }
1017  return result;
1018 }
1019 
1028 inline int ListCount(CNode* n, NodeOp_t op)
1029 {
1030  int result = 0;
1031  if( !n ) {
1032  return result;
1033  }
1034  switch( n->GetOp() ) {
1035  case eLIST:
1036  case eELIST:
1037  result += ListCount(n->Arg<CNode*>(0),op);
1038  result += ListCount(n->Arg<CNode*>(1),op);
1039  break;
1040  default:
1041  if( n->GetOp() == op ) {
1042  result = 1;
1043  }
1044  break;
1045  }
1046  return result;
1047 }
1048 
1055 inline int ListCount(CNode* n)
1056 {
1057  int result = 0;
1058  if( !n ) {
1059  return result;
1060  }
1061  switch( n->GetOp() ) {
1062  case eLIST:
1063  case eELIST:
1064  result += ListCount(n->Arg<CNode*>(0));
1065  result += ListCount(n->Arg<CNode*>(1));
1066  break;
1067  default:
1068  result = 1;
1069  break;
1070  }
1071  return result;
1072 }
1073 
1084 inline double s2d( char* s ) {
1085  return atof(s);
1086 }
1087 
1096 inline char* d2s( double d, CObstack* heap ) {
1097  char buffer[256];
1098  // note this isn't quite correct as it will turn
1099  // reals into ints, ie 2.0 => 2
1100  snprintf( buffer, sizeof(buffer), "%g", d );
1101  char* s = (char*)heap->Alloc(strlen(buffer)+1);
1102  strcpy( s, buffer );
1103  return s;
1104 }
1105 
1106 /*********************************************
1107  * Adjust nodes structure to be efficient for
1108  * tail recursion
1109  *********************************************/
1110 inline CNode* RebalanceRight( CNode* n ) {
1111  if( n == NULL ) {
1112  return n;
1113  }
1114  if( n->GetOp() != eLIST ) {
1115  return n;
1116  }
1117  CNode* result = n;
1118  CNode* parent = NULL;
1119  while( 1 ) {
1120  while( n->Arg<CNode*>(0) && n->Arg<CNode*>(0)->GetOp() == eLIST ) {
1121  CNode* l = n->Arg<CNode*>(0);
1122  CNode* ll = l->Arg<CNode*>(0);
1123  CNode* lr = l->Arg<CNode*>(1);
1124  l->Arg<CNode*>(1) = n;
1125  n->Arg<CNode*>(0) = lr;
1126  n = l;
1127  if( parent ) {
1128  parent->Arg<CNode*>(1) = n;
1129  } else {
1130  result = n;
1131  }
1132  }
1133  if( n->Arg<CNode*>(1) && n->Arg<CNode*>(1)->GetOp() == eLIST ) {
1134  parent = n;
1135  n = n->Arg<CNode*>(1);
1136  } else {
1137  break;
1138  }
1139  }
1140  return result;
1141 }
1142 /*********************************************
1143  * Analyse tree struct.
1144  * - depth is worst case stack depth right side
1145  * optimization.
1146  * count is number nodes.
1147  *********************************************/
1148 inline void MeasureDepth( CNode* n, int* count, int* depth )
1149 {
1150  *count = 0;
1151  *depth = 0;
1152  if( !n ) {
1153  return;
1154  }
1155  if( n->GetOp() == eLIST ) {
1156  int count0 = 0;
1157  int depth0 = 0;
1158  int count1 = 0;
1159  int depth1 = 0;
1160  if( n->Arg<CNode*>(0) ) {
1161  MeasureDepth( n->Arg<CNode*>(0), &count0, &depth0 );
1162  depth0++;
1163  }
1164  if( n->Arg<CNode*>(1) ) {
1165  MeasureDepth( n->Arg<CNode*>(1), &count1, &depth1 );
1166  }
1167  *count = count0+count1;
1168  *depth = depth0 > depth1 ? depth0 : depth1;
1169  }
1170  (*count)++;
1171 }
1172 
1173 
1174 /**************************************************
1175  * Helper routine for parser to build trees that
1176  * are effient for tail recursion.
1177  *************************************************/
1178 inline CNode_pr cLINK( CNode_pr pr1, CNode* n2 )
1179 {
1180  if( !n2 ) {
1181  return pr1;
1182  } else if( !pr1.tail ) {
1183  CNode_pr pr;
1184  pr.head = n2;
1185  pr.tail = n2;
1186  return pr;
1187  } else if( pr1.tail->GetOp() != eLIST ) {
1188  CNode* t = cLINK( pr1.head, n2 );
1189  CNode_pr pr;
1190  pr.head = t;
1191  pr.tail = t;
1192  return pr;
1193  } else {
1194  pr1.tail->Arg<CNode*>(1) = cLINK(pr1.tail->Arg<CNode*>(1),n2);
1195  CNode_pr pr;
1196  pr.head = pr1.head;
1197  pr.tail = pr1.tail->Arg<CNode*>(1);
1198  return pr;
1199  }
1200 }
1201 
1202 /**************************************************
1203  * convert hierarchical reference tree to string
1204  *************************************************/
1206 {
1207  string buffer;
1208  switch( ref->GetOp() ) {
1209  case eARRAY: {
1210  buffer = HierarchicalReference2String(ref->Arg<CNode*>(0)).c_str();
1211  vector<CNode*> indexes;
1212  EList2VectorExclude( ref->Arg<CNode*>(1),
1213  set<NodeOp_t>(), indexes );
1214  vector<CNode*>::iterator ptr;
1215  for( ptr = indexes.begin(); ptr != indexes.end(); ++ptr ) {
1216  switch( ref->Arg<CNode*>(0)->GetOp() ) {
1217  case eSLICE:
1218  case ePSLICE:
1219  case eMSLICE:
1220  break;
1221  default: {
1222  INT32 value = (*ptr)->EvalINT32();
1223  ostringstream subscript;
1224  subscript << '[' << value << ']';
1225  buffer += subscript.str();
1226  } break;
1227  }
1228  }
1229  } break;
1230  case eMEMBER:
1231  buffer = HierarchicalReference2String(ref->Arg<CNode*>(0)).c_str();
1232  buffer += ".";
1233  buffer += ref->Arg<CSymbol*>(1)->GetName();
1234  break;
1235  case eEXTERNAL_REF:
1236  buffer = ref->Arg<CSymbol*>(0)->GetName();
1237  ref = NULL;
1238  break;
1239  case eNET_REF:
1240  case eVAR_REF:
1241  case ePARAM_REF:
1242  case ePORT_REF:
1243  case eFWD_REF:
1244  case eGENVAR_REF:
1245  buffer = ref->Arg<CDecl*>(0)->GetName();
1246  ref = NULL;
1247  break;
1248  default:;
1249  MASSERT( FALSE );
1250  }
1251  return buffer;
1252 }
1253 
1254 /*****************************************************
1255  * Support routines for cnode_def.h constructs
1256  *****************************************************/
1257 inline CNode* cMAX_N( CNode* first, ... )
1258 {
1259  CNode* result = first;
1260  va_list ap;
1261  va_start( ap, first );
1262  while( 1 ) {
1263  CNode* arg = va_arg(ap,CNode*);
1264  if( !arg ) {
1265  break;
1266  }
1267  if( !Equivalent( result, arg ) ) {
1268  result = cMAX( result, arg );
1269  }
1270  }
1271  va_end( ap );
1272  return result;
1273 }
1274 
1275 inline CNode* cADD_N( CNode* first, ... )
1276 {
1277  CNode* result = first;
1278  va_list ap;
1279  va_start( ap, first );
1280  while( 1 ) {
1281  CNode* arg = va_arg(ap,CNode*);
1282  if( !arg ) {
1283  break;
1284  }
1285  result = cADD( result, arg );
1286  }
1287  va_end( ap );
1288  return result;
1289 }
1290 
1291 inline CNode* cMUL_N( CNode* first, ... )
1292 {
1293  CNode* result = first;
1294  va_list ap;
1295  va_start( ap, first );
1296  while( 1 ) {
1297  CNode* arg = va_arg(ap,CNode*);
1298  if( !arg ) {
1299  break;
1300  }
1301  result = cMUL( result, arg );
1302  }
1303  va_end( ap );
1304  return result;
1305 }
1306 
1307 inline CNode* cABSDIFFPLUS1_N( CNode* first, ... )
1308 {
1309  va_list ap;
1310  va_start( ap, first );
1311  CNode* second = va_arg(ap,CNode*);
1312  /*
1313  * only make sense for 2 args
1314  */
1315  MASSERT( va_arg(ap,CNode*) == NULL );
1316  va_end( ap );
1317 // return cADD(cABSDIFF(first,second),cINT32(1));
1318  return cHOOK(
1319  cGE(first,second),
1320  cADD(cSUB(first->Clone(),second->Clone()),cINT32(1)),
1321  cADD(cSUB(second->Clone(),first->Clone()),cINT32(1)) );
1322 
1323 }
1324 
1325 inline int cMAX( int a1, int a2 )
1326 {
1327  return a1 < a2 ? a2 : a1;
1328 }
1329 
1330 inline int cMAX( int a1, int a2, int a3 )
1331 {
1332  return cMAX(a1,cMAX(a2,a3));
1333 }
1334 
1335 inline int cADD( int a1, int a2 )
1336 {
1337  return a1 + a2;
1338 }
1339 
1340 inline int cMUL( int a1, int a2 )
1341 {
1342  return a1 * a2;
1343 }
1344 
1345 inline int cABSDIFFPLUS1( int a1, int a2 )
1346 {
1347  int diff = a1-a2;
1348  return (diff < 0 ? -diff : diff)+1;
1349 }
1350 
1351 
1352 #endif // CNODE_HPP
1353 
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:2879
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:286
real constant
Definition: cnode_def.h:654
vector subrange with ascending index select
Definition: cnode_def.h:1152
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:1340
static void UseEvalStack(void)
Use evaluation stack.
Definition: cnode.h:238
int Equivalent(CNode *a, CNode *b)
Definition: cnode_def.h:12084
Definition: cnode.h:77
Smart pointer for CNode class Creates safe references to CNode arguments Supports assignment...
Definition: cnode.h:125
CNode * operator->()
Definition: cnode.h:148
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:2788
CNode * RebalanceRight(CNode *n)
Definition: cnode.h:1110
Gate declaration object.
Definition: cgate.h:42
Definition: cnode.h:100
T * Ptr()
Definition: cnode.h:131
int IsScalar(void)
Determine if expression is a 1 bit signed or unsigned value.
Definition: cnode.h:490
CNode * cREAL(double number)
Short cut for creating RCONSTANT node with a given double value.
Definition: cnode.h:808
Definition: cnode.h:96
static void EnableLabelCache()
Enable cache of labeled nodes to be tracked.
Definition: cnode.h:278
int IsEvaluateable()
Checks to see if expression tree can be evaluated.
Definition: cnode_def.h:12632
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:1028
void Add(double *r, double *a, double *b)
Definition: cnode.h:673
int cADD(int a1, int a2)
Definition: cnode.h:1335
Declaration object for specify blocks.
Definition: cspecify.h:47
CNode * cMAX_N(CNode *first,...)
Definition: cnode.h:1257
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:1096
CNode * second
Definition: cnode.h:163
void Neg(double *r, double *a)
Definition: cnode.h:693
Definition: cnode.h:76
list of nodes
Definition: cnode_def.h:1119
vector constant
Definition: cnode_def.h:644
CNode * cSTRING(const char *s)
Short cut for creating VCONSTANT node with a given string value.
Definition: cnode.h:770
Coord_t * GetCoord()
Get node's file coordinates.
Definition: cnode.h:303
CNode * List2EList(list< CNode * > &v)
Converts a list of CNode* into a linked ELIST of the elements.
Definition: cnode.h:1006
Definition: cnode.h:95
CNode * cMUL_N(CNode *first,...)
Definition: cnode.h:1291
static CObstack * CurrentHeap()
Gets pointer to current heap allocator.
Definition: cnode.h:228
int IsConstant()
Checks expression tree to see if it is constant.
Definition: cnode_def.h:8057
CNode * GetWidthExp(void)
Create expression representing width of expression.
Definition: cnode_def.h:8695
CBlock CScope
Definition: cnode.h:65
CNode * cNEG(CNode *a0, Coord_t *loc=NULL)
Node construction shortcut for NEG negation.
Definition: cnode_def.h:4390
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:909
void MeasureDepth(CNode *n, int *count, int *depth)
Definition: cnode.h:1148
void PostVisit1(void(*callback)(CNode *, void *), void *data)
Walk tree invoking callback on each node after children have been visited.
Definition: cnode_def.h:10480
long INT32
Short cut for signed 32 bit integer.
Definition: glue.h:38
int IsReal(void)
Determine if expression is real.
Definition: cnode.h:500
int IsVolatile(void)
Checks to see if expression tree is volatile.
Definition: cnode_def.h:8219
int Precedence()
Get the precedence of the operator represented by the node.
Definition: cnode_def.h:7889
CNode_sp< T > Arg(int index)
Get a node's operand.
Definition: cnode.h:540
Edge_t
Edge values.
Definition: cnode.h:72
reference to port
Definition: cnode_def.h:996
void * Alloc(INT32 size)
Allocate block of storage with given size.
reference to a forward declared variable
Definition: cnode_def.h:1006
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:153
int operator!=(CNode_sp< T > p)
Definition: cnode.h:136
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:962
CNode * operator=(CNode *n)
Definition: cnode.h:147
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:4983
T operator=(T n)
Definition: cnode.h:129
static void ResetBuildStack(void)
Restore previous heap.
Definition: cnode.h:255
reference to a genvar
Definition: cnode_def.h:1016
CNode * third
Definition: cnode.h:164
int ArgCount(void)
Get the number of operands for the node.
Definition: cnode_def.h:7567
Helper class for building tail recursive binary CNode trees Used by parser.
Definition: cnode.h:143
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:162
Forward reference declaration.
Definition: cfref.h:51
Bulk object allocation object.
Definition: cobstack.h:46
CNode * cABSDIFFPLUS1_N(CNode *first,...)
Definition: cnode.h:1307
Definition: cnode.h:99
reference to net
Definition: cnode_def.h:966
Strength_t
Strength values.
Definition: cnode.h:93
Primary data structure representing parse tree nodes.
Definition: cnode.h:188
int operator==(CNode_sp< T > p)
Definition: cnode.h:135
NodeOp_t
Parse tree opcodes.
Definition: cnode_def.h:625
CNode * cLINK(CNode *n1, CNode *n2)
Short cut for linking together to nodes with a LIST operator.
Definition: cnode.h:868
CNode * cELINK(CNode *n1, CNode *n2)
Link together two nodes with an ELIST operator.
Definition: cnode.h:822
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:9293
Declaration object for module and gate instances.
Definition: cinstance.h:45
expression list
Definition: cnode_def.h:695
void EvalVector(CVector &v)
Evaluates expression tree evaluated in unconstrainted context.
Definition: cnode.cc:360
Definition: cnode.h:74
CNode * head
Definition: cnode.h:144
void Pow(double *r, double *a, double *b)
Definition: cnode.h:703
CNode * Vector2EList(const vector< CNode * > &v)
Converts a vector array of CNode* into a linked ELIST of the elements.
Definition: cnode.h:986
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:2223
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:510
CNode_sp(void **np)
Pointer to untyped argument.
Definition: cnode.h:128
static void SetBuildStack(CObstack *aStack)
Set heap to a specific heap.
Definition: cnode.h:247
int operator!=(T v)
Definition: cnode.h:134
CNode * cVECTOR(CVector &vec)
Short cut for creating VCONSTANT node with a given vector value.
Definition: cnode.h:753
CNode * PostSubVisit1(CNode *(*callback)(CNode *, void *), void *data)
Walk tree invoking callback on each node after children have been visited.
Definition: cnode_def.h:11013
Definition: cnode.h:75
void Div(double *r, double *a, double *b)
Definition: cnode.h:688
Definitions for parse tree nodes.
void SetOp(NodeOp_t aOp)
Set node's operation type.
Definition: cnode.h:320
Base class for describing declaration objects.
Definition: cdecl.h:164
CNode * tail
Definition: cnode.h:145
int IsVector(void)
Determine if expression is a multi-bit signed or unsigned value.
Definition: cnode.h:495
void Sub(double *r, double *a, double *b)
Definition: cnode.h:678
int operator==(CNode_pr p)
Definition: cnode.h:152
int Sized()
Get sized attribute.
Definition: cvector.h:143
Declaration object for variables.
Definition: cvar.h:50
external reference
Definition: cnode_def.h:2003
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:789
int IsWidthEvaluateable(void)
Evaluates if expression width can be evaluated.
Definition: cnode_def.h:9135
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:4511
void PreVisit1(int(*callback)(CNode *, void *), void *data)
Walk tree invoking callback on each node before children have been visited.
Definition: cnode_def.h:9960
Definition: cnode.h:78
INT32 GetWidth(void)
Evaluate width of expression.
Definition: cnode.h:485
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:4544
void Mul(double *r, double *a, double *b)
Definition: cnode.h:683
int IsWidthConstant(void)
Evaluates if expression width is constant.
Definition: cnode_def.h:8381
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:936
NodeType_t GetNodeType(void)
Get node expression type.
Definition: cnode.h:531
int GetPreferredBase()
Get preferred base for printing value.
Definition: cvector.h:137
void Plus(double *r, double *a)
Definition: cnode.h:698
int operator!=(CNode *v)
Definition: cnode.h:151
INT32 GetWidth(void)
Get vector bit width.
int Signed() const
Get signed attribute.
Definition: cvector.h:178
vector subrange
Definition: cnode_def.h:1141
real - have width 0
Definition: cdatatype.h:101
Declaration object for functions and tasks.
Definition: cfunction.h:50
Definition: cnode.h:73
int operator==(CNode *v)
Definition: cnode.h:150
CNode * cLIST(CNode *a0, CNode *a1, Coord_t *loc=NULL)
Node construction shortcut for LIST list of nodes.
Definition: cnode_def.h:4044
Definition: cnode.h:86
unsigned Hash()
Calculate hash of tree.
Definition: cnode_def.h:11548
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:886
T operator->()
Definition: cnode.h:130
CNode * cADD_N(CNode *first,...)
Definition: cnode.h:1275
CNode * cABS(CNode *a)
Short cut for creating an subtree that calculates the absolute value of an expression.
Definition: cnode.h:839
Strength_t s0
Definition: cnode.h:109
NodeType_t
Expression node type.
Definition: cdatatype.h:99
Definition: cnode.h:87
friend CNode_pr cLINK(CNode_pr pr1, CNode *n2)
Definition: cnode.h:1178
const char * GetOpName()
Return node's operation type as a string.
Definition: cnode.h:313
void Free(void *object)
Free all storage including and after object.
CNode * GetAttributes()
Get attributes attached to operation.
Definition: cnode.h:505
Definition: cnode.h:85
const char * nodeOpName[]
Definition: cnode_def.h:2290
dimensioned reference (array/bit select)
Definition: cnode_def.h:956
NodeOp_t GetOp()
Return node's operation type.
Definition: cnode.h:308
int IsWidthVolatile(void)
Evaluates if expression width is volatile.
Definition: cnode_def.h:8537
Definition: cnode.h:102
void Dump(FILE *f)
Print a compact representation of the parse tree.
Definition: cnode_def.h:15233
Declaration class for block constructs.
Definition: cblock.h:52
int cABSDIFFPLUS1(int a1, int a2)
Definition: cnode.h:1345
ILLEGAL_OP1(Com)
DelayMode_t
Timing mode values.
Definition: cnode.h:84
vector subrange with descending index select
Definition: cnode_def.h:1163
Helper class for building tail recursive binary CNode trees Used by parser.
Definition: cnode.h:161
reference to parameter
Definition: cnode_def.h:986
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:855
int operator==(T v)
Definition: cnode.h:133
string HierarchicalReference2String(CNode *ref)
Definition: cnode.h:1205
double s2d(char *s)
Convert char string to double.
Definition: cnode.h:1084
reference to variable
Definition: cnode_def.h:976
CNode * Clone(CObstack *heap=stack)
Replicate tree.
Definition: cnode_def.h:9464