-
Notifications
You must be signed in to change notification settings - Fork 273
/
Copy pathfloat_bv.h
193 lines (160 loc) · 5.19 KB
/
float_bv.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/*******************************************************************\
Module:
Author: Daniel Kroening, [email protected]
\*******************************************************************/
#ifndef CPROVER_SOLVERS_FLOATBV_FLOAT_BV_H
#define CPROVER_SOLVERS_FLOATBV_FLOAT_BV_H
#include <util/ieee_float.h>
#include <util/std_expr.h>
class float_bvt
{
public:
exprt operator()(const exprt &src) const
{
return convert(src);
}
exprt convert(const exprt &) const;
static exprt negation(const exprt &, const ieee_float_spect &);
static exprt abs(const exprt &, const ieee_float_spect &);
static exprt is_equal(const exprt &, const exprt &, const ieee_float_spect &);
static exprt is_zero(const exprt &);
static exprt isnan(const exprt &, const ieee_float_spect &);
static exprt isinf(const exprt &, const ieee_float_spect &);
static exprt isnormal(const exprt &, const ieee_float_spect &);
static exprt isfinite(const exprt &, const ieee_float_spect &);
// add/sub
exprt add_sub(
bool subtract,
const exprt &,
const exprt &,
const exprt &rm,
const ieee_float_spect &) const;
// mul/div
exprt
mul(const exprt &, const exprt &, const exprt &rm, const ieee_float_spect &)
const;
exprt
div(const exprt &, const exprt &, const exprt &rm, const ieee_float_spect &)
const;
// conversion
exprt from_unsigned_integer(
const exprt &,
const exprt &rm,
const ieee_float_spect &) const;
exprt from_signed_integer(
const exprt &,
const exprt &rm,
const ieee_float_spect &) const;
static exprt to_signed_integer(
const exprt &src,
std::size_t dest_width,
const exprt &rm,
const ieee_float_spect &);
static exprt to_unsigned_integer(
const exprt &src,
std::size_t dest_width,
const exprt &rm,
const ieee_float_spect &);
static exprt to_integer(
const exprt &src,
std::size_t dest_width,
bool is_signed,
const exprt &rm,
const ieee_float_spect &);
exprt conversion(
const exprt &src,
const exprt &rm,
const ieee_float_spect &src_spec,
const ieee_float_spect &dest_spec) const;
// relations
enum class relt { LT, LE, EQ, GT, GE };
static exprt
relation(const exprt &, relt rel, const exprt &, const ieee_float_spect &);
private:
// helpers
static ieee_float_spect get_spec(const exprt &);
// still biased
static exprt get_exponent(const exprt &, const ieee_float_spect &);
// without hidden bit
static exprt get_fraction(const exprt &, const ieee_float_spect &);
static exprt sign_bit(const exprt &);
static exprt exponent_all_ones(const exprt &, const ieee_float_spect &);
static exprt exponent_all_zeros(const exprt &, const ieee_float_spect &);
static exprt fraction_all_zeros(const exprt &, const ieee_float_spect &);
struct rounding_mode_bitst
{
// these are mutually exclusive, obviously
exprt round_to_even;
exprt round_to_zero;
exprt round_to_plus_inf;
exprt round_to_minus_inf;
exprt round_to_away;
void get(const exprt &rm);
explicit rounding_mode_bitst(const exprt &rm) { get(rm); }
};
// unpacked
static void normalization_shift(exprt &fraction, exprt &exponent);
static void denormalization_shift(
exprt &fraction,
exprt &exponent,
const ieee_float_spect &);
static exprt add_bias(const exprt &exponent, const ieee_float_spect &);
static exprt sub_bias(const exprt &exponent, const ieee_float_spect &);
static exprt limit_distance(const exprt &dist, mp_integer limit);
struct unpacked_floatt
{
exprt sign, infinity, zero, NaN;
exprt fraction, exponent;
unpacked_floatt():
sign(false_exprt()),
infinity(false_exprt()),
zero(false_exprt()),
NaN(false_exprt())
{
}
};
// This has a biased exponent (unsigned)
// and an _implicit_ hidden bit.
struct biased_floatt:public unpacked_floatt
{
};
// The hidden bit is explicit,
// and the exponent is not biased (signed)
struct unbiased_floatt:public unpacked_floatt
{
};
static biased_floatt bias(const unbiased_floatt &, const ieee_float_spect &);
// this takes unpacked format, and returns packed
exprt rounder(
const unbiased_floatt &,
const exprt &rm,
const ieee_float_spect &) const;
static exprt pack(const biased_floatt &, const ieee_float_spect &);
static unbiased_floatt unpack(const exprt &, const ieee_float_spect &);
static void round_fraction(
unbiased_floatt &result,
const rounding_mode_bitst &,
const ieee_float_spect &);
static void round_exponent(
unbiased_floatt &result,
const rounding_mode_bitst &,
const ieee_float_spect &);
// rounding decision for fraction
static exprt fraction_rounding_decision(
const std::size_t dest_bits,
const exprt sign,
const exprt &fraction,
const rounding_mode_bitst &);
// helpers for adder
// computes src1.exponent-src2.exponent with extension
static exprt
subtract_exponents(const unbiased_floatt &src1, const unbiased_floatt &src2);
// computes the "sticky-bit"
static exprt
sticky_right_shift(const exprt &op, const exprt &dist, exprt &sticky);
};
inline exprt float_bv(const exprt &src)
{
return float_bvt()(src);
}
#endif // CPROVER_SOLVERS_FLOATBV_FLOAT_BV_H