#include <stdio.h>
#include <assert.h>
#include "defines.h"
#include "static.h"
#include "expr.h"
#include "db.h"
#include "util.h"
#include "vector.h"
#include "binding.h"
Functions | |
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. | |
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. | |
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. | |
Variables | |
func_unit * | curr_funit |
int | curr_expr_id |
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).
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).
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.
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.
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.
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.
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. |
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.
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 }
int curr_expr_id |
This static value contains the current expression ID number to use for the next expression found, it is incremented by one when an expression is found. This allows us to have a unique expression ID for each expression (since expressions have no intrinsic names).
Referenced by db_create_expression(), db_get_exclusion_id_size(), db_write(), expression_assign_expr_ids(), expression_db_read(), fsm_arg_parse_state(), fsm_arg_parse_value(), instance_db_write(), static_expr_gen(), and static_expr_gen_unary().
Pointer to the functional unit structure for the functional unit that is currently being parsed.