Exemple #1
0
bvt boolbvt::convert_power(const binary_exprt &expr)
{
  const typet &type=ns.follow(expr.type());

  std::size_t width=boolbv_width(type);

  if(width==0)
    return conversion_failed(expr);

  if(type.id()==ID_unsignedbv ||
     type.id()==ID_signedbv)
  {
    // Let's do the special case 2**x
    bvt op0=convert_bv(expr.op0());
    bvt op1=convert_bv(expr.op1());

    literalt eq_2=
      bv_utils.equal(op0, bv_utils.build_constant(2, op0.size()));

    bvt one=bv_utils.build_constant(1, width);
    bvt shift=bv_utils.shift(one, bv_utilst::LEFT, op1);

    bvt nondet=prop.new_variables(width);

    return bv_utils.select(eq_2, shift, nondet);
  }

  return conversion_failed(expr);
}
Exemple #2
0
bvt boolbvt::convert_shift(const binary_exprt &expr)
{
  const irep_idt &type_id=expr.type().id();

  if(type_id!=ID_unsignedbv &&
     type_id!=ID_signedbv &&
     type_id!=ID_floatbv &&
     type_id!=ID_pointer &&
     type_id!=ID_bv &&
     type_id!=ID_verilog_signedbv &&
     type_id!=ID_verilog_unsignedbv)
    return conversion_failed(expr);

  std::size_t width=boolbv_width(expr.type());

  if(width==0)
    return conversion_failed(expr);

  if(expr.operands().size()!=2)
    throw "shifting takes two operands";

  const bvt &op=convert_bv(expr.op0());

  if(op.size()!=width)
    throw "convert_shift: unexpected operand 0 width";

  bv_utilst::shiftt shift;

  if(expr.id()==ID_shl)
    shift=bv_utilst::shiftt::LEFT;
  else if(expr.id()==ID_ashr)
    shift=bv_utilst::shiftt::ARIGHT;
  else if(expr.id()==ID_lshr)
    shift=bv_utilst::shiftt::LRIGHT;
  else
    throw "unexpected shift operator";

  // we allow a constant as shift distance

  if(expr.op1().is_constant())
  {
    mp_integer i;
    if(to_integer(expr.op1(), i))
      throw "convert_shift: failed to convert constant";

    std::size_t distance;

    if(i<0 || i>std::numeric_limits<signed>::max())
      distance=0;
    else
      distance=integer2size_t(i);

    if(type_id==ID_verilog_signedbv ||
       type_id==ID_verilog_unsignedbv)
      distance*=2;

    return bv_utils.shift(op, shift, distance);
  }
  else
  {
    const bvt &distance=convert_bv(expr.op1());
    return bv_utils.shift(op, shift, distance);
  }
}