[gcc/devel/jlaw/crc] sym-exec v4: - Fixed condition adding - Returning expression doing and condition adding status - Han

Jeff Law law@gcc.gnu.org
Tue Mar 21 15:08:07 GMT 2023


https://gcc.gnu.org/g:7770713ea086e24c31689d70199ddca8d44f65aa

commit 7770713ea086e24c31689d70199ddca8d44f65aa
Author: matevos <matevosmehrabyan@gmail.com>
Date:   Fri Nov 25 17:29:36 2022 +0400

    sym-exec v4: - Fixed condition adding - Returning expression doing and condition adding status - Handled global variables - Added Multiplication expression support - Updated addition and subtraction expression based of full adder - Added pointers basic addition, subtraction and dereferencing support - Some code refactored

Diff:
---
 gcc/sym-exec/expression-is-a-helper.h |  15 +-
 gcc/sym-exec/state.cc                 | 837 ++++++++++++++++++++++++++--------
 gcc/sym-exec/state.h                  | 125 +++--
 3 files changed, 763 insertions(+), 214 deletions(-)

diff --git a/gcc/sym-exec/expression-is-a-helper.h b/gcc/sym-exec/expression-is-a-helper.h
index 9cf50e90698..90a5917c843 100644
--- a/gcc/sym-exec/expression-is-a-helper.h
+++ b/gcc/sym-exec/expression-is-a-helper.h
@@ -1,7 +1,7 @@
 #ifndef SYM_EXEC_EXPRESSION_IS_A_HELPER_H
 #define SYM_EXEC_EXPRESSION_IS_A_HELPER_H
 
-#include "expression.h"
+#include "condition.h"
 #include "is-a.h"
 
 
@@ -38,7 +38,8 @@ is_a_helper <bit_expression *>::test (value * ptr)
 	 || type == value_type::SHIFT_RIGHT_EXPRESSION
 	 || type == value_type::SHIFT_LEFT_EXPRESSION
 	 || type == value_type::ADD_EXPRESSION
-	 || type == value_type::SUB_EXPRESSION;
+	 || type == value_type::SUB_EXPRESSION
+	 || type == value_type::BIT_CONDITION;
 }
 
 
@@ -113,4 +114,14 @@ is_a_helper <sub_expression *>::test (value * ptr)
   return ptr->get_type () == value_type::SUB_EXPRESSION;
 }
 
+
+template <>
+template <>
+inline bool
+is_a_helper <bit_condition *>::test (value * ptr)
+{
+  return ptr->get_type () == value_type::BIT_CONDITION;
+}
+
+
 #endif /* SYM_EXEC_EXPRESSION_IS_A_HELPER_H.  */
\ No newline at end of file
diff --git a/gcc/sym-exec/state.cc b/gcc/sym-exec/state.cc
index 7a308ea2c71..800dd8f13c5 100644
--- a/gcc/sym-exec/state.cc
+++ b/gcc/sym-exec/state.cc
@@ -48,6 +48,14 @@ state::is_declared (tree var)
 }
 
 
+void
+state::declare_if_needed (tree var, size_t size)
+{
+  if (TREE_CODE (var) != INTEGER_CST && !is_declared (var))
+    make_symbolic (var, size);
+}
+
+
 vec<value*> *
 state::get_bits (tree var)
 {
@@ -62,16 +70,30 @@ state::get_conditions ()
 }
 
 
-void
+bool
 state::check_args_compatibility (tree arg1, tree arg2, tree dest)
 {
-  gcc_assert ((is_declared (arg1) || TREE_CODE (arg1) == INTEGER_CST)
-	      && (is_declared (arg2) || TREE_CODE (arg2) == INTEGER_CST)
-	      && is_declared (dest));
-  gcc_assert ((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 (!is_declared (dest))
+    {
+      if (dump_file && (dump_flags & TDF_DETAILS))
+	fprintf (dump_file, "Sym-Exec: Destination var is not declared.\n");
+
+      return false;
+    }
+
+  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;
 }
 
 
@@ -277,11 +299,41 @@ state::make_symbolic (tree var, unsigned size)
 }
 
 
-void
+/* Performs AND operation on two bits.  */
+
+value *
+state::and_two_bits (value *arg1_bit, value* arg2_bit) const
+{
+  value *result = nullptr;
+
+  if (is_a<bit *> (arg1_bit) && is_a<bit *> (arg2_bit))
+    result = and_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 = and_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 = and_var_const (arg1_bit, as_a<bit *> (arg2_bit));
+
+  else
+    result = and_sym_bits (arg1_bit, arg2_bit);
+
+  return result;
+}
+
+
+bool
 state::do_binary_operation (tree arg1, tree arg2, tree dest,
 			    binary_func bin_func)
 {
-  check_args_compatibility (arg1, arg2, dest);
+  if (!check_args_compatibility (arg1, arg2, dest))
+    return false;
+
+  declare_if_needed (arg1, var_states.get (dest)->length ());
+  declare_if_needed (arg2, var_states.get (dest)->length ());
+
   vec<value*> * arg1_bits = var_states.get (arg1);
   vec<value*> arg1_const_bits (vNULL);
   if (arg1_bits == NULL && TREE_CODE (arg1) == INTEGER_CST)
@@ -303,15 +355,17 @@ state::do_binary_operation (tree arg1, tree arg2, tree dest,
   (this->*bin_func)(arg1_bits, arg2_bits, dest);
   free_bits (&arg1_const_bits);
   free_bits (&arg2_const_bits);
+
+  return true;
 }
 
 
 /* Does bit-level AND operation for given variables.  */
 
-void
+bool
 state::do_and (tree arg1, tree arg2, tree dest)
 {
-  do_binary_operation (arg1, arg2, dest, &state::do_and);
+  return do_binary_operation (arg1, arg2, dest, &state::do_and);
 }
 
 
@@ -320,41 +374,48 @@ state::do_and (vec<value*> * arg1_bits, vec<value*> * arg2_bits, tree dest)
 {
   /* Creating AND expressions for every bit pair of given arguments
      and store them as a new state for given destination.  */
+
   for (size_t i = 0; i < get_var_size (dest); i++)
     {
-      value *result = nullptr;
-      value *arg1_bit = (*arg1_bits)[i];
-      value *arg2_bit = (*arg2_bits)[i];
+      value* temp = (*var_states.get (dest))[i];
+      (*var_states.get (dest))[i] = and_two_bits ((*arg1_bits)[i],
+						  (*arg2_bits)[i]);
+      delete temp;
+    }
+}
 
-      if (is_a<bit *> (arg1_bit) && is_a<bit *> (arg2_bit))
-	result = and_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 = and_var_const (arg2_bit, as_a<bit *> (arg1_bit));
+/* Performs OR operation on two bits.  */
 
-      else if ((is_a<symbolic_bit *> (arg1_bit)
-		|| (is_a<bit_expression *> (arg1_bit)))
-	       && is_a<bit *> (arg2_bit))
-	result = and_var_const (arg1_bit, as_a<bit *> (arg2_bit));
+value *
+state::or_two_bits (value *arg1_bit, value* arg2_bit) const
+{
+  value *result = nullptr;
 
-      else
-	result = and_sym_bits (arg1_bit, arg2_bit);
+  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));
 
-      delete (*var_states.get (dest))[i];
-      (*var_states.get (dest))[i] = result;
-    }
+  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;
 }
 
 
 /* Does bit-level OR operation for given variables.  */
 
-void
+bool
 state::do_or (tree arg1, tree arg2, tree dest)
 {
-  do_binary_operation (arg1, arg2, dest, &state::do_or);
+  return do_binary_operation (arg1, arg2, dest, &state::do_or);
 }
 
 
@@ -365,38 +426,45 @@ state::do_or (vec<value*> * arg1_bits, vec<value*> * arg2_bits, tree dest)
      and store them as a new state for given destination.  */
   for (size_t i = 0; i < get_var_size (dest); i++)
     {
-      value *result = nullptr;
-      value *arg1_bit = (*arg1_bits)[i];
-      value *arg2_bit = (*arg2_bits)[i];
+      value * temp = (*var_states.get (dest))[i];
+      (*var_states.get (dest))[i] = or_two_bits ((*arg1_bits)[i],
+						 (*arg2_bits)[i]);
+      delete temp;
+    }
+}
 
-      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));
+/* Performs XOR operation on two bits.  */
 
-      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));
+value *
+state::xor_two_bits (value *arg1_bit, value* arg2_bit) const
+{
+  value *result = nullptr;
 
-      else
-	result = or_sym_bits (arg1_bit, arg2_bit);
+  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));
 
-      delete (*var_states.get (dest))[i];
-      (*var_states.get (dest))[i] = result;
-    }
+   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;
 }
 
 
 /* Does bit-level XOR operation for given variables.  */
 
-void
+bool
 state::do_xor (tree arg1, tree arg2, tree dest)
 {
-  do_binary_operation (arg1, arg2, dest, &state::do_xor);
+  return do_binary_operation (arg1, arg2, dest, &state::do_xor);
 }
 
 
@@ -405,29 +473,10 @@ state::do_xor (vec<value*> * arg1_bits, vec<value *> * arg2_bits, tree dest)
 {
   for (size_t i = 0; i < get_var_size (dest); i++)
     {
-      value *result = nullptr;
-      value *arg1_bit = (*arg1_bits)[i];
-      value *arg2_bit = (*arg2_bits)[i];
-
-      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);
-
-      delete (*var_states.get (dest))[i];
-      (*var_states.get (dest))[i] = result;
+      value * temp = (*var_states.get (dest))[i];
+      (*var_states.get (dest))[i] = xor_two_bits ((*arg1_bits)[i],
+						  (*arg2_bits)[i]);
+      delete temp;
     }
 }
 
@@ -435,21 +484,21 @@ state::do_xor (vec<value*> * arg1_bits, vec<value *> * arg2_bits, tree dest)
 /* Shifts value_vector right by shift_value bits.  */
 
 vec <value *>
-state::shift_right_by_const (const vec <value *> * value_vector,
+state::shift_right_by_const (const vec <value *> * number,
 			     size_t shift_value)
 {
   vec <value *> shift_result;
-  shift_result.create (value_vector->length ());
-  if (value_vector->length () <= shift_value)
-    for (size_t i = 0; i < value_vector->length (); i++)
+  shift_result.create (number->length ());
+  if (number->length () <= shift_value)
+    for (size_t i = 0; i < number->length (); i++)
       shift_result.quick_push (new bit (0));
   else
     {
       size_t i = 0;
-      for (; i < value_vector->length () - shift_value; ++i)
-	shift_result.quick_push (((*value_vector)[shift_value + i])->copy ());
+      for (; i < number->length () - shift_value; ++i)
+	shift_result.quick_push (((*number)[shift_value + i])->copy ());
 
-      for (; i < value_vector->length (); ++i)
+      for (; i < number->length (); ++i)
 	shift_result.quick_push (new bit (0));
     }
   return shift_result;
@@ -459,10 +508,13 @@ state::shift_right_by_const (const vec <value *> * value_vector,
 /* Checks if all vector elements are const_bit_expressions.  */
 
 bool
-state::is_bit_vector (vec <value *>* value_vector)
+state::is_bit_vector (const vec <value *>* bits)
 {
-  for (size_t i = 0; i < value_vector->length (); i++)
-    if (!(is_a <bit *> ((*value_vector)[i])))
+  if (bits == nullptr)
+    return false;
+
+  for (size_t i = 0; i < bits->length (); i++)
+    if (!(is_a <bit *> ((*bits)[i])))
 	return false;
   return true;
 }
@@ -471,15 +523,17 @@ state::is_bit_vector (vec <value *>* value_vector)
 /* Returns the value of the number represented as a bit vector.  */
 
 size_t
-state::get_value (vec <value *> * bit_vector)
+state::get_value (const vec <value *> * binary_value)
 {
   size_t number = 0;
-  for (int i = bit_vector->length () - 1; i >= 0; --i)
-    {
-      bit *cur_elem = dyn_cast<bit *> ((*bit_vector)[i]);
-      number = (number | cur_elem->get_val ()) << 1;
-    }
-
+  if (binary_value->length () <= sizeof (size_t))
+    for (unsigned i = 0; i < binary_value->length (); i++)
+      {
+	if (is_a<bit *> ((*binary_value)[i]))
+	  number = (number | as_a<bit*> ((*binary_value)[i])->get_val ()) << 1;
+	else
+	  return 0;
+      }
   return number;
 }
 
@@ -504,10 +558,10 @@ state::shift_left_sym_bits (vec<value*> * arg1_bits, vec<value*> * arg2_bits,
 
 /* Does shift_left operation for given variables.  */
 
-void
+bool
 state::do_shift_left (tree arg1, tree arg2, tree dest)
 {
-  do_binary_operation (arg1, arg2, dest, &state::do_shift_left);
+  return do_binary_operation (arg1, arg2, dest, &state::do_shift_left);
 }
 
 
@@ -518,12 +572,13 @@ state::do_shift_left (vec<value*> * arg1_bits, vec<value*> * arg2_bits,
   if (is_bit_vector (arg2_bits))
     {
       size_t shift_value = get_value (arg2_bits);
-      vec < value * > result = shift_left_by_const (arg1_bits, shift_value);
+      vec <value *> * result = shift_left_by_const (arg1_bits, 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];
+	  (*var_states.get (dest))[i] = (*result)[i];
 	}
+      delete result;
     }
   else
     shift_left_sym_bits (arg1_bits, arg2_bits, dest);
@@ -533,10 +588,10 @@ state::do_shift_left (vec<value*> * arg1_bits, vec<value*> * arg2_bits,
 
 /* Does shift_right operation for given variables.  */
 
-void
+bool
 state::do_shift_right (tree arg1, tree arg2, tree dest)
 {
-  do_binary_operation (arg1, arg2, dest, &state::do_shift_right);
+  return do_binary_operation (arg1, arg2, dest, &state::do_shift_right);
 }
 
 
@@ -560,78 +615,171 @@ state::do_shift_right (vec<value*> * arg1_bits, vec<value*> * arg2_bits,
 }
 
 
+/* Adds two bits and carry value.
+Resturn result and stores new carry bit in "carry".  */
+
+value*
+state::full_adder (value* var1, value* var2, value*& carry)
+{
+  value * new_carry = and_two_bits (var1, var2);
+  value * sum = xor_two_bits (var1, var2);
+
+  value* result = xor_two_bits (sum, carry);
+  value * 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 two variables.  */
 
-void
+bool
 state::do_add (tree arg1, tree arg2, tree dest)
 {
-  do_binary_operation (arg1, arg2, dest, &state::do_add);
+  return do_binary_operation (arg1, arg2, dest, &state::do_add);
 }
 
 
 void
 state::do_add (vec<value*> * arg1_bits, vec<value*> * arg2_bits, tree dest)
 {
-  for (size_t i = 0; i < get_var_size (dest); i++)
+  value * carry = new bit (0);
+  for (size_t i =  get_var_size (dest) - 1; i != 0; --i)
     {
-      value *new_val = new add_expression ((*arg1_bits)[i]->copy (),
-					   (*arg2_bits)[i]->copy ());
-      delete (*var_states.get (dest))[i];
-      (*var_states.get (dest))[i] = new_val;
+      value * temp = (*var_states.get (dest))[i];
+      (*var_states.get (dest))[i] = full_adder ((*arg1_bits)[i],
+						(*arg2_bits)[i],
+						carry);
+      delete temp;
     }
+  delete carry;
+}
+
+
+/* Returns the additive inverse of the number stored in number verctor.  */
+
+vec < value * > *
+state::additive_inverse (const vec < value * > *number)
+{
+  vec < value * > * result = new vec < value * > ();
+  vec < value * > * one = new vec < value * > ();
+
+  result->create (number->length ());
+  one->create (number -> length ());
+  size_t vec_len = number->length ();
+
+  for (size_t i = 0; i < vec_len; i++)
+    {
+      if (i == vec_len - 1)
+	one->quick_push (new bit (1));
+      else
+	one->quick_push (new bit (0));
+      result->quick_push (complement_a_bit ((*number)[i]->copy ()));
+    }
+
+  value * carry = new bit (0);
+  for (size_t i = vec_len - 1; i != 0; --i)
+    (*result)[i] = full_adder ((*result)[i], (*one)[i], carry);
+
+  delete carry;
+  return result;
 }
 
 
 /* Does subtraction.  */
 
-void
+bool
 state::do_sub (tree arg1, tree arg2, tree dest)
 {
-  do_binary_operation (arg1, arg2, dest, &state::do_sub);
+  return do_binary_operation (arg1, arg2, dest, &state::do_sub);
 }
 
 
 void
 state::do_sub (vec<value*> * arg1_bits, vec<value*> * arg2_bits, tree dest)
 {
-  for (size_t i = 0; i < get_var_size (dest); i++)
-    {
-      value *new_val = new sub_expression ((*arg1_bits)[i]->copy (),
-					   (*arg2_bits)[i]->copy ());
-      delete (*var_states.get (dest))[i];
-      (*var_states.get (dest))[i] = new_val;
-    }
+  vec < value * > * neg_arg2 = additive_inverse (arg2_bits);
+
+  do_add (arg1_bits, neg_arg2, dest);
+
+  free_bits (neg_arg2);
+  delete neg_arg2;
 }
 
 
+/* Performs complement operation on a bit.  */
+
+value *
+state::complement_a_bit (value *var) const
+{
+  value *result = nullptr;
+  bit* const_bit = dyn_cast<bit *> (var);
+  if (const_bit)
+    result = complement_const_bit (const_bit);
+  else
+    result = complement_sym_bit (var);
+
+  return result;
+ }
+
+
 /* Negates given variable.  */
 
-void
+bool
 state::do_complement (tree arg, tree dest)
 {
-  gcc_assert (is_declared (arg) && is_declared (dest));
-  gcc_assert (get_var_size (arg) == get_var_size (dest));
+  if (!is_declared (dest))
+    {
+      if (dump_file && (dump_flags & TDF_DETAILS))
+	fprintf (dump_file, "Sym-Exec: Destination var is not declared.\n");
+
+      return false;
+    }
+
+  declare_if_needed (arg, var_states.get (dest)->length ());
+  if (get_var_size (arg) != get_var_size (dest))
+    {
+      if (dump_file && (dump_flags & TDF_DETAILS))
+	fprintf (dump_file, "Sym-Exec: Incompatible destination"
+			    " and argument sizes.\n");
+
+      return false;
+    }
 
   /* Creating complement expressions for every bit the given argument
      and store it as a new state for given destination.  */
   for (size_t i = 0; i < get_var_size (dest); i++)
     {
-      value *result = nullptr;
-      bit *const_bit = dyn_cast<bit *> ((*var_states.get (arg))[i]);
-      if (const_bit)
-	result = complement_const_bit (const_bit);
-      else
-	result = complement_sym_bit ((*var_states.get (arg))[i]);
+      value *result = complement_a_bit ((*var_states.get (arg))[i]);
 
       delete (*var_states.get (dest))[i];
       (*var_states.get (dest))[i] = result;
     }
+
+  return true;
 }
 
 
-void
+bool
 state::do_assign (tree arg, tree dest)
 {
+  if (!is_declared (dest))
+    {
+      if (dump_file && (dump_flags & TDF_DETAILS))
+	fprintf (dump_file, "Sym-Exec: Destination var is not declared.\n");
+
+      return false;
+    }
+
+  declare_if_needed (arg, var_states.get (dest)->length ());
   vec<value*> * dest_bits = var_states.get (dest);
   /* If the argument is already defined, then we must just copy its bits.  */
   if (auto bits = var_states.get (arg))
@@ -660,7 +808,14 @@ state::do_assign (tree arg, tree dest)
 	}
     }
   else
-    gcc_assert (false);
+    {
+      if (dump_file && (dump_flags & TDF_DETAILS))
+	fprintf (dump_file, "Sym-Exec: Unsupported assignment"
+			    " for given argument.\n");
+
+      return false;
+    }
+  return true;
 }
 
 
@@ -855,25 +1010,25 @@ state::is_safe_branching (value* node) const
 }
 
 
-/* Shifts value_vector left by shift_value bits.  */
+/* Shifts number left by shift_value bits.  */
 
-vec <value *>
-state::shift_left_by_const (const vec < value * > * value_vector,
+vec <value *> *
+state::shift_left_by_const (const vec < value * > * number,
 			    size_t shift_value)
 {
-  vec <value *> shift_result;
-  shift_result.create (value_vector->length ());
-  if (value_vector->length () <= shift_value)
-    for (size_t i = 0; i < value_vector->length (); i++)
-      shift_result.quick_push (new bit (0));
+  vec <value *> *shift_result = new vec< value * > ();
+  shift_result->create (number->length ());
+
+  if (number->length () <= shift_value)
+    for (size_t i = 0; i < number->length (); i++)
+      shift_result->quick_push (new bit (0));
   else
     {
       size_t i = 0;
-      for (; i < value_vector->length () - shift_value; ++i)
-	shift_result.quick_push (new bit (0));
-
-      for (size_t j = 0; i < value_vector->length (); ++i, ++j)
-	shift_result.quick_push (((*value_vector)[j])->copy ());
+      for ( ; i < number->length () - shift_value; ++i)
+	shift_result->quick_push (new bit (0));
+      for (size_t j = 0; i < number->length (); ++i, ++j)
+	shift_result->quick_push (((*number)[j])->copy ());
     }
   return shift_result;
 }
@@ -897,6 +1052,84 @@ state::shift_right_sym_bits (vec<value*> * arg1_bits, vec<value*> * arg2_bits,
 }
 
 
+/* Adds two vectors, stores the result in the first one.  */
+
+void
+state::add_numbers (vec< value * > *var1, const vec< value * > *var2)
+{
+  value * carry = new bit (0);
+  for (unsigned i = 0; i < var1->length (); i++)
+    {
+      value *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, stroes the result in var1.  */
+
+void
+state::and_number_bit (vec< value * > *var1, value *var_bit)
+{
+  for (unsigned i = 0; i < var1->length (); i++)
+    {
+      value *tmp = (*var1)[i];
+      (*var1)[i] = and_two_bits ((*var1)[i], var_bit);
+      delete tmp;
+    }
+
+}
+
+
+/* Multiplies two variables, stores result in dest.  */
+
+bool
+state::do_mul (tree arg1, tree arg2, tree dest)
+{
+  return do_binary_operation (arg1, arg2, dest, &state::do_mul);
+}
+
+
+void
+state::do_mul (vec<value*> * arg1_bits, vec<value*> * arg2_bits, tree dest)
+{
+  vec <value *> *shifted = new vec <value *> ();
+  vec_copy_construct (shifted, arg1_bits, arg1_bits->length ());
+  vec <value *> * dest_bits = var_states.get (dest);
+
+  for (unsigned i = 0; i < dest_bits->length (); i++)
+    {
+      delete (*dest_bits)[i];
+      (*dest_bits)[i] = new bit (0);
+    }
+
+  for (unsigned i = arg2_bits->length () - 1; i != 0; --i)
+    {
+      if (is_a<bit *> ((*arg2_bits)[i]))
+	{
+	  if (as_a<bit *> ((*arg2_bits)[i])->get_val () != 0)
+	  add_numbers (dest_bits, shifted);
+	}
+      else if (is_a<symbolic_bit *> ((*arg2_bits)[i]))
+	{
+	  and_number_bit (shifted, as_a<symbolic_bit *> ((*arg2_bits)[i]));
+	  add_numbers (dest_bits, shifted);
+	}
+
+      vec <value *> *temp = shifted;
+      shifted = shift_left_by_const (shifted, 1);
+
+      free_bits (temp);
+      delete temp;
+    }
+
+  free_bits (shifted);
+  delete shifted;
+}
+
+
 bool
 state::check_const_bit_equality (vec<value *> * arg1_bits,
 				 vec<value *> * arg2_bits) const
@@ -908,12 +1141,16 @@ state::check_const_bit_equality (vec<value *> * arg1_bits,
 }
 
 
-void
+bool
 state::add_equal_cond (tree arg1, tree arg2)
 {
-  vec<value *> * arg1_bits = var_states.get (arg1);
-  vec<value *> * arg2_bits = var_states.get (arg2);
+  return add_binary_cond (arg1, arg2, &state::add_equal_cond);
+}
+
 
+void
+state::add_equal_cond (vec<value*> * arg1_bits, vec<value*> * arg2_bits)
+{
   if (is_bit_vector (arg1_bits) && is_bit_vector (arg2_bits))
     {
       bool result = check_const_bit_equality (arg1_bits, arg2_bits);
@@ -922,24 +1159,6 @@ state::add_equal_cond (tree arg1, tree arg2)
 						: condition_type::IS_FALSE));
       return;
     }
-  else if (is_bit_vector (arg1_bits) && TREE_CODE (arg2) == INTEGER_CST
-	   && (integer_onep (arg2) || integer_zerop (arg2)))
-    {
-      size_t i = 0;
-      if (integer_onep (arg2))
-	{
-	  conditions.add (new bit_condition ((*arg1_bits)[0]->copy (),
-					     new bit (1),
-					     condition_type::EQUAL));
-	  i++;
-	}
-
-      for (; i < arg1_bits->length (); i++)
-	conditions.add (new bit_condition ((*arg1_bits)[i]->copy (),
-					   new bit (0),
-					   condition_type::EQUAL));
-    }
-
   for (size_t i = 0; i < arg1_bits->length (); i++)
     {
       conditions.add (new bit_condition ((*arg1_bits)[i]->copy (),
@@ -960,12 +1179,16 @@ state::check_const_bit_are_not_equal (vec<value *> * arg1_bits,
 }
 
 
-void
+bool
 state::add_not_equal_cond (tree arg1, tree arg2)
 {
-  vec<value *> * arg1_bits = var_states.get (arg1);
-  vec<value *> * arg2_bits = var_states.get (arg2);
+  return add_binary_cond (arg1, arg2, &state::add_not_equal_cond);
+}
+
 
+void
+state::add_not_equal_cond (vec<value*> * arg1_bits, vec<value*> * arg2_bits)
+{
   if (is_bit_vector (arg1_bits) && is_bit_vector (arg2_bits))
     {
       bool result = check_const_bit_are_not_equal (arg1_bits, arg2_bits);
@@ -975,7 +1198,18 @@ state::add_not_equal_cond (tree arg1, tree arg2)
       return;
     }
 
-  /* TODO: add condition when one of arguments is symbolic.  */
+  bit_expression * prev = nullptr;
+  for (size_t i = 0; i < arg1_bits->length (); i++)
+    {
+      bit_condition* new_cond = new bit_condition ((*arg1_bits)[i]->copy (),
+						   (*arg2_bits)[i]->copy (),
+						   condition_type::NOT_EQUAL);
+      if (prev)
+	prev = new bit_or_expression (prev, new_cond);
+      else
+	prev = new_cond;
+    }
+  conditions.add (prev);
 }
 
 
@@ -994,12 +1228,17 @@ state::check_const_bit_is_greater_than (vec<value *> * arg1_bits,
 }
 
 
-void
+bool
 state::add_greater_than_cond (tree arg1, tree arg2)
 {
-  vec<value *> * arg1_bits = var_states.get (arg1);
-  vec<value *> * arg2_bits = var_states.get (arg2);
+  return add_binary_cond (arg1, arg2, &state::add_greater_than_cond);
+}
 
+
+void
+state::add_greater_than_cond (vec<value*> * arg1_bits,
+			      vec<value*> * arg2_bits)
+{
   if (is_bit_vector (arg1_bits) && is_bit_vector (arg2_bits))
     {
       bool result = check_const_bit_is_greater_than (arg1_bits, arg2_bits);
@@ -1009,7 +1248,35 @@ state::add_greater_than_cond (tree arg1, tree arg2)
       return;
     }
 
-  /* TODO: add condition when one of arguments is symbolic.  */
+  conditions.add (construct_great_than_cond (arg1_bits, arg2_bits));
+}
+
+
+bit_expression*
+state::construct_great_than_cond (vec<value*> * arg1_bits,
+				  vec<value*> * arg2_bits)
+{
+  bit_expression* prev = nullptr;
+  size_t i = 0;
+  for ( ; i < arg1_bits->length () - 1; i++)
+    {
+      bit_condition* greater_cond
+      = new bit_condition ((*arg1_bits)[i]->copy (), (*arg2_bits)[i]->copy (),
+			   condition_type::GREAT_THAN);
+      bit_condition* eq_cond = new bit_condition ((*arg1_bits)[i + 1]->copy (),
+						  (*arg2_bits)[i + 1]->copy (),
+						  condition_type::EQUAL);
+      bit_expression* and_expr = new bit_and_expression (eq_cond, greater_cond);
+      if (prev)
+	prev = new bit_or_expression (and_expr, prev);
+      else
+	prev = and_expr;
+    }
+
+  bit_condition* greater_cond = new bit_condition ((*arg1_bits)[i]->copy (),
+						   (*arg2_bits)[i]->copy (),
+						   condition_type::GREAT_THAN);
+  return new bit_or_expression (greater_cond, prev);
 }
 
 
@@ -1028,12 +1295,16 @@ state::check_const_bit_is_less_than (vec<value *> * arg1_bits,
 }
 
 
-void
+bool
 state::add_less_than_cond (tree arg1, tree arg2)
 {
-  vec<value *> * arg1_bits = var_states.get (arg1);
-  vec<value *> * arg2_bits = var_states.get (arg2);
+  return add_binary_cond (arg1, arg2, &state::add_less_than_cond);
+}
 
+
+void
+state::add_less_than_cond (vec<value*> * arg1_bits, vec<value*> * arg2_bits)
+{
   if (is_bit_vector (arg1_bits) && is_bit_vector (arg2_bits))
     {
       bool result = check_const_bit_is_less_than (arg1_bits, arg2_bits);
@@ -1043,16 +1314,49 @@ state::add_less_than_cond (tree arg1, tree arg2)
       return;
     }
 
-  /* TODO: add condition when one of arguments is symbolic.  */
+  conditions.add (construct_less_than_cond (arg1_bits, arg2_bits));
 }
 
 
-void
+bit_expression*
+state::construct_less_than_cond (vec<value*> * arg1_bits,
+				 vec<value*> * arg2_bits)
+{
+  bit_expression* prev = nullptr;
+  size_t i = 0;
+  for ( ; i < arg1_bits->length () - 1; i++)
+    {
+      bit_condition* less_cond = new bit_condition ((*arg1_bits)[i]->copy (),
+						    (*arg2_bits)[i]->copy (),
+						    condition_type::LESS_THAN);
+      bit_condition* eq_cond = new bit_condition ((*arg1_bits)[i + 1]->copy (),
+						  (*arg2_bits)[i + 1]->copy (),
+						  condition_type::EQUAL);
+      bit_expression* and_expr = new bit_and_expression (eq_cond, less_cond);
+      if (prev)
+	prev = new bit_or_expression (and_expr, prev);
+      else
+	prev = and_expr;
+    }
+
+  bit_condition* less_cond = new bit_condition ((*arg1_bits)[i]->copy (),
+						(*arg2_bits)[i]->copy (),
+						condition_type::LESS_THAN);
+  return new bit_or_expression (less_cond, prev);
+}
+
+
+bool
 state::add_greater_or_equal_cond (tree arg1, tree arg2)
 {
-  vec<value *> * arg1_bits = var_states.get (arg1);
-  vec<value *> * arg2_bits = var_states.get (arg2);
+  return add_binary_cond (arg1, arg2, &state::add_greater_or_equal_cond);
+}
 
+
+void
+state::add_greater_or_equal_cond (vec<value*> * arg1_bits,
+				  vec<value*> * arg2_bits)
+{
   if (is_bit_vector (arg1_bits) && is_bit_vector (arg2_bits))
     {
       bool is_greater_than = check_const_bit_is_greater_than (arg1_bits,
@@ -1065,16 +1369,23 @@ state::add_greater_or_equal_cond (tree arg1, tree arg2)
       return;
     }
 
-  /* TODO: add condition when one of arguments is symbolic.  */
+  conditions.add (
+	new bit_or_expression (construct_great_than_cond (arg1_bits, arg2_bits),
+			       construct_equal_cond (arg1_bits, arg2_bits)));
 }
 
 
-void
+bool
 state::add_less_or_equal_cond (tree arg1, tree arg2)
 {
-  vec<value *> * arg1_bits = var_states.get (arg1);
-  vec<value *> * arg2_bits = var_states.get (arg2);
+  return add_binary_cond (arg1, arg2, &state::add_less_or_equal_cond);
+}
+
 
+void
+state::add_less_or_equal_cond (vec<value*> * arg1_bits,
+			       vec<value*> * arg2_bits)
+{
   if (is_bit_vector (arg1_bits) && is_bit_vector (arg2_bits))
     {
       bool is_less_than = check_const_bit_is_less_than (arg1_bits, arg2_bits);
@@ -1086,25 +1397,183 @@ state::add_less_or_equal_cond (tree arg1, tree arg2)
       return;
     }
 
-  /* TODO: add condition when one of arguments is symbolic.  */
+  conditions.add (
+	new bit_or_expression (construct_less_than_cond (arg1_bits, arg2_bits),
+			       construct_equal_cond (arg1_bits, arg2_bits)));
 }
 
 
-void
+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;
+    }
   vec<value *> * arg_bits = var_states.get (arg);
-  condition_type result = condition_type::IS_FALSE;
   if (is_bit_vector (arg_bits))
     {
+      condition_type result = condition_type::IS_FALSE;
       for (size_t i = 0; i < arg_bits->length (); i++)
 	if ((*arg_bits)[i] != 0)
 	  {
 	    result = condition_type::IS_TRUE;
 	    break;
 	  }
+      conditions.add (new bit_condition (nullptr, nullptr, result));
+    }
+
+  bit_expression* prev = nullptr;
+  for (size_t i = 0; i < arg_bits->length (); i++)
+    {
+      bit_condition* not_eq_cond
+      = new bit_condition ((*arg_bits)[i], new bit (0),
+			   condition_type::NOT_EQUAL);
+      if (prev)
+	prev = new bit_or_expression (not_eq_cond, prev);
+      else
+	prev = not_eq_cond;
+    }
+
+  conditions.add (prev);
+  return true;
+}
+
+
+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 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 ());
+
+  vec<value*> * arg1_bits = var_states.get (arg1);
+  vec<value*> arg1_const_bits (vNULL);
+  if (arg1_bits == NULL && TREE_CODE (arg1) == INTEGER_CST)
+    {
+      arg1_const_bits = create_bits_for_const (arg1,
+				var_states.get (arg2)->length ());
+      arg1_bits = &arg1_const_bits;
+    }
+
+  vec<value*> * arg2_bits = var_states.get (arg2);
+  vec<value*> arg2_const_bits (vNULL);
+  if (arg2_bits == NULL && TREE_CODE (arg2) == INTEGER_CST)
+    {
+      arg2_const_bits = create_bits_for_const (arg2,
+				var_states.get (arg1)->length ());
+      arg2_bits = &arg2_const_bits;
+    }
+
+  (this->*cond_func)(arg1_bits, arg2_bits);
+  free_bits (&arg1_const_bits);
+  free_bits (&arg2_const_bits);
+  return true;
+}
+
+
+bit_expression*
+state::construct_equal_cond (vec<value*> * arg1_bits,
+			     vec<value*> * arg2_bits)
+{
+  bit_expression* prev = nullptr;
+  for (size_t i = 0; i < arg1_bits->length (); i++)
+    {
+      bit_condition* eq_expr = new bit_condition ((*arg1_bits)[i]->copy (),
+						  (*arg2_bits)[i]->copy (),
+						  condition_type::EQUAL);
+      if (prev)
+	prev = new bit_and_expression (eq_expr, prev);
+      else
+	prev = eq_expr;
+    }
+
+  return prev;
+}
+
+
+/* Gets the value of *arg1 and stores it in dest.  */
+
+bool
+state::do_mem_ref (tree arg1, tree dest)
+{
+  if (!is_declared (arg1) || !is_declared (dest))
+    {
+      if (dump_file && (dump_flags & TDF_DETAILS))
+	fprintf (dump_file, "Sym-Exec: For memory reference, both destination"
+			    "and argument must be declared\n");
+
+      return false;
+    }
+
+  for (unsigned i = 0; i < get_var_size (dest); i++)
+    {
+      delete (*var_states.get (dest))[i];
+      // TODO: Find a better way.
+      (*var_states.get (dest))[i] = new symbolic_bit (i);
+    }
+
+  return true;
+}
+
+
+/* Performs addition on arg1 pointer.  */
+
+bool
+state::do_pointer_plus (tree arg1, tree arg2, tree dest)
+{
+  if (!is_declared (arg1) || !is_declared (arg2) || !is_declared (dest))
+    {
+      if (dump_file && (dump_flags & TDF_DETAILS))
+	fprintf (dump_file, "Sym-Exec: For pointer addition destination"
+			    "and arguments must be declared\n");
+
+      return false;
+    }
+
+  if (is_bit_vector (var_states.get (arg2))
+	&& get_value (var_states.get (arg2)) == 0)
+    return do_mem_ref (arg1, dest);
+
+  return do_add (arg1, arg2, dest);
+}
+
+
+/* Perform subtractions on arg1 pointer.  */
+
+bool
+state::do_pointer_diff (tree arg1, tree arg2, tree dest)
+{
+  if (!is_declared (arg1) || !is_declared (arg2) || !is_declared (dest))
+    {
+      if (dump_file && (dump_flags & TDF_DETAILS))
+	fprintf (dump_file, "Sym-Exec: For pointer subtraction destination"
+			    "and arguments must be declared\n");
+
+      return false;
     }
-  conditions.add (new bit_condition (nullptr, nullptr, result));
 
-  /* TODO: add condition when one of arguments is symbolic.  */
+  if (is_bit_vector (var_states.get (arg2))
+  	&& get_value (var_states.get (arg2)) == 0)
+    return do_mem_ref (arg1, dest);
+
+  return do_sub (arg1, arg2, dest);
 }
diff --git a/gcc/sym-exec/state.h b/gcc/sym-exec/state.h
index 3a9808c73db..f074a9a63a2 100644
--- a/gcc/sym-exec/state.h
+++ b/gcc/sym-exec/state.h
@@ -36,19 +36,50 @@ class state {
  typedef void (state::*binary_func) (vec<value*> * arg1_bits,
 				     vec<value*> * arg2_bits, tree dest);
 
+ typedef void (state::*binary_cond_func) (vec<value*> * arg1_bits,
+					  vec<value*> * arg2_bits);
+
  private:
   /* Here is stored values of bit of each variable.  */
   hash_map<tree, vec < value * >> var_states;
 
   hash_set<bit_expression *> conditions;
 
+  /* Performs AND operation on two bits.  */
+  value * and_two_bits (value *var1, value* var2) const;
+
   vec<value*> create_bits_for_const (tree var, size_t size) const;
 
   void free_bits (vec<value*> * bits) const;
 
-  void check_args_compatibility (tree arg1, tree arg2, tree dest);
+  bool check_args_compatibility (tree arg1, tree arg2, tree dest);
+
+  void add_equal_cond (vec<value*> * arg1_bits, vec<value*> * arg2_bits);
+
+  void add_not_equal_cond (vec<value*> * arg1_bits, vec<value*> * arg2_bits);
+
+  void add_greater_than_cond (vec<value*> * arg1_bits, vec<value*> * arg2_bits);
+
+  void add_less_than_cond (vec<value*> * arg1_bits, vec<value*> * arg2_bits);
+
+  void add_greater_or_equal_cond (vec<value*> * arg1_bits,
+				  vec<value*> * arg2_bits);
+
+  void add_less_or_equal_cond (vec<value*> * arg1_bits,
+			       vec<value*> * arg2_bits);
+
+  bool add_binary_cond (tree arg1, tree arg2, binary_cond_func cond_func);
 
-  void do_binary_operation (tree arg1, tree arg2, tree dest,
+  bit_expression* construct_great_than_cond (vec<value*> * arg1_bits,
+					     vec<value*> * arg2_bits);
+
+  bit_expression* construct_less_than_cond (vec<value*> * arg1_bits,
+					    vec<value*> * arg2_bits);
+
+  bit_expression* construct_equal_cond (vec<value*> * arg1_bits,
+					vec<value*> * arg2_bits);
+
+  bool do_binary_operation (tree arg1, tree arg2, tree dest,
 			    binary_func bin_func);
 
   void do_and (vec<value*> * arg1_bits, vec<value*> * arg2_bits, tree dest);
@@ -67,6 +98,8 @@ class state {
 
   void do_sub (vec<value*> * arg1_bits, vec<value*> * arg2_bits, tree dest);
 
+  void do_mul (vec<value*> * arg1_bits, vec<value*> * arg2_bits, tree dest);
+
   /* Performs AND operation for 2 symbolic_bit operands.  */
   value *and_sym_bits (const value * var1, const value * var2) const;
 
@@ -76,6 +109,9 @@ class state {
   /* Performs AND operation for 2 constant bit operands.  */
   bit *and_const_bits (const bit * const_bit1, const bit * const_bit2) const;
 
+  /* Performs OR operation on two bits.  */
+  value * or_two_bits (value *var1, value* var2) const;
+
   /* Performs OR operation for 2 symbolic_bit operands.  */
   value *or_sym_bits (const value * var1, const value * var2) const;
 
@@ -85,12 +121,18 @@ class state {
   /* Performs OR operation for 2 constant bit operands.  */
   bit *or_const_bits (const bit * const_bit1, const bit * const_bit2) const;
 
+  /* Performs complement operation on a bit.  */
+  value * complement_a_bit (value *var) const;
+
   /* Performs NOT operation for constant bit.  */
   bit *complement_const_bit (const bit * const_bit) const;
 
   /* Performs NOT operation for symbolic_bit.  */
   value *complement_sym_bit (const value * var) const;
 
+  /* Performs XOR operation on two bits.  */
+  value * xor_two_bits (value *var1, value* var2) const;
+
   /* Performs XOR operation for 2 symbolic_bit operands.  */
   value *xor_sym_bits (const value * var1, const value * var2) const;
 
@@ -123,6 +165,31 @@ class state {
      exists or not.  */
   bool is_declared (tree var);
 
+  void declare_if_needed (tree var, size_t size);
+
+ /* Shifts value_vector left by shift_value bits.  */
+  vec <value *> *shift_left_by_const (const vec <value *> *arg_vector,
+				      size_t shift_value);
+
+  /* Checks if all vector elements are const_bit_expressions.  */
+  bool is_bit_vector (const vec <value *> *value_vector);
+
+  /* returns the value of the number represented as a bit vector.  */
+  size_t get_value (const vec <value *> *bit_vector);
+
+  /* Adds two bits and carry value.
+     Resturn result and stores new carry bit in "carry".  */
+  value* full_adder (value* var1, value* var2, value*& carry);
+
+  /* Returns the additive inverse of the number stored in number verctor.  */
+  vec <value *> * additive_inverse (const vec <value *> *number);
+
+  /* ANDs every bit of the vector with var_bit, stroes the result in var1.  */
+  void and_number_bit (vec<value *> *var1, value *var_bit);
+
+  /* Adds two vectors, stores the result in the first one.  */
+  void add_numbers (vec< value * > *var1, const vec< value * > *var2);
+
  public:
    state ();
 
@@ -155,54 +222,56 @@ class state {
   unsigned get_var_size (tree var);
 
   /* Does bit-level XOR operation for given variables.  */
-  void do_xor (tree arg1, tree arg2, tree dest);
+  bool do_xor (tree arg1, tree arg2, tree dest);
 
   /* Does bit-level AND operation for given variables.  */
-  void do_and (tree arg1, tree arg2, tree dest);
+  bool do_and (tree arg1, tree arg2, tree dest);
 
   /* Does bit-level OR operation for given variables.  */
-  void do_or (tree arg1, tree arg2, tree dest);
+  bool do_or (tree arg1, tree arg2, tree dest);
 
-  void do_assign (tree arg, tree dest);
-
-  /* Shifts value_vector left by shift_value bits.  */
-  vec <value *> shift_left_by_const (const vec <value *> * value_vector,
-				     size_t shift_value);
-
-  /* Checks if all vector elements are const_bit_expressions.  */
-  bool is_bit_vector (vec <value *> * value_vector);
-
-  /* Returns the value of the number represented as a bit vector.  */
-  size_t get_value (vec <value *> *  bit_vector);
+  bool do_assign (tree arg, tree dest);
 
   /* Does shift_left operation for given variables.  */
-  void do_shift_left (tree arg1, tree arg2, tree dest);
+  bool do_shift_left (tree arg1, tree arg2, tree dest);
 
   /* Does shift_right operation for given variables.  */
-  void do_shift_right (tree arg1, tree arg2, tree dest);
+  bool do_shift_right (tree arg1, tree arg2, tree dest);
 
   /* Adds two variables.  */
-  void do_add (tree arg1, tree arg2, tree dest);
+  bool do_add (tree arg1, tree arg2, tree dest);
 
   /* Does subtraction.  */
-  void do_sub (tree arg1, tree arg2, tree dest);
+  bool do_sub (tree arg1, tree arg2, tree dest);
+
+  /* Multiplies two variables, stores result in dest.  */
+  bool do_mul (tree arg1, tree arg2, tree dest);
 
   /* Negates given variable.  */
-  void do_complement (tree arg, tree dest);
+  bool do_complement (tree arg, tree dest);
+
+  bool add_equal_cond (tree arg1, tree arg2);
+
+  /* Gets the value of *arg1 and stores it in dest.  */
+  bool do_mem_ref (tree arg1, tree dest);
+
+  /* Performs addition on arg1 pointer.  */
+  bool do_pointer_plus (tree arg1, tree arg2, tree dest);
 
-  void add_equal_cond (tree arg1, tree arg2);
+  /* Perform subtractions on arg1 pointer.  */
+  bool do_pointer_diff (tree arg1, tree arg2, tree dest);
 
-  void add_not_equal_cond (tree arg1, tree arg2);
+  bool add_not_equal_cond (tree arg1, tree arg2);
 
-  void add_greater_than_cond (tree arg1, tree arg2);
+  bool add_greater_than_cond (tree arg1, tree arg2);
 
-  void add_less_than_cond (tree arg1, tree arg2);
+  bool add_less_than_cond (tree arg1, tree arg2);
 
-  void add_greater_or_equal_cond (tree arg1, tree arg2);
+  bool add_greater_or_equal_cond (tree arg1, tree arg2);
 
-  void add_less_or_equal_cond (tree arg1, tree arg2);
+  bool add_less_or_equal_cond (tree arg1, tree arg2);
 
-  void add_bool_cond (tree arg);
+  bool add_bool_cond (tree arg);
 
   bool check_const_bit_equality (vec<value *> * arg1_bits,
 				 vec<value *> * arg2_bits) const;


More information about the Gcc-cvs mailing list