summaryrefslogtreecommitdiff
path: root/src/util/floatingpoint.cpp
diff options
context:
space:
mode:
authorMartin <martin.brain@diffblue.com>2017-09-19 01:14:05 +0100
committerAndres Noetzli <andres.noetzli@gmail.com>2017-09-18 17:14:05 -0700
commit61a846a4998be697867292924454893271eb6496 (patch)
tree7d1c5a5cadb8a5c538efea00abdd82b5681b809a /src/util/floatingpoint.cpp
parent053003a64bde91aa32f688d248d83c3d4f271250 (diff)
Floating point symfpu support (#1103)
- Update the parser to the new constant construction - Fix the problem with parsing +/-zero and remove some dead code - Extend the interface for literal floating-point values. - Add a constructor so that a parameteric operator structure can be created from a type - Add constructors so parametric operator constants can be easily converted - Update SMT2 printing so that it uses the informative output
Diffstat (limited to 'src/util/floatingpoint.cpp')
-rw-r--r--src/util/floatingpoint.cpp303
1 files changed, 303 insertions, 0 deletions
diff --git a/src/util/floatingpoint.cpp b/src/util/floatingpoint.cpp
index 8c446d9d2..fe90279ec 100644
--- a/src/util/floatingpoint.cpp
+++ b/src/util/floatingpoint.cpp
@@ -36,4 +36,307 @@ void FloatingPointLiteral::unfinished (void) const {
Unimplemented("Floating-point literals not yet implemented.");
}
+ FloatingPoint::FloatingPoint (unsigned e, unsigned s, const BitVector &bv) :
+ fpl(e,s,0.0),
+ t(e,s) {}
+
+
+ static FloatingPointLiteral constructorHelperBitVector (const FloatingPointSize &ct, const RoundingMode &rm, const BitVector &bv, bool signedBV) {
+ if (signedBV) {
+ return FloatingPointLiteral(2,2,0.0);
+ } else {
+ return FloatingPointLiteral(2,2,0.0);
+ }
+ Unreachable("Constructor helper broken");
+ }
+
+ FloatingPoint::FloatingPoint (const FloatingPointSize &ct, const RoundingMode &rm, const BitVector &bv, bool signedBV) :
+ fpl(constructorHelperBitVector(ct, rm, bv, signedBV)),
+ t(ct) {}
+
+
+ static FloatingPointLiteral constructorHelperRational (const FloatingPointSize &ct, const RoundingMode &rm, const Rational &ri) {
+ Rational r(ri);
+ Rational two(2,1);
+
+ if (r.isZero()) {
+ return FloatingPointLiteral(2,2,0.0);
+ } else {
+ //int negative = (r.sgn() < 0) ? 1 : 0;
+ r = r.abs();
+
+ // Compute the exponent
+ Integer exp(0U);
+ Integer inc(1U);
+ Rational working(1,1);
+
+ if (r == working) {
+
+ } else if ( r < working ) {
+ while (r < working) {
+ exp -= inc;
+ working /= two;
+ }
+ } else {
+ while (r >= working) {
+ exp += inc;
+ working *= two;
+ }
+ exp -= inc;
+ working /= two;
+ }
+
+ Assert(working <= r);
+ Assert(r < working * two);
+
+ // Work out the number of bits required to represent the exponent for a normal number
+ unsigned expBits = 2; // No point starting with an invalid amount
+
+ Integer doubleInt(2);
+ if (exp.strictlyPositive()) {
+ Integer representable(4); // 1 more than exactly representable with expBits
+ while (representable <= exp) {// hence <=
+ representable *= doubleInt;
+ ++expBits;
+ }
+ } else if (exp.strictlyNegative()) {
+ Integer representable(-4); // Exactly representable with expBits + sign
+ // but -2^n and -(2^n - 1) are both subnormal
+ while ((representable + doubleInt) > exp) {
+ representable *= doubleInt;
+ ++expBits;
+ }
+ }
+ ++expBits; // To allow for sign
+
+ BitVector exactExp(expBits, exp);
+
+
+
+ // Compute the significand.
+ unsigned sigBits = ct.significand() + 2; // guard and sticky bits
+ BitVector sig(sigBits, 0U);
+ BitVector one(sigBits, 1U);
+ Rational workingSig(0,1);
+ for (unsigned i = 0; i < sigBits - 1; ++i) {
+ Rational mid(workingSig + working);
+
+ if (mid <= r) {
+ sig = sig | one;
+ workingSig = mid;
+ }
+
+ sig = sig.leftShift(one);
+ working /= two;
+ }
+
+ // Compute the sticky bit
+ Rational remainder(r - workingSig);
+ Assert(Rational(0,1) <= remainder);
+
+ if (!remainder.isZero()) {
+ sig = sig | one;
+ }
+
+ // Build an exact float
+ FloatingPointSize exactFormat(expBits, sigBits);
+
+ // A small subtlety... if the format has expBits the unpacked format
+ // may have more to allow subnormals to be normalised.
+ // Thus...
+ Unreachable("no concrete implementation of FloatingPointLiteral");
+ }
+ Unreachable("Constructor helper broken");
+ }
+
+ FloatingPoint::FloatingPoint (const FloatingPointSize &ct, const RoundingMode &rm, const Rational &r) :
+ fpl(constructorHelperRational(ct, rm, r)),
+ t(ct) {}
+
+
+ FloatingPoint FloatingPoint::makeNaN (const FloatingPointSize &t) {
+ return FloatingPoint(2, 2, BitVector(4U,0U));
+ }
+
+ FloatingPoint FloatingPoint::makeInf (const FloatingPointSize &t, bool sign) {
+ return FloatingPoint(2, 2, BitVector(4U,0U));
+ }
+
+ FloatingPoint FloatingPoint::makeZero (const FloatingPointSize &t, bool sign) {
+ return FloatingPoint(2, 2, BitVector(4U,0U));
+ }
+
+
+ /* Operations implemented using symfpu */
+ FloatingPoint FloatingPoint::absolute (void) const {
+ return *this;
+ }
+
+ FloatingPoint FloatingPoint::negate (void) const {
+ return *this;
+ }
+
+ FloatingPoint FloatingPoint::plus (const RoundingMode &rm, const FloatingPoint &arg) const {
+ Assert(this->t == arg.t);
+ return *this;
+ }
+
+ FloatingPoint FloatingPoint::sub (const RoundingMode &rm, const FloatingPoint &arg) const {
+ Assert(this->t == arg.t);
+ return *this;
+ }
+
+ FloatingPoint FloatingPoint::mult (const RoundingMode &rm, const FloatingPoint &arg) const {
+ Assert(this->t == arg.t);
+ return *this;
+ }
+
+ FloatingPoint FloatingPoint::fma (const RoundingMode &rm, const FloatingPoint &arg1, const FloatingPoint &arg2) const {
+ Assert(this->t == arg1.t);
+ Assert(this->t == arg2.t);
+ return *this;
+ }
+
+ FloatingPoint FloatingPoint::div (const RoundingMode &rm, const FloatingPoint &arg) const {
+ Assert(this->t == arg.t);
+ return *this;
+ }
+
+ FloatingPoint FloatingPoint::sqrt (const RoundingMode &rm) const {
+ return *this;
+ }
+
+ FloatingPoint FloatingPoint::rti (const RoundingMode &rm) const {
+ return *this;
+ }
+
+ FloatingPoint FloatingPoint::rem (const FloatingPoint &arg) const {
+ Assert(this->t == arg.t);
+ return *this;
+ }
+
+ FloatingPoint FloatingPoint::maxTotal (const FloatingPoint &arg, bool zeroCaseLeft) const {
+ Assert(this->t == arg.t);
+ return *this;
+ }
+
+ FloatingPoint FloatingPoint::minTotal (const FloatingPoint &arg, bool zeroCaseLeft) const {
+ Assert(this->t == arg.t);
+ return *this;
+ }
+
+ FloatingPoint::PartialFloatingPoint FloatingPoint::max (const FloatingPoint &arg) const {
+ FloatingPoint tmp(maxTotal(arg, true));
+ return PartialFloatingPoint(tmp, tmp == maxTotal(arg, false));
+ }
+
+ FloatingPoint::PartialFloatingPoint FloatingPoint::min (const FloatingPoint &arg) const {
+ FloatingPoint tmp(minTotal(arg, true));
+ return PartialFloatingPoint(tmp, tmp == minTotal(arg, false));
+ }
+
+ bool FloatingPoint::operator ==(const FloatingPoint& fp) const {
+ return ( (t == fp.t) );
+ }
+
+ bool FloatingPoint::operator <= (const FloatingPoint &arg) const {
+ Assert(this->t == arg.t);
+ return false;
+ }
+
+ bool FloatingPoint::operator < (const FloatingPoint &arg) const {
+ Assert(this->t == arg.t);
+ return false;
+ }
+
+ bool FloatingPoint::isNormal (void) const {
+ return false;
+ }
+
+ bool FloatingPoint::isSubnormal (void) const {
+ return false;
+ }
+
+ bool FloatingPoint::isZero (void) const {
+ return false;
+ }
+
+ bool FloatingPoint::isInfinite (void) const {
+ return false;
+ }
+
+ bool FloatingPoint::isNaN (void) const {
+ return false;
+ }
+
+ bool FloatingPoint::isNegative (void) const {
+ return false;
+ }
+
+ bool FloatingPoint::isPositive (void) const {
+ return false;
+ }
+
+ FloatingPoint FloatingPoint::convert (const FloatingPointSize &target, const RoundingMode &rm) const {
+ return *this;
+ }
+
+ BitVector FloatingPoint::convertToBVTotal (BitVectorSize width, const RoundingMode &rm, bool signedBV, BitVector undefinedCase) const {
+ if (signedBV)
+ return undefinedCase;
+ else
+ return undefinedCase;
+ }
+
+ Rational FloatingPoint::convertToRationalTotal (Rational undefinedCase) const {
+ PartialRational p(convertToRational());
+
+ return p.second ? p.first : undefinedCase;
+ }
+
+ FloatingPoint::PartialBitVector FloatingPoint::convertToBV (BitVectorSize width, const RoundingMode &rm, bool signedBV) const {
+ BitVector tmp(convertToBVTotal (width, rm, signedBV, BitVector(width, 0U)));
+ BitVector confirm(convertToBVTotal (width, rm, signedBV, BitVector(width, 1U)));
+
+ return PartialBitVector(tmp, tmp == confirm);
+ }
+
+ FloatingPoint::PartialRational FloatingPoint::convertToRational (void) const {
+ if (this->isNaN() || this->isInfinite()) {
+ return PartialRational(Rational(0U, 1U), false);
+ }
+ if (this->isZero()) {
+ return PartialRational(Rational(0U, 1U), true);
+
+ } else {
+
+ Integer sign(0);
+ Integer exp(0);
+ Integer significand(0);
+ Integer signedSignificand(sign * significand);
+
+ // Only have pow(uint32_t) so we should check this.
+ Assert(this->t.significand() <= 32);
+
+ if (!(exp.strictlyNegative())) {
+ Integer r(signedSignificand.multiplyByPow2(exp.toUnsignedInt()));
+ return PartialRational(Rational(r), true);
+ } else {
+ Integer one(1U);
+ Integer q(one.multiplyByPow2((-exp).toUnsignedInt()));
+ Rational r(signedSignificand, q);
+ return PartialRational(r, true);
+ }
+ }
+
+ Unreachable("Convert float literal to real broken.");
+ }
+
+ BitVector FloatingPoint::pack (void) const {
+ BitVector bv(4u,0u);
+ return bv;
+ }
+
+
+
}/* CVC4 namespace */
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback