/* State will store states of variables for a function's single execution path.
   It will be used for bit-level symbolic execution to determine values of bits
   of function's return value and symbolic marked arguments.
   Copyright (C) 2022-2026 Free Software Foundation, Inc.
   Contributed by Matevos Mehrabyan <matevosmehrabyan@gmail.com>

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

/* This symbolic executor is designed to handle operations on the bit level.
   It can save values of variables on the bit level.  For example byte x = 9
   would be represented by the bit-vector x = <0, 0, 0, 0, 1, 0, 1, 0> of
   size 8.  Variables without values will be represented by bit-vectors of
   symbolic bits: x = <x[size - 1], ..., x[1], x[0]> where x[i] is the value
   of bit i of variable x.

   Operations are also performed on the bit level.  For example, for operation
   z = x & y
   where
   x = <x[size - 1], ..., x[1], x[0]>
   y = <y[size - 1], ..., y[1], y[0]>
   z will have the value
   z = <x[size - 1] & y[size - 1], ..., x[1] & y[1], x[0] & y[0]>

   Each bit of variable can be accessed and examined separately if needed.
   Moreover, it does basic optimizations in place.
   For example, for operation
   z = x | y
   where
   x = <x[size - 1], ..., x[1], x[0]>,
   y = <1, ..., 0, 1>,
   z will have the value
   z = <1, ..., x[1], 1>
   as x | 0 == x and x | 1 == 1

   Besides variables, the symbolic executor can also store
   conditions on the bit level.
   For example, for x == y
   It would add {x[size - 1] == y[size - 1], ..., x[1] == y[1], x[0] == y[0]}
   conditions.

   For a more complex condition x > y, it would add
   {x[size - 1] > y[size - 1] || (x[size - 1] == y[size -1]
	&& (x[size - 2] > y[size - 2] || (x[size - 2] == y[size - 2]
		&& ... (x[0] >= y[0])...)}

   The symbolic executor doesn't run by itself.  Instead, it must be dictated
   what to do.  This makes it flexible and allows for various pre- and
   post-processing tasks.  Developers adding new operation support must consider
   that the operation must be represented on the bit level.  Because of
   this restriction, it may be hard to add support for some operations.

   To use the symbolic executor, you must create a state object.  It is the main
   object that contains variables as bit-vectors and conditions.
   It is the state object that provides operations for symbolic execution.

   If you are going to execute multiple execution paths, you should clone
   the state at branching instructions and execute one state for the execution
   path where the branching condition evaluates to 'true', and
   the other state for the execution path where the branching condition
   evaluates to 'false'.  Besides that, you should add the corresponding
   conditions to states if you need them.

   Variables are stored in the state's 'var_states' field.  It maps the tree
   object of the variable to its bit-vector.  Path conditions are stored in
   the 'conditions' field.

   To declare a variable, you should use 'declare_if_needed' method of state.
   It declares the variable if it was not previously declared.
   'create_val_for_const' is used for constant declaration.

   The list of supported operations can be found in 'state::do_operation'
   method.  It calls the corresponding operation based on the specified
   tree_code operation.  This is the method that you should use to dictate
   to the symbolic executor what operations to perform.  You can execute the
   desired operations explicitly if needed.  Variables for participant
   operands will be created implicitly if it was not previously declared.
   To add conditions to the state, you should use 'state::add_*_cond' methods.

   A sample usage of the symbolic executor:

   // Example.

   unsigned char foo (unsigned char x, unsigned char y)
   {
     unsigned char D.2352;
     unsigned char result;

     result = x & y;
     result = result | 9;
     if (result == 23) goto <D.2350>; else goto <D.2351>;
     <D.2350>:
     result = result ^ y;
     <D.2351>:
     D.2352 = result;
     return D.2352;
   }

   // Now, we create the initial state and add the variables to it.
   state s;
   s.declare_if_needed (x, tree_to_uhwi (TYPE_SIZE (TREE_TYPE (x))));
   s.declare_if_needed (y, tree_to_uhwi (TYPE_SIZE (TREE_TYPE (y))));
   s.declare_if_needed (d_2352, tree_to_uhwi (TYPE_SIZE (TREE_TYPE (d_2352))));
   s.declare_if_needed (result, tree_to_uhwi (TYPE_SIZE (TREE_TYPE (result))));

   s.do_operation (BIT_AND_EXPR, x, y, result);
   s.do_operation (BIT_OR_EXPR, result, 9, result);

   state s2 (s);  // We duplicate the state to save values for each branch.
   s.add_equal_cond (result, 23);
   s2.add_not_equal_cond (result, 23);

   s.do_operation (BIT_XOR_EXPR, result, y, result);
   s.do_assign (result, d_2352);
   s2.do_assign (result, d_2352);

   // Now, we have variable values for each execution branch, and we can examine
   // them to make decisions.

   value * res = s.get_value (result);
   if (is_a<bit_expression *> ((*res)[0]))
   {
     bit_expression * expr = is_a<bit_expression *> ((*res)[0]);
     if (is_a<bit *> (expr->get_left ())
	 && as_a<bit *> (expr->get_left ())->get_val () == 0)
     {
       ... // Do something.
     }
   }

   A more general usage would be to iterate over instructions and
   call the executor:

   state s;
   ...

   for (inst : instructions)
   {
     enum tree_code rhs_code = gimple_assign_rhs_code (inst);
     tree op1 = gimple_assign_rhs1 (gs);
     tree op2 = gimple_assign_rhs2 (gs);
     tree lhs = gimple_assign_lhs (gs);
     s.do_operation (rhs_code, op1, op2, lhs);
     ...
   }

   */

#include "sym-exec-state.h"

/* Returns the minimum of A, B, C.  */

size_t min (size_t a, size_t b, size_t c)
{
  size_t min = (a < b ? a : b);
  return min < c ? min : c;
}


/* Copy constructor for state.  It copies all variables and conditions
   of the given state.  */

state::state (const state &s)
{
  for (auto iter = s.var_states.begin (); iter != s.var_states.end (); ++iter)
    {
      value val ((*iter).second.length (), (*iter).second.is_unsigned);
      for (size_t i = 0; i < (*iter).second.length (); i++)
	val.push ((*iter).second[i]->copy ());

      var_states.put ((*iter).first, val);
    }

  for (auto iter = s.conditions.begin (); iter != s.conditions.end (); ++iter)
    conditions.add (as_a<bit_expression *> ((*iter)->copy ()));
}


/* Destructor for state.  */

state::~state ()
{
  clear_conditions ();
}


/* Checks whether state for variable with specified name already
   exists or not.  */

bool
state::is_declared (tree var)
{
  return var_states.get (var) != NULL;
}


/* 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);
      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 *
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 ()
{
  return conditions;
}


/* Checks if sizes of arguments and destination are compatible.  */

bool
state::check_args_compatibility (tree arg1, tree arg2, tree dest)
{
  if (!(get_var_size (arg1) == get_var_size (dest)
	|| TREE_CODE (arg1) == INTEGER_CST)
      || !(get_var_size (arg2) == get_var_size (dest)
	   || TREE_CODE (arg2) == INTEGER_CST))
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "Sym-Exec: Incompatible destination "
			    "and argument sizes.\n");

      return false;
    }

  return true;
}


/* Creates value for given constant tree.  */

value
state::create_val_for_const (tree var, size_t size)
{
  unsigned HOST_WIDE_INT val = TYPE_UNSIGNED (TREE_TYPE (var))
			       ? tree_to_uhwi (var) : tree_to_shwi (var);
  value result (size, TYPE_UNSIGNED (TREE_TYPE (var)));

  for (size_t i = 0; i < size; i++)
    {
      result.push (new bit (val & 1));
      val >>= 1;
    }

  return result;
}


/* Adds the given variable to state.  */

bool
state::add_var_state (tree var, value *vstate)
{
  size_t size = vstate->length ();
  value val (size, vstate->is_unsigned);
  for (size_t i = 0; i < size; i++)
    val.push ((*vstate)[i]->copy ());

  return var_states.put (var, val);
}


/* Adds the given condition to the state.  */

bool
state::add_condition (bit_expression *cond)
{
  return conditions.add (as_a<bit_expression *> (cond->copy ()));
}


/* Bulk add the given conditions to the state.  */

bool
state::bulk_add_conditions (const hash_set<bit_expression *> &conds)
{
  bool status = true;
  for (auto iter = conds.begin (); iter != conds.end (); ++iter)
    status &= add_condition (*iter);

  return status;
}


/* Remove all states from the states' vector.  */

void
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 ();
}


/* Removes all variables added to the state.  */

void
state::clear_var_states ()
{
  var_states.empty ();
}


/* Removes all conditions added to the state.  */

void
state::clear_conditions ()
{
  for (auto iter = conditions.begin (); iter != conditions.end (); ++iter)
    delete (*iter);
  conditions.empty ();
}


/* Performs AND operation for 2 symbolic_bit operands.  */

value_bit *
state::and_sym_bits (const value_bit *var1, const value_bit *var2)
{
  return new bit_and_expression (var1->copy (), var2->copy ());
}


/* Performs AND operation for a symbolic_bit and const_bit operands.  */

value_bit *
state::and_var_const (const value_bit *var1, const bit *const_bit)
{
  if (const_bit->get_val () == 1)
    return var1->copy ();

  return new bit (0);
}


/* Performs AND operation for 2 constant bit operands.  */

bit *
state::and_const_bits (const bit *const_bit1, const bit *const_bit2)
{
  if (const_bit1->get_val () == const_bit2->get_val ())
    return new bit (*const_bit1);

  return new bit (0);
}


/* Performs OR operation for 2 symbolic_bit operands.  */

value_bit *
state::or_sym_bits (const value_bit *var1, const value_bit *var2)
{
  return new bit_or_expression (var1->copy (), var2->copy ());
}


/* Performs OR operation for a symbolic_bit and a constant bit operands.  */

value_bit *
state::or_var_const (const value_bit *var1, const bit *const_bit)
{
  if (const_bit->get_val () == 0)
    return var1->copy ();

  return new bit (1);
}


/* Performs OR operation for 2 constant bit operands.  */

bit *
state::or_const_bits (const bit *const_bit1, const bit *const_bit2)
{
  if (const_bit1->get_val () == const_bit2->get_val ())
    return new bit (*const_bit1);

  return new bit (1);
}


/* Adds an empty state for the given variable.  */

bool
state::decl_var (tree var, unsigned size)
{
  if (is_declared (var))
    return false;

  value val (size, TYPE_UNSIGNED (TREE_TYPE (var)));
  for (unsigned i = 0; i < size; i++)
    val.push (nullptr);

  return var_states.put (var, val);
}


/* Returns size of the given variable.  */

unsigned
state::get_var_size (tree var)
{
  value *content = var_states.get (var);
  if (content == NULL)
    return 0;

  return content->allocated ();
}


/* Adds a variable with unknown value to state.  Such variables are
   represented as sequence of symbolic bits.  */

bool
state::make_symbolic (tree var, unsigned size)
{
  if (is_declared (var))
    return false;

  value val (size, TYPE_UNSIGNED (TREE_TYPE (var)));
  /* Initialize each bit of a variable with unknown value.  */
  for (size_t i = 0; i < size; i++)
    val.push (new symbolic_bit (i, var));

  return var_states.put (var, val);
}


/* Performs AND operation on two bits.  */

value_bit *
state::and_two_bits (value_bit *arg1, value_bit *arg2)
{
  value_bit *result = nullptr;

  if (is_a<bit *> (arg1) && is_a<bit *> (arg2))
    result = and_const_bits (as_a<bit *> (arg1), as_a<bit *> (arg2));

  else if (is_a<bit *> (arg1) && (is_a<symbolic_bit *> (arg2)
				  || (is_a<bit_expression *> (arg2))))
    result = and_var_const (arg2, as_a<bit *> (arg1));

  else if ((is_a<symbolic_bit *> (arg1)
	    || (is_a<bit_expression *> (arg1))) && is_a<bit *> (arg2))
    result = and_var_const (arg1, as_a<bit *> (arg2));

  else
    result = and_sym_bits (arg1, arg2);

  return result;
}


/* 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 **)
{
  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)
{
  return (bit_op) (bit1, bit2, bit3);
}


/* Does preprocessing and postprocessing for expressions with tree operands.
   Handles value creation for constant and their removement in the end.  */

bool
state::do_binary_operation (tree arg1, tree arg2, tree dest,
			    binary_func bin_func)
{
  declare_if_needed (dest, tree_to_uhwi (TYPE_SIZE (TREE_TYPE (dest))));
  declare_if_needed (arg1, var_states.get (dest)->allocated ());
  declare_if_needed (arg2, var_states.get (dest)->allocated ());

  if (!check_args_compatibility (arg1, arg2, dest))
    return false;

  size_t dest_size = var_states.get (dest)->length ();

  value *arg1_val = var_states.get (arg1);
  value arg1_const_val (dest_size, false);
  if (arg1_val == NULL && TREE_CODE (arg1) == INTEGER_CST)
    {
      arg1_const_val = create_val_for_const (arg1, dest_size);
      arg1_val = &arg1_const_val;
    }

  value *arg2_val = var_states.get (arg2);
  value arg2_const_val (dest_size, false);
  if (arg2_val == NULL && TREE_CODE (arg2) == INTEGER_CST)
    {
      arg2_const_val = create_val_for_const (arg2, dest_size);
      arg2_val = &arg2_const_val;
    }

  (this->*bin_func) (arg1_val, arg2_val, dest);
  print_value (var_states.get (dest));
  return true;
}


/* Performs AND operation on given values.  The result is stored in dest.  */

void
state::do_and (value *arg1, value *arg2, tree dest)
{
  /* Creating AND expressions for every bit pair of given arguments
     and store them as a new state for given destination.  */

  operate (arg1, arg2, nullptr, dest, &state::and_two_bits);
}


/* Performs OR operation on two bits.  */

value_bit *
state::or_two_bits (value_bit *arg1_bit, value_bit *arg2_bit)
{
  value_bit *result = nullptr;

  if (is_a<bit *> (arg1_bit) && is_a<bit *> (arg2_bit))
    result = or_const_bits (as_a<bit *> (arg1_bit), as_a<bit *> (arg2_bit));

  else if (is_a<bit *> (arg1_bit) && (is_a<symbolic_bit *> (arg2_bit)
				      || is_a<bit_expression *> (arg2_bit)))
    result = or_var_const (arg2_bit, as_a<bit *> (arg1_bit));

  else if ((is_a<symbolic_bit *> (arg1_bit)
	    || is_a<bit_expression *> (arg1_bit))
	   && is_a<bit *> (arg2_bit))
    result = or_var_const (arg1_bit, as_a<bit *> (arg2_bit));

  else
    result = or_sym_bits (arg1_bit, arg2_bit);

  return result;
}


/* Performs OR operation on given values.  The result is stored in dest.  */

void
state::do_or (value *arg1, value *arg2, tree dest)
{
  /* Creating OR expressions for every bit pair of given arguments
     and store them as a new state for given destination.  */
  operate (arg1, arg2, nullptr, dest, &state::or_two_bits);
}


/* Performs XOR operation on two bits.  */

value_bit *
state::xor_two_bits (value_bit *arg1_bit, value_bit *arg2_bit)
{
  value_bit *result = nullptr;

  if (is_a<bit *> (arg1_bit) && is_a<bit *> (arg2_bit))
    result = xor_const_bits (as_a<bit *> (arg1_bit), as_a<bit *> (arg2_bit));

  else if (is_a<bit *> (arg1_bit) && (is_a<symbolic_bit *> (arg2_bit)
				      || is_a<bit_expression *> (arg2_bit)))
    result = xor_var_const (arg2_bit, as_a<bit *> (arg1_bit));

  else if ((is_a<symbolic_bit *> (arg1_bit)
	    || is_a<bit_expression *> (arg1_bit))
	   && is_a<bit *> (arg2_bit))
    result = xor_var_const (arg1_bit, as_a<bit *> (arg2_bit));

  else
    result = xor_sym_bits (arg1_bit, arg2_bit);

  return result;
}


/* Performs XOR operation on given values.  The result is stored in dest.  */

void
state::do_xor (value *arg1, value *arg2, tree dest)
{
  operate (arg1, arg2, nullptr, dest, &state::xor_two_bits);
}


/* Shifts value right by size of shift_value.  */

value *
state::shift_right_by_const (value *var, size_t shift_value)
{
  value *shift_result = new value (var->length (), var->is_unsigned);
  if (var->length () <= shift_value)
    for (size_t i = 0; i < var->length (); i++)
      shift_result->push (new bit (0));
  else
    {
      size_t i = 0;
      for (; i < var->length () - shift_value; ++i)
	shift_result->push (((*var)[shift_value + i])->copy ());

      for (; i < var->length (); ++i)
	shift_result->push (var->is_unsigned ? new bit (0)
					     : var->last ()->copy ());
    }
  return shift_result;
}


/* Checks if all bits of the given value have constant bit type.  */

bool
state::is_bit_vector (const value *var)
{
  if (var == nullptr || !var->exists ())
    return false;

  for (size_t i = 0; i < var->length (); i++)
    if (!(is_a<bit *> ((*var)[i])))
      return false;
  return true;
}


/* Returns the number represented by the value.  */

unsigned HOST_WIDE_INT
state::make_number (const value *var)
{
  unsigned HOST_WIDE_INT
  number = 0;
  int value_size = var->length ();
  for (int i = value_size - 1; i >= 0; i--)
    {
      if (is_a<bit *> ((*var)[i]))
	number = (number << 1) | as_a<bit *> ((*var)[i])->get_val ();
      else
	return 0;
    }
  return number;
}


/* Shift_left operation.  Case: var2 is a symbolic value.  */

value_bit *
state::shift_left_sym_bits (value_bit *var1, value_bit *var2)
{
  return new shift_left_expression (var1->copy (), var2->copy ());
}


/* Performs shift left operation on given values.
   The result is stored in dest.  */

void
state::do_shift_left (value *arg1, value *arg2, tree dest)
{
  if (is_bit_vector (arg2))
    {
      size_t shift_value = make_number (arg2);
      value *result = shift_left_by_const (arg1, shift_value);
      for (size_t i = 0; i < get_var_size (dest); i++)
	{
	  delete (*var_states.get (dest))[i];
	  (*var_states.get (dest))[i] = (*result)[i]->copy ();
	}
      delete result;
    }
  else
    operate (arg1, arg2, nullptr, dest, &state::shift_left_sym_bits);
}


/* Performs shift right operation on given values.
   The result is stored in dest.  */

void
state::do_shift_right (value *arg1, value *arg2, tree dest)
{
  if (is_bit_vector (arg2))
    {
      size_t shift_value = make_number (arg2);
      value *result = shift_right_by_const (arg1, shift_value);
      for (size_t i = 0; i < get_var_size (dest); i++)
	{
	  delete (*var_states.get (dest))[i];
	  (*var_states.get (dest))[i] = (*result)[i]->copy ();
	}

      delete result;
    }
  else
    operate (arg1, arg2, nullptr, dest, &state::shift_right_sym_bits);
}


/* Adds two bits and carry value.
   Returns result and stores new carry bit in "carry".  */

value_bit *
state::full_adder (value_bit *var1, value_bit *var2, value_bit **carry)
{
  value_bit *new_carry = and_two_bits (var1, var2);
  value_bit *sum = xor_two_bits (var1, var2);

  value_bit *result = xor_two_bits (sum, *carry);
  value_bit *sum_and_carry = and_two_bits (sum, *carry);

  delete *carry;
  delete sum;

  *carry = or_two_bits (sum_and_carry, new_carry);

  delete sum_and_carry;
  delete new_carry;

  return result;
}


/* Adds given values.  The result is stored in dest.  */

void
state::do_add (value *arg1, value *arg2, tree dest)
{
  value_bit *carry = new bit (0);
  operate (arg1, arg2, &carry, dest, &state::full_adder);
  delete carry;
}


/* Returns the additive inverse of the given number.  */

value *
state::additive_inverse (const value *number)
{
  value *result = new value (number->length (), number->is_unsigned);
  value one (number->length (), number->is_unsigned);

  size_t size = number->length ();
  one.push (new bit (1));
  result->push (complement_a_bit ((*number)[0]));

  for (size_t i = 1; i < size; i++)
    {
      one.push (new bit (0));
      result->push (complement_a_bit ((*number)[i]));
    }

  value_bit *carry = new bit (0);
  for (size_t i = 0; i < size; ++i)
    {
      value_bit *cur_bit = (*result)[i];
      (*result)[i] = full_adder (cur_bit, one[i], &carry);
      delete cur_bit;
    }

  delete carry;
  return result;
}


/* Subtracks second value from the first.  The result is stored in dest.  */

void
state::do_sub (value *arg1, value *arg2, tree dest)
{
  value *neg_arg2 = additive_inverse (arg2);
  do_add (arg1, neg_arg2, dest);
  delete neg_arg2;
}


/* Performs complement operation on a bit.  */

value_bit *
state::complement_a_bit (value_bit *var)
{
  value_bit *result = nullptr;
  if (is_a<bit *> (var))
    result = complement_const_bit (as_a<bit *> (var));
  else
    result = complement_sym_bit (var);

  return result;
}


/* Negates given variable.  */

bool
state::do_complement (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 ());

  /* Creating complement expressions for every bit the given argument
     and store it as a new state for given destination.  */
  size_t iter_count = min (get_var_size (dest), get_var_size (arg),
			   get_var_size (arg));

  size_t i = 0;
  for (; i < iter_count; i++)
    {
      value_bit *result = complement_a_bit ((*var_states.get (arg))[i]);
      delete (*var_states.get (dest))[i];
      (*var_states.get (dest))[i] = result;
    }

  if (i >= get_var_size (dest))
    {
      print_value (var_states.get (dest));
      return true;
    }

  for (; i < get_var_size (dest); i++)
    {
      delete (*var_states.get (dest))[i];
      bit tmp (0);
      (*var_states.get (dest))[i] = complement_a_bit (&tmp);
    }

  print_value (var_states.get (dest));
  return true;
}


/* Does Assignment.  */

bool
state::do_assign (tree arg, tree dest)
{
  declare_if_needed (dest, tree_to_uhwi (TYPE_SIZE (TREE_TYPE (dest))));
  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);

  /* If the argument is already defined, then we must just copy its bits.  */
  if (auto arg_val = var_states.get (arg))
    {
      for (size_t i = 0; i < dest_val->length (); i++)
	{
	  value_bit *new_val = nullptr;
	  if (i < arg_val->length ())
	    new_val = (*arg_val)[i]->copy ();
	  else
	    new_val = new bit (0);

	  delete (*dest_val)[i];
	  (*dest_val)[i] = new_val;
	}
    }
    /* If the argument is a constant, we must save it as sequence of bits.  */
  else if (TREE_CODE (arg) == INTEGER_CST)
    {
      value arg_val
	= create_val_for_const (arg, dest_val->length ());
      for (size_t i = 0; i < dest_val->length (); i++)
	{
	  delete (*dest_val)[i];
	  (*dest_val)[i] = arg_val[i]->copy ();
	}
    }
  else
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "Sym-Exec: Unsupported assignment"
			    " for given argument.\n");

      return false;
    }

  print_value (var_states.get (dest));
  return true;
}


/* Assigns pow 2 value.  */

bool
state::do_assign_pow2 (tree dest, unsigned pow)
{
  value *dest_val = var_states.get (dest);
  unsigned dest_size = dest_val ? dest_val->allocated ()
				: tree_to_uhwi (TYPE_SIZE (TREE_TYPE (dest)));
  if (pow > dest_size)
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "Sym-Exec: pow %u of 2 won't fit in"
			    " specified destination\n", pow);
      return false;
    }

  if (!dest_val)
    {
      decl_var (dest, tree_to_uhwi (TYPE_SIZE (TREE_TYPE (dest))));
      dest_val = var_states.get (dest);
    }
  else
    dest_val->free_bits ();

  for (unsigned i = 0; i < dest_val->length (); i++)
    {
      if (i == pow)
	(*dest_val)[i] = new bit (1);
      else
	(*dest_val)[i] = new bit (0);
    }

  print_value (dest_val);
  return true;
}


/* Performs NOT operation for constant bit.  */

bit *
state::complement_const_bit (const bit *const_bit)
{
  return new bit (1u ^ const_bit->get_val ());
}


/* Performs NOT operation for symbolic_bit.  */

value_bit *
state::complement_sym_bit (const value_bit *var)
{
  return new bit_complement_expression (var->copy ());
}


/* Performs XOR operation for 2 symbolic_bit operands.  */

value_bit *
state::xor_sym_bits (const value_bit *var1, const value_bit *var2)
{
  value_bit *var2_copy = var2->copy ();
  bit_expression *node2_with_const_child = nullptr;
  bit_expression *parent_of_node2_with_child = nullptr;
  get_parent_with_const_child (var2_copy, node2_with_const_child,
			       parent_of_node2_with_child);

  if (node2_with_const_child != nullptr)
    {
      value_bit *var1_copy = var1->copy ();
      bit_expression *node1_with_const_child = nullptr;
      bit_expression *parent_of_node1_with_child = nullptr;
      get_parent_with_const_child (var1_copy, node1_with_const_child,
				   parent_of_node1_with_child);

      /* If both subtrees have constant bit nodes,
	 we can merge them together.  */
      if (node1_with_const_child != nullptr)
	{
	  value_bit *var1_reformed = nullptr;
	  value_bit *var2_reformed = nullptr;

	  /* If var1's const bit is in its left subtree.  */
	  value_bit *var1_left = node1_with_const_child->get_left ();
	  if (var1_left != nullptr && is_a<bit *> (var1_left))
	    {
	      var1_reformed = node1_with_const_child->get_right ()->copy ();
	      value_bit *var2_left = node2_with_const_child->get_left ();

	      /* If var2's const bit is in its left subtree.  */
	      if (var2_left != nullptr && is_a<bit *> (var2_left))
		var2_reformed = node2_with_const_child->get_right ()->copy ();
	      else /* Var2's const bit is in its right subtree.  */
		var2_reformed = node2_with_const_child->get_left ()->copy ();
	    }
	  else /* Var1's const bit is in its right subtree.  */
	    {
	      var1_reformed = node1_with_const_child->get_left ()->copy ();
	      value_bit *var2_left = node2_with_const_child->get_left ();

	      /* If var2's const bit is in its left subtree.  */
	      if (var2_left != nullptr && is_a<bit *> (var2_left))
		var2_reformed = node2_with_const_child->get_right ()->copy ();
	      else /* Var2's const bit is in its right subtree.  */
		var2_reformed = node2_with_const_child->get_left ()->copy ();
	    }

	  if (parent_of_node1_with_child)
	    {
	      parent_of_node1_with_child->get_left ()
	      == node1_with_const_child
	      ? parent_of_node1_with_child->set_left (var1_reformed)
	      : parent_of_node1_with_child->set_right (var1_reformed);
	      delete node1_with_const_child;
	    }
	  else
	    {
	      delete var1_copy;
	      var1_copy = var1_reformed;
	    }

	  if (parent_of_node2_with_child)
	    {
	      parent_of_node2_with_child->get_left ()
	      == node2_with_const_child
	      ? parent_of_node2_with_child->set_left (var2_reformed)
	      : parent_of_node2_with_child->set_right (var2_reformed);
	      delete node2_with_const_child;
	    }
	  else
	    {
	      delete var2_copy;
	      var2_copy = var2_reformed;
	    }

	  return new bit_xor_expression (var1_copy, var2_copy);
	}
      delete var1_copy;
    }

  delete var2_copy;
  return new bit_xor_expression (var1->copy (), var2->copy ());
}


/* Performs XOR operation for 2 constant bit operands.  */

bit *
state::xor_const_bits (const bit *const_bit1, const bit *const_bit2)
{
  return new bit (const_bit1->get_val () ^ const_bit2->get_val ());
}


/* Performs XOR operation for a symbolic_bit and const_bit operands.  */

value_bit *
state::xor_var_const (const value_bit *var, const bit *const_bit)
{
  if (const_bit->get_val () == 0)
    return var->copy ();

  value_bit *var_copy = var->copy ();
  bit_expression *node_with_const_child = nullptr;
  bit_expression *tmp = nullptr;
  get_parent_with_const_child (var_copy, node_with_const_child, tmp);

  if (node_with_const_child != nullptr)
    {
      value_bit *left = node_with_const_child->get_left ();
      if (left != nullptr && is_a<bit *> (left))
	{
	  bit *new_left = xor_const_bits (as_a<bit *> (left), const_bit);
	  delete left;
	  node_with_const_child->set_left (new_left);
	}
      else
	{
	  value_bit *right = node_with_const_child->get_right ();
	  bit *new_right = xor_const_bits (as_a<bit *> (right), const_bit);
	  delete right;
	  node_with_const_child->set_right (new_right);
	}
      return var_copy;
    }

  delete var_copy;
  return new bit_xor_expression (var->copy (), const_bit->copy ());
}


/* Return node which has a const bit child.  Traversal is done based
   on safe branching.  */

void
state::get_parent_with_const_child (value_bit *root, bit_expression *&parent,
				    bit_expression *&parent_of_parent)
{
  parent_of_parent = nullptr;
  parent = nullptr;

  if (!is_a<bit_expression *> (root))
    return;

  bit_expression *expr_root = as_a<bit_expression *> (root);
  hash_set < bit_expression * > nodes_to_consider;
  nodes_to_consider.add (expr_root);

  hash_map < bit_expression * , bit_expression * > node_to_parent;
  node_to_parent.put (expr_root, nullptr);

  /* Traversing expression tree:
     considering only commutative expression nodes.  */
  while (!nodes_to_consider.is_empty ())
    {
      bit_expression *cur_element = *nodes_to_consider.begin ();
      nodes_to_consider.remove (cur_element);

      value_bit *left = cur_element->get_left ();
      value_bit *right = cur_element->get_right ();

      if ((left != nullptr && is_a<bit *> (left))
	  || (right != nullptr && is_a<bit *> (right)))
	{
	  parent = cur_element;
	  parent_of_parent = *node_to_parent.get (cur_element);
	}

      if (left != nullptr && is_a<bit_xor_expression *> (left))
	{
	  nodes_to_consider.add (as_a<bit_expression *> (left));
	  node_to_parent.put (as_a<bit_expression *> (left), cur_element);
	}

      if (right != nullptr && is_a<bit_xor_expression *> (right))
	{
	  nodes_to_consider.add (as_a<bit_expression *> (right));
	  node_to_parent.put (as_a<bit_expression *> (right), cur_element);
	}
    }
}


/* Shifts number left by size of shift_value.  */

value *
state::shift_left_by_const (const value *number, size_t shift_value)
{
  value *shift_result = new value (number->length (), number->is_unsigned);
  if (number->length () <= shift_value)
    for (size_t i = 0; i < number->length (); i++)
      shift_result->push (new bit (0));

  else
    {
      size_t i = 0;
      for (; i < shift_value; ++i)
	shift_result->push (new bit (0));
      for (size_t j = 0; i < number->length (); ++i, j++)
	shift_result->push (((*number)[j])->copy ());
    }
  return shift_result;
}


/* Shift_right operation.  Case: var2 is a symbolic value.  */

value_bit *
state::shift_right_sym_bits (value_bit *var1, value_bit *var2)
{
  return new shift_right_expression (var1->copy (), var2->copy ());
}


/* Adds two values, stores the result in the first one.  */

void
state::add_numbers (value *var1, const value *var2)
{
  value_bit *carry = new bit (0);
  for (unsigned i = 0; i < var1->length (); i++)
    {
      value_bit *temp = (*var1)[i];
      (*var1)[i] = full_adder ((*var1)[i], (*var2)[i], &carry);
      delete temp;
    }
  delete carry;
}


/* ANDs every bit of the vector with var_bit, stores the result in var1.  */

void
state::and_number_bit (value *var1, value_bit *var_bit)
{
  for (unsigned i = 0; i < var1->length (); i++)
    {
      value_bit *tmp = (*var1)[i];
      (*var1)[i] = and_two_bits ((*var1)[i], var_bit);
      delete tmp;
    }

}


/* Multiplies given values.  The result is stored in dest.  */

void
state::do_mul (value *arg1, value *arg2, tree dest)
{
  value *shifted = new value (*arg1);
  value *dest_val = var_states.get (dest);

  for (unsigned i = 0; i < dest_val->length (); i++)
    {
      delete (*dest_val)[i];
      (*dest_val)[i] = new bit (0);
    }

  for (unsigned i = arg2->length (); i != 0; --i)
    {
      if (is_a<bit *> ((*arg2)[i - 1])
	  && as_a<bit *> ((*arg2)[i - 1])->get_val () != 0)
	add_numbers (dest_val, shifted);
      else if (is_a<symbolic_bit *> ((*arg2)[i - 1]))
	{
	  and_number_bit (shifted, as_a<symbolic_bit *> ((*arg2)[i - 1]));
	  add_numbers (dest_val, shifted);
	}

      value *temp = shifted;
      shifted = shift_left_by_const (shifted, 1);
      delete temp;
    }
  delete shifted;
}


/* Checks whether the given two constant values are equal.  */

bool
state::check_const_value_equality (value *arg1, value *arg2)
{
  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;
  return true;
}


/* Adds EQUAL condition of given variables to state.  */

bool
state::add_equal_cond (tree arg1, tree arg2)
{
  return add_binary_cond (arg1, arg2, &state::add_equal_cond);
}


/* Adds equality condition for two values.  */

void
state::add_equal_cond (value *arg1, value *arg2)
{

  /* If both arguments are constants then we can evaluate it.  */
  if (is_bit_vector (arg1) && is_bit_vector (arg2))
    {
      bool result = check_const_value_equality (arg1, arg2);
      last_cond_status = result ? condition_status::CS_TRUE
				: condition_status::CS_FALSE;
      return;
    }

  /* When some of 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])
	  && as_a<bit *> ((*arg1)[i])->get_val ()
	     != as_a<bit *> ((*arg2)[i])->get_val ())
	{
	  last_cond_status = condition_status::CS_FALSE;
	  return;
	}
    }

  for (size_t i = 0; i < arg1->length (); i++)
    {
      /* If there is a constant bit pair, then they are equal
	 as we checked not equality above.  */
      if (is_a<bit *> ((*arg1)[i]) && is_a<bit *> ((*arg2)[i]))
	continue;

      conditions.add (new bit_condition ((*arg1)[i]->copy (),
					 (*arg2)[i]->copy (),
					 EQ_EXPR));
    }
  last_cond_status = condition_status::CS_SYM;
}


/* Checks whether the given two constant values are not equal.  */

bool
state::check_const_value_are_not_equal (value *arg1, value *arg2)
{
  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 true;
  return false;
}


/* Adds NOT EQUAL condition of given variables to state.  */

bool
state::add_not_equal_cond (tree arg1, tree arg2)
{
  return add_binary_cond (arg1, arg2, &state::add_not_equal_cond);
}


/* Adds not equal condition for two values.  */

void
state::add_not_equal_cond (value *arg1, value *arg2)
{
  if (is_bit_vector (arg1) && is_bit_vector (arg2))
    {
      bool result = check_const_value_are_not_equal (arg1, arg2);
      last_cond_status = result ? condition_status::CS_TRUE
				: condition_status::CS_FALSE;
      return;
    }

  /* When some of bits are constants and they differ by value,
     then we can evaluate it to be true.  */
  for (size_t i = 0; i < arg1->length (); i++)
    {
      if (is_a<bit *> ((*arg1)[i]) && is_a<bit *> ((*arg2)[i])
	  && as_a<bit *> ((*arg1)[i])->get_val ()
	     != as_a<bit *> ((*arg2)[i])->get_val ())
	{
	  last_cond_status = condition_status::CS_TRUE;
	  return;
	}
    }

  bit_expression *prev = nullptr;
  for (size_t i = 0; i < arg1->length (); i++)
    {
      /* If there is a constant bit pair, then they are equal
	 as we checked not equality above.  */
      if (is_a<bit *> ((*arg1)[i]) && is_a<bit *> ((*arg2)[i]))
	continue;

      bit_condition *new_cond = new bit_condition ((*arg1)[i]->copy (),
						   (*arg2)[i]->copy (),
						   NE_EXPR);
      if (prev)
	prev = new bit_or_expression (prev, new_cond);
      else
	prev = new_cond;
    }

  last_cond_status = condition_status::CS_SYM;
  conditions.add (prev);
}


/* 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)
{
  for (int i = arg1->length () - 1; i >= 0; i--)
    {
      if (as_a<bit *> ((*arg1)[i])->get_val ()
	  > as_a<bit *> ((*arg2)[i])->get_val ())
	return true;
      else if (as_a<bit *> ((*arg1)[i])->get_val ()
	       < as_a<bit *> ((*arg2)[i])->get_val ())
	return false;
    }
  return false;
}


/* Adds GREATER THAN condition of given variables to state.  */

bool
state::add_greater_than_cond (tree arg1, tree arg2)
{
  return add_binary_cond (arg1, arg2, &state::add_greater_than_cond);
}


/* Adds greater than condition for two values.  */

void
state::add_greater_than_cond (value *arg1, value *arg2)
{
  if (is_bit_vector (arg1) && is_bit_vector (arg2))
    {
      bool result = check_const_value_is_greater_than (arg1, arg2);
      last_cond_status = result ? condition_status::CS_TRUE
				: condition_status::CS_FALSE;
      return;
    }

  if (is_bit_vector (arg2) && is_a<bit *> (arg1->last ())
      && make_number (arg2) == 0 && !arg1->is_unsigned)
    {
      if (as_a<bit *> (arg1->last ())->get_val () == 1)
	last_cond_status = condition_status::CS_FALSE;
      else
	{
	  for (size_t i = 0; i < arg1->length (); i++)
	    if (is_a<bit *> ((*arg1)[i])
		&& as_a<bit *> ((*arg1)[i])->get_val ())
	      {
		last_cond_status = condition_status::CS_TRUE;
		return;
	      }
	}
    }

  bit_expression *gt_cond = construct_great_than_cond (arg1, arg2);
  if (gt_cond)
    {
      /* Otherwise its status is already set.  */
      last_cond_status = condition_status::CS_SYM;
      conditions.add (gt_cond);
    }
}


/* Constructs expression trees of greater than condition for given values.  */

bit_expression *
state::construct_great_than_cond (value *arg1, value *arg2)
{
  bit_expression *prev = nullptr;
  int i = arg1->length () - 1;
  for (; i >= 0; i--)
    {
      if (is_a<bit *> ((*arg1)[i]) && is_a<bit *> ((*arg2)[i]))
	{
	  if (as_a<bit *> ((*arg1)[i])->get_val ()
	      > as_a<bit *> ((*arg2)[i])->get_val ())
	    {
	      if (!prev)
		last_cond_status = condition_status::CS_TRUE;
	      return prev;
	    }
	  else if (as_a<bit *> ((*arg1)[i])->get_val ()
		   < as_a<bit *> ((*arg2)[i])->get_val ())
	    {
	      if (prev)
		{
		  bit_expression *ret_val
		    = as_a<bit_expression *> (prev->get_left ()->copy ());
		  delete prev;
		  return ret_val;
		}
	      else
		{
		  last_cond_status = condition_status::CS_FALSE;
		  return nullptr;
		}
	    }
	}
      else
	{
	  bit_condition *gt_cond
	    = new bit_condition ((*arg1)[i]->copy (), (*arg2)[i]->copy (),
				 GT_EXPR);
	  bit_expression *expr = nullptr;
	  if (i)
	    {
	      bit_condition *eq_cond
		= new bit_condition ((*arg1)[i]->copy (), (*arg2)[i]->copy (),
				     EQ_EXPR);
	      expr = new bit_or_expression (gt_cond, eq_cond);
	    }
	  else
	    expr = gt_cond;

	  if (prev)
	    prev = new bit_and_expression (expr, prev);
	  else
	    prev = expr;
	}
    }

  return prev;
}


/* 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)
{
  for (int i = arg1->length () - 1; i >= 0; i--)
    {
      if (as_a<bit *> ((*arg1)[i])->get_val ()
	  < as_a<bit *> ((*arg2)[i])->get_val ())
	return true;
      else if (as_a<bit *> ((*arg1)[i])->get_val ()
	       > as_a<bit *> ((*arg2)[i])->get_val ())
	return false;
    }
  return false;
}


/* Adds LESS THAN condition of given variables to state.  */

bool
state::add_less_than_cond (tree arg1, tree arg2)
{
  return add_binary_cond (arg1, arg2, &state::add_less_than_cond);
}


/* Adds less than condition for two values.  */

void
state::add_less_than_cond (value *arg1, value *arg2)
{
  if (is_bit_vector (arg1) && is_bit_vector (arg2)
      && (make_number (arg2) != 0 || arg1->is_unsigned))
    {
      bool result = check_const_value_is_less_than (arg1, arg2);
      last_cond_status = result ? condition_status::CS_TRUE
				: condition_status::CS_FALSE;
      return;
    }

  last_cond_status = condition_status::CS_SYM;
  if (is_bit_vector (arg2) && make_number (arg2) == 0 && !arg1->is_unsigned)
    {
      if (is_a<bit *> (arg1->last ()))
	{
	  if (as_a<bit *> (arg1->last ())->get_val () == 1)
	    last_cond_status = condition_status::CS_TRUE;
	  else
	    last_cond_status = condition_status::CS_FALSE;
	}
      else
	conditions.add (new bit_condition (arg1->last ()->copy (), new bit (1),
					   EQ_EXPR));

      return;
    }

  bit_expression *lt_cond = construct_less_than_cond (arg1, arg2);
  if (lt_cond)
    /* Otherwise its status is already set.  */
    conditions.add (lt_cond);
}


/* Constructs expression trees of less than condition for given values.  */

bit_expression *
state::construct_less_than_cond (value *arg1, value *arg2)
{
  bit_expression *prev = nullptr;
  int i = arg1->length () - 1;
  for (; i >= 0; i--)
    {
      if (is_a<bit *> ((*arg1)[i]) && is_a<bit *> ((*arg2)[i]))
	{
	  if (as_a<bit *> ((*arg1)[i])->get_val ()
	      < as_a<bit *> ((*arg2)[i])->get_val ())
	    {
	      if (!prev)
		last_cond_status = condition_status::CS_TRUE;
	      return prev;
	    }
	  else if (as_a<bit *> ((*arg1)[i])->get_val ()
		   > as_a<bit *> ((*arg2)[i])->get_val ())
	    {
	      if (prev)
		{
		  bit_expression *ret_val
		    = as_a<bit_expression *> (prev->get_left ()->copy ());
		  delete prev;
		  return ret_val;
		}
	      else
		{
		  last_cond_status = condition_status::CS_FALSE;
		  return nullptr;
		}
	    }
	}
      else
	{
	  bit_condition *lt_cond
	    = new bit_condition ((*arg1)[i]->copy (), (*arg2)[i]->copy (),
				 LT_EXPR);
	  bit_expression *expr = nullptr;
	  if (i)
	    {
	      bit_condition *eq_cond
		= new bit_condition ((*arg1)[i]->copy (), (*arg2)[i]->copy (),
				     EQ_EXPR);
	      expr = new bit_or_expression (lt_cond, eq_cond);
	    }
	  else
	    expr = lt_cond;

	  if (prev)
	    prev = new bit_and_expression (expr, prev);
	  else
	    prev = expr;
	}
    }

  return prev;
}


/* Adds GREATER OR EQUAL condition of given variables to state.  */

bool
state::add_greater_or_equal_cond (tree arg1, tree arg2)
{
  return add_binary_cond (arg1, arg2, &state::add_greater_or_equal_cond);
}


/* Adds greater or equal condition for two values.  */

void
state::add_greater_or_equal_cond (value *arg1, value *arg2)
{
  if (is_bit_vector (arg1) && is_bit_vector (arg2)
      && (make_number (arg2) != 0 || arg1->is_unsigned))
    {
      bool is_greater_than = check_const_value_is_greater_than (arg1,
								arg2);
      bool is_equal = check_const_value_equality (arg1, arg2);
      last_cond_status = (is_greater_than | is_equal)
			 ? condition_status::CS_TRUE
			 : condition_status::CS_FALSE;
      return;
    }

  last_cond_status = condition_status::CS_SYM;
  if (is_bit_vector (arg2) && make_number (arg2) == 0 && !arg1->is_unsigned)
    {
      if (is_a<bit *> (arg1->last ()))
	{
	  if (as_a<bit *> (arg1->last ())->get_val () == 1)
	    last_cond_status = condition_status::CS_FALSE;
	  else
	    last_cond_status = condition_status::CS_TRUE;
	}
      else
	conditions.add (new bit_condition (arg1->last ()->copy (), new bit (0),
					   EQ_EXPR));

      return;
    }

  bit_expression *eq_cond = construct_equal_cond (arg1, arg2);
  if (!eq_cond)
    return;

  bit_expression *gt_cond = construct_great_than_cond (arg1, arg2);
  if (gt_cond)
    /* Otherwise its status is already set.  */
    conditions.add (new bit_or_expression (eq_cond, gt_cond));
}


/* Adds LESS OR EQUAL condition of given variables to state.  */

bool
state::add_less_or_equal_cond (tree arg1, tree arg2)
{
  return add_binary_cond (arg1, arg2, &state::add_less_or_equal_cond);
}


/* Adds less or equal condition for two values.  */

void
state::add_less_or_equal_cond (value *arg1, value *arg2)
{
  if (is_bit_vector (arg1) && is_bit_vector (arg2))
    {
      bool is_less_than = check_const_value_is_less_than (arg1, arg2);
      bool is_equal = check_const_value_equality (arg1, arg2);
      last_cond_status = (is_less_than | is_equal)
			 ? condition_status::CS_TRUE
			 : condition_status::CS_FALSE;
      return;
    }

  last_cond_status = condition_status::CS_SYM;
  bit_expression *eq_cond = construct_equal_cond (arg1, arg2);
  if (!eq_cond)
    return;

  bit_expression *lt_cond = construct_less_than_cond (arg1, arg2);
  if (lt_cond)
    /* Otherwise its status is already set.  */
    conditions.add (new bit_or_expression (eq_cond, lt_cond));
}


/* Adds a bool condition to state.  */

bool
state::add_bool_cond (tree arg)
{
  if (!is_declared (arg))
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "Sym-Exec: Argument must be declared "
			    "for bool condition.\n");

      return false;
    }

  value *arg_bits = var_states.get (arg);
  for (size_t i = 0; i < arg_bits->length (); i++)
    if (is_a<bit *> ((*arg_bits)[i])
	&& as_a<bit *> ((*arg_bits)[i])->get_val () != 0)
      {
	last_cond_status = condition_status::CS_TRUE;
	print_conditions ();
	return true;
      }

  if (is_bit_vector (arg_bits))
    {
      last_cond_status = condition_status::CS_FALSE;
      print_conditions ();
      return true;
    }

  bit_expression *prev = nullptr;
  for (size_t i = 0; i < arg_bits->length (); i++)
    {
      if (is_a<bit *> ((*arg_bits)[i]))
	continue;

      bit_condition *not_eq_cond
	= new bit_condition ((*arg_bits)[i], new bit (0), NE_EXPR);
      if (prev)
	prev = new bit_or_expression (not_eq_cond, prev);
      else
	prev = not_eq_cond;
    }

  last_cond_status = condition_status::CS_SYM;
  conditions.add (prev);
  print_conditions ();
  return true;
}


/* Does preprocessing and postprocessing for condition adding.
   Handles value creation for constants and their removement in the end.  */

bool
state::add_binary_cond (tree arg1, tree arg2, binary_cond_func cond_func)
{
  bool arg1_is_declared = is_declared (arg1);
  bool arg2_is_declared = is_declared (arg2);

  if (!arg1_is_declared && !arg2_is_declared)
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "Sym-Exec: At least one of arguments must be"
			    " declared for adding the condition.\n");

      return false;
    }

  if (arg1_is_declared)
    declare_if_needed (arg2, var_states.get (arg1)->length ());

  if (arg2_is_declared)
    declare_if_needed (arg1, var_states.get (arg2)->length ());

  value *arg1_val = var_states.get (arg1);
  value arg1_const_val (MAX_VALUE_SIZE, false);

  if (arg1_val == NULL && TREE_CODE (arg1) == INTEGER_CST)
    {
      arg1_const_val = create_val_for_const (arg1,
					     var_states.get (arg2)->length ());
      arg1_val = &arg1_const_val;
    }

  value *arg2_val = var_states.get (arg2);
  value arg2_const_val (MAX_VALUE_SIZE, false);
  if (arg2_val == NULL && TREE_CODE (arg2) == INTEGER_CST)
    {
      arg2_const_val = create_val_for_const (arg2,
					     var_states.get (arg1)->length ());
      arg2_val = &arg2_const_val;
    }

  (this->*cond_func) (arg1_val, arg2_val);
  print_conditions ();
  return true;
}


/* Constructs expression trees of equal condition for given values.  */

bit_expression *
state::construct_equal_cond (value *arg1, value *arg2)
{
  /* If both arguments are constants then we can evaluate it.  */
  if (is_bit_vector (arg1) && is_bit_vector (arg2))
    {
      bool result = check_const_value_equality (arg1, arg2);
      last_cond_status = result ? condition_status::CS_TRUE
				: condition_status::CS_FALSE;
      return nullptr;
    }

  /* 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])
	  && as_a<bit *> ((*arg1)[i])->get_val ()
	     != as_a<bit *> ((*arg2)[i])->get_val ())
	{
	  last_cond_status = condition_status::CS_FALSE;
	  return nullptr;
	}
    }

  bit_expression *prev = nullptr;
  for (size_t i = 0; i < arg1->length (); i++)
    {
      bit_condition *eq_expr = new bit_condition ((*arg1)[i]->copy (),
						  (*arg2)[i]->copy (), EQ_EXPR);
      if (prev)
	prev = new bit_and_expression (eq_expr, prev);
      else
	prev = eq_expr;
    }

  return prev;
}


/* Constructor for value.  The first argument is the size of the bit-vector
   and the second argument is the sign of the number.  */

value::value (unsigned size, bool is_unsigned) : is_unsigned (is_unsigned)
{
  number.create (size);
}


/* Copy constructor for value.  */

value::value (const value &other) : is_unsigned (other.is_unsigned)
{
  number.create (other.length ());
  for (size_t i = 0; i < other.length (); ++i)
    {
      value_bit *temp = other[i] ? other[i]->copy () : other[i];
      number.quick_push (temp);
    }
}


/* Returns pushed bits count.  */

unsigned
value::length () const
{
  return number.length ();
}


/* Wrapper of vec<..>::operator[] for the bit-vector.  */

value_bit *&
value::operator[] (unsigned i)
{
  return number[i];
}


/* Assignment operator.  If the specified value's size is smaller,
   then 0 constant bit will be assigned to the remaining upper bits.  */

value &
value::operator= (const value &other)
{
  unsigned smallest = number.allocated () < other.length ()
		      ? number.allocated () : other.length ();

  for (size_t i = 0; i < smallest; i++)
    if (i < number.length ())
      {
	delete number[i];
	number[i] = other[i]->copy ();
      }
    else
      number.quick_push (other[i]->copy ());

  for (size_t i = smallest; i < number.allocated (); i++)
    if (i < number.length ())
      {
	delete number[i];
	number[i] = other.is_unsigned ? new bit (0)
				      : other[other.length () - 1]->copy ();
      }
    else
      number.quick_push (other.is_unsigned
			 ? new bit (0) : other[other.length () - 1]->copy ());

  return (*this);
}


/* Wrapper of vec<..>::operator[] const for the bit-vector.  */

value_bit *
value::operator[] (unsigned i) const
{
  return number[i];
}


/* Wrapper of vec<..>.exists for the bit-vector.  */

bool
value::exists () const
{
  return number.exists ();
}


/* Returns the size in bits.  */

unsigned
value::allocated () const
{
  return number.allocated ();
}


/* Returns a reference the last bit.  */

value_bit *&
value::last ()
{
  return number.last ();
}


/* Make a copy of given bits.  */

vec<value_bit *> *
state::make_copy (vec<value_bit *> *bits)
{
  vec < value_bit * > *copied_bits = new vec<value_bit *> ();
  copied_bits->create (bits->length ());
  for (size_t i = 0; i < bits->length (); i++)
    copied_bits->quick_push ((*bits)[i]->copy ());

  return copied_bits;
}


/* Returns status of last added condition.  */

condition_status
state::get_last_cond_status ()
{
  return last_cond_status;
}


/* Prints the given value.  */

void
state::print_value (value *var)
{
  if (!dump_file || !(dump_flags & TDF_DETAILS))
    return;

  fprintf (dump_file, "{");
  for (int i = var->length () - 1; i >= 0; i--)
    {
      (*var)[i]->print ();

      if (i)
	fprintf (dump_file, ", ");
    }
  fprintf (dump_file, "}\n");
}


/* Create LFSR value for the reversed CRC.  */

void
state::create_reversed_lfsr (value &lfsr, const value &crc,
			     const value &polynomial)
{
  size_t size = polynomial.length ();

  /* Determine values of all bits, except MSB.  */
  for (size_t i = 0; i < size - 1; i++)
  {
    if (as_a<bit *> (polynomial[i])->get_val ())
      lfsr.push (state::xor_two_bits (crc[i + 1], crc[0]));
    else
      lfsr.push (crc[i + 1]->copy ());
  }

  /* Determine value of MSB.  */
  if (as_a<bit *> (polynomial[size - 1])->get_val ())
    lfsr.push (crc[0]->copy ());
  else
    lfsr.push (new bit (0));
}


/* Create LFSR value for the forward CRC.  */

void
state::create_forward_lfsr (value &lfsr, const value &crc,
			    const value &polynomial)
{
  size_t size = polynomial.length ();
  /* Determine value of LSB.  */
  if (as_a<bit *> (polynomial[0])->get_val ())
    lfsr.push (crc[size - 1]->copy ());
  else
    lfsr.push (new bit (0));

  /* Determine values of remaining bits.  */
  for (size_t i = 1; i < size; i++)
  {
    if (as_a<bit *> (polynomial[i])->get_val ())
      lfsr.push (state::xor_two_bits (crc[i - 1], crc[size - 1]));
    else
      lfsr.push (crc[i - 1]->copy ());
  }
}


/* 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 polynomial_length = polynomial->length ();
  unsigned HOST_WIDE_INT crc_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (crc)));
  if (crc_size < polynomial_length)
  {
    if (dump_file && (dump_flags & TDF_DETAILS))
      fprintf (dump_file, "LFSR state creation: "
			  "Polynomial doesn't fit into the crc.\n");

    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 (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 (polynomial_length, TYPE_UNSIGNED (TREE_TYPE (crc)));

  /* Calculate values for LFSR.  */
  if (is_bit_forward)
    create_forward_lfsr (*lfsr, crc_value, *polynomial);
  else
    create_reversed_lfsr (*lfsr, crc_value, *polynomial);

  return lfsr;
}


/* Prints added conditions.  */

void
state::print_conditions ()
{
  if (!dump_file || !(dump_flags & TDF_DETAILS))
    return;

  fprintf (dump_file, "Conditions {");
  auto iter = conditions.begin ();
  while (true)
    {
      if (iter != conditions.end ())
	{
	  (*iter)->print ();
	  ++iter;
	}

      if (iter != conditions.end ())
	fprintf (dump_file, ", ");
      else
	break;
    }
  fprintf (dump_file, "}\n");
}


/* Pushes the given bit to the end of the bit vector.  */

value_bit **
value::push (value_bit *elem)
{
  return number.quick_push (elem);
}


/* Destructor for value.  */

value::~value ()
{
  free_bits ();
  number.release ();
}


/* Removes given sequence of bits.  */

void
value::free_bits ()
{
  if (!number.exists ())
    return;

  for (size_t i = 0; i < number.length (); i++)
    {
      delete number[i];
      number[i] = nullptr;
    }
}


/* For the given value_bit, iterates over its expression tree, complements
   those bit which came from the given origin.  */

value_bit *
state::complement_bits_with_origin (value_bit *root, tree origin)
{
  /* Be careful.  This function doesn't make a full copy of the bit.  */
  if (!is_a<bit_expression *> (root))
    {
      if (is_a<symbolic_bit *> (root)
	  && as_a<symbolic_bit *> (root)->get_origin () == origin)
	root = new bit_complement_expression (root);

      return root;
    }

  bit_expression *expr_root = as_a<bit_expression *> (root);
  hash_set <value_bit *> nodes_to_consider;
  nodes_to_consider.add (expr_root);
  hash_map <value_bit *, value_bit *> node_to_parent;
  node_to_parent.put (expr_root, nullptr);

  /* Traversing expression tree.  */
  while (!nodes_to_consider.is_empty ())
    {
      value_bit *cur_element = *nodes_to_consider.begin ();
      nodes_to_consider.remove (cur_element);

      if (is_a<symbolic_bit *> (cur_element))
	{
	  if (as_a<symbolic_bit *> (cur_element)->get_origin () != origin)
	    continue;

	  bit_expression *parent
	  = as_a<bit_expression *> (*node_to_parent.get (cur_element));
	  if (is_a<bit_complement_expression *> (parent))
	    {
	      value_bit *parent_of_parent = *node_to_parent.get (parent);
	      if (parent_of_parent)
		{
		  bit_expression *parent_of_parent_expr
		  = as_a<bit_expression *> (parent_of_parent);
		  parent->set_right (nullptr);
		  delete parent;
		  parent_of_parent_expr->get_left () == parent
		    ? parent_of_parent_expr->set_left (cur_element)
		    : parent_of_parent_expr->set_right (cur_element);
		}
	      else
		{
		  /* Parent is our root.  */
		  as_a<bit_expression *> (root)->set_right (nullptr);
		  delete root;
		  root = cur_element;
		}
	    }
	  else
	    {
	      value_bit* new_bit = new bit_complement_expression (cur_element);
	      parent->get_left () == cur_element ? parent->set_left (new_bit)
						 : parent->set_right (new_bit);
	    }
	  continue;
	}

      bit_expression* cur_elem_expr = as_a<bit_expression *> (cur_element);
      value_bit *left = cur_elem_expr->get_left ();
      value_bit *right = cur_elem_expr->get_right ();
      if (left != nullptr && !is_a<bit *> (left))
	{
	  nodes_to_consider.add (left);
	  node_to_parent.put (left, cur_element);
	}

      if (right != nullptr && !is_a<bit *> (right))
	{
	  nodes_to_consider.add (right);
	  node_to_parent.put (right, cur_element);
	}
    }

  return root;
}


/* Iterates over every bit of the given value and complements their
   expression trees' those bits, that came from the given origin.  */

void
state::complement_val_bits_with_origin (value *val, tree origin)
{
  for (size_t i = 0; i < val->length (); i++)
    {
      (*val)[i] = complement_bits_with_origin ((*val)[i], origin);
    }
}


/* Complements all bits of all values that came from the given origin.  */

void
state::complement_all_vars_bits_with_origin (tree origin)
{
  for (auto iter = var_states.begin (); iter != var_states.end (); ++iter)
    {
      complement_val_bits_with_origin (&(*iter).second, origin);
    }
}


/* Complements all bits with the given origin of all added conditions.  */

void
state::complement_conditions_with_origin (tree origin)
{
  hash_set<bit_expression *> updated_conditions;
  for (auto iter = conditions.begin (); iter != conditions.end (); ++iter)
    updated_conditions.add (as_a<bit_expression *> (
      complement_bits_with_origin (*iter, origin)));

  conditions.empty ();
  for (auto iter = updated_conditions.begin ();
       iter != updated_conditions.end (); ++iter)
    conditions.add (*iter);
}


/* Complements all bits with the given origin of all values
   and added conditions.  */

void
state::complement_state_with_origin (tree origin)
{
  complement_all_vars_bits_with_origin (origin);
  complement_conditions_with_origin (origin);
}


/* Performs the specified operation on passed variables.  */

bool
state::do_operation (tree_code op_code, tree arg1, tree arg2, tree dest)
{
  switch (op_code)
    {
      case BIT_NOT_EXPR:
	return do_complement (arg1, dest);
      case NOP_EXPR:
      case SSA_NAME:
      case VAR_DECL:
      case INTEGER_CST:
	return do_assign (arg1, dest);
      case LSHIFT_EXPR:
	return do_binary_operation (arg1, arg2, dest, &state::do_shift_left);
      case RSHIFT_EXPR:
	return do_binary_operation (arg1, arg2, dest, &state::do_shift_right);
      case BIT_AND_EXPR:
	return do_binary_operation (arg1, arg2, dest, &state::do_and);
      case BIT_IOR_EXPR:
	return do_binary_operation (arg1, arg2, dest, &state::do_or);
      case BIT_XOR_EXPR:
	return do_binary_operation (arg1, arg2, dest, &state::do_xor);
      case PLUS_EXPR:
	return do_binary_operation (arg1, arg2, dest, &state::do_add);
      case MINUS_EXPR:
	return do_binary_operation (arg1, arg2, dest, &state::do_sub);
      case MULT_EXPR:
	return do_binary_operation (arg1, arg2, dest, &state::do_mul);
      default:
	{
	  if (dump_file)
	    fprintf (dump_file,
		     "Warning, encountered unsupported operation "
		     "with %s code while executing assign statement!\n",
		     get_tree_code_name (op_code));
	  return false;
	}
    }
}
