https://gcc.gnu.org/g:525b7590e3668c7a72b0d77c89bdd1ac5f6ada8a
commit 525b7590e3668c7a72b0d77c89bdd1ac5f6ada8a Author: Mariam Arutunian <mariamarutun...@gmail.com> Date: Mon Apr 15 15:36:18 2024 +0400 Refactored sym-exec: Added comments, changed members' names ... Diff: --- gcc/sym-exec/condition.cc | 14 ++-- gcc/sym-exec/condition.h | 2 +- gcc/sym-exec/expression.cc | 114 +++++++++++++++--------------- gcc/sym-exec/expression.h | 26 +++---- gcc/sym-exec/state.cc | 172 +++++++++++++++++++++++++++++++++++---------- gcc/sym-exec/state.h | 62 +++++++++++++--- 6 files changed, 265 insertions(+), 125 deletions(-) diff --git a/gcc/sym-exec/condition.cc b/gcc/sym-exec/condition.cc index 39d9d9eddf3..5b558d1e315 100644 --- a/gcc/sym-exec/condition.cc +++ b/gcc/sym-exec/condition.cc @@ -2,24 +2,24 @@ bit_condition::bit_condition (value_bit *left, value_bit *right, tree_code code) { - this->left = left; - this->right = right; - this->code = code; - type = BIT_CONDITION; + this->m_left = left; + this->m_right = right; + this->m_code = code; + m_type = BIT_CONDITION; } bit_condition::bit_condition (const bit_condition &expr) { bit_expression::copy (&expr); - code = expr.get_code (); + m_code = expr.get_code (); } tree_code bit_condition::get_code () const { - return code; + return m_code; } @@ -33,7 +33,7 @@ bit_condition::copy () const void bit_condition::print_expr_sign () { - switch (code) + switch (m_code) { case GT_EXPR: fprintf (dump_file, " > "); diff --git a/gcc/sym-exec/condition.h b/gcc/sym-exec/condition.h index dc3ec382d2f..1882c6cfa91 100644 --- a/gcc/sym-exec/condition.h +++ b/gcc/sym-exec/condition.h @@ -13,7 +13,7 @@ enum condition_status { class bit_condition : public bit_expression { private: - tree_code code; + tree_code m_code; void print_expr_sign (); public: diff --git a/gcc/sym-exec/expression.cc b/gcc/sym-exec/expression.cc index 7a830eb437a..0f885550ab8 100644 --- a/gcc/sym-exec/expression.cc +++ b/gcc/sym-exec/expression.cc @@ -7,76 +7,76 @@ value_type value_bit::get_type () const { - return type; + return m_type; } - -symbolic_bit::symbolic_bit (size_t i, tree orig) : value_bit (i), origin (orig) +symbolic_bit::symbolic_bit (size_t i, tree orig) + : value_bit (i), m_origin (orig) { - type = SYMBOLIC_BIT; + m_type = SYMBOLIC_BIT; } -bit::bit (unsigned char i) : val (i) +bit::bit (unsigned char i) : m_val (i) { - type = BIT; + m_type = BIT; } value_bit * bit_expression::get_left () { - return left; + return m_left; } value_bit * bit_expression::get_right () { - return right; + return m_right; } void bit_expression::set_left (value_bit *expr) { - left = expr; + m_left = expr; } void bit_expression::set_right (value_bit *expr) { - right = expr; + m_right = expr; } size_t value_bit::get_index () const { - return index; + return m_index; } unsigned char bit::get_val () const { - return val; + return m_val; } void bit::set_val (unsigned char new_val) { - val = new_val; + m_val = new_val; } bit_complement_expression::bit_complement_expression (value_bit *right) { - this->left = nullptr; - this->right = right; - type = BIT_COMPLEMENT_EXPRESSION; + this->m_left = nullptr; + this->m_right = right; + m_type = BIT_COMPLEMENT_EXPRESSION; } @@ -89,10 +89,10 @@ bit_complement_expression::bit_complement_expression ( bit_expression::~bit_expression () { - delete left; - left = nullptr; - delete right; - right = nullptr; + delete m_left; + m_left = nullptr; + delete m_right; + m_right = nullptr; } @@ -113,13 +113,13 @@ bit::copy () const void bit_expression::copy (const bit_expression *expr) { - if (expr->left) - left = expr->left->copy (); + if (expr->m_left) + m_left = expr->m_left->copy (); - if (expr->right) - right = expr->right->copy (); + if (expr->m_right) + m_right = expr->m_right->copy (); - type = expr->type; + m_type = expr->m_type; } @@ -181,9 +181,9 @@ bit_complement_expression::copy () const bit_xor_expression::bit_xor_expression (value_bit *left, value_bit *right) { - this->left = left; - this->right = right; - type = BIT_XOR_EXPRESSION; + this->m_left = left; + this->m_right = right; + m_type = BIT_XOR_EXPRESSION; } @@ -195,9 +195,9 @@ bit_xor_expression::bit_xor_expression (const bit_xor_expression &expr) bit_and_expression::bit_and_expression (value_bit *left, value_bit *right) { - this->left = left; - this->right = right; - type = BIT_AND_EXPRESSION; + this->m_left = left; + this->m_right = right; + m_type = BIT_AND_EXPRESSION; } @@ -209,9 +209,9 @@ bit_and_expression::bit_and_expression (const bit_and_expression &expr) bit_or_expression::bit_or_expression (value_bit *left, value_bit *right) { - this->left = left; - this->right = right; - type = BIT_OR_EXPRESSION; + this->m_left = left; + this->m_right = right; + m_type = BIT_OR_EXPRESSION; } @@ -224,9 +224,9 @@ bit_or_expression::bit_or_expression (const bit_or_expression &expr) shift_right_expression::shift_right_expression (value_bit *left, value_bit *right) { - this->left = left; - this->right = right; - type = SHIFT_RIGHT_EXPRESSION; + this->m_left = left; + this->m_right = right; + m_type = SHIFT_RIGHT_EXPRESSION; } @@ -239,9 +239,9 @@ shift_right_expression::shift_right_expression ( shift_left_expression::shift_left_expression (value_bit *left, value_bit *right) { - this->left = left; - this->right = right; - type = SHIFT_LEFT_EXPRESSION; + this->m_left = left; + this->m_right = right; + m_type = SHIFT_LEFT_EXPRESSION; } @@ -253,9 +253,9 @@ shift_left_expression::shift_left_expression (const shift_left_expression &expr) add_expression::add_expression (value_bit *left, value_bit *right) { - this->left = left; - this->right = right; - type = ADD_EXPRESSION; + this->m_left = left; + this->m_right = right; + m_type = ADD_EXPRESSION; } @@ -267,9 +267,9 @@ add_expression::add_expression (const add_expression &expr) sub_expression::sub_expression (value_bit *left, value_bit *right) { - this->left = left; - this->right = right; - type = SUB_EXPRESSION; + this->m_left = left; + this->m_right = right; + m_type = SUB_EXPRESSION; } @@ -282,7 +282,7 @@ sub_expression::sub_expression (const sub_expression &expr) tree symbolic_bit::get_origin () { - return origin; + return m_origin; } @@ -291,8 +291,8 @@ symbolic_bit::print () { if (dump_file) { - print_generic_expr (dump_file, origin, dump_flags); - fprintf (dump_file, "[%lu]", index); + print_generic_expr (dump_file, m_origin, dump_flags); + fprintf (dump_file, "[%zu]", m_index); } } @@ -301,14 +301,14 @@ void bit::print () { if (dump_file) - fprintf (dump_file, "%u", val); + fprintf (dump_file, "%u", m_val); } void bit_expression::print_expr_sign () { - switch (type) + switch (m_type) { case BIT_XOR_EXPRESSION: fprintf (dump_file, " ^ "); @@ -343,15 +343,15 @@ bit_expression::print () if (dump_file) { fprintf (dump_file, "("); - if (left) - left->print (); + if (m_left) + m_left->print (); else fprintf (dump_file, "null"); print_expr_sign (); - if (right) - right->print (); + if (m_right) + m_right->print (); else fprintf (dump_file, "null"); @@ -366,8 +366,8 @@ bit_complement_expression::print () if (dump_file) { fprintf (dump_file, "!"); - if (right) - right->print (); + if (m_right) + m_right->print (); else fprintf (dump_file, "null"); } diff --git a/gcc/sym-exec/expression.h b/gcc/sym-exec/expression.h index 10b501e782b..da17b8042c7 100644 --- a/gcc/sym-exec/expression.h +++ b/gcc/sym-exec/expression.h @@ -38,15 +38,15 @@ class value_bit { protected: /* This will help us to understand where is moved the bit from its initial position. */ - const size_t index; - value_type type; + const size_t m_index; + value_type m_type; public: - value_bit () : index (0) + value_bit () : m_index (0) {}; - value_bit (size_t i) : index (i) + value_bit (size_t i) : m_index (i) {}; - value_bit (const value_bit &val) : index (val.index) + value_bit (const value_bit &val) : m_index (val.m_index) {}; size_t get_index () const; value_type get_type () const; @@ -60,12 +60,12 @@ class value_bit { /* Represents value of a single bit of symbolic marked variables. */ class symbolic_bit : public value_bit { - tree origin = nullptr; + tree m_origin = nullptr; public: symbolic_bit (size_t i, tree orig); - symbolic_bit (const symbolic_bit &sym_bit) : symbolic_bit (sym_bit.index, - sym_bit.origin) + symbolic_bit (const symbolic_bit &sym_bit) : symbolic_bit (sym_bit.m_index, + sym_bit.m_origin) {}; value_bit *copy () const; @@ -79,11 +79,11 @@ class symbolic_bit : public value_bit { class bit : public value_bit { private: /* This is the value of a bit. It must be either 1 or 0. */ - unsigned char val = 0; + unsigned char m_val = 0; public: bit (unsigned char i); - bit (const bit &b) : bit (b.val) + bit (const bit &b) : bit (b.m_val) {}; unsigned char get_val () const; void set_val (unsigned char new_val); @@ -93,12 +93,12 @@ class bit : public value_bit { /* Bit-level base expression class. In general expressions consist of - two operands. Here we named them left and right. */ + two operands. Here we named them m_left and right. */ class bit_expression : public value_bit { protected: - value_bit *left = nullptr; - value_bit *right = nullptr; + value_bit *m_left = nullptr; + value_bit *m_right = nullptr; void copy (const bit_expression *expr); virtual void print_expr_sign (); diff --git a/gcc/sym-exec/state.cc b/gcc/sym-exec/state.cc index 95702af9c98..4fd29237c5b 100644 --- a/gcc/sym-exec/state.cc +++ b/gcc/sym-exec/state.cc @@ -43,20 +43,35 @@ state::is_declared (tree var) } +/* Declares given variable if it has not been declared yet. */ + void state::declare_if_needed (tree var, size_t size) { if (TREE_CODE (var) != INTEGER_CST && !is_declared (var)) - make_symbolic (var, size); + { + make_symbolic (var, size); + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, + "Declaring var "); + print_generic_expr (dump_file, var, dump_flags); + fprintf (dump_file, + " with size %zd\n", size); + } + } } +/* Get value of the given variable. */ + value * state::get_value (tree var) { return var_states.get (var); } + /* Get the value of the tree, which is in the beginning of the var_states. */ value * @@ -65,6 +80,9 @@ state::get_first_value () return &(*(var_states.begin ())).second; } + +/* Returns the list of conditions in the state. */ + const hash_set<bit_expression *> & state::get_conditions () { @@ -112,6 +130,8 @@ state::create_val_for_const (tree var, size_t size) } +/* Adds the given variable to state. */ + bool state::add_var_state (tree var, value *vstate) { @@ -124,6 +144,8 @@ state::add_var_state (tree var, value *vstate) } +/* Adds the given condition to the state. */ + bool state::add_condition (bit_expression *cond) { @@ -131,6 +153,8 @@ state::add_condition (bit_expression *cond) } +/* Bulk add the given conditions to the state. */ + bool state::bulk_add_conditions (const hash_set<bit_expression *> &conds) { @@ -142,14 +166,25 @@ state::bulk_add_conditions (const hash_set<bit_expression *> &conds) } +/* Remove all states from the states' vector. */ + void -state::clear_states (vec<state *> *states) +state::remove_states (vec<state *> *states) { while (!states->is_empty ()) { delete states->last (); states->pop (); } +} + + +/* Remove all states from the states' vector and release the vector. */ + +void +state::clear_states (vec<state *> *states) +{ + remove_states (states); states->release (); } @@ -283,7 +318,7 @@ state::make_symbolic (tree var, unsigned size) } -/* Performs AND operation on two values. */ +/* Performs AND operation on two bits. */ value_bit * state::and_two_bits (value_bit *arg1, value_bit *arg2) @@ -308,14 +343,20 @@ state::and_two_bits (value_bit *arg1, value_bit *arg2) } +/* A wrapper for operations on two bits. + Operation and operands are passed as arguments. */ + value_bit * state::operate_bits (bit_func bit_op, value_bit *bit1, value_bit *bit2, - value_bit **bit3) + value_bit **) { return (bit_op) (bit1, bit2); } +/* A wrapper for operations on three bits. + Operation and operands are passed as arguments. */ + value_bit * state::operate_bits (bit_func3 bit_op, value_bit *bit1, value_bit *bit2, value_bit **bit3) @@ -371,6 +412,8 @@ state::do_and (tree arg1, tree arg2, tree dest) } +/* Performs AND operation on given values. The result is stored in dest. */ + void state::do_and (value *arg1, value *arg2, tree dest) { @@ -416,6 +459,8 @@ state::do_or (tree arg1, tree arg2, tree dest) } +/* Performs OR operation on given values. The result is stored in dest. */ + void state::do_or (value *arg1, value *arg2, tree dest) { @@ -460,6 +505,8 @@ state::do_xor (tree arg1, tree arg2, tree dest) } +/* Performs XOR operation on given values. The result is stored in dest. */ + void state::do_xor (value *arg1, value *arg2, tree dest) { @@ -542,6 +589,9 @@ state::do_shift_left (tree arg1, tree arg2, tree dest) } +/* Performs shift left operation on given values. + The result is stored in dest. */ + void state::do_shift_left (value *arg1, value *arg2, tree dest) { @@ -570,6 +620,9 @@ state::do_shift_right (tree arg1, tree arg2, tree dest) } +/* Performs shift right operation on given values. + The result is stored in dest. */ + void state::do_shift_right (value *arg1, value *arg2, tree dest) { @@ -623,6 +676,8 @@ state::do_add (tree arg1, tree arg2, tree dest) } +/* Adds given values. The result is stored in dest. */ + void state::do_add (value *arg1, value *arg2, tree dest) { @@ -672,6 +727,8 @@ state::do_sub (tree arg1, tree arg2, tree dest) } +/* Subtracks second value from the first. The result is stored in dest. */ + void state::do_sub (value *arg1, value *arg2, tree dest) { @@ -735,11 +792,16 @@ state::do_complement (tree arg, tree dest) } +/* Does Assignment. */ + bool state::do_assign (tree arg, tree dest) { declare_if_needed (dest, tree_to_uhwi (TYPE_SIZE (TREE_TYPE (dest)))); - declare_if_needed (arg, var_states.get (dest)->allocated ()); + if (TREE_CODE (arg) != INTEGER_CST) + declare_if_needed (arg, tree_to_uhwi (TYPE_SIZE (TREE_TYPE (arg)))); + else + declare_if_needed (arg, var_states.get (dest)->allocated ()); value *dest_val = var_states.get (dest); @@ -815,6 +877,7 @@ state::do_assign_pow2 (tree dest, unsigned pow) (*dest_val)[i] = new bit (0); } + print_value (dest_val); return true; } @@ -1126,10 +1189,12 @@ state::do_mul (value *arg1, value *arg2, tree dest) } +/* Checks whether the given two constant values are equal. */ + bool state::check_const_value_equality (value *arg1, value *arg2) { - for (size_t i = 1; i < arg1->length (); i++) + for (size_t i = 0; i < arg1->length (); i++) if (as_a<bit *> ((*arg1)[i])->get_val () != as_a<bit *> ((*arg2)[i])->get_val ()) return false; @@ -1137,6 +1202,8 @@ state::check_const_value_equality (value *arg1, value *arg2) } +/* Adds EQUAL condition of given variables to state. */ + bool state::add_equal_cond (tree arg1, tree arg2) { @@ -1187,6 +1254,8 @@ state::add_equal_cond (value *arg1, value *arg2) } +/* Checks whether the given two constant values are not equal. */ + bool state::check_const_value_are_not_equal (value *arg1, value *arg2) { @@ -1198,6 +1267,8 @@ state::check_const_value_are_not_equal (value *arg1, value *arg2) } +/* Adds NOT EQUAL condition of given variables to state. */ + bool state::add_not_equal_cond (tree arg1, tree arg2) { @@ -1253,6 +1324,9 @@ state::add_not_equal_cond (value *arg1, value *arg2) } +/* Checks whether the first given constant value + is greater than the second one. */ + bool state::check_const_value_is_greater_than (value *arg1, value *arg2) { @@ -1269,6 +1343,8 @@ state::check_const_value_is_greater_than (value *arg1, value *arg2) } +/* Adds GREATER THAN condition of given variables to state. */ + bool state::add_greater_than_cond (tree arg1, tree arg2) { @@ -1378,6 +1454,9 @@ state::construct_great_than_cond (value *arg1, value *arg2) } +/* Checks whether the first given constant value + is less than the second one. */ + bool state::check_const_value_is_less_than (value *arg1, value *arg2) { @@ -1394,6 +1473,8 @@ state::check_const_value_is_less_than (value *arg1, value *arg2) } +/* Adds LESS THAN condition of given variables to state. */ + bool state::add_less_than_cond (tree arg1, tree arg2) { @@ -1501,6 +1582,8 @@ state::construct_less_than_cond (value *arg1, value *arg2) } +/* Adds GREATER OR EQUAL condition of given variables to state. */ + bool state::add_greater_or_equal_cond (tree arg1, tree arg2) { @@ -1553,7 +1636,7 @@ state::add_greater_or_equal_cond (value *arg1, value *arg2) } -/* Adds less or equal condition for two sequences of bits. */ +/* Adds LESS OR EQUAL condition of given variables to state. */ bool state::add_less_or_equal_cond (tree arg1, tree arg2) @@ -1589,6 +1672,8 @@ state::add_less_or_equal_cond (value *arg1, value *arg2) } +/* Adds a bool condition to state. */ + bool state::add_bool_cond (tree arg) { @@ -1652,7 +1737,7 @@ state::add_binary_cond (tree arg1, tree arg2, binary_cond_func cond_func) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Sym-Exec: At least one of arguments must be" - " declared for adding condition.\n"); + " declared for adding the condition.\n"); return false; } @@ -1702,8 +1787,8 @@ state::construct_equal_cond (value *arg1, value *arg2) return nullptr; } - /* When some of bits are constants and they differ by value, - then we can evalate it to be false. */ + /* When some bits are constants, and they differ by value, + then we can evaluate it to be false. */ for (size_t i = 0; i < arg1->length (); i++) { if (is_a<bit *> ((*arg1)[i]) && is_a<bit *> ((*arg2)[i]) @@ -1866,6 +1951,8 @@ value::last () } +/* Make a copy of given bits. */ + vec<value_bit *> * state::make_copy (vec<value_bit *> *bits) { @@ -1946,29 +2033,13 @@ state::do_cast (tree var, tree dest, size_t cast_size) return true; } -/* Get the last 1 bit index. */ -size_t -last_set_bit (const value &polynomial) -{ - for (size_t i = 0; i < polynomial.length (); ++i) - { - if (as_a<bit *> (polynomial[polynomial.length () - i - 1])->get_val ()) - return polynomial.length () - i - 1; - } - return 0; -} - /* Create LFSR value for the reversed CRC. */ void state::create_reversed_lfsr (value &lfsr, const value &crc, const value &polynomial) { - /* Get the minimal byte size to keep the polynomial. - Ie, if the last 1 bit of the polynomial is at 6 index, size will be 8. */ - size_t size = ((last_set_bit (polynomial)/8) + 1) * 8; - if (size == 0) - return; + size_t size = polynomial.length (); /* Determine values of all bits, except MSB. */ for (size_t i = 0; i < size - 1; i++) @@ -1993,10 +2064,7 @@ void state::create_forward_lfsr (value &lfsr, const value &crc, const value &polynomial) { - size_t size = ((last_set_bit (polynomial)/8) + 1) * 8; - if (size == 0) - return; - + size_t size = polynomial.length (); /* Determine value of LSB. */ if (as_a<bit *> (polynomial[0])->get_val ()) lfsr.push (crc[size - 1]->copy ()); @@ -2014,15 +2082,29 @@ state::create_forward_lfsr (value &lfsr, const value &crc, } +/* Get the last 1 bit index. */ + +size_t +last_set_bit (const value &polynomial) +{ + for (size_t i = 0; i < polynomial.length (); ++i) + { + if (as_a<bit *> (polynomial[polynomial.length () - i - 1])->get_val ()) + return polynomial.length () - i - 1; + } + return 0; +} + + /* Create LFSR value. */ value * state::create_lfsr (tree crc, value *polynomial, bool is_bit_forward) { /* Check size compatibility․ */ - unsigned HOST_WIDE_INT size = polynomial->length (); + unsigned HOST_WIDE_INT polynomial_length = polynomial->length (); unsigned HOST_WIDE_INT crc_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (crc))); - if (crc_size < size) + if (crc_size < polynomial_length) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "LFSR state creation: " @@ -2031,14 +2113,30 @@ state::create_lfsr (tree crc, value *polynomial, bool is_bit_forward) return nullptr; } + /* Get the minimal byte size to keep the polynomial. + Ie, if the last 1 bit of the polynomial is at 6 index, size will be 8. */ + size_t required_polynomial_size = ((last_set_bit (*polynomial)/8) + 1) * 8; + + /* Polynomial's length actually equals to the CRC variable's size. + Now we detect only those CRC calculation algorithms, where leading 1 of the + polynomial isn't kept. */ + if (required_polynomial_size == 0 + || required_polynomial_size != polynomial_length) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "Polynomial's all bits are zeros " + "or the size of the polynomial is uncertain.\n"); + return nullptr; + } + /* Create vector of symbolic bits for crc. */ - value crc_value (size, TYPE_UNSIGNED (TREE_TYPE (crc))); + value crc_value (polynomial_length, TYPE_UNSIGNED (TREE_TYPE (crc))); - for (unsigned HOST_WIDE_INT i = 0; i < size; i++) - crc_value.push (new symbolic_bit (i, crc)); + for (unsigned HOST_WIDE_INT i = 0; i < polynomial_length; i++) + crc_value.push (new symbolic_bit (i, crc)); /* create LFSR vector. */ - value *lfsr = new value (size, TYPE_UNSIGNED (TREE_TYPE (crc))); + value *lfsr = new value (polynomial_length, TYPE_UNSIGNED (TREE_TYPE (crc))); /* Calculate values for LFSR. */ if (is_bit_forward) diff --git a/gcc/sym-exec/state.h b/gcc/sym-exec/state.h index 1fe85f85805..b20c8deab2f 100644 --- a/gcc/sym-exec/state.h +++ b/gcc/sym-exec/state.h @@ -90,12 +90,18 @@ class state { /* Constructs expression trees of equal condition for given values. */ bit_expression *construct_equal_cond (value *arg1, value *arg2); + /* A wrapper for operations on two bits. + Operation and operands are passed as arguments. */ static value_bit *operate_bits (bit_func bit_op, value_bit *bit1, value_bit *bit2, value_bit **bit3); + /* A wrapper for operations on three bits. + Operation and operands are passed as arguments. */ static value_bit *operate_bits (bit_func3 bit_op, value_bit *bit1, value_bit *bit2, value_bit **bit3); + /* Performs the given operation on passed arguments. + The result is stored in dest. */ template<class func> void operate (value *arg1, value *arg2, value_bit **bit_arg, tree dest, func bit_op); @@ -105,29 +111,39 @@ class state { bool do_binary_operation (tree arg1, tree arg2, tree dest, binary_func bin_func); + /* Performs AND operation on given values. The result is stored in dest. */ void do_and (value *arg1, value *arg2, tree dest); + /* Performs OR operation on given values. The result is stored in dest. */ void do_or (value *arg1, value *arg2, tree dest); + /* Performs XOR operation on given values. The result is stored in dest. */ void do_xor (value *arg1, value *arg2, tree dest); + /* Performs shift right operation on given values. + The result is stored in dest. */ void do_shift_right (value *arg1, value *arg2, tree dest); + /* Performs shift left operation on given values. + The result is stored in dest. */ void do_shift_left (value *arg1, value *arg2, tree dest); + /* Adds given values. The result is stored in dest. */ void do_add (value *arg1, value *arg2, tree dest); + /* Subtracks second value from the first. The result is stored in dest. */ void do_sub (value *arg1, value *arg2, tree dest); /* Casts arg to cast_size size, stores value in dest. */ bool do_cast (tree arg, tree dest, size_t cast_size); - /* Performs AND operation on two values. */ + /* Performs AND operation on two bits. */ static value_bit *and_two_bits (value_bit *arg1, value_bit *arg2); /* ANDs every bit of the value with var_bit, stroes the result in var1. */ void and_number_bit (value *var1, value_bit *var_bit); + /* Multiplies given values. The result is stored in dest. */ void do_mul (value *arg1, value *arg2, tree dest); /* Performs AND operation for 2 symbolic_bit operands. */ @@ -197,14 +213,12 @@ class state { exists or not. */ bool is_declared (tree var); + /* Declares given variable if it has not been declared yet. */ void declare_if_needed (tree var, size_t size); /* Shifts number left by size of shift_value. */ value *shift_left_by_const (const value *number, size_t shift_value); - /* Checks if all bits of the given value have constant bit type. */ - bool is_bit_vector (const value *var); - /* Adds two bits and carry value. Resturn result and stores new carry bit in "carry". */ static value_bit *full_adder (value_bit *var1, value_bit *var2, @@ -216,17 +230,16 @@ class state { /* Adds two values, stores the result in the first one. */ void add_numbers (value *var1, const value *var2); + /* Make a copy of given bits. */ static vec<value_bit *> *make_copy (vec<value_bit *> *bits); /* Create LFSR value for the reversed CRC. */ - static void - create_reversed_lfsr (value &lfsr, const value &crc, - const value &polynomial); + static void create_reversed_lfsr (value &lfsr, const value &crc, + const value &polynomial); /* Create LFSR value for the forward CRC. */ - static void - create_forward_lfsr (value &lfsr, const value &crc, - const value &polynomial); + static void create_forward_lfsr (value &lfsr, const value &crc, + const value &polynomial); public: state () = default; @@ -238,23 +251,32 @@ class state { state (const state &s); + /* Adds the given variable to state. */ bool add_var_state (tree var, value *state); + /* Remove all states from the states' vector. */ + static void remove_states (vec<state *> *states); + + /* Remove all states from the states' vector and release the vector. */ static void clear_states (vec<state *> *states); void clear_var_states (); void clear_conditions (); + /* Adds the given condition to the state. */ bool add_condition (bit_expression *cond); + /* Bulk add the given conditions to the state. */ bool bulk_add_conditions (const hash_set<bit_expression *> &conds); + /* Get value of the given variable. */ value *get_value (tree var); /* Get the value of the tree, which is in the beginning of the var_states. */ value *get_first_value (); + /* Returns the list of conditions in the state. */ const hash_set<bit_expression *> &get_conditions (); /* Adds a variable with unknown value to state. Such variables are @@ -270,6 +292,9 @@ class state { /* Prints added conditions. */ void print_conditions (); + /* Checks if all bits of the given value have constant bit type. */ + static bool is_bit_vector (const value *var); + /* Returns the number represented by the value. */ static unsigned HOST_WIDE_INT make_number (const value *var); @@ -283,6 +308,7 @@ class state { /* Does bit-level OR operation for given variables. */ bool do_or (tree arg1, tree arg2, tree dest); + /* Does Assignment. */ bool do_assign (tree arg, tree dest); /* Assigns pow 2 value. */ @@ -306,6 +332,7 @@ class state { /* Negates given variable. */ bool do_complement (tree arg, tree dest); + /* Adds EQUAL condition of given variables to state. */ bool add_equal_cond (tree arg1, tree arg2); /* Gets the value of *arg1 and stores it in dest. */ @@ -317,24 +344,36 @@ class state { /* Perform subtractions on arg1 pointer. */ bool do_pointer_diff (tree arg1, tree arg2, tree dest); + /* Adds NOT EQUAL condition of given variables to state. */ bool add_not_equal_cond (tree arg1, tree arg2); + /* Adds GREATER THAN condition of given variables to state. */ bool add_greater_than_cond (tree arg1, tree arg2); + /* Adds LESS THAN condition of given variables to state. */ bool add_less_than_cond (tree arg1, tree arg2); + /* Adds GREATER OR EQUAL condition of given variables to state. */ bool add_greater_or_equal_cond (tree arg1, tree arg2); + /* Adds LESS OR EQUAL condition of given variables to state. */ bool add_less_or_equal_cond (tree arg1, tree arg2); + /* Adds a bool condition to state. */ bool add_bool_cond (tree arg); + /* Checks whether the given two constant values are equal. */ static bool check_const_value_equality (value *arg1, value *arg2); + /* Checks whether the given two constant values are not equal. */ static bool check_const_value_are_not_equal (value *arg1, value *arg2); + /* Checks whether the first given constant value + is greater than the second one. */ static bool check_const_value_is_greater_than (value *arg1, value *arg2); + /* Checks whether the first given constant value + is less than the second one. */ static bool check_const_value_is_less_than (value *arg1, value *arg2); static value_bit *complement_bits_with_origin (value_bit *root, tree origin); @@ -358,6 +397,9 @@ class state { size_t min (size_t a, size_t b, size_t c); +/* Performs the given operation on passed arguments. + The result is stored in dest. */ + template<class func> void state::operate (value *arg1, value *arg2, value_bit **bit_arg, tree dest,