/********************* */ /*! \file floatingpoint_literal_symfpu_traits.cpp ** \verbatim ** Top contributors (to current version): ** Aina Niemetz ** This file is part of the CVC4 project. ** Copyright (c) 2009-2021 by the authors listed in the file AUTHORS ** in the top-level source directory and their institutional affiliations. ** All rights reserved. See the file COPYING in the top-level source ** directory for licensing information.\endverbatim ** ** \brief SymFPU glue code for floating-point values. **/ #if CVC4_USE_SYMFPU #include "util/floatingpoint_literal_symfpu_traits.h" #include "base/check.h" namespace cvc5 { namespace symfpuLiteral { template wrappedBitVector wrappedBitVector::one( const Cvc5BitWidth& w) { return wrappedBitVector(w, 1); } template wrappedBitVector wrappedBitVector::zero( const Cvc5BitWidth& w) { return wrappedBitVector(w, 0); } template wrappedBitVector wrappedBitVector::allOnes( const Cvc5BitWidth& w) { return ~wrappedBitVector::zero(w); } template Cvc5Prop wrappedBitVector::isAllOnes() const { return (*this == wrappedBitVector::allOnes(getWidth())); } template Cvc5Prop wrappedBitVector::isAllZeros() const { return (*this == wrappedBitVector::zero(getWidth())); } template wrappedBitVector wrappedBitVector::maxValue( const Cvc5BitWidth& w) { if (isSigned) { BitVector base(w - 1, 0U); return wrappedBitVector((~base).zeroExtend(1)); } else { return wrappedBitVector::allOnes(w); } } template wrappedBitVector wrappedBitVector::minValue( const Cvc5BitWidth& w) { if (isSigned) { BitVector base(w, 1U); BitVector shiftAmount(w, w - 1); BitVector result(base.leftShift(shiftAmount)); return wrappedBitVector(result); } else { return wrappedBitVector::zero(w); } } /*** Operators ***/ template wrappedBitVector wrappedBitVector::operator<<( const wrappedBitVector& op) const { return BitVector::leftShift(op); } template <> wrappedBitVector wrappedBitVector::operator>>( const wrappedBitVector& op) const { return BitVector::arithRightShift(op); } template <> wrappedBitVector wrappedBitVector::operator>>( const wrappedBitVector& op) const { return BitVector::logicalRightShift(op); } template wrappedBitVector wrappedBitVector::operator|( const wrappedBitVector& op) const { return BitVector::operator|(op); } template wrappedBitVector wrappedBitVector::operator&( const wrappedBitVector& op) const { return BitVector::operator&(op); } template wrappedBitVector wrappedBitVector::operator+( const wrappedBitVector& op) const { return BitVector::operator+(op); } template wrappedBitVector wrappedBitVector::operator-( const wrappedBitVector& op) const { return BitVector::operator-(op); } template wrappedBitVector wrappedBitVector::operator*( const wrappedBitVector& op) const { return BitVector::operator*(op); } template <> wrappedBitVector wrappedBitVector::operator/( const wrappedBitVector& op) const { return BitVector::unsignedDivTotal(op); } template <> wrappedBitVector wrappedBitVector::operator%( const wrappedBitVector& op) const { return BitVector::unsignedRemTotal(op); } template wrappedBitVector wrappedBitVector::operator-(void) const { return BitVector::operator-(); } template wrappedBitVector wrappedBitVector::operator~(void) const { return BitVector::operator~(); } template wrappedBitVector wrappedBitVector::increment() const { return *this + wrappedBitVector::one(getWidth()); } template wrappedBitVector wrappedBitVector::decrement() const { return *this - wrappedBitVector::one(getWidth()); } template wrappedBitVector wrappedBitVector::signExtendRightShift( const wrappedBitVector& op) const { return BitVector::arithRightShift(BitVector(getWidth(), op)); } /*** Modular opertaions ***/ // No overflow checking so these are the same as other operations template wrappedBitVector wrappedBitVector::modularLeftShift( const wrappedBitVector& op) const { return *this << op; } template wrappedBitVector wrappedBitVector::modularRightShift( const wrappedBitVector& op) const { return *this >> op; } template wrappedBitVector wrappedBitVector::modularIncrement() const { return increment(); } template wrappedBitVector wrappedBitVector::modularDecrement() const { return decrement(); } template wrappedBitVector wrappedBitVector::modularAdd( const wrappedBitVector& op) const { return *this + op; } template wrappedBitVector wrappedBitVector::modularNegate() const { return -(*this); } /*** Comparisons ***/ template Cvc5Prop wrappedBitVector::operator==( const wrappedBitVector& op) const { return BitVector::operator==(op); } template <> Cvc5Prop wrappedBitVector::operator<=( const wrappedBitVector& op) const { return signedLessThanEq(op); } template <> Cvc5Prop wrappedBitVector::operator>=( const wrappedBitVector& op) const { return !(signedLessThan(op)); } template <> Cvc5Prop wrappedBitVector::operator<( const wrappedBitVector& op) const { return signedLessThan(op); } template <> Cvc5Prop wrappedBitVector::operator>( const wrappedBitVector& op) const { return !(signedLessThanEq(op)); } template <> Cvc5Prop wrappedBitVector::operator<=( const wrappedBitVector& op) const { return unsignedLessThanEq(op); } template <> Cvc5Prop wrappedBitVector::operator>=( const wrappedBitVector& op) const { return !(unsignedLessThan(op)); } template <> Cvc5Prop wrappedBitVector::operator<( const wrappedBitVector& op) const { return unsignedLessThan(op); } template <> Cvc5Prop wrappedBitVector::operator>( const wrappedBitVector& op) const { return !(unsignedLessThanEq(op)); } /*** Type conversion ***/ // Node makes no distinction between signed and unsigned, thus ... template wrappedBitVector wrappedBitVector::toSigned(void) const { return wrappedBitVector(*this); } template wrappedBitVector wrappedBitVector::toUnsigned(void) const { return wrappedBitVector(*this); } /*** Bit hacks ***/ template wrappedBitVector wrappedBitVector::extend( Cvc5BitWidth extension) const { if (isSigned) { return BitVector::signExtend(extension); } else { return BitVector::zeroExtend(extension); } } template wrappedBitVector wrappedBitVector::contract( Cvc5BitWidth reduction) const { Assert(getWidth() > reduction); return extract((getWidth() - 1) - reduction, 0); } template wrappedBitVector wrappedBitVector::resize( Cvc5BitWidth newSize) const { Cvc5BitWidth width = getWidth(); if (newSize > width) { return extend(newSize - width); } else if (newSize < width) { return contract(width - newSize); } else { return *this; } } template wrappedBitVector wrappedBitVector::matchWidth( const wrappedBitVector& op) const { Assert(getWidth() <= op.getWidth()); return extend(op.getWidth() - getWidth()); } template wrappedBitVector wrappedBitVector::append( const wrappedBitVector& op) const { return BitVector::concat(op); } // Inclusive of end points, thus if the same, extracts just one bit template wrappedBitVector wrappedBitVector::extract( Cvc5BitWidth upper, Cvc5BitWidth lower) const { Assert(upper >= lower); return BitVector::extract(upper, lower); } // Explicit instantiation template class wrappedBitVector; template class wrappedBitVector; traits::rm traits::RNE(void) { return ::cvc5::ROUND_NEAREST_TIES_TO_EVEN; }; traits::rm traits::RNA(void) { return ::cvc5::ROUND_NEAREST_TIES_TO_AWAY; }; traits::rm traits::RTP(void) { return ::cvc5::ROUND_TOWARD_POSITIVE; }; traits::rm traits::RTN(void) { return ::cvc5::ROUND_TOWARD_NEGATIVE; }; traits::rm traits::RTZ(void) { return ::cvc5::ROUND_TOWARD_ZERO; }; // This is a literal back-end so props are actually bools // so these can be handled in the same way as the internal assertions above void traits::precondition(const traits::prop& p) { Assert(p); return; } void traits::postcondition(const traits::prop& p) { Assert(p); return; } void traits::invariant(const traits::prop& p) { Assert(p); return; } } // namespace symfpuLiteral } // namespace cvc5 #endif