}
// The value "b" is in the range [low,high] inclusive.
+// Unfortunately it's not idempotent, <....1> [5,6], doesn't completely set it.
Result fix(FixedBits& b, BEEV::CBV low, BEEV::CBV high)
{
FixedBits init =b;
const unsigned width = a.getWidth();
- assert(!b.containsZero());
-
BEEV::CBV minTop = CONSTANTBV::BitVector_Create(width, true);
BEEV::CBV maxTop = CONSTANTBV::BitVector_Create(width, true);
log << endl;
}
- // We loop. There are 6 cases.
-
+ // If a bit is changed, then we fixed point again.
+ bool bitEverChanged = false;
+ bool bitJustChanged = true;
Result result = NO_CHANGE;
- // If a bit is changed, then we fixed point again.
- bool bitEverChanged = false;
- bool bitJustChanged = true;
+ // We loop. There are 6 cases.
while (bitJustChanged) {
bitJustChanged = false;
changed = false;
CONSTANTBV::ErrCode e;
+ // The main loop doesn't work if there is a division by zero possible.
+ // If the minimum bottom is zero, but the minimum quotient is > 1, then in our semantics
+ // of 1/0 = 1
+ if (CONSTANTBV::BitVector_is_empty(minBottom) && CONSTANTBV::BitVector_Lexicompare(minQuotient, one) > 0)
+ {
+ CONSTANTBV::BitVector_increment(minBottom);
+ if (CONSTANTBV::BitVector_Lexicompare(minBottom, maxBottom) > 0)
+ {
+ result = CONFLICT;
+ goto end;
+ }
+ }
+
+ if (CONSTANTBV::BitVector_is_empty(minBottom))
+ {
+ goto end; // Possible division by zero. Hard to work with..
+ }
+
bool carry_1 = false;
CONSTANTBV::BitVector_sub(copy, minTop, minRemainder, &carry_1);
if (!carry_1) // Not sure if it goes negative.
//bool carry_2 = false;
//CONSTANTBV::BitVector_sub(copy,maxTop,minRemainder,&carry_2);
//assert(!carry_1); // Not sure if it goes negative.
+
e = CONSTANTBV::BitVector_Div_Pos(q, copy, minBottom, r);
assert(e == CONSTANTBV::ErrCode_Ok);
{
Result r1 = fix(a, minTop, maxTop);
+ r1 = merge(r1,fix(a, minTop, maxTop));
+
Result r2 = fix(b, minBottom, maxBottom);
+ // We call is a second time because it's not idepotent..
+ r2 = merge(r2,fix(b, minBottom, maxBottom));
+
Result r3;
if (whatIs == QUOTIENT_IS_OUTPUT)
- r3 = fix(output, minQuotient, maxQuotient);
+ {
+ r3 = fix(output, minQuotient, maxQuotient);
+ r3 = merge(r3,fix(output, minQuotient, maxQuotient));
+ }
else
r3 = fix(output, minRemainder, maxRemainder);
return r1;
}
-Result bvUnsignedDivisionBothWays(vector<FixedBits*>& children,
- FixedBits& output, STPMgr* bm) {
-
- if (children[1]->containsZero())
- {
- for (int i=children[0]->getWidth()-1; i > 0 ; i--)
- {
- if (children[0]->isFixedToZero(i))
- {
- if (output.isFixedToOne(i))
- return CONFLICT;
- else if (!output.isFixed(i))
- {
- output.setFixed(i,true);
- output.setValue(i,false);
- }
- }
- else
- {
- break;
- }
- }
- return NOT_IMPLEMENTED;
- }
+ Result
+ bvUnsignedDivisionBothWays(vector<FixedBits*>& children, FixedBits& output, STPMgr* bm)
+ {
+ Result r0 = NO_CHANGE;
- Result r = bvUnsignedQuotientAndRemainder(children, output, bm,
- QUOTIENT_IS_OUTPUT);
+ // Enforce that the output must be less than the numerator.
+ // Make special allowance for 0/0 = 1.
+ for (int i = children[0]->getWidth() - 1; i > 0; i--)
+ {
+ if (children[0]->isFixedToZero(i))
+ {
+ if (output.isFixedToOne(i))
+ return CONFLICT;
+ else if (!output.isFixed(i))
+ {
+ output.setFixed(i, true);
+ output.setValue(i, false);
+ r0 = CHANGED;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
- // The current unsigned division doesn't even do constant propagation!!!!!
- /*
- if (r!= CONFLICT && children[0]->isTotallyFixed() && children[1]->isTotallyFixed())
- {
- cerr << *children[0] << " / ";
- cerr << *children[1];
- cerr << output << endl;
- assert(output.isTotallyFixed());
- }
- */
+ Result r = bvUnsignedQuotientAndRemainder(children, output, bm, QUOTIENT_IS_OUTPUT);
- return r;
-}
+ return merge(r0,r);
+ }
bool canBe(const FixedBits& b, int index, bool value) {
if (!b.isFixed(index))