static.h File Reference

Contains functions for handling creation of static expressions. More...

#include "defines.h"

Go to the source code of this file.

Functions

static_exprstatic_expr_gen_unary (static_expr *stexp, exp_op_type op, int line, int first, int last)
 Calculates new values for unary static expressions and returns the new static expression.
static_exprstatic_expr_gen (static_expr *right, static_expr *left, int op, int line, int first, int last, char *func_name)
 Calculates new values for static expression and returns the new static expression.
void static_expr_calc_lsb_and_width_pre (static_expr *left, static_expr *right, unsigned int *width, int *lsb, int *big_endian)
 Calculates LSB, width and endianness for specified left/right pair for vector (used before parameter resolve).
void static_expr_calc_lsb_and_width_post (static_expr *left, static_expr *right, unsigned int *width, int *lsb, int *big_endian)
 Calculates LSB, width and endianness for specified left/right pair for vector (used after parameter resolve).
void static_expr_dealloc (static_expr *stexp, bool rm_exp)
 Deallocates static_expr memory from heap.

Detailed Description

Contains functions for handling creation of static expressions.

Author:
Trevor Williams (phase1geo@gmail.com)
Date:
10/02/2002

Function Documentation

void static_expr_calc_lsb_and_width_post ( static_expr left,
static_expr right,
unsigned int *  width,
int *  lsb,
int *  big_endian 
)

Calculates LSB, width and endianness for specified left/right pair for vector (used after parameter resolve).

Parameters:
left Pointer to static expression on left of vector.
right Pointer to static expression on right of vector.
width Calculated width of combined right/left static expressions.
lsb Calculated lsb of combined right/left static expressions.
big_endian Set to 1 if the left expression is less than the right expression.

Calculates the LSB and width of a vector defined by the specified left and right static expressions. This function assumes that any expressions have been calculated for a legal value.

References static_expr_s::exp, static_expr_s::num, PROFILE, PROFILE_END, expression_s::value, and vector_to_int().

Referenced by instance_compare(), and instance_resolve_inst().

00421   { PROFILE(STATIC_EXPR_CALC_LSB_AND_WIDTH_POST);
00422   
00423   assert( left  != NULL );
00424   assert( right != NULL );
00425 
00426   *width      = 1;
00427   *lsb        = -1;
00428   *big_endian = 0;
00429 
00430   /* If the right static expression contains an expression, get its integer value and place it in the num field */
00431   if( right->exp != NULL ) {
00432     right->num = vector_to_int( right->exp->value );
00433   }
00434 
00435   /* If the left static expression contains an expression, get its integer value and place it in the num field */
00436   if( left->exp != NULL ) {
00437     left->num = vector_to_int( left->exp->value );
00438   }
00439   
00440   /* Get initial value for LSB */
00441   *lsb = right->num;
00442   assert( *lsb >= 0 );
00443 
00444   /* Calculate width and make sure that LSB is the lower of the two values */
00445   if( *lsb <= left->num ) {
00446     *width = (left->num - *lsb) + 1;
00447     assert( *width > 0 );
00448   } else {
00449     *width      = (*lsb - left->num) + 1;
00450     *lsb        = left->num;
00451     *big_endian = 1;
00452     assert( *width > 0 );
00453     assert( *lsb >= 0 );
00454   }
00455 
00456   PROFILE_END;
00457 
00458 }

void static_expr_calc_lsb_and_width_pre ( static_expr left,
static_expr right,
unsigned int *  width,
int *  lsb,
int *  big_endian 
)

Calculates LSB, width and endianness for specified left/right pair for vector (used before parameter resolve).

Parameters:
left Pointer to static expression on left of vector.
right Pointer to static expression on right of vector.
width Calculated width of combined right/left static expressions.
lsb Calculated lsb of combined right/left static expressions.
big_endian Set to 1 if the MSB/LSB is specified in big endian order.

Calculates the LSB, width and endianness of a vector defined by the specified left and right static expressions. If the width cannot be obtained immediately (parameter in static expression), set width to 0. If the LSB cannot be obtained immediately (parameter in static expression), set LSB to -1. The endianness can only be used if the width is known. The returned width and lsb parameters can be used to size a vector instantiation.

References static_expr_s::exp, static_expr_s::num, PROFILE, and PROFILE_END.

00371   { PROFILE(STATIC_EXPR_CALC_LSB_AND_WIDTH_PRE);
00372 
00373   *width      = 0;
00374   *lsb        = -1;
00375   *big_endian = 0;
00376 
00377   if( (right != NULL) && (right->exp == NULL) ) {
00378     *lsb = right->num;
00379     assert( *lsb >= 0 );
00380   }
00381 
00382   if( (left != NULL) && (left->exp == NULL) ) {
00383     if( *lsb != -1 ) {
00384       if( *lsb <= left->num ) {
00385         *width = (left->num - *lsb) + 1;
00386         assert( *width > 0 );
00387       } else {
00388         *width      = (*lsb - left->num) + 1;
00389         *lsb        = left->num;
00390         *big_endian = 1;
00391         assert( *width > 0 );
00392         assert( *lsb >= 0 );
00393       }
00394     } else {
00395       *lsb = left->num;
00396       assert( *lsb >= 0 );
00397     }
00398   }
00399 
00400   PROFILE_END;
00401 
00402 }

void static_expr_dealloc ( static_expr stexp,
bool  rm_exp 
)

Deallocates static_expr memory from heap.

Parameters:
stexp Pointer to static expression to deallocate.
rm_exp Specifies that expression tree should be deallocated.

Deallocates all allocated memory from the heap for the specified static_expr structure.

References static_expr_s::exp, expression_dealloc(), FALSE, free_safe, and PROFILE.

Referenced by db_create_expr_from_static(), enumerate_dealloc(), instance_dealloc_single(), instance_resolve_inst(), mod_parm_dealloc(), parser_dealloc_sig_range(), and static_expr_gen().

00470   { PROFILE(STATIC_EXPR_DEALLOC);
00471 
00472   if( stexp != NULL ) {
00473 
00474     if( rm_exp && (stexp->exp != NULL) ) {
00475       expression_dealloc( stexp->exp, FALSE );
00476     }
00477 
00478     free_safe( stexp, sizeof( static_expr ) );
00479 
00480   }
00481 
00482 }

static_expr* static_expr_gen ( static_expr right,
static_expr left,
int  op,
int  line,
int  first,
int  last,
char *  func_name 
)

Calculates new values for static expression and returns the new static expression.

Returns:
Returns pointer to new static_expr structure.
Exceptions:
anonymous expression_create expression_create expression_create expression_create expression_create expression_create

Used by the parser to calculate a new static_expr structure based on the operation encountered while parsing. Based on the operation type specified in the argument list, performs unary operation (if both operands are static numbers, storing result into original static_expr number field and returns If only one of the operands is an expression, create a EXP_OP_STATIC expression for the other operand and create an expression consisting of these two expressions and the specified operation. If both operands are expressions, simply create a new expression consisting of those two expressions and specified operator. Store the newly create expression in the original right static_expr and deallocate the left static_expr.

Parameters:
right Pointer to right static expression
left Pointer to left static expression
op Static expression operation
line Line number that static expression operation found on
first Column index of first character in expression
last Column index of last character in expression
func_name Name of function to call (only valid when op == EXP_OP_FUNC_CALL)

References bind_add(), curr_expr_id, static_expr_s::exp, EXP_OP_ADD, EXP_OP_AND, EXP_OP_DIVIDE, EXP_OP_EQ, EXP_OP_EXPONENT, EXP_OP_FUNC_CALL, EXP_OP_GE, EXP_OP_GT, EXP_OP_LAND, EXP_OP_LE, EXP_OP_LIST, EXP_OP_LOR, EXP_OP_LSHIFT, EXP_OP_LT, EXP_OP_MOD, EXP_OP_MULTIPLY, EXP_OP_NAND, EXP_OP_NE, EXP_OP_NOR, EXP_OP_NXOR, EXP_OP_OR, EXP_OP_RSHIFT, EXP_OP_SBIT_SEL, EXP_OP_SCLOG2, EXP_OP_STATIC, EXP_OP_SUBTRACT, EXP_OP_XOR, expression_create(), FALSE, FUNIT_FUNCTION, malloc_safe, static_expr_s::num, PROFILE, static_expr_dealloc(), TRUE, expression_s::value, VDATA_UL, vector_create(), vector_dealloc(), vector_from_int(), and VTYPE_EXP.

00205   { PROFILE(STATIC_EXPR_GEN);
00206 
00207   expression* tmpexp;     /* Temporary expression for holding newly created parent expression */
00208   int         i;          /* Loop iterator */
00209   int         value = 1;  /* Temporary value */
00210   
00211   assert( (op == EXP_OP_XOR)    || (op == EXP_OP_MULTIPLY) || (op == EXP_OP_DIVIDE) || (op == EXP_OP_MOD)       ||
00212           (op == EXP_OP_ADD)    || (op == EXP_OP_SUBTRACT) || (op == EXP_OP_AND)    || (op == EXP_OP_OR)        ||
00213           (op == EXP_OP_NOR)    || (op == EXP_OP_NAND)     || (op == EXP_OP_NXOR)   || (op == EXP_OP_EXPONENT)  ||
00214           (op == EXP_OP_LSHIFT) || (op == EXP_OP_RSHIFT)   || (op == EXP_OP_LIST)   || (op == EXP_OP_FUNC_CALL) ||
00215           (op == EXP_OP_GE)     || (op == EXP_OP_LE)       || (op == EXP_OP_EQ)     || (op == EXP_OP_GT)        ||
00216           (op == EXP_OP_LT)     || (op == EXP_OP_SBIT_SEL) || (op == EXP_OP_LAND)   || (op == EXP_OP_LOR)       ||
00217           (op == EXP_OP_NE)     || (op == EXP_OP_SCLOG2) );
00218 
00219   if( (right != NULL) && (left != NULL) ) {
00220 
00221     if( right->exp == NULL ) {
00222 
00223       if( left->exp == NULL ) {
00224 
00225         switch( op ) {
00226           case EXP_OP_XOR      :  right->num = left->num ^ right->num;     break;
00227           case EXP_OP_MULTIPLY :  right->num = left->num * right->num;     break;
00228           case EXP_OP_DIVIDE   :  right->num = left->num / right->num;     break;
00229           case EXP_OP_MOD      :  right->num = left->num % right->num;     break;
00230           case EXP_OP_ADD      :  right->num = left->num + right->num;     break;
00231           case EXP_OP_SUBTRACT :  right->num = left->num - right->num;     break;
00232           case EXP_OP_EXPONENT :
00233             for( i=0; i<right->num; i++ ) {
00234               value *= left->num;
00235             }
00236             right->num = value;
00237             break;
00238           case EXP_OP_AND      :  right->num = left->num & right->num;     break;
00239           case EXP_OP_OR       :  right->num = left->num | right->num;     break;
00240           case EXP_OP_NOR      :  right->num = ~(left->num | right->num);  break;
00241           case EXP_OP_NAND     :  right->num = ~(left->num & right->num);  break;
00242           case EXP_OP_NXOR     :  right->num = ~(left->num ^ right->num);  break;
00243           /*@-shiftnegative -shiftimplementation@*/
00244           case EXP_OP_LSHIFT   :  right->num = left->num << right->num;    break;
00245           case EXP_OP_RSHIFT   :  right->num = left->num >> right->num;    break;
00246           /*@=shiftnegative =shiftimplementation@*/
00247           case EXP_OP_GE       :  right->num = (left->num >= right->num) ? 1 : 0;  break;
00248           case EXP_OP_LE       :  right->num = (left->num <= right->num) ? 1 : 0;  break;
00249           case EXP_OP_EQ       :  right->num = (left->num == right->num) ? 1 : 0;  break;
00250           case EXP_OP_NE       :  right->num = (left->num != right->num) ? 1 : 0;  break;
00251           case EXP_OP_GT       :  right->num = (left->num > right->num)  ? 1 : 0;  break;
00252           case EXP_OP_LT       :  right->num = (left->num < right->num)  ? 1 : 0;  break;
00253           case EXP_OP_LAND     :  right->num = (left->num && right->num) ? 1 : 0;  break;
00254           case EXP_OP_LOR      :  right->num = (left->num || right->num) ? 1 : 0;  break;
00255           default              :  break;
00256         }
00257 
00258       } else {
00259 
00260         right->exp = expression_create( NULL, NULL, EXP_OP_STATIC, FALSE, curr_expr_id, line, first, last, FALSE );
00261         curr_expr_id++;
00262         {
00263           vector* vec = vector_create( 32, VTYPE_EXP, VDATA_UL, TRUE );
00264           vector_dealloc( right->exp->value );
00265           right->exp->value = vec;
00266         }
00267         (void)vector_from_int( right->exp->value, right->num );
00268 
00269         tmpexp = expression_create( right->exp, left->exp, op, FALSE, curr_expr_id, line, first, last, FALSE );
00270         curr_expr_id++;
00271         right->exp = tmpexp;
00272         
00273       }
00274 
00275     } else {
00276 
00277       if( left->exp == NULL ) {
00278 
00279         left->exp = expression_create( NULL, NULL, EXP_OP_STATIC, FALSE, curr_expr_id, line, first, last, FALSE );
00280         curr_expr_id++;
00281         {
00282           vector* vec = vector_create( 32, VTYPE_EXP, VDATA_UL, TRUE );
00283           vector_dealloc( left->exp->value );
00284           left->exp->value = vec;
00285         }
00286         (void)vector_from_int( left->exp->value, left->num );
00287 
00288         tmpexp = expression_create( right->exp, left->exp, op, FALSE, curr_expr_id, line, first, last, FALSE );
00289         curr_expr_id++;
00290         right->exp = tmpexp;
00291 
00292       } else {
00293 
00294         tmpexp = expression_create( right->exp, left->exp, op, FALSE, curr_expr_id, line, first, last, FALSE );
00295         curr_expr_id++;
00296         right->exp = tmpexp;
00297 
00298       }
00299 
00300     }
00301 
00302   } else if( (op == EXP_OP_FUNC_CALL) || (op == EXP_OP_SBIT_SEL) ) {
00303 
00304     /*
00305      If this is a function call or SBIT_SEL, only the left expression will be a valid expression (so we need to special
00306      handle this)
00307     */
00308 
00309     assert( right == NULL );
00310     assert( left  != NULL );
00311 
00312     right = (static_expr*)malloc_safe( sizeof( static_expr ) );
00313     right->exp = expression_create( NULL, left->exp, op, FALSE, curr_expr_id, line, first, last, FALSE );
00314     curr_expr_id++;
00315 
00316     /* Make sure that we bind this later */
00317     bind_add( FUNIT_FUNCTION, func_name, right->exp, curr_funit );
00318 
00319   } else if( op == EXP_OP_SCLOG2 ) {
00320 
00321     assert( right == NULL );
00322     assert( left  != NULL );
00323 
00324     right      = (static_expr*)malloc_safe( sizeof( static_expr ) );
00325     right->exp = NULL;
00326 
00327     if( left->exp == NULL ) {
00328       unsigned int val      = left->num;
00329       unsigned int num_ones = 0;
00330       right->num = 0;
00331       while( val != 0 ) {
00332         right->num++;
00333         num_ones += (val & 0x1);
00334         val >>= 1;
00335       }
00336       if( num_ones == 1 ) {
00337         right->num--;
00338       }
00339     } else {
00340       right->exp = expression_create( NULL, left->exp, op, FALSE, curr_expr_id, line, first, last, FALSE );
00341       curr_expr_id++;
00342     }
00343 
00344   }
00345 
00346   static_expr_dealloc( left, FALSE );
00347 
00348   return( right );
00349 
00350 }

static_expr* static_expr_gen_unary ( static_expr stexp,
exp_op_type  op,
int  line,
int  first,
int  last 
)

Calculates new values for unary static expressions and returns the new static expression.

Parameters:
stexp Pointer to static expression.
op Unary static expression operation.
line Line number that this expression was found on in file.
first Column index of first character in this expression.
last Column index of last character in this expression.
Returns:
Returns pointer to new static_expr structure.
Exceptions:
anonymous expression_create expression_create

Used by the parser to calculate a new static_expr structure based on the unary operation encountered while parsing. Based on the operation type specified in the argument list, performs unary operation (if operand is a static number and not an expression -- parameter in operand expression tree), storing result into original static_expr number field and returns the original structure back to the calling function. If the operand is an expression, create an expression for the specified operation type and store this expression in the original expression pointer field.

Parameters:
stexp Pointer to static expression
op Unary static expression operation
line Line number that this expression was found on in file
first Column index of first character in this expression
last Column index of last character in this expression

References curr_expr_id, static_expr_s::exp, EXP_OP_PASSIGN, EXP_OP_STATIC, EXP_OP_UAND, EXP_OP_UINV, EXP_OP_UNAND, EXP_OP_UNOR, EXP_OP_UNOT, EXP_OP_UNXOR, EXP_OP_UOR, EXP_OP_UXOR, expression_create(), FALSE, static_expr_s::num, PROFILE, PROFILE_END, TRUE, expression_s::value, VDATA_UL, vector_create(), vector_dealloc(), vector_from_int(), and VTYPE_EXP.

00095   { PROFILE(STATIC_EXPR_GEN_UNARY);
00096 
00097   expression*  tmpexp;  /* Container for newly created expression */
00098   int          uop;     /* Temporary bit holder */
00099   unsigned int i;       /* Loop iterator */
00100 
00101   if( stexp != NULL ) {
00102 
00103     assert( (op == EXP_OP_UINV)  || (op == EXP_OP_UAND) || (op == EXP_OP_UOR)   || (op == EXP_OP_UXOR)  ||
00104             (op == EXP_OP_UNAND) || (op == EXP_OP_UNOR) || (op == EXP_OP_UNXOR) || (op == EXP_OP_UNOT)  ||
00105             (op == EXP_OP_PASSIGN) );
00106 
00107     if( stexp->exp == NULL ) {
00108 
00109       switch( op ) {
00110 
00111         case EXP_OP_UINV :
00112           stexp->num = ~stexp->num;
00113           break;
00114 
00115         case EXP_OP_UAND  :
00116         case EXP_OP_UOR   :
00117         case EXP_OP_UXOR  :
00118         case EXP_OP_UNAND :
00119         case EXP_OP_UNOR  :
00120         case EXP_OP_UNXOR :
00121           uop = stexp->num & 0x1;
00122           for( i=1; i<(SIZEOF_INT * 8); i++ ) {
00123             switch( op ) {
00124               case EXP_OP_UNAND :
00125               /*@-shiftimplementation@*/
00126               case EXP_OP_UAND  :  uop = uop & ((stexp->num >> i) & 0x1);  break;
00127               case EXP_OP_UNOR  :
00128               case EXP_OP_UOR   :  uop = uop | ((stexp->num >> i) & 0x1);  break;
00129               case EXP_OP_UNXOR :
00130               case EXP_OP_UXOR  :  uop = uop ^ ((stexp->num >> i) & 0x1);  break;
00131               /*@=shiftimplementation@*/
00132               default           :  break;
00133             }
00134           }
00135           switch( op ) {
00136             case EXP_OP_UAND  :
00137             case EXP_OP_UOR   :
00138             case EXP_OP_UXOR  :  stexp->num = uop;                 break;
00139             case EXP_OP_UNAND :
00140             case EXP_OP_UNOR  :
00141             case EXP_OP_UNXOR :  stexp->num = (uop == 0) ? 1 : 0;  break;
00142             default           :  break;
00143           }
00144           break;
00145 
00146         case EXP_OP_UNOT :
00147           stexp->num = (stexp->num == 0) ? 1 : 0;
00148           break;
00149 
00150         case EXP_OP_PASSIGN :
00151           tmpexp = expression_create( NULL, NULL, EXP_OP_STATIC, FALSE, curr_expr_id, line, first, last, FALSE );
00152           curr_expr_id++;
00153           {
00154             vector* vec = vector_create( 32, VTYPE_EXP, VDATA_UL, TRUE );
00155             vector_dealloc( tmpexp->value );
00156             tmpexp->value = vec;
00157           }
00158           (void)vector_from_int( tmpexp->value, stexp->num );
00159 
00160           stexp->exp = expression_create( tmpexp, NULL, op, FALSE, curr_expr_id, line, first, last, FALSE );
00161           curr_expr_id++;
00162           break;
00163         default :  break;
00164       }
00165 
00166     } else {
00167 
00168       tmpexp = expression_create( stexp->exp, NULL, op, FALSE, curr_expr_id, line, first, last, FALSE );
00169       curr_expr_id++;
00170       stexp->exp = tmpexp;
00171 
00172     }
00173 
00174   }
00175 
00176   PROFILE_END;
00177 
00178   return( stexp );
00179 
00180 }

Generated on Sun Nov 21 00:55:41 2010 for Covered by  doxygen 1.6.3