コード例 #1
0
ファイル: float_utils.cpp プロジェクト: diffblue/cbmc
bvt float_utilst::from_unsigned_integer(const bvt &src)
{
  unbiased_floatt result;

  result.fraction=src;

  // build an exponent (unbiased) -- this is signed!
  result.exponent=
    bv_utils.build_constant(
      src.size()-1,
      address_bits(src.size()-1).to_long()+1);

  result.sign=const_literal(false);

  return rounder(result);
}
コード例 #2
0
ファイル: float_utils.cpp プロジェクト: diffblue/cbmc
bvt float_utilst::from_signed_integer(const bvt &src)
{
  unbiased_floatt result;

  // we need to convert negative integers
  result.sign=sign_bit(src);

  result.fraction=bv_utils.absolute_value(src);

  // build an exponent (unbiased) -- this is signed!
  result.exponent=
    bv_utils.build_constant(
      src.size()-1,
      address_bits(src.size()-1).to_long()+1);

  return rounder(result);
}
コード例 #3
0
ファイル: float_utils.cpp プロジェクト: diffblue/cbmc
bvt float_utilst::limit_distance(
  const bvt &dist,
  mp_integer limit)
{
  std::size_t nb_bits=integer2unsigned(address_bits(limit));

  bvt upper_bits=dist;
  upper_bits.erase(upper_bits.begin(), upper_bits.begin()+nb_bits);
  literalt or_upper_bits=prop.lor(upper_bits);

  bvt lower_bits=dist;
  lower_bits.resize(nb_bits);

  bvt result;
  result.resize(lower_bits.size());

  // bitwise or with or_upper_bits
  for(std::size_t i=0; i<result.size(); i++)
    result[i]=prop.lor(lower_bits[i], or_upper_bits);

  return result;
}
コード例 #4
0
ファイル: float_utils.cpp プロジェクト: diffblue/cbmc
bvt float_utilst::rounder(const unbiased_floatt &src)
{
  // incoming: some fraction (with explicit 1),
  //           some exponent without bias
  // outgoing: rounded, with right size, with hidden bit, bias

  bvt aligned_fraction=src.fraction,
      aligned_exponent=src.exponent;

  {
    std::size_t exponent_bits=
      std::max((std::size_t)integer2size_t(address_bits(spec.f)),
               (std::size_t)spec.e)+1;

    // before normalization, make sure exponent is large enough
    if(aligned_exponent.size()<exponent_bits)
    {
      // sign extend
      aligned_exponent=
        bv_utils.sign_extension(aligned_exponent, exponent_bits);
    }
  }

  // align it!
  normalization_shift(aligned_fraction, aligned_exponent);
  denormalization_shift(aligned_fraction, aligned_exponent);

  unbiased_floatt result;
  result.fraction=aligned_fraction;
  result.exponent=aligned_exponent;
  result.sign=src.sign;
  result.NaN=src.NaN;
  result.infinity=src.infinity;

  round_fraction(result);
  round_exponent(result);

  return pack(bias(result));
}
コード例 #5
0
ファイル: float_utils.cpp プロジェクト: diffblue/cbmc
void float_utilst::normalization_shift(bvt &fraction, bvt &exponent)
{
  #if 0
  // this thing is quadratic!

  bvt new_fraction=prop.new_variables(fraction.size());
  bvt new_exponent=prop.new_variables(exponent.size());

  // i is the shift distance
  for(std::size_t i=0; i<fraction.size(); i++)
  {
    bvt equal;

    // the bits above need to be zero
    for(std::size_t j=0; j<i; j++)
      equal.push_back(
        !fraction[fraction.size()-1-j]);

    // this one needs to be one
    equal.push_back(fraction[fraction.size()-1-i]);

    // iff all of that holds, we shift here!
    literalt shift=prop.land(equal);

    // build shifted value
    bvt shifted_fraction=bv_utils.shift(fraction, bv_utilst::LEFT, i);
    bv_utils.cond_implies_equal(shift, shifted_fraction, new_fraction);

    // build new exponent
    bvt adjustment=bv_utils.build_constant(-i, exponent.size());
    bvt added_exponent=bv_utils.add(exponent, adjustment);
    bv_utils.cond_implies_equal(shift, added_exponent, new_exponent);
  }

  // Fraction all zero? It stays zero.
  // The exponent is undefined in that case.
  literalt fraction_all_zero=bv_utils.is_zero(fraction);
  bvt zero_fraction;
  zero_fraction.resize(fraction.size(), const_literal(false));
  bv_utils.cond_implies_equal(fraction_all_zero, zero_fraction, new_fraction);

  fraction=new_fraction;
  exponent=new_exponent;

  #else

  // n-log-n alignment shifter.
  // The worst-case shift is the number of fraction
  // bits minus one, in case the faction is one exactly.
  assert(!fraction.empty());
  unsigned depth=integer2unsigned(address_bits(fraction.size()-1));

  if(exponent.size()<depth)
    exponent=bv_utils.sign_extension(exponent, depth);

  bvt exponent_delta=bv_utils.zeros(exponent.size());

  for(int d=depth-1; d>=0; d--)
  {
    std::size_t distance=(1<<d);
    assert(fraction.size()>distance);

    // check if first 'distance'-many bits are zeros
    const bvt prefix=bv_utils.extract_msb(fraction, distance);
    literalt prefix_is_zero=bv_utils.is_zero(prefix);

    // If so, shift the zeros out left by 'distance'.
    // Otherwise, leave as is.
    const bvt shifted=
      bv_utils.shift(fraction, bv_utilst::LEFT, distance);

    fraction=
      bv_utils.select(prefix_is_zero, shifted, fraction);

    // add corresponding weight to exponent
    assert(d<(signed)exponent_delta.size());
    exponent_delta[d]=prefix_is_zero;
  }

  exponent=bv_utils.sub(exponent, exponent_delta);

  #endif
}
コード例 #6
0
ファイル: boolbv_width.cpp プロジェクト: rbavishi/iCBMC
const boolbv_widtht::entryt &boolbv_widtht::get_entry(const typet &type) const
{
  // check cache first

  std::pair<cachet::iterator, bool> cache_result=
    cache.insert(std::pair<typet, entryt>(type, entryt()));
    
  entryt &entry=cache_result.first->second;

  if(!cache_result.second) // found!
    return entry;
    
  entry.total_width=0;
  
  const irep_idt type_id=type.id();

  if(type_id==ID_struct)
  {
    const struct_typet::componentst &components=
      to_struct_type(type).components();

    std::size_t offset=0;
    entry.members.resize(components.size());
  
    for(std::size_t i=0; i<entry.members.size(); i++)
    {
      std::size_t sub_width=operator()(components[i].type());
      entry.members[i].offset=offset;
      entry.members[i].width=sub_width;
      offset+=sub_width;
    }
    
    entry.total_width=offset;
  }
  else if(type_id==ID_union)
  {
    const union_typet::componentst &components=
      to_union_type(type).components();

    entry.members.resize(components.size());
    
    std::size_t max_width=0;
  
    for(std::size_t i=0; i<entry.members.size(); i++)
    {
      std::size_t sub_width=operator()(components[i].type());
      entry.members[i].width=sub_width;
      max_width=std::max(max_width, sub_width);
    }

    entry.total_width=max_width;
  }
  else if(type_id==ID_bool)
    entry.total_width=1;
  else if(type_id==ID_c_bool)
  {
    entry.total_width=to_c_bool_type(type).get_width();
    assert(entry.total_width!=0);
  }
  else if(type_id==ID_signedbv)
  {
    entry.total_width=to_signedbv_type(type).get_width();
    assert(entry.total_width!=0);
  }
  else if(type_id==ID_unsignedbv)
  {
    entry.total_width=to_unsignedbv_type(type).get_width();
    assert(entry.total_width!=0);
  }
  else if(type_id==ID_floatbv)
  {
    entry.total_width=to_floatbv_type(type).get_width();
    assert(entry.total_width!=0);
  }
  else if(type_id==ID_fixedbv)
  {
    entry.total_width=to_fixedbv_type(type).get_width();
    assert(entry.total_width!=0);
  }
  else if(type_id==ID_bv)
  {
    entry.total_width=to_bv_type(type).get_width();
    assert(entry.total_width!=0);
  }
  else if(type_id==ID_verilogbv)
  {
    // we encode with two bits
    entry.total_width=type.get_unsigned_int(ID_width)*2;
    assert(entry.total_width!=0);
  }
  else if(type_id==ID_range)
  {
    mp_integer from=string2integer(type.get_string(ID_from)),
                 to=string2integer(type.get_string(ID_to));

    mp_integer size=to-from+1;

    if(size>=1)
    {
      entry.total_width=integer2unsigned(address_bits(size));
      assert(entry.total_width!=0);
    }
  }
  else if(type_id==ID_array)
  {
    const array_typet &array_type=to_array_type(type);
    std::size_t sub_width=operator()(array_type.subtype());

    mp_integer array_size;

    if(to_integer(array_type.size(), array_size))
    {
      // we can still use the theory of arrays for this
      entry.total_width=0;
    }
    else
    {
      mp_integer total=array_size*sub_width;
      if(total>(1<<30)) // realistic limit
        throw "array too large for flattening";

      entry.total_width=integer2unsigned(total);
    }
  }
  else if(type_id==ID_vector)
  {
    const vector_typet &vector_type=to_vector_type(type);
    std::size_t sub_width=operator()(vector_type.subtype());

    mp_integer vector_size;

    if(to_integer(vector_type.size(), vector_size))
    {
      // we can still use the theory of arrays for this
      entry.total_width=0;
    }
    else
    {
      mp_integer total=vector_size*sub_width;
      if(total>(1<<30)) // realistic limit
        throw "vector too large for flattening";

      entry.total_width=integer2unsigned(vector_size*sub_width);
    }
  }
  else if(type_id==ID_complex)
  {
    std::size_t sub_width=operator()(type.subtype());
    entry.total_width=integer2unsigned(2*sub_width);
  }
  else if(type_id==ID_code)
  {
  }
  else if(type_id==ID_enum)
  {
    // get number of necessary bits

    std::size_t size=type.find(ID_elements).get_sub().size();
    entry.total_width=integer2unsigned(address_bits(size));
    assert(entry.total_width!=0);
  }
  else if(type_id==ID_c_enum)
  {
    // these have a subtype
    entry.total_width=type.subtype().get_unsigned_int(ID_width);
    assert(entry.total_width!=0);
  }
  else if(type_id==ID_incomplete_c_enum)
  {
    // no width
  }
  else if(type_id==ID_pointer ||
          type_id==ID_reference)
  {
    entry.total_width=config.ansi_c.pointer_width;
  }
  else if(type_id==ID_symbol)
    entry=get_entry(ns.follow(type));
  else if(type_id==ID_struct_tag)
    entry=get_entry(ns.follow_tag(to_struct_tag_type(type)));
  else if(type_id==ID_union_tag)
    entry=get_entry(ns.follow_tag(to_union_tag_type(type)));
  else if(type_id==ID_c_enum_tag)
    entry=get_entry(ns.follow_tag(to_c_enum_tag_type(type)));
  else if(type_id==ID_c_bit_field)
  {
    entry.total_width=to_c_bit_field_type(type).get_width();
  }
  
  return entry;
}