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; }
315  void SetOp( NodeOp_t aOp ) {
316  int oldCount = ArgCount();
317  op = aOp;
318  MASSERT( oldCount == ArgCount() );
319  }
325  unsigned Hash();
331  template<class T> CNode_sp<T> Arg( int index );
336  int ArgCount( void );
344  CNode* Clone( CObstack* heap = stack );
349  int Precedence();
356  void PostVisit1( void (*callback)(CNode*,void*), void* data );
365  CNode* PostSubVisit1( CNode* (*callback)(CNode*,void*),
366  void* data );
374  void PreVisit1( int (*callback)(CNode*,void*), void* data );
383  CNode* Simplify( INT32 newWidth, NodeType_t newType );
393  int IsNonX( int integerIsNonX = 0, char* exclude = NULL );
399  int IsConstant();
409  int IsEvaluateable();
415  int IsVolatile( void );
420  INT32 EvalINT32();
427  void EvalVector( CVector& v );
436  void EvalVector( CVector& v, INT32 newWidth, NodeType_t newType );
442  double EvalReal( void );
447  void Dump( FILE* f );
453  int IsWidthConstant( void );
459  int IsWidthVolatile( void );
469  int IsWidthEvaluateable( void );
474  CNode* GetWidthExp( void );
480  INT32 GetWidth( void ) { LabelBits(TRUE); return width; }
485  int IsScalar( void ) { LabelBits(TRUE); return width==1; }
490  int IsVector( void ) { LabelBits(TRUE); return width>1; }
495  int IsReal( void ) { LabelBits(TRUE); return type==eR; }
500  CNode* GetAttributes() { return attributes; }
505  void SetAttributes( CNode* attr ) { attributes = attr; }
513  int HasAttribute( const char* name, CNode* n=NULL, int init = 1 );
521  CAttr* GetAttribute( const char* name, CNode* n=NULL, int init = 1 );
526  NodeType_t GetNodeType( void ) { LabelBits(TRUE); return type; }
527 };
528 
529 
530 /************************************************
531  Arg<CNode*>
532  - returns CNode smart pointer to arg by index
533  ***********************************************/
534 
535 template<class T> CNode_sp<T> CNode::Arg(int index)
536 {
537  switch( ArgCount() ) {
538  case 1:
539  switch( index ) {
540  case 0:
541  return CNode_sp<T>(&left);
542  default:
543  MASSERT( FALSE );
544  return NULL;
545  }
546  case 2:
547  switch( index ) {
548  case 0:
549  return CNode_sp<T>(&left);
550  case 1:
551  return CNode_sp<T>(&right);
552  default:
553  MASSERT( FALSE );
554  return NULL;
555  }
556  case 3:
557  switch( index ) {
558  case 0:
559  return CNode_sp<T>(&GetNLeft()->left);
560  case 1:
561  return CNode_sp<T>(&GetNLeft()->right);
562  case 2:
563  return CNode_sp<T>(&right);
564  default:
565  MASSERT( FALSE );
566  return NULL;
567  }
568  case 4:
569  switch( index ) {
570  case 0:
571  return CNode_sp<T>(&GetNLeft()->left);
572  case 1:
573  return CNode_sp<T>(&GetNLeft()->right);
574  case 2:
575  return CNode_sp<T>(&GetNRight()->left);
576  case 3:
577  return CNode_sp<T>(&GetNRight()->right);
578  default:
579  MASSERT( FALSE );
580  return NULL;
581  }
582  case 5:
583  switch( index ) {
584  case 0:
585  return CNode_sp<T>(&GetNLeft()->GetNLeft()->left);
586  case 1:
587  return CNode_sp<T>(&GetNLeft()->GetNLeft()->right);
588  case 2:
589  return CNode_sp<T>(&GetNLeft()->right);
590  case 3:
591  return CNode_sp<T>(&GetNRight()->left);
592  case 4:
593  return CNode_sp<T>(&GetNRight()->right);
594  default:
595  MASSERT( FALSE );
596  return NULL;
597  }
598  case 6:
599  switch( index ) {
600  case 0:
601  return CNode_sp<T>(&GetNLeft()->GetNLeft()->left);
602  case 1:
603  return CNode_sp<T>(&GetNLeft()->GetNLeft()->right);
604  case 2:
605  return CNode_sp<T>(&GetNLeft()->GetNRight()->left);
606  case 3:
607  return CNode_sp<T>(&GetNLeft()->GetNRight()->right);
608  case 4:
609  return CNode_sp<T>(&GetNRight()->left);
610  case 5:
611  return CNode_sp<T>(&GetNRight()->right);
612  default:
613  MASSERT( FALSE );
614  return NULL;
615  }
616  case 7:
617  switch( index ) {
618  case 0:
619  return CNode_sp<T>(&GetNLeft()->GetNLeft()->left);
620  case 1:
621  return CNode_sp<T>(&GetNLeft()->GetNLeft()->right);
622  case 2:
623  return CNode_sp<T>(&GetNLeft()->GetNRight()->left);
624  case 3:
625  return CNode_sp<T>(&GetNLeft()->GetNRight()->right);
626  case 4:
627  return CNode_sp<T>(&GetNRight()->GetNLeft()->left);
628  case 5:
629  return CNode_sp<T>(&GetNRight()->GetNLeft()->right);
630  case 6:
631  return CNode_sp<T>(&GetNRight()->right);
632  default:
633  MASSERT( FALSE );
634  return NULL;
635  }
636  case 8:
637  switch( index ) {
638  case 0:
639  return CNode_sp<T>(&GetNLeft()->GetNLeft()->left);
640  case 1:
641  return CNode_sp<T>(&GetNLeft()->GetNLeft()->right);
642  case 2:
643  return CNode_sp<T>(&GetNLeft()->GetNRight()->left);
644  case 3:
645  return CNode_sp<T>(&GetNLeft()->GetNRight()->right);
646  case 4:
647  return CNode_sp<T>(&GetNRight()->GetNLeft()->left);
648  case 5:
649  return CNode_sp<T>(&GetNRight()->GetNLeft()->right);
650  case 6:
651  return CNode_sp<T>(&GetNRight()->GetNRight()->left);
652  case 7:
653  return CNode_sp<T>(&GetNRight()->GetNRight()->right);
654  default:
655  MASSERT( FALSE );
656  return NULL;
657  }
658 
659  default:
660  MASSERT( FALSE );
661  }
662 }
663 int Equivalent( CNode* a, CNode* b );
664 /******************************************************
665  real operation routines
666  ******************************************************/
667 
668 inline void Add( double* r, double* a, double* b )
669 {
670  *r = *a + *b;
671 }
672 
673 inline void Sub( double* r, double* a, double* b )
674 {
675  *r = *a - *b;
676 }
677 
678 inline void Mul( double* r, double* a, double* b )
679 {
680  *r = *a * *b;
681 }
682 
683 inline void Div( double* r, double* a, double* b )
684 {
685  *r = *a / *b;
686 }
687 
688 inline void Neg( double* r, double* a )
689 {
690  *r = - *a;
691 }
692 
693 inline void Plus( double* r, double* a )
694 {
695  *r = *a;
696 }
697 
698 inline void Pow( double* r, double* a, double* b )
699 {
700  *r = pow(*a,*b);
701 }
702 
703 
704 /*****************************************************
705  * Create stubs for illegal operations
706  ****************************************************/
707 #define ILLEGAL_OP2(op) \
708 inline void op( double*, double*, double* )\
709 { fatal( NULL, #op " is illegal for reals" ); }
710 
711 #define ILLEGAL_OP1(op) \
712 inline void op( double*, double* )\
713 { fatal( NULL, #op " is illegal for reals" ); }
714 
715 ILLEGAL_OP2(Rsh);
716 ILLEGAL_OP2(Lsh);
717 
718 ILLEGAL_OP2(Rep);
719 ILLEGAL_OP2(Mod);
720 ILLEGAL_OP2(And);
721 ILLEGAL_OP2(Xor);
722 ILLEGAL_OP2(Xnor);
723 ILLEGAL_OP2(Or);
724 ILLEGAL_OP2(Lor);
725 ILLEGAL_OP2(Land);
726 ILLEGAL_OP1(Com);
727 ILLEGAL_OP1(Rand);
728 ILLEGAL_OP1(Rnand);
729 ILLEGAL_OP1(Ror);
730 ILLEGAL_OP1(Rnor);
731 ILLEGAL_OP1(Rxor);
732 ILLEGAL_OP1(Rxnor);
733 
734 #define DEFINE_CONSTRUCTOR
735 #include "cnode_def.h"
736 #undef DEFINE_CONSTRUCTOR
737 
738 /****************************************************
739  Node building helper routines
740 *****************************************************/
741 
748 inline CNode* cVECTOR( CVector& vec )
749 {
751  CNode* n;
752  *v = vec;
754  n = new(CNode::CurrentHeap()) CNode( NULL, eVCONSTANT );
755  n->Arg<CVector*>(0) = v;
756  return n;
757 }
758 
765 inline CNode* cSTRING( const char* s )
766 {
767  int len = strlen( s );
768  if( !len ) {
769  len = 1;
770  }
772  v->LoadString( s );
773  CNode* n = new(CNode::CurrentHeap()) CNode( NULL, eVCONSTANT );
774  n->Arg<CVector*>(0) = v;
775  return n;
776 }
777 
784 inline CNode* cINT32( INT32 i )
785 {
787  CNode* n;
788  *v = i;
789  v->Sized(FALSE);
790  v->Signed(TRUE);
791  v->Based(FALSE);
792  n = new(CNode::CurrentHeap()) CNode( NULL, eVCONSTANT );
793  n->Arg<CVector*>(0) = v;
794  return n;
795 }
796 
803 inline CNode* cREAL( double number )
804 {
805  CNode* node = new(CNode::CurrentHeap()) CNode( NULL, eRCONSTANT );
806  node->Arg<char*>(0) = d2s(number,CNode::CurrentHeap());
807  return node;
808 }
809 
817 inline CNode* cELINK( CNode* n1, CNode* n2 )
818 {
819  if( n1 == NULL ) {
820  return n2;
821  } else if( n2 == NULL ) {
822  return n1;
823  }
824  return cELIST( n1, n2 );
825 }
826 
834 inline CNode* cABS( CNode* a )
835 {
836  CNode* a1 = a->Clone();
837  CNode* a2 = a->Clone();
838  CNode* c = cGE(a,cINT32(0));
839  return cHOOK( c, a1, cNEG( a2) );
840 }
841 
850 inline CNode* cABSDIFF( CNode* a, CNode* b )
851 {
852  return cABS( cSUB( a, b ) );
853 }
854 
863 inline CNode* cLINK( CNode* n1, CNode* n2 )
864 {
865  if( n1 == NULL ) {
866  return n2;
867  } else if( n2 == NULL ) {
868  return n1;
869  }
870  return cLIST( n1, n2 );
871 }
872 
881 inline CNode* cMAX( CNode* n1, CNode* n2 )
882 {
883  CNode* cond = cLT(n2->Clone(),n1->Clone());
884  return cHOOK(cond,n1,n2);
885 }
886 
887 
888 /****************************************************
889  utility routines
890 *****************************************************/
891 
904 template<class T> void ArgList2Vector(CNode* n, NodeOp_t op,
905  int argNumber, vector<T>& v)
906 {
907  if( !n ) {
908  return;
909  }
910  switch( n->GetOp() ) {
911  case eLIST:
912  ArgList2Vector<T>(n->Arg<CNode*>(0),op,argNumber,v);
913  ArgList2Vector<T>(n->Arg<CNode*>(1),op,argNumber,v);
914  break;
915  default:
916  if( n->GetOp() == op ) {
917  v.push_back(n->Arg<T>(argNumber));
918  }
919  break;
920  }
921 }
922 
931 inline void EList2VectorExclude(CNode* n, const set<NodeOp_t>& excludeOps, vector<CNode*>& v)
932 {
933  if( !n ) {
934  return;
935  }
936  switch( n->GetOp() ) {
937  case eELIST:
938  EList2VectorExclude(n->Arg<CNode*>(0),excludeOps,v);
939  EList2VectorExclude(n->Arg<CNode*>(1),excludeOps,v);
940  break;
941  default:
942  if( excludeOps.find(n->GetOp()) == excludeOps.end() ) {
943  v.push_back(n);
944  }
945  break;
946  }
947 }
948 
957 inline void List2VectorExclude(CNode* n, const set<NodeOp_t>& excludeOps, vector<CNode*>& v)
958 {
959  if( !n ) {
960  return;
961  }
962  switch( n->GetOp() ) {
963  case eLIST:
964  List2VectorExclude(n->Arg<CNode*>(0),excludeOps,v);
965  List2VectorExclude(n->Arg<CNode*>(1),excludeOps,v);
966  break;
967  default:
968  if( excludeOps.find(n->GetOp()) == excludeOps.end() ) {
969  v.push_back(n);
970  }
971  break;
972  }
973 }
974 
981 inline CNode* Vector2EList(const vector<CNode*>& v)
982 {
983  CNode* result = NULL;
984  vector<CNode*>::const_reverse_iterator ptr;
985  for( ptr = v.rbegin(); ptr != v.rend(); ++ptr ) {
986  if( result ) {
987  result = cELIST(*ptr, result);
988  } else {
989  result = *ptr;
990  }
991  }
992  return result;
993 }
994 
1001 inline CNode* List2EList(list<CNode*>& v)
1002 {
1003  CNode* result = NULL;
1004  list<CNode*>::reverse_iterator ptr;
1005  for( ptr = v.rbegin(); ptr != v.rend(); ++ptr ) {
1006  if( result ) {
1007  result = cELIST(*ptr, result);
1008  } else {
1009  result = *ptr;
1010  }
1011  }
1012  return result;
1013 }
1014 
1023 inline int ListCount(CNode* n, NodeOp_t op)
1024 {
1025  int result = 0;
1026  if( !n ) {
1027  return result;
1028  }
1029  switch( n->GetOp() ) {
1030  case eLIST:
1031  case eELIST:
1032  result += ListCount(n->Arg<CNode*>(0),op);
1033  result += ListCount(n->Arg<CNode*>(1),op);
1034  break;
1035  default:
1036  if( n->GetOp() == op ) {
1037  result = 1;
1038  }
1039  break;
1040  }
1041  return result;
1042 }
1043 
1050 inline int ListCount(CNode* n)
1051 {
1052  int result = 0;
1053  if( !n ) {
1054  return result;
1055  }
1056  switch( n->GetOp() ) {
1057  case eLIST:
1058  case eELIST:
1059  result += ListCount(n->Arg<CNode*>(0));
1060  result += ListCount(n->Arg<CNode*>(1));
1061  break;
1062  default:
1063  result = 1;
1064  break;
1065  }
1066  return result;
1067 }
1068 
1079 inline double s2d( char* s ) {
1080  return atof(s);
1081 }
1082 
1091 inline char* d2s( double d, CObstack* heap ) {
1092  char buffer[256];
1093  // note this isn't quite correct as it will turn
1094  // reals into ints, ie 2.0 => 2
1095  snprintf( buffer, sizeof(buffer), "%g", d );
1096  char* s = (char*)heap->Alloc(strlen(buffer)+1);
1097  strcpy( s, buffer );
1098  return s;
1099 }
1100 
1101 /*********************************************
1102  * Adjust nodes structure to be efficient for
1103  * tail recursion
1104  *********************************************/
1105 inline CNode* RebalanceRight( CNode* n ) {
1106  if( n == NULL ) {
1107  return n;
1108  }
1109  if( n->GetOp() != eLIST ) {
1110  return n;
1111  }
1112  CNode* result = n;
1113  CNode* parent = NULL;
1114  while( 1 ) {
1115  while( n->Arg<CNode*>(0) && n->Arg<CNode*>(0)->GetOp() == eLIST ) {
1116  CNode* l = n->Arg<CNode*>(0);
1117  CNode* ll = l->Arg<CNode*>(0);
1118  CNode* lr = l->Arg<CNode*>(1);
1119  l->Arg<CNode*>(1) = n;
1120  n->Arg<CNode*>(0) = lr;
1121  n = l;
1122  if( parent ) {
1123  parent->Arg<CNode*>(1) = n;
1124  } else {
1125  result = n;
1126  }
1127  }
1128  if( n->Arg<CNode*>(1) && n->Arg<CNode*>(1)->GetOp() == eLIST ) {
1129  parent = n;
1130  n = n->Arg<CNode*>(1);
1131  } else {
1132  break;
1133  }
1134  }
1135  return result;
1136 }
1137 /*********************************************
1138  * Analyse tree struct.
1139  * - depth is worst case stack depth right side
1140  * optimization.
1141  * count is number nodes.
1142  *********************************************/
1143 inline void MeasureDepth( CNode* n, int* count, int* depth )
1144 {
1145  *count = 0;
1146  *depth = 0;
1147  if( !n ) {
1148  return;
1149  }
1150  if( n->GetOp() == eLIST ) {
1151  int count0 = 0;
1152  int depth0 = 0;
1153  int count1 = 0;
1154  int depth1 = 0;
1155  if( n->Arg<CNode*>(0) ) {
1156  MeasureDepth( n->Arg<CNode*>(0), &count0, &depth0 );
1157  depth0++;
1158  }
1159  if( n->Arg<CNode*>(1) ) {
1160  MeasureDepth( n->Arg<CNode*>(1), &count1, &depth1 );
1161  }
1162  *count = count0+count1;
1163  *depth = depth0 > depth1 ? depth0 : depth1;
1164  }
1165  (*count)++;
1166 }
1167 
1168 
1169 /**************************************************
1170  * Helper routine for parser to build trees that
1171  * are effient for tail recursion.
1172  *************************************************/
1173 inline CNode_pr cLINK( CNode_pr pr1, CNode* n2 )
1174 {
1175  if( !n2 ) {
1176  return pr1;
1177  } else if( !pr1.tail ) {
1178  CNode_pr pr;
1179  pr.head = n2;
1180  pr.tail = n2;
1181  return pr;
1182  } else if( pr1.tail->GetOp() != eLIST ) {
1183  CNode* t = cLINK( pr1.head, n2 );
1184  CNode_pr pr;
1185  pr.head = t;
1186  pr.tail = t;
1187  return pr;
1188  } else {
1189  pr1.tail->Arg<CNode*>(1) = cLINK(pr1.tail->Arg<CNode*>(1),n2);
1190  CNode_pr pr;
1191  pr.head = pr1.head;
1192  pr.tail = pr1.tail->Arg<CNode*>(1);
1193  return pr;
1194  }
1195 }
1196 
1197 /**************************************************
1198  * convert hierarchical reference tree to string
1199  *************************************************/
1201 {
1202  string buffer;
1203  switch( ref->GetOp() ) {
1204  case eARRAY: {
1205  buffer = HierarchicalReference2String(ref->Arg<CNode*>(0)).c_str();
1206  vector<CNode*> indexes;
1207  EList2VectorExclude( ref->Arg<CNode*>(1),
1208  set<NodeOp_t>(), indexes );
1209  vector<CNode*>::iterator ptr;
1210  for( ptr = indexes.begin(); ptr != indexes.end(); ++ptr ) {
1211  switch( ref->Arg<CNode*>(0)->GetOp() ) {
1212  case eSLICE:
1213  case ePSLICE:
1214  case eMSLICE:
1215  break;
1216  default: {
1217  INT32 value = (*ptr)->EvalINT32();
1218  ostringstream subscript;
1219  subscript << '[' << value << ']';
1220  buffer += subscript.str();
1221  } break;
1222  }
1223  }
1224  } break;
1225  case eMEMBER:
1226  buffer = HierarchicalReference2String(ref->Arg<CNode*>(0)).c_str();
1227  buffer += ".";
1228  buffer += ref->Arg<CSymbol*>(1)->GetName();
1229  break;
1230  case eEXTERNAL_REF:
1231  buffer = ref->Arg<CSymbol*>(0)->GetName();
1232  ref = NULL;
1233  break;
1234  case eNET_REF:
1235  case eVAR_REF:
1236  case ePARAM_REF:
1237  case ePORT_REF:
1238  case eFWD_REF:
1239  case eGENVAR_REF:
1240  buffer = ref->Arg<CDecl*>(0)->GetName();
1241  ref = NULL;
1242  break;
1243  default:;
1244  MASSERT( FALSE );
1245  }
1246  return buffer;
1247 }
1248 
1249 /*****************************************************
1250  * Support routines for cnode_def.h constructs
1251  *****************************************************/
1252 inline CNode* cMAX_N( CNode* first, ... )
1253 {
1254  CNode* result = first;
1255  va_list ap;
1256  va_start( ap, first );
1257  while( 1 ) {
1258  CNode* arg = va_arg(ap,CNode*);
1259  if( !arg ) {
1260  break;
1261  }
1262  if( !Equivalent( result, arg ) ) {
1263  result = cMAX( result, arg );
1264  }
1265  }
1266  va_end( ap );
1267  return result;
1268 }
1269 
1270 inline CNode* cADD_N( CNode* first, ... )
1271 {
1272  CNode* result = first;
1273  va_list ap;
1274  va_start( ap, first );
1275  while( 1 ) {
1276  CNode* arg = va_arg(ap,CNode*);
1277  if( !arg ) {
1278  break;
1279  }
1280  result = cADD( result, arg );
1281  }
1282  va_end( ap );
1283  return result;
1284 }
1285 
1286 inline CNode* cMUL_N( CNode* first, ... )
1287 {
1288  CNode* result = first;
1289  va_list ap;
1290  va_start( ap, first );
1291  while( 1 ) {
1292  CNode* arg = va_arg(ap,CNode*);
1293  if( !arg ) {
1294  break;
1295  }
1296  result = cMUL( result, arg );
1297  }
1298  va_end( ap );
1299  return result;
1300 }
1301 
1302 inline CNode* cABSDIFFPLUS1_N( CNode* first, ... )
1303 {
1304  va_list ap;
1305  va_start( ap, first );
1306  CNode* second = va_arg(ap,CNode*);
1307  /*
1308  * only make sense for 2 args
1309  */
1310  MASSERT( va_arg(ap,CNode*) == NULL );
1311  va_end( ap );
1312 // return cADD(cABSDIFF(first,second),cINT32(1));
1313  return cHOOK(
1314  cGE(first,second),
1315  cADD(cSUB(first->Clone(),second->Clone()),cINT32(1)),
1316  cADD(cSUB(second->Clone(),first->Clone()),cINT32(1)) );
1317 
1318 }
1319 
1320 inline int cMAX( int a1, int a2 )
1321 {
1322  return a1 < a2 ? a2 : a1;
1323 }
1324 
1325 inline int cMAX( int a1, int a2, int a3 )
1326 {
1327  return cMAX(a1,cMAX(a2,a3));
1328 }
1329 
1330 inline int cADD( int a1, int a2 )
1331 {
1332  return a1 + a2;
1333 }
1334 
1335 inline int cMUL( int a1, int a2 )
1336 {
1337  return a1 * a2;
1338 }
1339 
1340 inline int cABSDIFFPLUS1( int a1, int a2 )
1341 {
1342  int diff = a1-a2;
1343  return (diff < 0 ? -diff : diff)+1;
1344 }
1345 
1346 
1347 #endif // CNODE_HPP
1348 
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:2860
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:649
vector subrange with ascending index select
Definition: cnode_def.h:1147
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:1335
static void UseEvalStack(void)
Use evaluation stack.
Definition: cnode.h:238
int Equivalent(CNode *a, CNode *b)
Definition: cnode_def.h:12010
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:2769
CNode * RebalanceRight(CNode *n)
Definition: cnode.h:1105
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:485
CNode * cREAL(double number)
Short cut for creating RCONSTANT node with a given double value.
Definition: cnode.h:803
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:12554
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:1023
void Add(double *r, double *a, double *b)
Definition: cnode.h:668
int cADD(int a1, int a2)
Definition: cnode.h:1330
Declaration object for specify blocks.
Definition: cspecify.h:47
CNode * cMAX_N(CNode *first,...)
Definition: cnode.h:1252
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:1091
CNode * second
Definition: cnode.h:163
void Neg(double *r, double *a)
Definition: cnode.h:688
Definition: cnode.h:76
list of nodes
Definition: cnode_def.h:1114
vector constant
Definition: cnode_def.h:639
CNode * cSTRING(const char *s)
Short cut for creating VCONSTANT node with a given string value.
Definition: cnode.h:765
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:1001
Definition: cnode.h:95
CNode * cMUL_N(CNode *first,...)
Definition: cnode.h:1286
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:7999
CNode * GetWidthExp(void)
Create expression representing width of expression.
Definition: cnode_def.h:8637
CBlock CScope
Definition: cnode.h:65
CNode * cNEG(CNode *a0, Coord_t *loc=NULL)
Node construction shortcut for NEG negation.
Definition: cnode_def.h:4371
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:904
void MeasureDepth(CNode *n, int *count, int *depth)
Definition: cnode.h:1143
void PostVisit1(void(*callback)(CNode *, void *), void *data)
Walk tree invoking callback on each node after children have been visited.
Definition: cnode_def.h:10416
long INT32
Short cut for signed 32 bit integer.
Definition: glue.h:38
int IsReal(void)
Determine if expression is real.
Definition: cnode.h:495
int IsVolatile(void)
Checks to see if expression tree is volatile.
Definition: cnode_def.h:8161
int Precedence()
Get the precedence of the operator represented by the node.
Definition: cnode_def.h:7831
CNode_sp< T > Arg(int index)
Get a node's operand.
Definition: cnode.h:535
Edge_t
Edge values.
Definition: cnode.h:72
reference to port
Definition: cnode_def.h:991
void * Alloc(INT32 size)
Allocate block of storage with given size.
reference to a forward declared variable
Definition: cnode_def.h:1001
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:957
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:4964
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:1011
CNode * third
Definition: cnode.h:164
int ArgCount(void)
Get the number of operands for the node.
Definition: cnode_def.h:7511
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:1302
Definition: cnode.h:99
reference to net
Definition: cnode_def.h:961
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:620
CNode * cLINK(CNode *n1, CNode *n2)
Short cut for linking together to nodes with a LIST operator.
Definition: cnode.h:863
CNode * cELINK(CNode *n1, CNode *n2)
Link together two nodes with an ELIST operator.
Definition: cnode.h:817
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:9235
Declaration object for module and gate instances.
Definition: cinstance.h:45
expression list
Definition: cnode_def.h:690
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:698
CNode * Vector2EList(const vector< CNode * > &v)
Converts a vector array of CNode* into a linked ELIST of the elements.
Definition: cnode.h:981
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:2206
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:505
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:748
CNode * PostSubVisit1(CNode *(*callback)(CNode *, void *), void *data)
Walk tree invoking callback on each node after children have been visited.
Definition: cnode_def.h:10946
Definition: cnode.h:75
void Div(double *r, double *a, double *b)
Definition: cnode.h:683
Definitions for parse tree nodes.
void SetOp(NodeOp_t aOp)
Set node's operation type.
Definition: cnode.h:315
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:490
void Sub(double *r, double *a, double *b)
Definition: cnode.h:673
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:1986
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:784
int IsWidthEvaluateable(void)
Evaluates if expression width can be evaluated.
Definition: cnode_def.h:9077
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:4492
void PreVisit1(int(*callback)(CNode *, void *), void *data)
Walk tree invoking callback on each node before children have been visited.
Definition: cnode_def.h:9899
Definition: cnode.h:78
INT32 GetWidth(void)
Evaluate width of expression.
Definition: cnode.h:480
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:4525
void Mul(double *r, double *a, double *b)
Definition: cnode.h:678
int IsWidthConstant(void)
Evaluates if expression width is constant.
Definition: cnode_def.h:8323
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:931
NodeType_t GetNodeType(void)
Get node expression type.
Definition: cnode.h:526
int GetPreferredBase()
Get preferred base for printing value.
Definition: cvector.h:137
void Plus(double *r, double *a)
Definition: cnode.h:693
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:1136
real - have width 0
Definition: cdatatype.h:99
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:4025
Definition: cnode.h:86
unsigned Hash()
Calculate hash of tree.
Definition: cnode_def.h:11478
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:881
T operator->()
Definition: cnode.h:130
CNode * cADD_N(CNode *first,...)
Definition: cnode.h:1270
CNode * cABS(CNode *a)
Short cut for creating an subtree that calculates the absolute value of an expression.
Definition: cnode.h:834
Strength_t s0
Definition: cnode.h:109
NodeType_t
Expression node type.
Definition: cdatatype.h:97
Definition: cnode.h:87
friend CNode_pr cLINK(CNode_pr pr1, CNode *n2)
Definition: cnode.h:1173
void Free(void *object)
Free all storage including and after object.
CNode * GetAttributes()
Get attributes attached to operation.
Definition: cnode.h:500
Definition: cnode.h:85
dimensioned reference (array/bit select)
Definition: cnode_def.h:951
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:8479
Definition: cnode.h:102
void Dump(FILE *f)
Print a compact representation of the parse tree.
Definition: cnode_def.h:15149
Declaration class for block constructs.
Definition: cblock.h:52
int cABSDIFFPLUS1(int a1, int a2)
Definition: cnode.h:1340
ILLEGAL_OP1(Com)
DelayMode_t
Timing mode values.
Definition: cnode.h:84
vector subrange with descending index select
Definition: cnode_def.h:1158
Helper class for building tail recursive binary CNode trees Used by parser.
Definition: cnode.h:161
reference to parameter
Definition: cnode_def.h:981
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:850
int operator==(T v)
Definition: cnode.h:133
string HierarchicalReference2String(CNode *ref)
Definition: cnode.h:1200
double s2d(char *s)
Convert char string to double.
Definition: cnode.h:1079
reference to variable
Definition: cnode_def.h:971
CNode * Clone(CObstack *heap=stack)
Replicate tree.
Definition: cnode_def.h:9406