CBMC
Loading...
Searching...
No Matches
float_bv.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module:
4
5Author: Daniel Kroening, kroening@kroening.com
6
7\*******************************************************************/
8
9#include "float_bv.h"
10
11#include <algorithm>
12
13#include <util/arith_tools.h>
14#include <util/bitvector_expr.h>
16#include <util/floatbv_expr.h>
17#include <util/std_expr.h>
18
19exprt float_bvt::convert(const exprt &expr) const
20{
21 if(expr.id()==ID_abs)
22 return abs(to_abs_expr(expr).op(), get_spec(expr));
23 else if(expr.id()==ID_unary_minus)
24 return negation(to_unary_minus_expr(expr).op(), get_spec(expr));
25 else if(expr.id()==ID_ieee_float_equal)
26 {
27 const auto &equal_expr = to_ieee_float_equal_expr(expr);
28 return is_equal(
29 equal_expr.lhs(), equal_expr.rhs(), get_spec(equal_expr.lhs()));
30 }
31 else if(expr.id()==ID_ieee_float_notequal)
32 {
33 const auto &notequal_expr = to_ieee_float_notequal_expr(expr);
34 return not_exprt(is_equal(
35 notequal_expr.lhs(), notequal_expr.rhs(), get_spec(notequal_expr.lhs())));
36 }
37 else if(expr.id()==ID_floatbv_typecast)
38 {
39 const auto &floatbv_typecast_expr = to_floatbv_typecast_expr(expr);
40 const auto &op = floatbv_typecast_expr.op();
41 const typet &src_type = floatbv_typecast_expr.op().type();
42 const typet &dest_type = floatbv_typecast_expr.type();
43 const auto &rounding_mode = floatbv_typecast_expr.rounding_mode();
44
45 if(dest_type.id()==ID_signedbv &&
46 src_type.id()==ID_floatbv) // float -> signed
47 return to_signed_integer(
48 op,
49 to_signedbv_type(dest_type).get_width(),
50 rounding_mode,
51 get_spec(op));
52 else if(dest_type.id()==ID_unsignedbv &&
53 src_type.id()==ID_floatbv) // float -> unsigned
55 op,
56 to_unsignedbv_type(dest_type).get_width(),
57 rounding_mode,
58 get_spec(op));
59 else if(src_type.id()==ID_signedbv &&
60 dest_type.id()==ID_floatbv) // signed -> float
61 return from_signed_integer(op, rounding_mode, get_spec(expr));
62 else if(src_type.id()==ID_unsignedbv &&
63 dest_type.id()==ID_floatbv) // unsigned -> float
64 {
65 return from_unsigned_integer(op, rounding_mode, get_spec(expr));
66 }
67 else if(dest_type.id()==ID_floatbv &&
68 src_type.id()==ID_floatbv) // float -> float
69 {
70 return conversion(op, rounding_mode, get_spec(op), get_spec(expr));
71 }
72 else
73 return nil_exprt();
74 }
75 else if(
76 expr.id() == ID_typecast && expr.is_boolean() &&
77 to_typecast_expr(expr).op().type().id() == ID_floatbv) // float -> bool
78 {
79 return not_exprt(is_zero(to_typecast_expr(expr).op()));
80 }
81 else if(
82 expr.id() == ID_typecast && expr.type().id() == ID_bv &&
83 to_typecast_expr(expr).op().type().id() == ID_floatbv) // float -> raw bv
84 {
85 const typecast_exprt &tc = to_typecast_expr(expr);
86 const bitvector_typet &dest_type = to_bitvector_type(expr.type());
87 const floatbv_typet &src_type = to_floatbv_type(tc.op().type());
88 if(
89 dest_type.get_width() != src_type.get_width() ||
90 dest_type.get_width() == 0)
91 {
92 return nil_exprt{};
93 }
94
95 return extractbits_exprt{to_typecast_expr(expr).op(), 0, dest_type};
96 }
97 else if(expr.id()==ID_floatbv_plus)
98 {
99 const auto &float_expr = to_ieee_float_op_expr(expr);
100 return add_sub(
101 false,
102 float_expr.lhs(),
103 float_expr.rhs(),
104 float_expr.rounding_mode(),
105 get_spec(expr));
106 }
107 else if(expr.id()==ID_floatbv_minus)
108 {
109 const auto &float_expr = to_ieee_float_op_expr(expr);
110 return add_sub(
111 true,
112 float_expr.lhs(),
113 float_expr.rhs(),
114 float_expr.rounding_mode(),
115 get_spec(expr));
116 }
117 else if(expr.id()==ID_floatbv_mult)
118 {
119 const auto &float_expr = to_ieee_float_op_expr(expr);
120 return mul(
121 float_expr.lhs(),
122 float_expr.rhs(),
123 float_expr.rounding_mode(),
124 get_spec(expr));
125 }
126 else if(expr.id()==ID_floatbv_div)
127 {
128 const auto &float_expr = to_ieee_float_op_expr(expr);
129 return div(
130 float_expr.lhs(),
131 float_expr.rhs(),
132 float_expr.rounding_mode(),
133 get_spec(expr));
134 }
135 else if(expr.id() == ID_floatbv_fma)
136 {
137 const auto &fma_expr = to_floatbv_fma_expr(expr);
138 const ieee_float_spect spec{to_floatbv_type(fma_expr.type())};
139 return fma(
140 fma_expr.op_multiply_lhs(),
141 fma_expr.op_multiply_rhs(),
142 fma_expr.op_add(),
143 fma_expr.rounding_mode(),
144 spec);
145 }
146 else if(expr.id()==ID_isnan)
147 {
148 const auto &op = to_unary_expr(expr).op();
149 return isnan(op, get_spec(op));
150 }
151 else if(expr.id()==ID_isfinite)
152 {
153 const auto &op = to_unary_expr(expr).op();
154 return isfinite(op, get_spec(op));
155 }
156 else if(expr.id()==ID_isinf)
157 {
158 const auto &op = to_unary_expr(expr).op();
159 return isinf(op, get_spec(op));
160 }
161 else if(expr.id()==ID_isnormal)
162 {
163 const auto &op = to_unary_expr(expr).op();
164 return isnormal(op, get_spec(op));
165 }
166 else if(expr.id()==ID_lt)
167 {
168 const auto &rel_expr = to_binary_relation_expr(expr);
169 return relation(
170 rel_expr.lhs(), relt::LT, rel_expr.rhs(), get_spec(rel_expr.lhs()));
171 }
172 else if(expr.id()==ID_gt)
173 {
174 const auto &rel_expr = to_binary_relation_expr(expr);
175 return relation(
176 rel_expr.lhs(), relt::GT, rel_expr.rhs(), get_spec(rel_expr.lhs()));
177 }
178 else if(expr.id()==ID_le)
179 {
180 const auto &rel_expr = to_binary_relation_expr(expr);
181 return relation(
182 rel_expr.lhs(), relt::LE, rel_expr.rhs(), get_spec(rel_expr.lhs()));
183 }
184 else if(expr.id()==ID_ge)
185 {
186 const auto &rel_expr = to_binary_relation_expr(expr);
187 return relation(
188 rel_expr.lhs(), relt::GE, rel_expr.rhs(), get_spec(rel_expr.lhs()));
189 }
190 else if(expr.id()==ID_sign)
191 return sign_bit(to_unary_expr(expr).op());
192
193 return nil_exprt();
194}
195
197{
198 const floatbv_typet &type=to_floatbv_type(expr.type());
199 return ieee_float_spect(type);
200}
201
203{
204 // we mask away the sign bit, which is the most significant bit
205 const mp_integer v = power(2, spec.width() - 1) - 1;
206
207 const constant_exprt mask(integer2bvrep(v, spec.width()), op.type());
208
209 return bitand_exprt(op, mask);
210}
211
213{
214 // we flip the sign bit with an xor
215 const mp_integer v = power(2, spec.width() - 1);
216
217 constant_exprt mask(integer2bvrep(v, spec.width()), op.type());
218
219 return bitxor_exprt(op, mask);
220}
221
223 const exprt &src0,
224 const exprt &src1,
225 const ieee_float_spect &spec)
226{
227 // special cases: -0 and 0 are equal
228 const exprt is_zero0 = is_zero(src0);
229 const exprt is_zero1 = is_zero(src1);
230 const and_exprt both_zero(is_zero0, is_zero1);
231
232 // NaN compares to nothing
233 exprt isnan0=isnan(src0, spec);
234 exprt isnan1=isnan(src1, spec);
235 const or_exprt nan(isnan0, isnan1);
236
237 const equal_exprt bitwise_equal(src0, src1);
238
239 return and_exprt(
240 or_exprt(bitwise_equal, both_zero),
241 not_exprt(nan));
242}
243
245{
246 // we mask away the sign bit, which is the most significant bit
247 const floatbv_typet &type=to_floatbv_type(src.type());
248 std::size_t width=type.get_width();
249
250 const mp_integer v = power(2, width - 1) - 1;
251
252 constant_exprt mask(integer2bvrep(v, width), src.type());
253
254 ieee_float_valuet z(type);
255 z.make_zero();
256
257 return equal_exprt(bitand_exprt(src, mask), z.to_expr());
258}
259
261 const exprt &src,
262 const ieee_float_spect &spec)
263{
264 exprt exponent=get_exponent(src, spec);
265 exprt all_ones=to_unsignedbv_type(exponent.type()).largest_expr();
266 return equal_exprt(exponent, all_ones);
267}
268
270 const exprt &src,
271 const ieee_float_spect &spec)
272{
273 exprt exponent=get_exponent(src, spec);
274 exprt all_zeros=to_unsignedbv_type(exponent.type()).zero_expr();
275 return equal_exprt(exponent, all_zeros);
276}
277
279 const exprt &src,
280 const ieee_float_spect &spec)
281{
282 // does not include hidden bit
283 exprt fraction=get_fraction(src, spec);
284 exprt all_zeros=to_unsignedbv_type(fraction.type()).zero_expr();
285 return equal_exprt(fraction, all_zeros);
286}
287
289{
290 exprt round_to_even_const=from_integer(ieee_floatt::ROUND_TO_EVEN, rm.type());
291 exprt round_to_plus_inf_const=
293 exprt round_to_minus_inf_const=
295 exprt round_to_zero_const=from_integer(ieee_floatt::ROUND_TO_ZERO, rm.type());
296 exprt round_to_away_const =
298
299 round_to_even=equal_exprt(rm, round_to_even_const);
300 round_to_plus_inf=equal_exprt(rm, round_to_plus_inf_const);
301 round_to_minus_inf=equal_exprt(rm, round_to_minus_inf_const);
302 round_to_zero=equal_exprt(rm, round_to_zero_const);
303 round_to_away = equal_exprt(rm, round_to_away_const);
304}
305
307{
308 const bitvector_typet &bv_type=to_bitvector_type(op.type());
309 std::size_t width=bv_type.get_width();
310 return extractbit_exprt(op, width-1);
311}
312
314 const exprt &src,
315 const exprt &rm,
316 const ieee_float_spect &spec) const
317{
318 std::size_t src_width=to_signedbv_type(src.type()).get_width();
319
320 unbiased_floatt result;
321
322 // we need to adjust for negative integers
323 result.sign=sign_bit(src);
324
325 result.fraction=
326 typecast_exprt(abs_exprt(src), unsignedbv_typet(src_width));
327
328 // build an exponent (unbiased) -- this is signed!
329 result.exponent=
331 src_width-1,
332 signedbv_typet(address_bits(src_width - 1) + 1));
333
334 return rounder(result, rm, spec);
335}
336
338 const exprt &src,
339 const exprt &rm,
340 const ieee_float_spect &spec) const
341{
342 unbiased_floatt result;
343
344 result.fraction=src;
345
346 std::size_t src_width=to_unsignedbv_type(src.type()).get_width();
347
348 // build an exponent (unbiased) -- this is signed!
349 result.exponent=
351 src_width-1,
352 signedbv_typet(address_bits(src_width - 1) + 1));
353
354 result.sign=false_exprt();
355
356 return rounder(result, rm, spec);
357}
358
360 const exprt &src,
361 std::size_t dest_width,
362 const exprt &rm,
363 const ieee_float_spect &spec)
364{
365 return to_integer(src, dest_width, true, rm, spec);
366}
367
369 const exprt &src,
370 std::size_t dest_width,
371 const exprt &rm,
372 const ieee_float_spect &spec)
373{
374 return to_integer(src, dest_width, false, rm, spec);
375}
376
378 const exprt &src,
379 std::size_t dest_width,
380 bool is_signed,
381 const exprt &rm,
382 const ieee_float_spect &spec)
383{
384 // Keep in sync with float_utilst::to_integer — the body below is a
385 // line-for-line translation of that function between the exprt and
386 // literalt/bvt APIs.
387
388 const unbiased_floatt unpacked=unpack(src, spec);
389
390 rounding_mode_bitst rounding_mode_bits(rm);
391
392 // Right now hard-wired to round-to-zero, which is
393 // the usual case in ANSI-C.
394
395 const std::size_t fraction_width =
397
398 // Extend the fraction to dest_width if needed, padding with zeros
399 // at the LSB end (like float_utilst does).
400 exprt fraction = unpacked.fraction;
401 std::size_t effective_width = fraction_width;
402
403 if(dest_width > fraction_width)
404 {
405 effective_width = dest_width;
406 fraction = concatenation_exprt(
407 fraction,
408 from_integer(0, unsignedbv_typet(dest_width - fraction_width)),
409 unsignedbv_typet(effective_width));
410 }
411
412 // if the exponent is positive, shift right by (effective_width - 1) minus
413 // the exponent. The shift distance is built in a signed type wide enough to
414 // hold both `effective_width - 1` and the (sign-extended) exponent, so it
415 // does not wrap for wide destination types -- e.g. a narrow source such as
416 // _Float16 (spec.e = 5) converted to a 64-bit integer. Keep in sync with
417 // float_utilst::to_integer.
418 const signedbv_typet distance_type(std::max(
419 static_cast<std::size_t>(spec.e), address_bits(effective_width) + 1));
420 const exprt offset = from_integer(effective_width - 1, distance_type);
421 const minus_exprt distance(
422 offset, typecast_exprt(unpacked.exponent, distance_type));
423 const lshr_exprt shift_result(fraction, distance);
424
425 // if the exponent is negative, we have zero anyways
426 exprt result=shift_result;
427 const sign_exprt exponent_sign(unpacked.exponent);
428
429 result=
430 if_exprt(exponent_sign, from_integer(0, result.type()), result);
431
432 // chop out the right number of bits from the result
433 typet result_type=
434 is_signed?static_cast<typet>(signedbv_typet(dest_width)):
435 static_cast<typet>(unsignedbv_typet(dest_width));
436
437 result=typecast_exprt(result, result_type);
438
439 // if signed, apply sign.
440 if(is_signed)
441 {
442 result=if_exprt(
443 unpacked.sign, unary_minus_exprt(result), result);
444 }
445 else
446 {
447 // It's unclear what the behaviour for negative floats
448 // to integer shall be.
449 }
450
451 return result;
452}
453
455 const exprt &src,
456 const exprt &rm,
457 const ieee_float_spect &src_spec,
458 const ieee_float_spect &dest_spec) const
459{
460 // Catch the special case in which we extend,
461 // e.g. single to double.
462 // In this case, rounding can be avoided,
463 // but a denormal number may be come normal.
464 // Be careful to exclude the difficult case
465 // when denormalised numbers in the old format
466 // can be converted to denormalised numbers in the
467 // new format. Note that this is rare and will only
468 // happen with very non-standard formats.
469
470 int sourceSmallestNormalExponent = -((1 << (src_spec.e - 1)) - 1);
471 int sourceSmallestDenormalExponent =
472 sourceSmallestNormalExponent - src_spec.f;
473
474 // Using the fact that f doesn't include the hidden bit
475
476 int destSmallestNormalExponent = -((1 << (dest_spec.e - 1)) - 1);
477
478 if(dest_spec.e>=src_spec.e &&
479 dest_spec.f>=src_spec.f &&
480 !(sourceSmallestDenormalExponent < destSmallestNormalExponent))
481 {
482 unbiased_floatt unpacked_src=unpack(src, src_spec);
483 unbiased_floatt result;
484
485 // the fraction gets zero-padded
486 std::size_t padding=dest_spec.f-src_spec.f;
487 result.fraction=
489 unpacked_src.fraction,
490 from_integer(0, unsignedbv_typet(padding)),
491 unsignedbv_typet(dest_spec.f+1));
492
493 // the exponent gets sign-extended
494 INVARIANT(
495 unpacked_src.exponent.type().id() == ID_signedbv,
496 "the exponent needs to have a signed type");
497 result.exponent=
498 typecast_exprt(unpacked_src.exponent, signedbv_typet(dest_spec.e));
499
500 // if the number was denormal and is normal in the new format,
501 // normalise it!
502 if(dest_spec.e > src_spec.e)
503 {
504 normalization_shift(result.fraction, result.exponent);
505 // normalization_shift unconditionally extends the exponent size to avoid
506 // arithmetic overflow, but this cannot have happened here as the exponent
507 // had already been extended to dest_spec's size
508 result.exponent =
509 typecast_exprt(result.exponent, signedbv_typet(dest_spec.e));
510 }
511
512 // the flags get copied
513 result.sign=unpacked_src.sign;
514 result.NaN=unpacked_src.NaN;
515 result.infinity=unpacked_src.infinity;
516
517 // no rounding needed!
518 return pack(bias(result, dest_spec), dest_spec);
519 }
520 else
521 {
522 // we actually need to round
523 unbiased_floatt result=unpack(src, src_spec);
524 return rounder(result, rm, dest_spec);
525 }
526}
527
529 const exprt &src,
530 const ieee_float_spect &spec)
531{
532 return and_exprt(
533 not_exprt(exponent_all_zeros(src, spec)),
534 not_exprt(exponent_all_ones(src, spec)));
535}
536
539 const unbiased_floatt &src1,
540 const unbiased_floatt &src2)
541{
542 // extend both by one bit
543 std::size_t old_width1=to_signedbv_type(src1.exponent.type()).get_width();
544 std::size_t old_width2=to_signedbv_type(src2.exponent.type()).get_width();
545 PRECONDITION(old_width1 == old_width2);
546
547 const typecast_exprt extended_exponent1(
548 src1.exponent, signedbv_typet(old_width1 + 1));
549
550 const typecast_exprt extended_exponent2(
551 src2.exponent, signedbv_typet(old_width2 + 1));
552
553 // compute shift distance (here is the subtraction)
554 return minus_exprt(extended_exponent1, extended_exponent2);
555}
556
558 bool subtract,
559 const exprt &op0,
560 const exprt &op1,
561 const exprt &rm,
562 const ieee_float_spect &spec) const
563{
564 unbiased_floatt unpacked1=unpack(op0, spec);
565 unbiased_floatt unpacked2=unpack(op1, spec);
566
567 // subtract?
568 if(subtract)
569 unpacked2.sign=not_exprt(unpacked2.sign);
570
571 // figure out which operand has the bigger exponent
572 const exprt exponent_difference=subtract_exponents(unpacked1, unpacked2);
573 const sign_exprt src2_bigger(exponent_difference);
574
575 const exprt bigger_exponent=
576 if_exprt(src2_bigger, unpacked2.exponent, unpacked1.exponent);
577
578 // swap fractions as needed
579 const exprt new_fraction1=
580 if_exprt(src2_bigger, unpacked2.fraction, unpacked1.fraction);
581
582 const exprt new_fraction2=
583 if_exprt(src2_bigger, unpacked1.fraction, unpacked2.fraction);
584
585 // compute distance
586 const exprt distance=
587 typecast_exprt(abs_exprt(exponent_difference), unsignedbv_typet(spec.e));
588
589 // limit the distance: shifting more than f+3 bits is unnecessary
590 const exprt limited_dist=limit_distance(distance, spec.f+3);
591
592 // pad fractions with 3 zeros from below
593 exprt three_zeros=from_integer(0, unsignedbv_typet(3));
594 // add 4 to spec.f because unpacked new_fraction has the hidden bit
595 const exprt fraction1_padded=
596 concatenation_exprt(new_fraction1, three_zeros, unsignedbv_typet(spec.f+4));
597 const exprt fraction2_padded=
598 concatenation_exprt(new_fraction2, three_zeros, unsignedbv_typet(spec.f+4));
599
600 // shift new_fraction2
601 exprt sticky_bit;
602 const exprt fraction1_shifted=fraction1_padded;
603 const exprt fraction2_shifted=sticky_right_shift(
604 fraction2_padded, limited_dist, sticky_bit);
605
606 // sticky bit: 'or' of the bits lost by the right-shift
607 const bitor_exprt fraction2_stickied(
608 fraction2_shifted,
610 from_integer(0, unsignedbv_typet(spec.f + 3)),
611 sticky_bit,
612 fraction2_shifted.type()));
613
614 // need to have two extra fraction bits for addition and rounding
615 const exprt fraction1_ext=
616 typecast_exprt(fraction1_shifted, unsignedbv_typet(spec.f+4+2));
617 const exprt fraction2_ext=
618 typecast_exprt(fraction2_stickied, unsignedbv_typet(spec.f+4+2));
619
620 unbiased_floatt result;
621
622 // now add/sub them
623 const notequal_exprt subtract_lit(unpacked1.sign, unpacked2.sign);
624
625 result.fraction=
626 if_exprt(subtract_lit,
627 minus_exprt(fraction1_ext, fraction2_ext),
628 plus_exprt(fraction1_ext, fraction2_ext));
629
630 // sign of result
631 std::size_t width=to_bitvector_type(result.fraction.type()).get_width();
632 const sign_exprt fraction_sign(
633 typecast_exprt(result.fraction, signedbv_typet(width)));
634 result.fraction=
637 unsignedbv_typet(width));
638
639 result.exponent=bigger_exponent;
640
641 // adjust the exponent for the fact that we added two bits to the fraction
642 result.exponent=
644 from_integer(2, signedbv_typet(spec.e+1)));
645
646 // NaN?
647 result.NaN=or_exprt(
648 and_exprt(and_exprt(unpacked1.infinity, unpacked2.infinity),
649 notequal_exprt(unpacked1.sign, unpacked2.sign)),
650 or_exprt(unpacked1.NaN, unpacked2.NaN));
651
652 // infinity?
653 result.infinity=and_exprt(
654 not_exprt(result.NaN),
655 or_exprt(unpacked1.infinity, unpacked2.infinity));
656
657 // zero?
658 // Note that:
659 // 1. The zero flag isn't used apart from in divide and
660 // is only set on unpack
661 // 2. Subnormals mean that addition or subtraction can't round to 0,
662 // thus we can perform this test now
663 // 3. The rules for sign are different for zero
664 result.zero=
665 and_exprt(
666 not_exprt(or_exprt(result.infinity, result.NaN)),
668 result.fraction,
669 from_integer(0, result.fraction.type())));
670
671 // sign
672 const notequal_exprt add_sub_sign(
673 if_exprt(src2_bigger, unpacked2.sign, unpacked1.sign), fraction_sign);
674
675 const if_exprt infinity_sign(
676 unpacked1.infinity, unpacked1.sign, unpacked2.sign);
677
678 #if 1
679 rounding_mode_bitst rounding_mode_bits(rm);
680
681 const if_exprt zero_sign(
682 rounding_mode_bits.round_to_minus_inf,
683 or_exprt(unpacked1.sign, unpacked2.sign),
684 and_exprt(unpacked1.sign, unpacked2.sign));
685
686 result.sign=if_exprt(
687 result.infinity,
688 infinity_sign,
689 if_exprt(result.zero,
690 zero_sign,
691 add_sub_sign));
692 #else
693 result.sign=if_exprt(
694 result.infinity,
695 infinity_sign,
696 add_sub_sign);
697 #endif
698
699 return rounder(result, rm, spec);
700}
701
704 const exprt &dist,
705 mp_integer limit)
706{
707 std::size_t nb_bits = address_bits(limit);
708 std::size_t dist_width=to_unsignedbv_type(dist.type()).get_width();
709
710 if(dist_width<=nb_bits)
711 return dist;
712
713 const extractbits_exprt upper_bits(
714 dist, nb_bits, unsignedbv_typet(dist_width - nb_bits));
715 const equal_exprt upper_bits_zero(
716 upper_bits, from_integer(0, upper_bits.type()));
717
718 const extractbits_exprt lower_bits(dist, 0, unsignedbv_typet(nb_bits));
719
720 return if_exprt(
721 upper_bits_zero,
722 lower_bits,
723 unsignedbv_typet(nb_bits).largest_expr());
724}
725
727 const exprt &src1,
728 const exprt &src2,
729 const exprt &rm,
730 const ieee_float_spect &spec) const
731{
732 // unpack
733 const unbiased_floatt unpacked1=unpack(src1, spec);
734 const unbiased_floatt unpacked2=unpack(src2, spec);
735
736 // zero-extend the fractions (unpacked fraction has the hidden bit)
737 typet new_fraction_type=unsignedbv_typet((spec.f+1)*2);
738 const exprt fraction1 =
739 zero_extend_exprt{unpacked1.fraction, new_fraction_type};
740 const exprt fraction2 =
741 zero_extend_exprt{unpacked2.fraction, new_fraction_type};
742
743 // multiply the fractions
744 unbiased_floatt result;
745 result.fraction=mult_exprt(fraction1, fraction2);
746
747 // extend exponents to account for overflow
748 // add two bits, as we do extra arithmetic on it later
749 typet new_exponent_type=signedbv_typet(spec.e+2);
750 const exprt exponent1=typecast_exprt(unpacked1.exponent, new_exponent_type);
751 const exprt exponent2=typecast_exprt(unpacked2.exponent, new_exponent_type);
752
753 const plus_exprt added_exponent(exponent1, exponent2);
754
755 // Adjust exponent; we are thowing in an extra fraction bit,
756 // it has been extended above.
757 result.exponent=
758 plus_exprt(added_exponent, from_integer(1, new_exponent_type));
759
760 // new sign
761 result.sign=notequal_exprt(unpacked1.sign, unpacked2.sign);
762
763 // infinity?
764 result.infinity=or_exprt(unpacked1.infinity, unpacked2.infinity);
765
766 // NaN?
767 result.NaN = disjunction(
768 {isnan(src1, spec),
769 isnan(src2, spec),
770 // infinity * 0 is NaN!
771 and_exprt(unpacked1.zero, unpacked2.infinity),
772 and_exprt(unpacked2.zero, unpacked1.infinity)});
773
774 return rounder(result, rm, spec);
775}
776
778 const exprt &src1,
779 const exprt &src2,
780 const exprt &rm,
781 const ieee_float_spect &spec) const
782{
783 // unpack
784 const unbiased_floatt unpacked1=unpack(src1, spec);
785 const unbiased_floatt unpacked2=unpack(src2, spec);
786
787 std::size_t fraction_width=
789 std::size_t div_width=fraction_width*2+1;
790
791 // pad fraction1 with zeros
792 const concatenation_exprt fraction1(
793 unpacked1.fraction,
794 from_integer(0, unsignedbv_typet(div_width - fraction_width)),
795 unsignedbv_typet(div_width));
796
797 // zero-extend fraction2 to match fraction1
798 const zero_extend_exprt fraction2{unpacked2.fraction, fraction1.type()};
799
800 // divide fractions
801 unbiased_floatt result;
802 exprt rem;
803
804 // the below should be merged somehow
805 result.fraction=div_exprt(fraction1, fraction2);
806 rem=mod_exprt(fraction1, fraction2);
807
808 // is there a remainder?
809 const notequal_exprt have_remainder(rem, from_integer(0, rem.type()));
810
811 // we throw this into the result, as least-significant bit,
812 // to get the right rounding decision
813 result.fraction=
815 result.fraction, have_remainder, unsignedbv_typet(div_width+1));
816
817 // We will subtract the exponents;
818 // to account for overflow, we add a bit.
819 const typecast_exprt exponent1(
820 unpacked1.exponent, signedbv_typet(spec.e + 1));
821 const typecast_exprt exponent2(
822 unpacked2.exponent, signedbv_typet(spec.e + 1));
823
824 // subtract exponents
825 const minus_exprt added_exponent(exponent1, exponent2);
826
827 // adjust, as we have thown in extra fraction bits
828 result.exponent=plus_exprt(
829 added_exponent,
830 from_integer(spec.f, added_exponent.type()));
831
832 // new sign
833 result.sign=notequal_exprt(unpacked1.sign, unpacked2.sign);
834
835 // Infinity? This happens when
836 // 1) dividing a non-nan/non-zero by zero, or
837 // 2) first operand is inf and second is non-nan and non-zero
838 // In particular, inf/0=inf.
839 result.infinity=
840 or_exprt(
841 and_exprt(not_exprt(unpacked1.zero),
842 and_exprt(not_exprt(unpacked1.NaN),
843 unpacked2.zero)),
844 and_exprt(unpacked1.infinity,
845 and_exprt(not_exprt(unpacked2.NaN),
846 not_exprt(unpacked2.zero))));
847
848 // NaN?
849 result.NaN=or_exprt(unpacked1.NaN,
850 or_exprt(unpacked2.NaN,
851 or_exprt(and_exprt(unpacked1.zero, unpacked2.zero),
852 and_exprt(unpacked1.infinity, unpacked2.infinity))));
853
854 // Division by infinity produces zero, unless we have NaN
855 const and_exprt force_zero(not_exprt(unpacked1.NaN), unpacked2.infinity);
856
857 result.fraction=
858 if_exprt(
859 force_zero,
860 from_integer(0, result.fraction.type()),
861 result.fraction);
862
863 return rounder(result, rm, spec);
864}
865
867 const exprt &multiply_lhs,
868 const exprt &multiply_rhs,
869 const exprt &addend,
870 const exprt &rm,
871 const ieee_float_spect &spec) const
872{
873 // Fused multiply-add: round(multiply_lhs * multiply_rhs + addend) with single
874 // rounding. Multiply at double width (exact), add at double width (exact),
875 // then round once.
876
877 const unbiased_floatt unpacked_lhs = unpack(multiply_lhs, spec);
878 const unbiased_floatt unpacked_rhs = unpack(multiply_rhs, spec);
879 const unbiased_floatt unpacked_add = unpack(addend, spec);
880
881 const std::size_t frac_size = spec.f + 1;
882 const std::size_t prod_width = frac_size * 2;
883 const typet prod_frac_type = unsignedbv_typet(prod_width);
884
885 // Exact product: multiply fractions at double width
886 const exprt fraction1 =
887 zero_extend_exprt{unpacked_lhs.fraction, prod_frac_type};
888 const exprt fraction2 =
889 zero_extend_exprt{unpacked_rhs.fraction, prod_frac_type};
890 exprt prod_fraction = mult_exprt(fraction1, fraction2);
891
892 const typet wide_exp_type = signedbv_typet(spec.e + 2);
893 exprt prod_exponent = plus_exprt(
894 typecast_exprt(unpacked_lhs.exponent, wide_exp_type),
895 typecast_exprt(unpacked_rhs.exponent, wide_exp_type));
896 prod_exponent = plus_exprt(prod_exponent, from_integer(1, wide_exp_type));
897
898 // When either multiplicand is zero, the product fraction is all zeros
899 // but prod_exponent is still the sum of the operand exponents, which can
900 // be very large. During alignment the addend would then be treated as
901 // the smaller operand and shifted out, losing its bits. Force
902 // prod_exponent to the minimum representable value in that case so the
903 // addend always dominates.
904 exprt product_is_zero = or_exprt{unpacked_lhs.zero, unpacked_rhs.zero};
905 prod_exponent = if_exprt{
906 product_is_zero,
907 from_integer(-(mp_integer(1) << (spec.e)), wide_exp_type),
908 prod_exponent};
909
910 exprt prod_sign = notequal_exprt(unpacked_lhs.sign, unpacked_rhs.sign);
911
912 // Align addend fraction to product width (pad on the right)
913 const std::size_t c_pad = prod_width - frac_size;
914 exprt c_fraction = concatenation_exprt(
915 unpacked_add.fraction,
917 prod_frac_type);
918 exprt c_exponent = typecast_exprt(unpacked_add.exponent, wide_exp_type);
919
920 // Add product + c: align fractions by exponent difference
921 exprt exp_diff = minus_exprt(prod_exponent, c_exponent);
922 exprt c_bigger = sign_exprt(exp_diff);
923
924 exprt bigger_exp = if_exprt(c_bigger, c_exponent, prod_exponent);
925 exprt big_frac = if_exprt(c_bigger, c_fraction, prod_fraction);
926 exprt small_frac = if_exprt(c_bigger, prod_fraction, c_fraction);
927
928 exprt distance =
929 typecast_exprt(abs_exprt(exp_diff), unsignedbv_typet(spec.e + 2));
930 exprt limited_dist = limit_distance(distance, prod_width + 3);
931
932 // Pad with 3 guard bits
933 const typet padded_type = unsignedbv_typet(prod_width + 3);
934 exprt big_padded = concatenation_exprt(
935 big_frac, from_integer(0, unsignedbv_typet(3)), padded_type);
936 exprt small_padded = concatenation_exprt(
937 small_frac, from_integer(0, unsignedbv_typet(3)), padded_type);
938
939 // Shift smaller fraction right, tracking sticky bit
940 exprt sticky_bit;
941 exprt small_shifted =
942 sticky_right_shift(small_padded, limited_dist, sticky_bit);
943 small_shifted =
944 bitor_exprt(small_shifted, typecast_exprt(sticky_bit, padded_type));
945
946 // Extend for potential carry/borrow
947 const typet sum_type = unsignedbv_typet(prod_width + 5);
948 exprt big_ext = zero_extend_exprt{big_padded, sum_type};
949 exprt small_ext = zero_extend_exprt{small_shifted, sum_type};
950
951 // Add or subtract based on signs
952 exprt subtract_lit = notequal_exprt(prod_sign, unpacked_add.sign);
953 exprt sum = if_exprt(
954 subtract_lit,
955 minus_exprt(big_ext, small_ext),
956 plus_exprt(big_ext, small_ext));
957
958 // Handle negative result (from subtraction)
959 exprt fraction_sign =
960 sign_exprt(typecast_exprt(sum, signedbv_typet(prod_width + 5)));
961 sum = if_exprt(
962 fraction_sign,
963 unary_minus_exprt(typecast_exprt(sum, signedbv_typet(prod_width + 5))),
964 typecast_exprt(sum, signedbv_typet(prod_width + 5)));
965 sum = typecast_exprt(sum, sum_type);
966
967 unbiased_floatt result;
968 result.fraction = sum;
969 result.exponent = plus_exprt(
970 typecast_exprt(bigger_exp, signedbv_typet(spec.e + 3)),
971 from_integer(2, signedbv_typet(spec.e + 3)));
972
973 // NaN
974 exprt prod_inf = or_exprt(unpacked_lhs.infinity, unpacked_rhs.infinity);
975 result.NaN = disjunction(
976 {isnan(multiply_lhs, spec),
977 isnan(multiply_rhs, spec),
978 isnan(addend, spec),
979 and_exprt(unpacked_lhs.zero, unpacked_rhs.infinity),
980 and_exprt(unpacked_rhs.zero, unpacked_lhs.infinity),
981 and_exprt(
982 and_exprt(prod_inf, unpacked_add.infinity),
983 notequal_exprt(prod_sign, unpacked_add.sign))});
984
985 // Infinity
986 result.infinity =
987 and_exprt(not_exprt(result.NaN), or_exprt(prod_inf, unpacked_add.infinity));
988
989 // An exact zero result: as in add_sub, this can be decided before rounding.
990 result.zero = and_exprt{
991 not_exprt{or_exprt{result.infinity, result.NaN}},
992 equal_exprt{result.fraction, from_integer(0, result.fraction.type())}};
993
994 // Sign. As for addition, an infinite result takes the sign of the infinite
995 // operand, and an exact zero result is negative only if both the product
996 // and the addend are, or, when rounding towards minus infinity, if either
997 // of them is.
998 exprt add_sub_sign = notequal_exprt(
999 if_exprt(c_bigger, unpacked_add.sign, prod_sign), fraction_sign);
1000 exprt infinity_sign = if_exprt{prod_inf, prod_sign, unpacked_add.sign};
1001 rounding_mode_bitst rounding_mode_bits{rm};
1002 exprt zero_sign = if_exprt{
1003 rounding_mode_bits.round_to_minus_inf,
1004 or_exprt{prod_sign, unpacked_add.sign},
1005 and_exprt{prod_sign, unpacked_add.sign}};
1006 result.sign = if_exprt{
1007 result.infinity,
1008 infinity_sign,
1009 if_exprt{result.zero, zero_sign, add_sub_sign}};
1010
1011 return rounder(result, rm, spec);
1012}
1013
1015 const exprt &src1,
1016 relt rel,
1017 const exprt &src2,
1018 const ieee_float_spect &spec)
1019{
1020 if(rel==relt::GT)
1021 return relation(src2, relt::LT, src1, spec); // swapped
1022 else if(rel==relt::GE)
1023 return relation(src2, relt::LE, src1, spec); // swapped
1024
1025 INVARIANT(
1026 rel == relt::EQ || rel == relt::LT || rel == relt::LE,
1027 "relation should be equality, less-than, or less-or-equal");
1028
1029 // special cases: -0 and 0 are equal
1030 const exprt is_zero1 = is_zero(src1);
1031 const exprt is_zero2 = is_zero(src2);
1032 const and_exprt both_zero(is_zero1, is_zero2);
1033
1034 // NaN compares to nothing
1035 exprt isnan1=isnan(src1, spec);
1036 exprt isnan2=isnan(src2, spec);
1037 const or_exprt nan(isnan1, isnan2);
1038
1039 if(rel==relt::LT || rel==relt::LE)
1040 {
1041 const equal_exprt bitwise_equal(src1, src2);
1042
1043 // signs different? trivial! Unless Zero.
1044
1045 const notequal_exprt signs_different(sign_bit(src1), sign_bit(src2));
1046
1047 // as long as the signs match: compare like unsigned numbers
1048
1049 // this works due to the BIAS
1050 const binary_relation_exprt less_than1(
1052 typecast_exprt(src1, bv_typet(spec.width())),
1053 unsignedbv_typet(spec.width())),
1054 ID_lt,
1056 typecast_exprt(src2, bv_typet(spec.width())),
1057 unsignedbv_typet(spec.width())));
1058
1059 // if both are negative (and not the same), need to turn around!
1060 const notequal_exprt less_than2(
1061 less_than1, and_exprt(sign_bit(src1), sign_bit(src2)));
1062
1063 const if_exprt less_than3(signs_different, sign_bit(src1), less_than2);
1064
1065 if(rel==relt::LT)
1066 {
1067 and_exprt and_bv{{less_than3,
1068 // for the case of two negative numbers
1069 not_exprt(bitwise_equal),
1070 not_exprt(both_zero),
1071 not_exprt(nan)}};
1072
1073 return std::move(and_bv);
1074 }
1075 else if(rel==relt::LE)
1076 {
1077 or_exprt or_bv{{less_than3, both_zero, bitwise_equal}};
1078
1079 return and_exprt(or_bv, not_exprt(nan));
1080 }
1081 else
1083 }
1084 else if(rel==relt::EQ)
1085 {
1086 const equal_exprt bitwise_equal(src1, src2);
1087
1088 return and_exprt(
1089 or_exprt(bitwise_equal, both_zero),
1090 not_exprt(nan));
1091 }
1092
1094 return false_exprt();
1095}
1096
1098 const exprt &src,
1099 const ieee_float_spect &spec)
1100{
1101 return and_exprt(
1102 exponent_all_ones(src, spec),
1103 fraction_all_zeros(src, spec));
1104}
1105
1107 const exprt &src,
1108 const ieee_float_spect &spec)
1109{
1110 return not_exprt(or_exprt(isinf(src, spec), isnan(src, spec)));
1111}
1112
1115 const exprt &src,
1116 const ieee_float_spect &spec)
1117{
1118 return extractbits_exprt(src, spec.f, unsignedbv_typet(spec.e));
1119}
1120
1123 const exprt &src,
1124 const ieee_float_spect &spec)
1125{
1126 return extractbits_exprt(src, 0, unsignedbv_typet(spec.f));
1127}
1128
1130 const exprt &src,
1131 const ieee_float_spect &spec)
1132{
1133 return and_exprt(exponent_all_ones(src, spec),
1134 not_exprt(fraction_all_zeros(src, spec)));
1135}
1136
1139 exprt &fraction,
1140 exprt &exponent)
1141{
1142 // n-log-n alignment shifter.
1143 // The worst-case shift is the number of fraction
1144 // bits minus one, in case the fraction is one exactly.
1145 std::size_t fraction_bits=to_unsignedbv_type(fraction.type()).get_width();
1146 std::size_t exponent_bits=to_signedbv_type(exponent.type()).get_width();
1147 PRECONDITION(fraction_bits != 0);
1148
1149 std::size_t depth = address_bits(fraction_bits - 1);
1150
1151 exponent = typecast_exprt(
1152 exponent, signedbv_typet(std::max(depth, exponent_bits + 1)));
1153
1154 exprt exponent_delta=from_integer(0, exponent.type());
1155
1156 for(int d=depth-1; d>=0; d--)
1157 {
1158 unsigned distance=(1<<d);
1159 INVARIANT(
1160 fraction_bits > distance,
1161 "distance must be within the range of fraction bits");
1162
1163 // check if first 'distance'-many bits are zeros
1164 const extractbits_exprt prefix(
1165 fraction, fraction_bits - distance, unsignedbv_typet(distance));
1166 const equal_exprt prefix_is_zero(prefix, from_integer(0, prefix.type()));
1167
1168 // If so, shift the zeros out left by 'distance'.
1169 // Otherwise, leave as is.
1170 const shl_exprt shifted(fraction, distance);
1171
1172 fraction=
1173 if_exprt(prefix_is_zero, shifted, fraction);
1174
1175 // add corresponding weight to exponent
1176 INVARIANT(
1177 d < (signed int)exponent_bits,
1178 "depth must be smaller than exponent bits");
1179
1180 exponent_delta=
1181 bitor_exprt(exponent_delta,
1182 shl_exprt(typecast_exprt(prefix_is_zero, exponent_delta.type()), d));
1183 }
1184
1185 exponent=minus_exprt(exponent, exponent_delta);
1186}
1187
1190 exprt &fraction,
1191 exprt &exponent,
1192 const ieee_float_spect &spec)
1193{
1194 mp_integer bias=spec.bias();
1195
1196 // Is the exponent strictly less than -bias+1, i.e., exponent<-bias+1?
1197 // This is transformed to distance=(-bias+1)-exponent
1198 // i.e., distance>0
1199 // Note that 1-bias is the exponent represented by 0...01,
1200 // i.e. the exponent of the smallest normal number and thus the 'base'
1201 // exponent for subnormal numbers.
1202
1203 std::size_t exponent_bits=to_signedbv_type(exponent.type()).get_width();
1204 PRECONDITION(exponent_bits >= spec.e);
1205
1206#if 1
1207 // Need to sign extend to avoid overflow. Note that this is a
1208 // relatively rare problem as the value needs to be close to the top
1209 // of the exponent range and then range must not have been
1210 // previously extended as add, multiply, etc. do. This is primarily
1211 // to handle casting down from larger ranges.
1212 exponent=typecast_exprt(exponent, signedbv_typet(exponent_bits+1));
1213#endif
1214
1215 const minus_exprt distance(
1216 from_integer(-bias + 1, exponent.type()), exponent);
1217
1218 // use sign bit
1219 const and_exprt denormal(
1220 not_exprt(sign_exprt(distance)),
1221 notequal_exprt(distance, from_integer(0, distance.type())));
1222
1223#if 1
1224 // Care must be taken to not loose information required for the
1225 // guard and sticky bits. +3 is for the hidden, guard and sticky bits.
1226 std::size_t fraction_bits=to_unsignedbv_type(fraction.type()).get_width();
1227
1228 if(fraction_bits < spec.f+3)
1229 {
1230 // Add zeros at the LSB end for the guard bit to shift into
1231 fraction=
1233 fraction, unsignedbv_typet(spec.f + 3 - fraction_bits).zero_expr(),
1234 unsignedbv_typet(spec.f+3));
1235 }
1236
1237 exprt denormalisedFraction = fraction;
1238
1239 exprt sticky_bit = false_exprt();
1240 denormalisedFraction =
1241 sticky_right_shift(fraction, distance, sticky_bit);
1242
1243 denormalisedFraction=
1244 bitor_exprt(denormalisedFraction,
1245 typecast_exprt(sticky_bit, denormalisedFraction.type()));
1246
1247 fraction=
1248 if_exprt(
1249 denormal,
1250 denormalisedFraction,
1251 fraction);
1252
1253#else
1254 fraction=
1255 if_exprt(
1256 denormal,
1257 lshr_exprt(fraction, distance),
1258 fraction);
1259#endif
1260
1261 exponent=
1262 if_exprt(denormal,
1263 from_integer(-bias, exponent.type()),
1264 exponent);
1265}
1266
1268 const unbiased_floatt &src,
1269 const exprt &rm,
1270 const ieee_float_spect &spec) const
1271{
1272 // incoming: some fraction (with explicit 1),
1273 // some exponent without bias
1274 // outgoing: rounded, with right size, with hidden bit, bias
1275
1276 exprt aligned_fraction=src.fraction,
1277 aligned_exponent=src.exponent;
1278
1279 {
1280 std::size_t exponent_bits = std::max(address_bits(spec.f), spec.e) + 1;
1281
1282 // before normalization, make sure exponent is large enough
1283 if(to_signedbv_type(aligned_exponent.type()).get_width()<exponent_bits)
1284 {
1285 // sign extend
1286 aligned_exponent=
1287 typecast_exprt(aligned_exponent, signedbv_typet(exponent_bits));
1288 }
1289 }
1290
1291 // align it!
1292 normalization_shift(aligned_fraction, aligned_exponent);
1293 denormalization_shift(aligned_fraction, aligned_exponent, spec);
1294
1295 unbiased_floatt result;
1296 result.fraction=aligned_fraction;
1297 result.exponent=aligned_exponent;
1298 result.sign=src.sign;
1299 result.NaN=src.NaN;
1300 result.infinity=src.infinity;
1301
1302 rounding_mode_bitst rounding_mode_bits(rm);
1303 round_fraction(result, rounding_mode_bits, spec);
1304 round_exponent(result, rounding_mode_bits, spec);
1305
1306 return pack(bias(result, spec), spec);
1307}
1308
1311 const std::size_t dest_bits,
1312 const exprt sign,
1313 const exprt &fraction,
1314 const rounding_mode_bitst &rounding_mode_bits)
1315{
1316 std::size_t fraction_bits=
1317 to_unsignedbv_type(fraction.type()).get_width();
1318
1319 PRECONDITION(dest_bits < fraction_bits);
1320
1321 // we have too many fraction bits
1322 std::size_t extra_bits=fraction_bits-dest_bits;
1323
1324 // more than two extra bits are superflus, and are
1325 // turned into a sticky bit
1326
1327 exprt sticky_bit=false_exprt();
1328
1329 if(extra_bits>=2)
1330 {
1331 // We keep most-significant bits, and thus the tail is made
1332 // of least-significant bits.
1333 const extractbits_exprt tail(
1334 fraction, 0, unsignedbv_typet(extra_bits - 2 + 1));
1335 sticky_bit=notequal_exprt(tail, from_integer(0, tail.type()));
1336 }
1337
1338 // the rounding bit is the last extra bit
1339 INVARIANT(
1340 extra_bits >= 1, "the extra bits contain at least the rounding bit");
1341 const extractbit_exprt rounding_bit(fraction, extra_bits - 1);
1342
1343 // we get one bit of the fraction for some rounding decisions
1344 const extractbit_exprt rounding_least(fraction, extra_bits);
1345
1346 // round-to-nearest (ties to even)
1347 const and_exprt round_to_even(
1348 rounding_bit, or_exprt(rounding_least, sticky_bit));
1349
1350 // round up
1351 const and_exprt round_to_plus_inf(
1352 not_exprt(sign), or_exprt(rounding_bit, sticky_bit));
1353
1354 // round down
1355 const and_exprt round_to_minus_inf(sign, or_exprt(rounding_bit, sticky_bit));
1356
1357 // round to zero
1358 false_exprt round_to_zero;
1359
1360 // round-to-nearest (ties to away)
1361 const auto round_to_away = rounding_bit;
1362
1363 // now select appropriate one
1364 // clang-format off
1365 return if_exprt(rounding_mode_bits.round_to_even, round_to_even,
1366 if_exprt(rounding_mode_bits.round_to_plus_inf, round_to_plus_inf,
1367 if_exprt(rounding_mode_bits.round_to_minus_inf, round_to_minus_inf,
1368 if_exprt(rounding_mode_bits.round_to_zero, round_to_zero,
1369 if_exprt(rounding_mode_bits.round_to_away, round_to_away,
1370 false_exprt()))))); // otherwise zero
1371 // clang-format off
1372}
1373
1375 unbiased_floatt &result,
1376 const rounding_mode_bitst &rounding_mode_bits,
1377 const ieee_float_spect &spec)
1378{
1379 std::size_t fraction_size=spec.f+1;
1380 std::size_t result_fraction_size=
1382
1383 // do we need to enlarge the fraction?
1384 if(result_fraction_size<fraction_size)
1385 {
1386 // pad with zeros at bottom
1387 std::size_t padding=fraction_size-result_fraction_size;
1388
1390 result.fraction,
1391 unsignedbv_typet(padding).zero_expr(),
1392 unsignedbv_typet(fraction_size));
1393 }
1394 else if(result_fraction_size==fraction_size) // it stays
1395 {
1396 // do nothing
1397 }
1398 else // fraction gets smaller -- rounding
1399 {
1400 std::size_t extra_bits=result_fraction_size-fraction_size;
1401 INVARIANT(
1402 extra_bits >= 1, "the extra bits include at least the rounding bit");
1403
1404 // this computes the rounding decision
1406 fraction_size, result.sign, result.fraction, rounding_mode_bits);
1407
1408 // chop off all the extra bits
1409 result.fraction = extractbits_exprt(
1410 result.fraction, extra_bits, unsignedbv_typet(fraction_size));
1411
1412#if 0
1413 // *** does not catch when the overflow goes subnormal -> normal ***
1414 // incrementing the fraction might result in an overflow
1415 result.fraction=
1416 bv_utils.zero_extension(result.fraction, result.fraction.size()+1);
1417
1418 result.fraction=bv_utils.incrementer(result.fraction, increment);
1419
1420 exprt overflow=result.fraction.back();
1421
1422 // In case of an overflow, the exponent has to be incremented.
1423 // "Post normalization" is then required.
1424 result.exponent=
1425 bv_utils.incrementer(result.exponent, overflow);
1426
1427 // post normalization of the fraction
1428 exprt integer_part1=result.fraction.back();
1429 exprt integer_part0=result.fraction[result.fraction.size()-2];
1430 const or_exprt new_integer_part(integer_part1, integer_part0);
1431
1432 result.fraction.resize(result.fraction.size()-1);
1433 result.fraction.back()=new_integer_part;
1434
1435#else
1436 // When incrementing due to rounding there are two edge
1437 // cases we need to be aware of:
1438 // 1. If the number is normal, the increment can overflow.
1439 // In this case we need to increment the exponent and
1440 // set the MSB of the fraction to 1.
1441 // 2. If the number is the largest subnormal, the increment
1442 // can change the MSB making it normal. Thus the exponent
1443 // must be incremented but the fraction will be OK.
1444 const extractbit_exprt old_msb(result.fraction, fraction_size - 1);
1445
1446 // increment if 'increment' is true
1447 result.fraction=
1448 plus_exprt(result.fraction,
1449 typecast_exprt(increment, result.fraction.type()));
1450
1451 // Normal overflow when old MSB == 1 and new MSB == 0
1452 const extractbit_exprt new_msb(result.fraction, fraction_size - 1);
1453 const and_exprt overflow(old_msb, not_exprt(new_msb));
1454
1455 // Subnormal to normal transition when old MSB == 0 and new MSB == 1
1456 const and_exprt subnormal_to_normal(not_exprt(old_msb), new_msb);
1457
1458 // In case of an overflow or subnormal to normal conversion,
1459 // the exponent has to be incremented.
1460 result.exponent=
1461 plus_exprt(
1462 result.exponent,
1463 if_exprt(
1464 or_exprt(overflow, subnormal_to_normal),
1465 from_integer(1, result.exponent.type()),
1466 from_integer(0, result.exponent.type())));
1467
1468 // post normalization of the fraction
1469 // In the case of overflow, set the MSB to 1
1470 // The subnormal case will have (only) the MSB set to 1
1471 result.fraction=bitor_exprt(
1472 result.fraction,
1473 if_exprt(overflow,
1474 from_integer(1<<(fraction_size-1), result.fraction.type()),
1475 from_integer(0, result.fraction.type())));
1476#endif
1477 }
1478}
1479
1481 unbiased_floatt &result,
1482 const rounding_mode_bitst &rounding_mode_bits,
1483 const ieee_float_spect &spec)
1484{
1485 std::size_t result_exponent_size=
1487
1488 PRECONDITION(result_exponent_size >= spec.e);
1489
1490 // do we need to enlarge the exponent?
1491 if(result_exponent_size == spec.e) // it stays
1492 {
1493 // do nothing
1494 }
1495 else // exponent gets smaller -- chop off top bits
1496 {
1497 exprt old_exponent=result.exponent;
1498 result.exponent =
1499 extractbits_exprt(result.exponent, 0, signedbv_typet(spec.e));
1500
1501 // max_exponent is the maximum representable
1502 // i.e. 1 higher than the maximum possible for a normal number
1503 exprt max_exponent=
1505 spec.max_exponent()-spec.bias(), old_exponent.type());
1506
1507 // the exponent is garbage if the fractional is zero
1508
1509 const and_exprt exponent_too_large(
1510 binary_relation_exprt(old_exponent, ID_ge, max_exponent),
1511 notequal_exprt(result.fraction, from_integer(0, result.fraction.type())));
1512
1513#if 1
1514 // Directed rounding modes round overflow to the maximum normal
1515 // depending on the particular mode and the sign
1516 const or_exprt overflow_to_inf(
1517 rounding_mode_bits.round_to_even,
1518 or_exprt(
1519 and_exprt(rounding_mode_bits.round_to_plus_inf, not_exprt(result.sign)),
1520 and_exprt(rounding_mode_bits.round_to_minus_inf, result.sign)));
1521
1522 const and_exprt set_to_max(exponent_too_large, not_exprt(overflow_to_inf));
1523
1524 exprt largest_normal_exponent=
1526 spec.max_exponent()-(spec.bias() + 1), result.exponent.type());
1527
1528 result.exponent=
1529 if_exprt(set_to_max, largest_normal_exponent, result.exponent);
1530
1531 result.fraction=
1532 if_exprt(set_to_max,
1534 result.fraction);
1535
1536 result.infinity=or_exprt(result.infinity,
1537 and_exprt(exponent_too_large,
1538 overflow_to_inf));
1539#else
1540 result.infinity=or_exprt(result.infinity, exponent_too_large);
1541#endif
1542 }
1543}
1544
1547 const unbiased_floatt &src,
1548 const ieee_float_spect &spec)
1549{
1550 biased_floatt result;
1551
1552 result.sign=src.sign;
1553 result.NaN=src.NaN;
1554 result.infinity=src.infinity;
1555
1556 // we need to bias the new exponent
1557 result.exponent=add_bias(src.exponent, spec);
1558
1559 // strip off the hidden bit
1561 to_unsignedbv_type(src.fraction.type()).get_width() == spec.f + 1);
1562
1563 const extractbit_exprt hidden_bit(src.fraction, spec.f);
1564 const not_exprt denormal(hidden_bit);
1565
1566 result.fraction =
1568
1569 // make exponent zero if its denormal
1570 // (includes zero)
1571 result.exponent=
1572 if_exprt(denormal, from_integer(0, result.exponent.type()),
1573 result.exponent);
1574
1575 return result;
1576}
1577
1579 const exprt &src,
1580 const ieee_float_spect &spec)
1581{
1582 typet t=unsignedbv_typet(spec.e);
1583 return plus_exprt(
1584 typecast_exprt(src, t),
1585 from_integer(spec.bias(), t));
1586}
1587
1589 const exprt &src,
1590 const ieee_float_spect &spec)
1591{
1592 typet t=signedbv_typet(spec.e);
1593 return minus_exprt(
1594 typecast_exprt(src, t),
1595 from_integer(spec.bias(), t));
1596}
1597
1599 const exprt &src,
1600 const ieee_float_spect &spec)
1601{
1602 unbiased_floatt result;
1603
1604 result.sign=sign_bit(src);
1605
1606 result.fraction=get_fraction(src, spec);
1607
1608 // add hidden bit
1609 exprt hidden_bit=isnormal(src, spec);
1610 result.fraction=
1611 concatenation_exprt(hidden_bit, result.fraction,
1612 unsignedbv_typet(spec.f+1));
1613
1614 result.exponent=get_exponent(src, spec);
1615
1616 // unbias the exponent
1617 exprt denormal=exponent_all_zeros(src, spec);
1618
1619 result.exponent=
1620 if_exprt(denormal,
1621 from_integer(-spec.bias()+1, signedbv_typet(spec.e)),
1622 sub_bias(result.exponent, spec));
1623
1624 result.infinity=isinf(src, spec);
1625 result.zero = is_zero(src);
1626 result.NaN=isnan(src, spec);
1627
1628 return result;
1629}
1630
1632 const biased_floatt &src,
1633 const ieee_float_spect &spec)
1634{
1637
1638 // do sign -- we make this 'false' for NaN
1639 const if_exprt sign_bit(src.NaN, false_exprt(), src.sign);
1640
1641 // the fraction is zero in case of infinity,
1642 // and one in case of NaN
1643 const if_exprt fraction(
1644 src.NaN,
1645 from_integer(1, src.fraction.type()),
1646 if_exprt(src.infinity, from_integer(0, src.fraction.type()), src.fraction));
1647
1648 const or_exprt infinity_or_NaN(src.NaN, src.infinity);
1649
1650 // do exponent
1651 const if_exprt exponent(
1652 infinity_or_NaN, from_integer(-1, src.exponent.type()), src.exponent);
1653
1654 // stitch all three together
1655 return typecast_exprt(
1657 {std::move(sign_bit), std::move(exponent), std::move(fraction)},
1658 bv_typet(spec.f + spec.e + 1)),
1659 spec.to_type());
1660}
1661
1663 const exprt &op,
1664 const exprt &dist,
1665 exprt &sticky)
1666{
1667 std::size_t d=1, width=to_unsignedbv_type(op.type()).get_width();
1668 exprt result=op;
1669 sticky=false_exprt();
1670
1671 std::size_t dist_width=to_bitvector_type(dist.type()).get_width();
1672
1673 for(std::size_t stage=0; stage<dist_width; stage++)
1674 {
1675 const lshr_exprt tmp(result, d);
1676
1677 exprt lost_bits;
1678
1679 if(d<=width)
1680 lost_bits = extractbits_exprt(result, 0, unsignedbv_typet(d));
1681 else
1682 lost_bits=result;
1683
1684 const extractbit_exprt dist_bit(dist, stage);
1685
1686 sticky=
1687 or_exprt(
1688 and_exprt(
1689 dist_bit,
1690 notequal_exprt(lost_bits, from_integer(0, lost_bits.type()))),
1691 sticky);
1692
1693 result=if_exprt(dist_bit, tmp, result);
1694
1695 d=d<<1;
1696 }
1697
1698 return result;
1699}
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.
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.
const floatbv_typet & to_floatbv_type(const typet &type)
Cast a typet to a floatbv_typet.
const unsignedbv_typet & to_unsignedbv_type(const typet &type)
Cast a typet to an unsignedbv_typet.
const signedbv_typet & to_signedbv_type(const typet &type)
Cast a typet to a signedbv_typet.
Absolute value.
Definition std_expr.h:440
Boolean AND All operands must be boolean, and the result is always boolean.
Definition std_expr.h:2043
A base class for relations, i.e., binary predicates whose two operands have the same type.
Definition std_expr.h:784
Bit-wise AND Any number of operands that is greater or equal one.
Bit-wise OR Any number of operands that is greater or equal one.
Base class of fixed-width bit-vector types.
std::size_t get_width() const
Bit-wise XOR Any number of operands that is greater or equal one.
Fixed-width bit-vector without numerical interpretation.
Concatenation of bit-vector operands.
A constant literal expression.
Definition std_expr.h:3007
Division.
Definition std_expr.h:1152
Equality.
Definition std_expr.h:1339
Base class for all expressions.
Definition expr.h:57
bool is_boolean() const
Return whether the expression represents a Boolean.
Definition expr.h:229
typet & type()
Return the type of the expression.
Definition expr.h:85
Extracts a single bit of a bit-vector operand.
Extracts a sub-range of a bit-vector operand.
The Boolean constant false.
Definition std_expr.h:3135
static unbiased_floatt unpack(const exprt &, const ieee_float_spect &)
static void normalization_shift(exprt &fraction, exprt &exponent)
normalize fraction/exponent pair returns 'zero' if fraction is zero
static exprt get_fraction(const exprt &, const ieee_float_spect &)
Gets the fraction without hidden bit in a floating-point bit-vector src.
static exprt sub_bias(const exprt &exponent, const ieee_float_spect &)
static exprt exponent_all_ones(const exprt &, const ieee_float_spect &)
Definition float_bv.cpp:260
static exprt to_integer(const exprt &src, std::size_t dest_width, bool is_signed, const exprt &rm, const ieee_float_spect &)
Definition float_bv.cpp:377
exprt from_unsigned_integer(const exprt &, const exprt &rm, const ieee_float_spect &) const
Definition float_bv.cpp:337
static exprt isfinite(const exprt &, const ieee_float_spect &)
static exprt isnormal(const exprt &, const ieee_float_spect &)
Definition float_bv.cpp:528
exprt from_signed_integer(const exprt &, const exprt &rm, const ieee_float_spect &) const
Definition float_bv.cpp:313
exprt add_sub(bool subtract, const exprt &, const exprt &, const exprt &rm, const ieee_float_spect &) const
Definition float_bv.cpp:557
static exprt is_zero(const exprt &)
Definition float_bv.cpp:244
static exprt abs(const exprt &, const ieee_float_spect &)
Definition float_bv.cpp:202
static void round_fraction(unbiased_floatt &result, const rounding_mode_bitst &, const ieee_float_spect &)
static exprt fraction_rounding_decision(const std::size_t dest_bits, const exprt sign, const exprt &fraction, const rounding_mode_bitst &)
rounding decision for fraction using sticky bit
exprt conversion(const exprt &src, const exprt &rm, const ieee_float_spect &src_spec, const ieee_float_spect &dest_spec) const
Definition float_bv.cpp:454
static exprt isnan(const exprt &, const ieee_float_spect &)
static biased_floatt bias(const unbiased_floatt &, const ieee_float_spect &)
takes an unbiased float, and applies the bias
static exprt get_exponent(const exprt &, const ieee_float_spect &)
Gets the unbiased exponent in a floating-point bit-vector.
static void denormalization_shift(exprt &fraction, exprt &exponent, const ieee_float_spect &)
make sure exponent is not too small; the exponent is unbiased
static exprt add_bias(const exprt &exponent, const ieee_float_spect &)
static exprt sticky_right_shift(const exprt &op, const exprt &dist, exprt &sticky)
exprt rounder(const unbiased_floatt &, const exprt &rm, const ieee_float_spect &) const
exprt fma(const exprt &multiply_lhs, const exprt &multiply_rhs, const exprt &addend, const exprt &rm, const ieee_float_spect &) const
Fused multiply-add: round(multiply_lhs * multiply_rhs + addend) with a single rounding step.
Definition float_bv.cpp:866
static exprt subtract_exponents(const unbiased_floatt &src1, const unbiased_floatt &src2)
Subtracts the exponents.
Definition float_bv.cpp:538
exprt div(const exprt &, const exprt &, const exprt &rm, const ieee_float_spect &) const
Definition float_bv.cpp:777
exprt convert(const exprt &) const
Definition float_bv.cpp:19
static ieee_float_spect get_spec(const exprt &)
Definition float_bv.cpp:196
static exprt to_unsigned_integer(const exprt &src, std::size_t dest_width, const exprt &rm, const ieee_float_spect &)
Definition float_bv.cpp:368
static exprt negation(const exprt &, const ieee_float_spect &)
Definition float_bv.cpp:212
static exprt relation(const exprt &, relt rel, const exprt &, const ieee_float_spect &)
static exprt isinf(const exprt &, const ieee_float_spect &)
static exprt sign_bit(const exprt &)
Definition float_bv.cpp:306
exprt mul(const exprt &, const exprt &, const exprt &rm, const ieee_float_spect &) const
Definition float_bv.cpp:726
static exprt fraction_all_zeros(const exprt &, const ieee_float_spect &)
Definition float_bv.cpp:278
static exprt exponent_all_zeros(const exprt &, const ieee_float_spect &)
Definition float_bv.cpp:269
static exprt is_equal(const exprt &, const exprt &, const ieee_float_spect &)
Definition float_bv.cpp:222
static exprt to_signed_integer(const exprt &src, std::size_t dest_width, const exprt &rm, const ieee_float_spect &)
Definition float_bv.cpp:359
static exprt limit_distance(const exprt &dist, mp_integer limit)
Limits the shift distance.
Definition float_bv.cpp:703
static exprt pack(const biased_floatt &, const ieee_float_spect &)
static void round_exponent(unbiased_floatt &result, const rounding_mode_bitst &, const ieee_float_spect &)
Fixed-width bit-vector with IEEE floating-point interpretation.
class floatbv_typet to_type() const
mp_integer bias() const
mp_integer max_exponent() const
std::size_t f
Definition ieee_float.h:26
std::size_t width() const
Definition ieee_float.h:50
std::size_t e
Definition ieee_float.h:26
An IEEE 754 floating-point value, including specificiation.
Definition ieee_float.h:117
constant_exprt to_expr() const
The trinary if-then-else operator.
Definition std_expr.h:2426
constant_exprt largest_expr() const
Return an expression representing the largest value of this type.
constant_exprt zero_expr() const
Return an expression representing the zero value of this type.
const irep_idt & id() const
Definition irep.h:390
Logical right shift.
Binary minus.
Definition std_expr.h:1065
Modulo defined as lhs-(rhs * truncate(lhs/rhs)).
Definition std_expr.h:1216
Binary multiplication Associativity is not specified.
Definition std_expr.h:1104
The NIL expression.
Definition std_expr.h:3144
Boolean negation.
Definition std_expr.h:2388
Disequality.
Definition std_expr.h:1393
Boolean OR All operands must be boolean, and the result is always boolean.
Definition std_expr.h:2193
The plus expression Associativity is not specified.
Definition std_expr.h:1006
Left shift.
Sign of an expression Predicate is true if _op is negative, false otherwise.
Definition std_expr.h:612
Fixed-width bit-vector with two's complement interpretation.
Semantic type conversion.
Definition std_expr.h:1995
The type of an expression, extends irept.
Definition type.h:29
const exprt & op() const
Definition std_expr.h:394
The unary minus expression.
Definition std_expr.h:477
Fixed-width bit-vector with unsigned binary interpretation.
zero extension The operand is converted to the given type by either a) truncating if the new type is ...
API to expression classes for floating-point arithmetic.
const ieee_float_op_exprt & to_ieee_float_op_expr(const exprt &expr)
Cast an exprt to an ieee_float_op_exprt.
const floatbv_fma_exprt & to_floatbv_fma_expr(const exprt &expr)
const ieee_float_notequal_exprt & to_ieee_float_notequal_expr(const exprt &expr)
Cast an exprt to an ieee_float_notequal_exprt.
const ieee_float_equal_exprt & to_ieee_float_equal_expr(const exprt &expr)
Cast an exprt to an ieee_float_equal_exprt.
const floatbv_typecast_exprt & to_floatbv_typecast_expr(const exprt &expr)
Cast an exprt to a floatbv_typecast_exprt.
double nan(const char *str)
Definition math.c:626
const std::size_t sharing_mapt< keyT, valueT, fail_if_equal, hashT, equalT >::mask
BigInt mp_integer
Definition smt_terms.h:17
#define UNREACHABLE
This should be used to mark dead code.
Definition invariant.h:525
#define PRECONDITION(CONDITION)
Definition invariant.h:463
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
Definition invariant.h:423
exprt disjunction(const exprt::operandst &op)
1) generates a disjunction for two or more operands 2) for one operand, returns the operand 3) return...
Definition std_expr.cpp:240
API to expression classes.
const binary_relation_exprt & to_binary_relation_expr(const exprt &expr)
Cast an exprt to a binary_relation_exprt.
Definition std_expr.h:828
const typecast_exprt & to_typecast_expr(const exprt &expr)
Cast an exprt to a typecast_exprt.
Definition std_expr.h:2024
const unary_exprt & to_unary_expr(const exprt &expr)
Cast an exprt to a unary_exprt.
Definition std_expr.h:424
const abs_exprt & to_abs_expr(const exprt &expr)
Cast an exprt to a abs_exprt.
Definition std_expr.h:459
const unary_minus_exprt & to_unary_minus_expr(const exprt &expr)
Cast an exprt to a unary_minus_exprt.
Definition std_expr.h:502
void get(const exprt &rm)
Definition float_bv.cpp:288
bool is_signed(const typet &t)
Convenience function – is the type signed?
Definition util.cpp:45