CBMC
Loading...
Searching...
No Matches
boolbv_typecast.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module:
4
5Author: Daniel Kroening, kroening@kroening.com
6
7\*******************************************************************/
8
10#include <util/c_types.h>
11#include <util/namespace.h>
12
14
15#include "boolbv.h"
16#include "boolbv_type.h"
18
20{
21 const exprt &op = expr.op();
22 const bvt &op_bv = convert_bv(op);
23
24 bvt bv;
25
26 if(type_conversion(op.type(), op_bv, expr.type(), bv))
27 return conversion_failed(expr);
28
29 return bv;
30}
31
33 const typet &src_type,
34 const bvt &src,
35 const typet &dest_type,
36 bvt &dest)
37{
40
42 return type_conversion(
44 src,
46 dest);
47
49 return type_conversion(
51 src,
53 dest);
54
55 std::size_t src_width = src.size();
56 std::size_t dest_width = boolbv_width(dest_type);
57
58 if(dest_width == 0 || src_width == 0)
59 return true;
60
61 dest.clear();
62 dest.reserve(dest_width);
63
64 if(dest_type.id() == ID_complex)
65 {
66 if(src_type == to_complex_type(dest_type).subtype())
67 {
68 dest.insert(dest.end(), src.begin(), src.end());
69
70 // pad with zeros
71 for(std::size_t i = src.size(); i < dest_width; i++)
72 dest.push_back(const_literal(false));
73
74 return false;
75 }
76 else if(src_type.id() == ID_complex)
77 {
78 // recursively do both halfs
79 bvt lower, upper, lower_res, upper_res;
80 lower.assign(src.begin(), src.begin() + src.size() / 2);
81 upper.assign(src.begin() + src.size() / 2, src.end());
83 to_complex_type(src_type).subtype(),
84 lower,
85 to_complex_type(dest_type).subtype(),
86 lower_res);
88 to_complex_type(src_type).subtype(),
89 upper,
90 to_complex_type(dest_type).subtype(),
91 upper_res);
93 lower_res.size() + upper_res.size() == dest_width,
94 "lower result bitvector size plus upper result bitvector size shall "
95 "equal the destination bitvector size");
96 dest = lower_res;
97 dest.insert(dest.end(), upper_res.begin(), upper_res.end());
98 return false;
99 }
100 }
101
102 if(src_type.id() == ID_complex)
103 {
104 INVARIANT(
105 dest_type.id() == ID_complex,
106 "destination type shall be of complex type when source type is of "
107 "complex type");
108 if(
109 dest_type.id() == ID_signedbv || dest_type.id() == ID_unsignedbv ||
110 dest_type.id() == ID_floatbv || dest_type.id() == ID_fixedbv ||
111 dest_type.id() == ID_c_enum || dest_type.id() == ID_c_enum_tag ||
112 dest_type.id() == ID_bool)
113 {
114 // A cast from complex x to real T
115 // is (T) __real__ x.
116 bvt tmp_src(src);
117 tmp_src.resize(src.size() / 2); // cut off imag part
118 return type_conversion(
119 to_complex_type(src_type).subtype(), tmp_src, dest_type, dest);
120 }
121 }
122
123 switch(dest_bvtype)
124 {
126 if(
128 src_bvtype == bvtypet::IS_C_BOOL) // unsigned to range
129 {
130 // need to do arithmetic: add -dest_from
131 mp_integer offset = -to_range_type(dest_type).get_from();
132 dest = bv_utils.add(
135
136 return false;
137 }
138 else if(src_bvtype == bvtypet::IS_SIGNED) // signed to range
139 {
140 // need to do arithmetic: add -dest_from
141 mp_integer offset = -to_range_type(dest_type).get_from();
142 dest = bv_utils.add(
145
146 return false;
147 }
148 else if(src_bvtype == bvtypet::IS_RANGE) // range to range
149 {
152
153 // need to do arithmetic: add src_from-dest_from
154 mp_integer offset = src_from - dest_from;
155 dest = bv_utils.add(
158
159 return false;
160 }
161 else if(src_type.id() == ID_bool) // bool to range
162 {
163 // need to do arithmetic: add -dest_from
164 mp_integer offset = -to_range_type(dest_type).get_from();
165 dest = bv_utils.add(
168
169 return false;
170 }
171 break;
172
173 case bvtypet::IS_FLOAT: // to float
174 {
176
177 switch(src_bvtype)
178 {
179 case bvtypet::IS_FLOAT: // float to float
180 // we don't have a rounding mode here,
181 // which is why we refuse.
182 break;
183
184 case bvtypet::IS_SIGNED: // signed to float
187 dest = float_utils.from_signed_integer(src);
188 return false;
189
190 case bvtypet::IS_UNSIGNED: // unsigned to float
191 case bvtypet::IS_C_BOOL: // _Bool to float
193 dest = float_utils.from_unsigned_integer(src);
194 return false;
195
196 case bvtypet::IS_BV:
197 INVARIANT(src_width >= dest_width, "cannot extend bv-typed bitvector");
198 dest = src;
200 dest.resize(dest_width);
201 return false;
202
209 if(src_type.id() == ID_bool)
210 {
211 // bool to float
212
213 // build a one
215 dest = convert_bv(one.to_expr());
216
217 INVARIANT(
218 src_width == 1, "bitvector of type boolean shall have width one");
219
220 for(auto &literal : dest)
221 literal = prop.land(literal, src[0]);
222
223 return false;
224 }
225 }
226 }
227 break;
228
231 {
232 // fixed to fixed
233
234 std::size_t dest_fraction_bits =
235 to_fixedbv_type(dest_type).get_fraction_bits();
237 std::size_t op_fraction_bits =
238 to_fixedbv_type(src_type).get_fraction_bits();
239 std::size_t op_int_bits = src_width - op_fraction_bits;
240
241 dest.resize(dest_width);
242
243 // i == position after dot
244 // i == 0: first position after dot
245
246 for(std::size_t i = 0; i < dest_fraction_bits; i++)
247 {
248 // position in bv
249 std::size_t p = dest_fraction_bits - i - 1;
250
251 if(i < op_fraction_bits)
252 dest[p] = src[op_fraction_bits - i - 1];
253 else
254 dest[p] = const_literal(false); // zero padding
255 }
256
257 for(std::size_t i = 0; i < dest_int_bits; i++)
258 {
259 // position in bv
260 std::size_t p = dest_fraction_bits + i;
261 INVARIANT(p < dest_width, "bit index shall be within bounds");
262
263 if(i < op_int_bits)
264 dest[p] = src[i + op_fraction_bits];
265 else
266 dest[p] = src[src_width - 1]; // sign extension
267 }
268
269 return false;
270 }
271 else if(src_bvtype == bvtypet::IS_BV)
272 {
273 INVARIANT(src_width >= dest_width, "cannot extend bv-typed bitvector");
274 dest = src;
276 dest.resize(dest_width);
277 return false;
278 }
279 else if(
282 {
283 // integer to fixed
284
285 std::size_t dest_fraction_bits =
286 to_fixedbv_type(dest_type).get_fraction_bits();
287
288 for(std::size_t i = 0; i < dest_fraction_bits; i++)
289 dest.push_back(const_literal(false)); // zero padding
290
291 for(std::size_t i = 0; i < dest_width - dest_fraction_bits; i++)
292 {
293 literalt l;
294
295 if(i < src_width)
296 l = src[i];
297 else
298 {
299 if(
302 l = src[src_width - 1]; // sign extension
303 else
304 l = const_literal(false); // zero extension
305 }
306
307 dest.push_back(l);
308 }
309
310 return false;
311 }
312 else if(src_type.id() == ID_bool)
313 {
314 // bool to fixed
315 std::size_t fraction_bits =
316 to_fixedbv_type(dest_type).get_fraction_bits();
317
318 INVARIANT(
319 src_width == 1, "bitvector of type boolean shall have width one");
320
321 for(std::size_t i = 0; i < dest_width; i++)
322 {
323 if(i == fraction_bits)
324 dest.push_back(src[0]);
325 else
326 dest.push_back(const_literal(false));
327 }
328
329 return false;
330 }
331 break;
332
336 {
337 switch(src_bvtype)
338 {
339 case bvtypet::IS_FLOAT: // float to integer
340 // we don't have a rounding mode here,
341 // which is why we refuse.
342 break;
343
344 case bvtypet::IS_FIXED: // fixed to integer
345 {
346 std::size_t op_fraction_bits =
347 to_fixedbv_type(src_type).get_fraction_bits();
348
349 for(std::size_t i = 0; i < dest_width; i++)
350 {
352 dest.push_back(src[i + op_fraction_bits]);
353 else
354 {
356 dest.push_back(src[src_width - 1]); // sign extension
357 else
358 dest.push_back(const_literal(false)); // zero extension
359 }
360 }
361
362 // we might need to round up in case of negative numbers
363 // e.g., (int)(-1.00001)==1
364
365 bvt fraction_bits_bv = src;
368
369 dest = bv_utils.incrementer(dest, round_up);
370
371 return false;
372 }
373
374 case bvtypet::IS_UNSIGNED: // integer to integer
378 {
379 // We do sign extension for any source type
380 // that is signed, independently of the
381 // destination type.
382 // E.g., ((short)(ulong)(short)-1)==-1
383 bool sign_extension =
385
386 for(std::size_t i = 0; i < dest_width; i++)
387 {
388 if(i < src_width)
389 dest.push_back(src[i]);
390 else if(sign_extension)
391 dest.push_back(src[src_width - 1]); // sign extension
392 else
393 dest.push_back(const_literal(false));
394 }
395
396 return false;
397 }
398 // verilog_unsignedbv to signed/unsigned/enum
400 {
401 for(std::size_t i = 0; i < dest_width; i++)
402 {
403 std::size_t src_index = i * 2; // we take every second bit
404
405 if(src_index < src_width)
406 dest.push_back(src[src_index]);
407 else // always zero-extend
408 dest.push_back(const_literal(false));
409 }
410
411 return false;
412 }
413 break;
414
415 case bvtypet::IS_VERILOG_SIGNED: // verilog_signedbv to signed/unsigned/enum
416 {
417 for(std::size_t i = 0; i < dest_width; i++)
418 {
419 std::size_t src_index = i * 2; // we take every second bit
420
421 if(src_index < src_width)
422 dest.push_back(src[src_index]);
423 else // always sign-extend
424 dest.push_back(src.back());
425 }
426
427 return false;
428 }
429 break;
430
431 case bvtypet::IS_BV:
432 INVARIANT(src_width >= dest_width, "cannot extend bv-typed bitvector");
433 dest = src;
435 dest.resize(dest_width);
436 return false;
437
441 if(src_type.id() == ID_bool)
442 {
443 // bool to integer
444
445 INVARIANT(
446 src_width == 1, "bitvector of type boolean shall have width one");
447
448 for(std::size_t i = 0; i < dest_width; i++)
449 {
450 if(i == 0)
451 dest.push_back(src[0]);
452 else
453 dest.push_back(const_literal(false));
454 }
455
456 return false;
457 }
458 }
459 break;
460 }
461
463 if(
465 src_type.id() == ID_bool)
466 {
467 for(std::size_t i = 0, j = 0; i < dest_width; i += 2, j++)
468 {
469 if(j < src_width)
470 dest.push_back(src[j]);
471 else
472 dest.push_back(const_literal(false));
473
474 dest.push_back(const_literal(false));
475 }
476
477 return false;
478 }
480 {
481 for(std::size_t i = 0, j = 0; i < dest_width; i += 2, j++)
482 {
483 if(j < src_width)
484 dest.push_back(src[j]);
485 else
486 dest.push_back(src.back());
487
488 dest.push_back(const_literal(false));
489 }
490
491 return false;
492 }
494 {
495 // verilog_unsignedbv to verilog_unsignedbv
496 dest = src;
497
499 dest.resize(dest_width);
500 else
501 {
502 dest = src;
503 while(dest.size() < dest_width)
504 {
505 dest.push_back(const_literal(false));
506 dest.push_back(const_literal(false));
507 }
508 }
509 return false;
510 }
511 break;
512
513 case bvtypet::IS_BV:
514 INVARIANT(src_width >= dest_width, "cannot extend bv-typed bitvector");
515 dest = src;
517 dest.resize(dest_width);
518 return false;
519
521 dest.resize(dest_width, const_literal(false));
522
524 {
526 dest[0] = !float_utils.is_zero(src);
527 }
529 dest[0] = src[0];
530 else
531 dest[0] = !bv_utils.is_zero(src);
532
533 return false;
534
538 if(dest_type.id() == ID_array)
539 {
540 if(src_width == dest_width)
541 {
542 dest = src;
543 return false;
544 }
545 }
546 else if(dest_type.id() == ID_struct || dest_type.id() == ID_struct_tag)
547 {
550 ? ns.follow_tag(to_struct_tag_type(dest_type))
552
553 if(src_type.id() == ID_struct || src_type.id() == ID_struct_tag)
554 {
555 // we do subsets
556
557 dest.resize(dest_width, const_literal(false));
558
559 const struct_typet &op_struct =
560 src_type.id() == ID_struct_tag
561 ? ns.follow_tag(to_struct_tag_type(src_type))
563
564 const struct_typet::componentst &dest_comp = dest_struct.components();
565
566 const struct_typet::componentst &op_comp = op_struct.components();
567
568 // build offset maps
571
572 // build name map
573 typedef std::map<irep_idt, std::size_t> op_mapt;
575
576 for(std::size_t i = 0; i < op_comp.size(); i++)
577 op_map[op_comp[i].get_name()] = i;
578
579 // now gather required fields
580 for(std::size_t i = 0; i < dest_comp.size(); i++)
581 {
582 std::size_t offset = dest_offsets[i];
583 std::size_t comp_width = boolbv_width(dest_comp[i].type());
584 if(comp_width == 0)
585 continue;
586
587 op_mapt::const_iterator it = op_map.find(dest_comp[i].get_name());
588
589 if(it == op_map.end())
590 {
591 // not found
592
593 // filling with free variables
594 for(std::size_t j = 0; j < comp_width; j++)
595 dest[offset + j] = prop.new_variable();
596 }
597 else
598 {
599 // found
600 if(dest_comp[i].type() != dest_comp[it->second].type())
601 {
602 // filling with free variables
603 for(std::size_t j = 0; j < comp_width; j++)
604 dest[offset + j] = prop.new_variable();
605 }
606 else
607 {
608 std::size_t op_offset = op_offsets[it->second];
609 for(std::size_t j = 0; j < comp_width; j++)
610 dest[offset + j] = src[op_offset + j];
611 }
612 }
613 }
614
615 return false;
616 }
617 }
618 }
619
620 return true;
621}
622
625{
626 if(expr.op().type().id() == ID_range)
627 {
628 mp_integer from = string2integer(expr.op().type().get_string(ID_from));
629 mp_integer to = string2integer(expr.op().type().get_string(ID_to));
630
631 if(from == 1 && to == 1)
632 return const_literal(true);
633 else if(from == 0 && to == 0)
634 return const_literal(false);
635 }
636
637 const bvt &bv = convert_bv(expr.op());
638
639 if(!bv.empty())
640 return prop.lor(bv);
641
642 return SUB::convert_rest(expr);
643}
Pre-defined bitvector types.
const fixedbv_typet & to_fixedbv_type(const typet &type)
Cast a typet to a fixedbv_typet.
const floatbv_typet & to_floatbv_type(const typet &type)
Cast a typet to a floatbv_typet.
bvtypet get_bvtype(const typet &type)
bvtypet
Definition boolbv_type.h:17
@ IS_VERILOG_UNSIGNED
@ IS_VERILOG_SIGNED
@ IS_C_BIT_FIELD
typet c_bit_field_replacement_type(const c_bit_field_typet &src, const namespacet &ns)
const c_bit_field_typet & to_c_bit_field_type(const typet &type)
Cast a typet to a c_bit_field_typet.
Definition c_types.h:80
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
const namespacet & ns
Definition arrays.h:56
virtual const bvt & convert_bv(const exprt &expr, const std::optional< std::size_t > expected_width={})
Convert expression to vector of literalts, using an internal cache to speed up conversion if availabl...
Definition boolbv.cpp:39
offset_mapt build_offset_map(const struct_typet &src)
Definition boolbv.cpp:586
virtual literalt convert_typecast(const typecast_exprt &expr)
conversion from bitvector types to boolean
bv_utilst bv_utils
Definition boolbv.h:119
bvt conversion_failed(const exprt &expr)
Print that the expression of x has failed conversion, then return a vector of x's width.
Definition boolbv.cpp:94
virtual std::size_t boolbv_width(const typet &type) const
Definition boolbv.h:104
virtual bvt convert_bv_typecast(const typecast_exprt &expr)
bool type_conversion(const typet &src_type, const bvt &src, const typet &dest_type, bvt &dest)
std::vector< std::size_t > offset_mapt
Definition boolbv.h:281
bvt add(const bvt &op0, const bvt &op1)
Definition bv_utils.h:66
static bvt zero_extension(const bvt &bv, std::size_t new_size)
Definition bv_utils.h:187
static bvt build_constant(const mp_integer &i, std::size_t width)
Definition bv_utils.cpp:16
literalt is_zero(const bvt &op)
Definition bv_utils.h:143
bvt incrementer(const bvt &op, literalt carry_in)
Definition bv_utils.cpp:630
static bvt sign_extension(const bvt &bv, std::size_t new_size)
Definition bv_utils.h:182
Base class for all expressions.
Definition expr.h:57
typet & type()
Return the type of the expression.
Definition expr.h:85
static ieee_float_valuet one(const floatbv_typet &)
virtual literalt convert_rest(const exprt &expr)
virtual literalt land(literalt a, literalt b)=0
virtual literalt new_variable()=0
virtual literalt lor(literalt a, literalt b)=0
Structure type, corresponds to C style structs.
Definition std_types.h:231
std::vector< componentt > componentst
Definition std_types.h:140
Semantic type conversion.
Definition std_expr.h:2091
The type of an expression, extends irept.
Definition type.h:29
const exprt & op() const
Definition std_expr.h:391
std::vector< literalt > bvt
Definition literal.h:201
literalt const_literal(bool value)
Definition literal.h:188
const mp_integer string2integer(const std::string &n, unsigned base)
Definition mp_arith.cpp:54
BigInt mp_integer
Definition smt_terms.h:17
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
Definition invariant.h:423
const range_typet & to_range_type(const typet &type)
Cast a typet to a range_typet.
Definition std_types.h:1040
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
Definition std_types.h:308
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.
Definition std_types.h:518
const complex_typet & to_complex_type(const typet &type)
Cast a typet to a complex_typet.
Definition std_types.h:1158