175 #define GET_CVALUE(dtype, symbol) ((symbol)->const_value_##dtype->value) |
175 #define GET_CVALUE(dtype, symbol) ((symbol)->const_value_##dtype->value) |
176 #define SET_OVFLOW(dtype, symbol) ((symbol)->const_value_##dtype->status) = symbol_c::cs_overflow |
176 #define SET_OVFLOW(dtype, symbol) ((symbol)->const_value_##dtype->status) = symbol_c::cs_overflow |
177 /* The following test is correct in the presence of a NULL pointer, as the logical evaluation will be suspended as soon as the first condition is false! */ |
177 /* The following test is correct in the presence of a NULL pointer, as the logical evaluation will be suspended as soon as the first condition is false! */ |
178 #define VALID_CVALUE(dtype, symbol) ((NULL != (symbol)->const_value_##dtype) && (symbol_c::cs_const_value == (symbol)->const_value_##dtype->status)) |
178 #define VALID_CVALUE(dtype, symbol) ((NULL != (symbol)->const_value_##dtype) && (symbol_c::cs_const_value == (symbol)->const_value_##dtype->status)) |
179 #define ISZERO_CVALUE(dtype, symbol) ((VALID_CVALUE(dtype, symbol)) && (GET_CVALUE(dtype, symbol) == 0)) |
179 #define ISZERO_CVALUE(dtype, symbol) ((VALID_CVALUE(dtype, symbol)) && (GET_CVALUE(dtype, symbol) == 0)) |
|
180 |
180 #define DO_BINARY_OPER(dtype, oper)\ |
181 #define DO_BINARY_OPER(dtype, oper)\ |
181 if (VALID_CVALUE(dtype, symbol->r_exp) && VALID_CVALUE(dtype, symbol->l_exp)) { \ |
182 if (VALID_CVALUE(dtype, symbol->r_exp) && VALID_CVALUE(dtype, symbol->l_exp)) { \ |
182 NEW_CVALUE(dtype, symbol); \ |
183 NEW_CVALUE(dtype, symbol); \ |
183 SET_CVALUE(dtype, symbol, GET_CVALUE(dtype, symbol->l_exp) oper GET_CVALUE(dtype, symbol->r_exp)); \ |
184 SET_CVALUE(dtype, symbol, GET_CVALUE(dtype, symbol->l_exp) oper GET_CVALUE(dtype, symbol->r_exp)); \ |
184 } |
185 } |
185 |
186 |
|
187 #define DO_UNARY_OPER(dtype, oper, arg)\ |
|
188 if (VALID_CVALUE(dtype, arg)) { \ |
|
189 NEW_CVALUE(dtype, symbol); \ |
|
190 SET_CVALUE(dtype, symbol, oper GET_CVALUE(dtype, arg)); \ |
|
191 } |
186 |
192 |
187 |
193 |
188 |
194 |
189 |
195 |
190 |
196 |
385 /*********************/ |
391 /*********************/ |
386 /******************************/ |
392 /******************************/ |
387 /* B 1.2.1 - Numeric Literals */ |
393 /* B 1.2.1 - Numeric Literals */ |
388 /******************************/ |
394 /******************************/ |
389 void *constant_folding_c::visit(real_c *symbol) { |
395 void *constant_folding_c::visit(real_c *symbol) { |
390 NEW_CVALUE(real64, symbol); |
396 NEW_CVALUE(real64, symbol); SET_CVALUE(real64, symbol, extract_real_value(symbol)); |
391 SET_CVALUE(real64, symbol, extract_real_value(symbol)); |
|
392 return NULL; |
397 return NULL; |
393 } |
398 } |
394 |
399 |
395 |
400 |
396 void *constant_folding_c::visit(integer_c *symbol) { |
401 void *constant_folding_c::visit(integer_c *symbol) { |
397 NEW_CVALUE( int64, symbol); |
402 NEW_CVALUE( int64, symbol); SET_CVALUE( int64, symbol, extract_integer_value(symbol)); |
398 SET_CVALUE( int64, symbol, extract_integer_value(symbol)); |
403 NEW_CVALUE(uint64, symbol); SET_CVALUE(uint64, symbol, extract_integer_value(symbol)); |
399 NEW_CVALUE(uint64, symbol); |
|
400 SET_CVALUE(uint64, symbol, extract_integer_value(symbol)); |
|
401 return NULL; |
404 return NULL; |
402 } |
405 } |
403 |
406 |
404 |
407 |
405 void *constant_folding_c::visit(neg_real_c *symbol) { |
408 void *constant_folding_c::visit(neg_real_c *symbol) { |
406 symbol->exp->accept(*this); |
409 symbol->exp->accept(*this); |
407 if (!VALID_CVALUE(real64, symbol->exp)) |
410 DO_UNARY_OPER(real64, -, symbol->exp); |
408 return NULL; |
|
409 NEW_CVALUE(real64, symbol); |
|
410 SET_CVALUE(real64, symbol, - GET_CVALUE( real64, symbol->exp)); |
|
411 CHECK_OVERFLOW_real64(symbol); |
411 CHECK_OVERFLOW_real64(symbol); |
412 return NULL; |
412 return NULL; |
413 } |
413 } |
414 |
414 |
415 /* | '-' integer {$$ = new neg_integer_c($2, locloc(@$));} */ |
415 /* | '-' integer {$$ = new neg_integer_c($2, locloc(@$));} */ |
416 void *constant_folding_c::visit(neg_integer_c *symbol) { |
416 void *constant_folding_c::visit(neg_integer_c *symbol) { |
417 symbol->exp->accept(*this); |
417 symbol->exp->accept(*this); |
418 if (VALID_CVALUE(int64, symbol->exp)) { |
418 DO_UNARY_OPER(int64, -, symbol->exp); |
419 NEW_CVALUE( int64, symbol); |
|
420 SET_CVALUE( int64, symbol, - GET_CVALUE( int64, symbol->exp)); |
|
421 } |
|
422 CHECK_OVERFLOW_int64_NEG(symbol, symbol->exp); |
419 CHECK_OVERFLOW_int64_NEG(symbol, symbol->exp); |
423 return NULL; |
420 return NULL; |
424 } |
421 } |
425 |
422 |
426 |
423 |
433 return NULL; |
430 return NULL; |
434 } |
431 } |
435 |
432 |
436 |
433 |
437 void *constant_folding_c::visit(hex_integer_c *symbol) { |
434 void *constant_folding_c::visit(hex_integer_c *symbol) { |
438 NEW_CVALUE( int64, symbol); |
435 NEW_CVALUE( int64, symbol); SET_CVALUE( int64, symbol, extract_hex_value(symbol)); |
439 SET_CVALUE( int64, symbol, extract_hex_value(symbol)); |
436 NEW_CVALUE(uint64, symbol); SET_CVALUE(uint64, symbol, extract_hex_value(symbol)); |
440 NEW_CVALUE(uint64, symbol); |
|
441 SET_CVALUE(uint64, symbol, extract_hex_value(symbol)); |
|
442 return NULL; |
437 return NULL; |
443 } |
438 } |
444 |
439 |
445 |
440 |
446 /* |
441 /* |
451 | integer_type_name '#' hex_integer {$$ = new integer_literal_c($1, $3, locloc(@$));} |
446 | integer_type_name '#' hex_integer {$$ = new integer_literal_c($1, $3, locloc(@$));} |
452 */ |
447 */ |
453 // SYM_REF2(integer_literal_c, type, value) |
448 // SYM_REF2(integer_literal_c, type, value) |
454 void *constant_folding_c::visit(integer_literal_c *symbol) { |
449 void *constant_folding_c::visit(integer_literal_c *symbol) { |
455 symbol->value->accept(*this); |
450 symbol->value->accept(*this); |
456 if (VALID_CVALUE( int64, symbol->value)) { |
451 DO_UNARY_OPER( int64, /* none */, symbol->value); |
457 NEW_CVALUE( int64, symbol); |
452 DO_UNARY_OPER(uint64, /* none */, symbol->value); |
458 SET_CVALUE( int64, symbol, GET_CVALUE( int64, symbol->value)); |
|
459 } |
|
460 if (VALID_CVALUE(uint64, symbol->value)) { |
|
461 NEW_CVALUE(uint64, symbol); |
|
462 SET_CVALUE(uint64, symbol, GET_CVALUE(uint64, symbol->value)); |
|
463 } |
|
464 return NULL; |
453 return NULL; |
465 } |
454 } |
466 |
455 |
467 |
456 |
468 void *constant_folding_c::visit(real_literal_c *symbol) { |
457 void *constant_folding_c::visit(real_literal_c *symbol) { |
469 symbol->value->accept(*this); |
458 symbol->value->accept(*this); |
470 if (VALID_CVALUE(real64, symbol->value)) { |
459 DO_UNARY_OPER(real64, /* none */, symbol->value); |
471 NEW_CVALUE(real64, symbol); |
|
472 SET_CVALUE(real64, symbol, GET_CVALUE(real64, symbol->value)); |
|
473 } |
|
474 return NULL; |
460 return NULL; |
475 } |
461 } |
476 |
462 |
477 |
463 |
478 void *constant_folding_c::visit(bit_string_literal_c *symbol) { |
464 void *constant_folding_c::visit(bit_string_literal_c *symbol) { |
480 } |
466 } |
481 |
467 |
482 |
468 |
483 void *constant_folding_c::visit(boolean_literal_c *symbol) { |
469 void *constant_folding_c::visit(boolean_literal_c *symbol) { |
484 symbol->value->accept(*this); |
470 symbol->value->accept(*this); |
485 if (VALID_CVALUE(bool, symbol->value)) { |
471 DO_UNARY_OPER(bool, /* none */, symbol->value); |
486 NEW_CVALUE(bool, symbol); |
|
487 SET_CVALUE(bool, symbol, GET_CVALUE( bool, symbol->value)); |
|
488 } |
|
489 return NULL; |
472 return NULL; |
490 } |
473 } |
491 |
474 |
492 |
475 |
493 void *constant_folding_c::visit(boolean_true_c *symbol) { |
476 void *constant_folding_c::visit(boolean_true_c *symbol) { |
494 NEW_CVALUE(bool, symbol); |
477 NEW_CVALUE(bool, symbol); SET_CVALUE(bool, symbol, true); |
495 SET_CVALUE(bool, symbol, true); |
|
496 return NULL; |
478 return NULL; |
497 } |
479 } |
498 |
480 |
499 |
481 |
500 void *constant_folding_c::visit(boolean_false_c *symbol) { |
482 void *constant_folding_c::visit(boolean_false_c *symbol) { |
501 NEW_CVALUE(bool, symbol); |
483 NEW_CVALUE(bool, symbol); SET_CVALUE(bool, symbol, false); |
502 SET_CVALUE(bool, symbol, false); |
|
503 return NULL; |
484 return NULL; |
504 } |
485 } |
505 |
486 |
506 |
487 |
507 /***************************************/ |
488 /***************************************/ |
679 } |
660 } |
680 |
661 |
681 |
662 |
682 void *constant_folding_c::visit(neg_expression_c *symbol) { |
663 void *constant_folding_c::visit(neg_expression_c *symbol) { |
683 symbol->exp->accept(*this); |
664 symbol->exp->accept(*this); |
684 if (VALID_CVALUE( int64, symbol->exp)) { |
665 DO_UNARY_OPER( int64, -, symbol->exp); CHECK_OVERFLOW_int64_NEG(symbol, symbol->exp); |
685 NEW_CVALUE( int64, symbol); |
666 DO_UNARY_OPER(real64, -, symbol->exp); CHECK_OVERFLOW_real64(symbol); |
686 SET_CVALUE( int64, symbol, - GET_CVALUE( int64, symbol->exp)); |
|
687 } |
|
688 if (VALID_CVALUE(real64, symbol->exp)) { |
|
689 NEW_CVALUE(real64, symbol); |
|
690 SET_CVALUE(real64, symbol, - GET_CVALUE(real64, symbol->exp)); |
|
691 } |
|
692 CHECK_OVERFLOW_int64_NEG(symbol, symbol->exp); |
|
693 CHECK_OVERFLOW_real64(symbol); |
|
694 return NULL; |
667 return NULL; |
695 } |
668 } |
696 |
669 |
697 |
670 |
698 |
671 |
699 void *constant_folding_c::visit(not_expression_c *symbol) { |
672 void *constant_folding_c::visit(not_expression_c *symbol) { |
700 symbol->exp->accept(*this); |
673 symbol->exp->accept(*this); |
701 if (VALID_CVALUE( bool, symbol->exp)) { |
674 DO_UNARY_OPER( bool, !, symbol->exp); |
702 NEW_CVALUE( bool, symbol); |
675 DO_UNARY_OPER(uint64, ~, symbol->exp); |
703 SET_CVALUE( bool, symbol, ! GET_CVALUE( bool, symbol->exp)); |
676 return NULL; |
704 } |
677 } |
705 if (VALID_CVALUE(uint64, symbol->exp)) { |
678 |
706 NEW_CVALUE(uint64, symbol); |
679 |
707 SET_CVALUE(uint64, symbol, ~ GET_CVALUE(uint64, symbol->exp)); |
|
708 } |
|
709 return NULL; |
|
710 } |
|
711 |
|
712 |
|