mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-23 02:44:18 +08:00
Refactored sym-exec: Added comments, changed members' names ...
This commit is contained in:
parent
4953a04ee6
commit
525b7590e3
@ -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, " > ");
|
||||
|
@ -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:
|
||||
|
@ -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), m_origin (orig)
|
||||
{
|
||||
m_type = SYMBOLIC_BIT;
|
||||
}
|
||||
|
||||
|
||||
symbolic_bit::symbolic_bit (size_t i, tree orig) : value_bit (i), origin (orig)
|
||||
bit::bit (unsigned char i) : m_val (i)
|
||||
{
|
||||
type = SYMBOLIC_BIT;
|
||||
}
|
||||
|
||||
|
||||
bit::bit (unsigned char i) : 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");
|
||||
}
|
||||
|
@ -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 ();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/* Create vector of symbolic bits for crc. */
|
||||
value crc_value (size, TYPE_UNSIGNED (TREE_TYPE (crc)));
|
||||
/* 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;
|
||||
|
||||
for (unsigned HOST_WIDE_INT i = 0; i < size; i++)
|
||||
crc_value.push (new symbolic_bit (i, crc));
|
||||
/* 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 (polynomial_length, TYPE_UNSIGNED (TREE_TYPE (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)
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user