GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/util/floatingpoint_literal_symfpu_traits.cpp Lines: 113 122 92.6 %
Date: 2021-09-10 Branches: 67 268 25.0 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Martin Brain, Aina Niemetz
4
 *
5
 * This file is part of the cvc5 project.
6
 *
7
 * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
8
 * in the top-level source directory and their institutional affiliations.
9
 * All rights reserved.  See the file COPYING in the top-level source
10
 * directory for licensing information.
11
 * ****************************************************************************
12
 *
13
 * SymFPU glue code for floating-point values.
14
 */
15
16
#include "util/floatingpoint_literal_symfpu_traits.h"
17
18
#include "base/check.h"
19
20
namespace cvc5 {
21
namespace symfpuLiteral {
22
23
template <bool isSigned>
24
287642
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::one(
25
    const Cvc5BitWidth& w)
26
{
27
287642
  return wrappedBitVector<isSigned>(w, 1);
28
}
29
30
template <bool isSigned>
31
157228
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::zero(
32
    const Cvc5BitWidth& w)
33
{
34
157228
  return wrappedBitVector<isSigned>(w, 0);
35
}
36
37
template <bool isSigned>
38
19082
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::allOnes(
39
    const Cvc5BitWidth& w)
40
{
41
19082
  return ~wrappedBitVector<isSigned>::zero(w);
42
}
43
44
template <bool isSigned>
45
10817
Cvc5Prop wrappedBitVector<isSigned>::isAllOnes() const
46
{
47
10817
  return (*this == wrappedBitVector<isSigned>::allOnes(getWidth()));
48
}
49
template <bool isSigned>
50
50992
Cvc5Prop wrappedBitVector<isSigned>::isAllZeros() const
51
{
52
50992
  return (*this == wrappedBitVector<isSigned>::zero(getWidth()));
53
}
54
55
template <bool isSigned>
56
45
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::maxValue(
57
    const Cvc5BitWidth& w)
58
{
59
  if (isSigned)
60
  {
61
90
    BitVector base(w - 1, 0U);
62
45
    return wrappedBitVector<true>((~base).zeroExtend(1));
63
  }
64
  else
65
  {
66
    return wrappedBitVector<false>::allOnes(w);
67
  }
68
}
69
70
template <bool isSigned>
71
15
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::minValue(
72
    const Cvc5BitWidth& w)
73
{
74
  if (isSigned)
75
  {
76
30
    BitVector base(w, 1U);
77
30
    BitVector shiftAmount(w, w - 1);
78
30
    BitVector result(base.leftShift(shiftAmount));
79
15
    return wrappedBitVector<true>(result);
80
  }
81
  else
82
  {
83
    return wrappedBitVector<false>::zero(w);
84
  }
85
}
86
87
/*** Operators ***/
88
template <bool isSigned>
89
217682
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::operator<<(
90
    const wrappedBitVector<isSigned>& op) const
91
{
92
217682
  return BitVector::leftShift(op);
93
}
94
95
template <>
96
wrappedBitVector<true> wrappedBitVector<true>::operator>>(
97
    const wrappedBitVector<true>& op) const
98
{
99
  return BitVector::arithRightShift(op);
100
}
101
102
template <>
103
4899
wrappedBitVector<false> wrappedBitVector<false>::operator>>(
104
    const wrappedBitVector<false>& op) const
105
{
106
4899
  return BitVector::logicalRightShift(op);
107
}
108
109
template <bool isSigned>
110
4788
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::operator|(
111
    const wrappedBitVector<isSigned>& op) const
112
{
113
4788
  return BitVector::operator|(op);
114
}
115
116
template <bool isSigned>
117
46104
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::operator&(
118
    const wrappedBitVector<isSigned>& op) const
119
{
120
46104
  return BitVector::operator&(op);
121
}
122
123
template <bool isSigned>
124
11531
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::operator+(
125
    const wrappedBitVector<isSigned>& op) const
126
{
127
11531
  return BitVector::operator+(op);
128
}
129
130
template <bool isSigned>
131
270568
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::operator-(
132
    const wrappedBitVector<isSigned>& op) const
133
{
134
270568
  return BitVector::operator-(op);
135
}
136
137
template <bool isSigned>
138
505
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::operator*(
139
    const wrappedBitVector<isSigned>& op) const
140
{
141
505
  return BitVector::operator*(op);
142
}
143
144
template <>
145
196
wrappedBitVector<false> wrappedBitVector<false>::operator/(
146
    const wrappedBitVector<false>& op) const
147
{
148
196
  return BitVector::unsignedDivTotal(op);
149
}
150
151
template <>
152
196
wrappedBitVector<false> wrappedBitVector<false>::operator%(
153
    const wrappedBitVector<false>& op) const
154
{
155
196
  return BitVector::unsignedRemTotal(op);
156
}
157
158
template <bool isSigned>
159
112463
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::operator-(void) const
160
{
161
112463
  return BitVector::operator-();
162
}
163
164
template <bool isSigned>
165
22815
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::operator~(void) const
166
{
167
22815
  return BitVector::operator~();
168
}
169
170
template <bool isSigned>
171
140
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::increment() const
172
{
173
140
  return *this + wrappedBitVector<isSigned>::one(getWidth());
174
}
175
176
template <bool isSigned>
177
22256
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::decrement() const
178
{
179
22256
  return *this - wrappedBitVector<isSigned>::one(getWidth());
180
}
181
182
template <bool isSigned>
183
1623
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::signExtendRightShift(
184
    const wrappedBitVector<isSigned>& op) const
185
{
186
1623
  return BitVector::arithRightShift(BitVector(getWidth(), op));
187
}
188
189
/*** Modular opertaions ***/
190
// No overflow checking so these are the same as other operations
191
template <bool isSigned>
192
26179
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::modularLeftShift(
193
    const wrappedBitVector<isSigned>& op) const
194
{
195
26179
  return *this << op;
196
}
197
198
template <bool isSigned>
199
593
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::modularRightShift(
200
    const wrappedBitVector<isSigned>& op) const
201
{
202
593
  return *this >> op;
203
}
204
205
template <bool isSigned>
206
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::modularIncrement() const
207
{
208
  return increment();
209
}
210
211
template <bool isSigned>
212
20116
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::modularDecrement() const
213
{
214
20116
  return decrement();
215
}
216
217
template <bool isSigned>
218
5207
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::modularAdd(
219
    const wrappedBitVector<isSigned>& op) const
220
{
221
5207
  return *this + op;
222
}
223
224
template <bool isSigned>
225
5062
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::modularNegate() const
226
{
227
5062
  return -(*this);
228
}
229
230
/*** Comparisons ***/
231
232
template <bool isSigned>
233
107051
Cvc5Prop wrappedBitVector<isSigned>::operator==(
234
    const wrappedBitVector<isSigned>& op) const
235
{
236
107051
  return BitVector::operator==(op);
237
}
238
239
template <>
240
159232
Cvc5Prop wrappedBitVector<true>::operator<=(
241
    const wrappedBitVector<true>& op) const
242
{
243
159232
  return signedLessThanEq(op);
244
}
245
246
template <>
247
1140
Cvc5Prop wrappedBitVector<true>::operator>=(
248
    const wrappedBitVector<true>& op) const
249
{
250
1140
  return !(signedLessThan(op));
251
}
252
253
template <>
254
5622
Cvc5Prop wrappedBitVector<true>::operator<(
255
    const wrappedBitVector<true>& op) const
256
{
257
5622
  return signedLessThan(op);
258
}
259
260
template <>
261
5488
Cvc5Prop wrappedBitVector<true>::operator>(
262
    const wrappedBitVector<true>& op) const
263
{
264
5488
  return !(signedLessThanEq(op));
265
}
266
267
template <>
268
410
Cvc5Prop wrappedBitVector<false>::operator<=(
269
    const wrappedBitVector<false>& op) const
270
{
271
410
  return unsignedLessThanEq(op);
272
}
273
274
template <>
275
5134
Cvc5Prop wrappedBitVector<false>::operator>=(
276
    const wrappedBitVector<false>& op) const
277
{
278
5134
  return !(unsignedLessThan(op));
279
}
280
281
template <>
282
1176
Cvc5Prop wrappedBitVector<false>::operator<(
283
    const wrappedBitVector<false>& op) const
284
{
285
1176
  return unsignedLessThan(op);
286
}
287
288
template <>
289
19
Cvc5Prop wrappedBitVector<false>::operator>(
290
    const wrappedBitVector<false>& op) const
291
{
292
19
  return !(unsignedLessThanEq(op));
293
}
294
295
/*** Type conversion ***/
296
297
// Node makes no distinction between signed and unsigned, thus ...
298
template <bool isSigned>
299
1422
wrappedBitVector<true> wrappedBitVector<isSigned>::toSigned(void) const
300
{
301
1422
  return wrappedBitVector<true>(*this);
302
}
303
304
template <bool isSigned>
305
27189
wrappedBitVector<false> wrappedBitVector<isSigned>::toUnsigned(void) const
306
{
307
27189
  return wrappedBitVector<false>(*this);
308
}
309
310
/*** Bit hacks ***/
311
312
template <bool isSigned>
313
69071
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::extend(
314
    Cvc5BitWidth extension) const
315
{
316
  if (isSigned)
317
  {
318
16563
    return BitVector::signExtend(extension);
319
  }
320
  else
321
  {
322
52508
    return BitVector::zeroExtend(extension);
323
  }
324
}
325
326
template <bool isSigned>
327
1593
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::contract(
328
    Cvc5BitWidth reduction) const
329
{
330
1593
  Assert(getWidth() > reduction);
331
332
1593
  return extract((getWidth() - 1) - reduction, 0);
333
}
334
335
template <bool isSigned>
336
21805
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::resize(
337
    Cvc5BitWidth newSize) const
338
{
339
21805
  Cvc5BitWidth width = getWidth();
340
341
21805
  if (newSize > width)
342
  {
343
21805
    return extend(newSize - width);
344
  }
345
  else if (newSize < width)
346
  {
347
    return contract(width - newSize);
348
  }
349
  else
350
  {
351
    return *this;
352
  }
353
}
354
355
template <bool isSigned>
356
28941
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::matchWidth(
357
    const wrappedBitVector<isSigned>& op) const
358
{
359
28941
  Assert(getWidth() <= op.getWidth());
360
28941
  return extend(op.getWidth() - getWidth());
361
}
362
363
template <bool isSigned>
364
16578
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::append(
365
    const wrappedBitVector<isSigned>& op) const
366
{
367
16578
  return BitVector::concat(op);
368
}
369
370
// Inclusive of end points, thus if the same, extracts just one bit
371
template <bool isSigned>
372
50620
wrappedBitVector<isSigned> wrappedBitVector<isSigned>::extract(
373
    Cvc5BitWidth upper, Cvc5BitWidth lower) const
374
{
375
50620
  Assert(upper >= lower);
376
50620
  return BitVector::extract(upper, lower);
377
}
378
379
// Explicit instantiation
380
template class wrappedBitVector<true>;
381
template class wrappedBitVector<false>;
382
383
3358
traits::rm traits::RNE(void)
384
{
385
3358
  return RoundingMode::ROUND_NEAREST_TIES_TO_EVEN;
386
};
387
1977
traits::rm traits::RNA(void)
388
{
389
1977
  return RoundingMode::ROUND_NEAREST_TIES_TO_AWAY;
390
};
391
1803
traits::rm traits::RTP(void) { return RoundingMode::ROUND_TOWARD_POSITIVE; };
392
2916
traits::rm traits::RTN(void) { return RoundingMode::ROUND_TOWARD_NEGATIVE; };
393
1541
traits::rm traits::RTZ(void) { return RoundingMode::ROUND_TOWARD_ZERO; };
394
// This is a literal back-end so props are actually bools
395
// so these can be handled in the same way as the internal assertions above
396
397
57252
void traits::precondition(const traits::prop& p)
398
{
399
57252
  Assert(p);
400
57252
  return;
401
}
402
12012
void traits::postcondition(const traits::prop& p)
403
{
404
12012
  Assert(p);
405
12012
  return;
406
}
407
55931
void traits::invariant(const traits::prop& p)
408
{
409
55931
  Assert(p);
410
55931
  return;
411
}
412
}  // namespace symfpuLiteral
413
29502
}  // namespace cvc5