cprover
Loading...
Searching...
No Matches
bitvector_expr.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: API to expression classes for bitvectors
4
5Author: Daniel Kroening, kroening@kroening.com
6
7\*******************************************************************/
8
9#include "bitvector_expr.h"
10
11#include "arith_tools.h"
12#include "bitvector_types.h"
13#include "mathematical_types.h"
14
16 exprt _src,
17 const irep_idt &_id,
18 const std::size_t _distance)
19 : binary_exprt(std::move(_src), _id, from_integer(_distance, integer_typet()))
20{
21}
22
23extractbit_exprt::extractbit_exprt(exprt _src, const std::size_t _index)
25 std::move(_src),
26 ID_extractbit,
27 from_integer(_index, integer_typet()))
28{
29}
30
32 exprt _src,
33 const std::size_t _upper,
34 const std::size_t _lower,
35 typet _type)
36 : expr_protectedt(ID_extractbits, std::move(_type))
37{
38 PRECONDITION(_upper >= _lower);
40 std::move(_src),
41 from_integer(_upper, integer_typet()),
42 from_integer(_lower, integer_typet()));
43}
44
46{
47 // Hacker's Delight, variant pop0:
48 // x = (x & 0x55555555) + ((x >> 1) & 0x55555555);
49 // x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
50 // x = (x & 0x0F0F0F0F) + ((x >> 4) & 0x0F0F0F0F);
51 // x = (x & 0x00FF00FF) + ((x >> 8) & 0x00FF00FF);
52 // etc.
53 // return x;
54 // http://www.hackersdelight.org/permissions.htm
55
56 // make sure the operand width is a power of two
57 exprt x = op();
58 const auto x_width = to_bitvector_type(x.type()).get_width();
59 CHECK_RETURN(x_width >= 1);
60 const std::size_t bits = address_bits(x_width);
61 const std::size_t new_width = numeric_cast_v<std::size_t>(power(2, bits));
62
63 const bool need_typecast =
64 new_width > x_width || x.type().id() != ID_unsignedbv;
65
66 if(need_typecast)
67 x = typecast_exprt(x, unsignedbv_typet(new_width));
68
69 // repeatedly compute x = (x & bitmask) + ((x >> shift) & bitmask)
70 for(std::size_t shift = 1; shift < new_width; shift <<= 1)
71 {
72 // x >> shift
73 lshr_exprt shifted_x(
74 x, from_integer(shift, unsignedbv_typet(address_bits(shift) + 1)));
75 // bitmask is a string of alternating shift-many bits starting from lsb set
76 // to 1
77 std::string bitstring;
78 bitstring.reserve(new_width);
79 for(std::size_t i = 0; i < new_width / (2 * shift); ++i)
80 bitstring += std::string(shift, '0') + std::string(shift, '1');
81 const mp_integer value = binary2integer(bitstring, false);
82 const constant_exprt bitmask(integer2bvrep(value, new_width), x.type());
83 // build the expression
84 x = plus_exprt(bitand_exprt(x, bitmask), bitand_exprt(shifted_x, bitmask));
85 }
86
87 // the result is restricted to the result type
89}
90
92{
93 // x = x | (x >> 1);
94 // x = x | (x >> 2);
95 // x = x | (x >> 4);
96 // x = x | (x >> 8);
97 // etc.
98 // return popcount(~x);
99
100 // make sure the operand width is a power of two
101 exprt x = op();
102 const auto x_width = to_bitvector_type(x.type()).get_width();
103 CHECK_RETURN(x_width >= 1);
104 const std::size_t bits = address_bits(x_width);
105 const std::size_t new_width = numeric_cast_v<std::size_t>(power(2, bits));
106
107 const bool need_typecast =
108 new_width > x_width || x.type().id() != ID_unsignedbv;
109
110 if(need_typecast)
111 x = typecast_exprt(x, unsignedbv_typet(new_width));
112
113 // repeatedly compute x = x | (x >> shift)
114 for(std::size_t shift = 1; shift < new_width; shift <<= 1)
115 {
116 // x >> shift
117 lshr_exprt shifted_x(
118 x, from_integer(shift, unsignedbv_typet(address_bits(shift) + 1)));
119 // build the expression
120 x = bitor_exprt{x, shifted_x};
121 }
122
123 // the result is restricted to the result type
124 return popcount_exprt{
126 .lower();
127}
128
130{
131 exprt x = op();
132
133 // popcount(~(x | (~x + 1)))
134 // compute -x using two's complement
135 plus_exprt minus_x{bitnot_exprt{x}, from_integer(1, x.type())};
136 bitor_exprt x_or_minus_x{x, std::move(minus_x)};
137 popcount_exprt popcount{bitnot_exprt{std::move(x_or_minus_x)}};
138
139 return typecast_exprt::conditional_cast(popcount.lower(), type());
140}
141
143{
144 const std::size_t int_width = to_bitvector_type(type()).get_width();
145
146 exprt::operandst result_bits;
147 result_bits.reserve(int_width);
148
149 const symbol_exprt to_reverse("to_reverse", op().type());
150 for(std::size_t i = 0; i < int_width; ++i)
151 result_bits.push_back(extractbit_exprt{to_reverse, i});
152
153 return let_exprt{to_reverse, op(), concatenation_exprt{result_bits, type()}};
154}
155
157{
158 std::size_t lhs_ssize = to_bitvector_type(lhs().type()).get_width();
159 if(lhs().type().id() == ID_unsignedbv)
160 ++lhs_ssize;
161 std::size_t rhs_ssize = to_bitvector_type(rhs().type()).get_width();
162 if(rhs().type().id() == ID_unsignedbv)
163 ++rhs_ssize;
164
165 std::size_t ssize = std::max(lhs_ssize, rhs_ssize) + 1;
166 signedbv_typet ssize_type{ssize};
167 plus_exprt exact_result{
168 typecast_exprt{lhs(), ssize_type}, typecast_exprt{rhs(), ssize_type}};
169
170 return notequal_exprt{
171 typecast_exprt{typecast_exprt{exact_result, lhs().type()}, ssize_type},
172 exact_result};
173}
174
176{
177 std::size_t lhs_ssize = to_bitvector_type(lhs().type()).get_width();
178 if(lhs().type().id() == ID_unsignedbv)
179 ++lhs_ssize;
180 std::size_t rhs_ssize = to_bitvector_type(rhs().type()).get_width();
181 if(rhs().type().id() == ID_unsignedbv)
182 ++rhs_ssize;
183
184 std::size_t ssize = std::max(lhs_ssize, rhs_ssize) + 1;
185 signedbv_typet ssize_type{ssize};
186 minus_exprt exact_result{
187 typecast_exprt{lhs(), ssize_type}, typecast_exprt{rhs(), ssize_type}};
188
189 return notequal_exprt{
190 typecast_exprt{typecast_exprt{exact_result, lhs().type()}, ssize_type},
191 exact_result};
192}
193
195{
196 std::size_t lhs_ssize = to_bitvector_type(lhs().type()).get_width();
197 if(lhs().type().id() == ID_unsignedbv)
198 ++lhs_ssize;
199 std::size_t rhs_ssize = to_bitvector_type(rhs().type()).get_width();
200 if(rhs().type().id() == ID_unsignedbv)
201 ++rhs_ssize;
202
203 std::size_t ssize = lhs_ssize + rhs_ssize;
204 signedbv_typet ssize_type{ssize};
205 mult_exprt exact_result{
206 typecast_exprt{lhs(), ssize_type}, typecast_exprt{rhs(), ssize_type}};
207
208 return notequal_exprt{
209 typecast_exprt{typecast_exprt{exact_result, lhs().type()}, ssize_type},
210 exact_result};
211}
212
214{
215 exprt x = op();
216 const auto int_width = to_bitvector_type(x.type()).get_width();
217 CHECK_RETURN(int_width >= 1);
218
219 // bitwidth(x) - clz(x & ~((unsigned)x - 1));
220 const unsignedbv_typet ut{int_width};
221 minus_exprt minus_one{
225 minus_exprt result{from_integer(int_width, x.type()), clz.lower()};
226
227 return typecast_exprt::conditional_cast(result, type());
228}
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
std::size_t address_bits(const mp_integer &size)
ceil(log2(size))
irep_idt integer2bvrep(const mp_integer &src, std::size_t width)
convert an integer to bit-vector representation with given width This uses two's complement for negat...
mp_integer power(const mp_integer &base, const mp_integer &exponent)
A multi-precision implementation of the power operator.
Target numeric_cast_v(const mp_integer &arg)
Convert an mp_integer to integral type Target An invariant will fail if the conversion is not possibl...
API to expression classes for bitvectors.
Pre-defined bitvector types.
const bitvector_typet & to_bitvector_type(const typet &type)
Cast a typet to a bitvector_typet.
A base class for binary expressions.
Definition std_expr.h:583
exprt & lhs()
Definition std_expr.h:613
exprt & rhs()
Definition std_expr.h:623
A base class for expressions that are predicates, i.e., Boolean-typed, and that take exactly two argu...
Definition std_expr.h:676
Bit-wise AND.
Bit-wise negation of bit-vectors.
Bit-wise OR.
exprt lower() const
Lower a bitreverse_exprt to arithmetic and logic expressions.
std::size_t get_width() const
Definition std_types.h:876
Concatenation of bit-vector operands.
A constant literal expression.
Definition std_expr.h:2942
The count leading zeros (counting the number of zero bits starting from the most-significant bit) exp...
exprt lower() const
Lower a count_leading_zeros_exprt to arithmetic and logic expressions.
exprt lower() const
Lower a count_trailing_zeros_exprt to arithmetic and logic expressions.
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition dstring.h:39
Base class for all expressions.
Definition expr.h:336
Base class for all expressions.
Definition expr.h:56
std::vector< exprt > operandst
Definition expr.h:58
typet & type()
Return the type of the expression.
Definition expr.h:84
void add_to_operands(const exprt &expr)
Add the given argument to the end of exprt's operands.
Definition expr.h:162
Extracts a single bit of a bit-vector operand.
extractbit_exprt(exprt _src, exprt _index)
Extract the _index-th least significant bit from _src.
extractbits_exprt(exprt _src, exprt _upper, exprt _lower, typet _type)
Extract the bits [_lower .
exprt lower() const
Lower a find_first_set_exprt to arithmetic and logic expressions.
Unbounded, signed integers (mathematical integers, not bitvectors)
const irep_idt & id() const
Definition irep.h:396
A let expression.
Definition std_expr.h:3149
Logical right shift.
Binary minus.
Definition std_expr.h:1006
exprt lower() const
Lower a minus_overflow_exprt to arithmetic and logic expressions.
Binary multiplication Associativity is not specified.
Definition std_expr.h:1052
exprt lower() const
Lower a mult_overflow_exprt to arithmetic and logic expressions.
Disequality.
Definition std_expr.h:1365
The plus expression Associativity is not specified.
Definition std_expr.h:947
exprt lower() const
Lower a plus_overflow_exprt to arithmetic and logic expressions.
The popcount (counting the number of bits set to 1) expression.
exprt lower() const
Lower a popcount_exprt to arithmetic and logic expressions.
shift_exprt(exprt _src, const irep_idt &_id, exprt _distance)
Fixed-width bit-vector with two's complement interpretation.
Expression to hold a symbol (variable)
Definition std_expr.h:113
Semantic type conversion.
Definition std_expr.h:2017
static exprt conditional_cast(const exprt &expr, const typet &type)
Definition std_expr.h:2025
The type of an expression, extends irept.
Definition type.h:29
const exprt & op() const
Definition std_expr.h:326
Fixed-width bit-vector with unsigned binary interpretation.
Mathematical types.
const mp_integer binary2integer(const std::string &n, bool is_signed)
convert binary string representation to mp_integer
Definition mp_arith.cpp:117
STL namespace.
BigInt mp_integer
Definition smt_terms.h:18
#define CHECK_RETURN(CONDITION)
Definition invariant.h:495
#define PRECONDITION(CONDITION)
Definition invariant.h:463