1 /********************* */
2 /*! \file floatingpoint_literal_symfpu_traits.cpp
4 ** Top contributors (to current version):
6 ** This file is part of the CVC4 project.
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.\endverbatim
12 ** \brief SymFPU glue code for floating-point values.
17 #include "util/floatingpoint_literal_symfpu_traits.h"
19 #include "base/check.h"
22 namespace symfpuLiteral
{
24 template <bool isSigned
>
25 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::one(
26 const Cvc5BitWidth
& w
)
28 return wrappedBitVector
<isSigned
>(w
, 1);
31 template <bool isSigned
>
32 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::zero(
33 const Cvc5BitWidth
& w
)
35 return wrappedBitVector
<isSigned
>(w
, 0);
38 template <bool isSigned
>
39 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::allOnes(
40 const Cvc5BitWidth
& w
)
42 return ~wrappedBitVector
<isSigned
>::zero(w
);
45 template <bool isSigned
>
46 Cvc5Prop wrappedBitVector
<isSigned
>::isAllOnes() const
48 return (*this == wrappedBitVector
<isSigned
>::allOnes(getWidth()));
50 template <bool isSigned
>
51 Cvc5Prop wrappedBitVector
<isSigned
>::isAllZeros() const
53 return (*this == wrappedBitVector
<isSigned
>::zero(getWidth()));
56 template <bool isSigned
>
57 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::maxValue(
58 const Cvc5BitWidth
& w
)
62 BitVector
base(w
- 1, 0U);
63 return wrappedBitVector
<true>((~base
).zeroExtend(1));
67 return wrappedBitVector
<false>::allOnes(w
);
71 template <bool isSigned
>
72 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::minValue(
73 const Cvc5BitWidth
& w
)
77 BitVector
base(w
, 1U);
78 BitVector
shiftAmount(w
, w
- 1);
79 BitVector
result(base
.leftShift(shiftAmount
));
80 return wrappedBitVector
<true>(result
);
84 return wrappedBitVector
<false>::zero(w
);
89 template <bool isSigned
>
90 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::operator<<(
91 const wrappedBitVector
<isSigned
>& op
) const
93 return BitVector::leftShift(op
);
97 wrappedBitVector
<true> wrappedBitVector
<true>::operator>>(
98 const wrappedBitVector
<true>& op
) const
100 return BitVector::arithRightShift(op
);
104 wrappedBitVector
<false> wrappedBitVector
<false>::operator>>(
105 const wrappedBitVector
<false>& op
) const
107 return BitVector::logicalRightShift(op
);
110 template <bool isSigned
>
111 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::operator|(
112 const wrappedBitVector
<isSigned
>& op
) const
114 return BitVector::operator|(op
);
117 template <bool isSigned
>
118 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::operator&(
119 const wrappedBitVector
<isSigned
>& op
) const
121 return BitVector::operator&(op
);
124 template <bool isSigned
>
125 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::operator+(
126 const wrappedBitVector
<isSigned
>& op
) const
128 return BitVector::operator+(op
);
131 template <bool isSigned
>
132 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::operator-(
133 const wrappedBitVector
<isSigned
>& op
) const
135 return BitVector::operator-(op
);
138 template <bool isSigned
>
139 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::operator*(
140 const wrappedBitVector
<isSigned
>& op
) const
142 return BitVector::operator*(op
);
146 wrappedBitVector
<false> wrappedBitVector
<false>::operator/(
147 const wrappedBitVector
<false>& op
) const
149 return BitVector::unsignedDivTotal(op
);
153 wrappedBitVector
<false> wrappedBitVector
<false>::operator%(
154 const wrappedBitVector
<false>& op
) const
156 return BitVector::unsignedRemTotal(op
);
159 template <bool isSigned
>
160 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::operator-(void) const
162 return BitVector::operator-();
165 template <bool isSigned
>
166 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::operator~(void) const
168 return BitVector::operator~();
171 template <bool isSigned
>
172 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::increment() const
174 return *this + wrappedBitVector
<isSigned
>::one(getWidth());
177 template <bool isSigned
>
178 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::decrement() const
180 return *this - wrappedBitVector
<isSigned
>::one(getWidth());
183 template <bool isSigned
>
184 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::signExtendRightShift(
185 const wrappedBitVector
<isSigned
>& op
) const
187 return BitVector::arithRightShift(BitVector(getWidth(), op
));
190 /*** Modular opertaions ***/
191 // No overflow checking so these are the same as other operations
192 template <bool isSigned
>
193 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::modularLeftShift(
194 const wrappedBitVector
<isSigned
>& op
) const
199 template <bool isSigned
>
200 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::modularRightShift(
201 const wrappedBitVector
<isSigned
>& op
) const
206 template <bool isSigned
>
207 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::modularIncrement() const
212 template <bool isSigned
>
213 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::modularDecrement() const
218 template <bool isSigned
>
219 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::modularAdd(
220 const wrappedBitVector
<isSigned
>& op
) const
225 template <bool isSigned
>
226 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::modularNegate() const
231 /*** Comparisons ***/
233 template <bool isSigned
>
234 Cvc5Prop wrappedBitVector
<isSigned
>::operator==(
235 const wrappedBitVector
<isSigned
>& op
) const
237 return BitVector::operator==(op
);
241 Cvc5Prop wrappedBitVector
<true>::operator<=(
242 const wrappedBitVector
<true>& op
) const
244 return signedLessThanEq(op
);
248 Cvc5Prop wrappedBitVector
<true>::operator>=(
249 const wrappedBitVector
<true>& op
) const
251 return !(signedLessThan(op
));
255 Cvc5Prop wrappedBitVector
<true>::operator<(
256 const wrappedBitVector
<true>& op
) const
258 return signedLessThan(op
);
262 Cvc5Prop wrappedBitVector
<true>::operator>(
263 const wrappedBitVector
<true>& op
) const
265 return !(signedLessThanEq(op
));
269 Cvc5Prop wrappedBitVector
<false>::operator<=(
270 const wrappedBitVector
<false>& op
) const
272 return unsignedLessThanEq(op
);
276 Cvc5Prop wrappedBitVector
<false>::operator>=(
277 const wrappedBitVector
<false>& op
) const
279 return !(unsignedLessThan(op
));
283 Cvc5Prop wrappedBitVector
<false>::operator<(
284 const wrappedBitVector
<false>& op
) const
286 return unsignedLessThan(op
);
290 Cvc5Prop wrappedBitVector
<false>::operator>(
291 const wrappedBitVector
<false>& op
) const
293 return !(unsignedLessThanEq(op
));
296 /*** Type conversion ***/
298 // Node makes no distinction between signed and unsigned, thus ...
299 template <bool isSigned
>
300 wrappedBitVector
<true> wrappedBitVector
<isSigned
>::toSigned(void) const
302 return wrappedBitVector
<true>(*this);
305 template <bool isSigned
>
306 wrappedBitVector
<false> wrappedBitVector
<isSigned
>::toUnsigned(void) const
308 return wrappedBitVector
<false>(*this);
313 template <bool isSigned
>
314 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::extend(
315 Cvc5BitWidth extension
) const
319 return BitVector::signExtend(extension
);
323 return BitVector::zeroExtend(extension
);
327 template <bool isSigned
>
328 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::contract(
329 Cvc5BitWidth reduction
) const
331 Assert(getWidth() > reduction
);
333 return extract((getWidth() - 1) - reduction
, 0);
336 template <bool isSigned
>
337 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::resize(
338 Cvc5BitWidth newSize
) const
340 Cvc5BitWidth width
= getWidth();
344 return extend(newSize
- width
);
346 else if (newSize
< width
)
348 return contract(width
- newSize
);
356 template <bool isSigned
>
357 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::matchWidth(
358 const wrappedBitVector
<isSigned
>& op
) const
360 Assert(getWidth() <= op
.getWidth());
361 return extend(op
.getWidth() - getWidth());
364 template <bool isSigned
>
365 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::append(
366 const wrappedBitVector
<isSigned
>& op
) const
368 return BitVector::concat(op
);
371 // Inclusive of end points, thus if the same, extracts just one bit
372 template <bool isSigned
>
373 wrappedBitVector
<isSigned
> wrappedBitVector
<isSigned
>::extract(
374 Cvc5BitWidth upper
, Cvc5BitWidth lower
) const
376 Assert(upper
>= lower
);
377 return BitVector::extract(upper
, lower
);
380 // Explicit instantiation
381 template class wrappedBitVector
<true>;
382 template class wrappedBitVector
<false>;
384 traits::rm
traits::RNE(void) { return ::cvc5::ROUND_NEAREST_TIES_TO_EVEN
; };
385 traits::rm
traits::RNA(void) { return ::cvc5::ROUND_NEAREST_TIES_TO_AWAY
; };
386 traits::rm
traits::RTP(void) { return ::cvc5::ROUND_TOWARD_POSITIVE
; };
387 traits::rm
traits::RTN(void) { return ::cvc5::ROUND_TOWARD_NEGATIVE
; };
388 traits::rm
traits::RTZ(void) { return ::cvc5::ROUND_TOWARD_ZERO
; };
389 // This is a literal back-end so props are actually bools
390 // so these can be handled in the same way as the internal assertions above
392 void traits::precondition(const traits::prop
& p
)
397 void traits::postcondition(const traits::prop
& p
)
402 void traits::invariant(const traits::prop
& p
)
407 } // namespace symfpuLiteral