// UMINUS, is NEG followed by +1
Result bvUnaryMinusBothWays(vector<FixedBits*>& children, FixedBits& output)
{
  assert(children.size() == 1);
  const int bitWidth = children[0]->getWidth();

  // If it's only one bit. This will be negative one.
  FixedBits one(bitWidth, false);
  one.fixToZero();
  one.setFixed(0, true);
  one.setValue(0, true);

  FixedBits notted(bitWidth, false);

  vector<FixedBits*> args;
  args.push_back(&notted);
  args.push_back(&one);

  Result result = NO_CHANGE;
  while (true) // until it fixed points
  {
    FixedBits initialNot(notted);
    FixedBits initialIn(*children[0]);
    FixedBits initialOut(output);

    result = bvNotBothWays(*children[0], notted);
    if (CONFLICT == result)
      return CONFLICT;

    result = bvAddBothWays(args, output);
    if (CONFLICT == result)
      return CONFLICT;

    if (FixedBits::equals(initialNot, notted) &&
        FixedBits::equals(initialIn, *children[0]) &&
        FixedBits::equals(initialOut, output))
      break;
  }

  return NOT_IMPLEMENTED; // don't set the status properly yet..
}
Пример #2
0
Result bvAddBothWays(vector<FixedBits*>& children, FixedBits& output)
{
        const size_t numberOfChildren = children.size();
        if (numberOfChildren==2)
        {
          return bvAddBothWays(*children[0],*children[1],output);
        }

	const unsigned bitWidth = output.getWidth();


	for (size_t i = 0; i < numberOfChildren; i++)
	{
		assert(children[i]->getWidth() == bitWidth );
	}

	int columnL[bitWidth]; // minimum  ""            ""
	int columnH[bitWidth]; // maximum number of true partial products.

	initialiseColumnCounts(columnL, columnH, bitWidth, numberOfChildren, children);

	int sumH[bitWidth];
	int sumL[bitWidth];
	sumL[0] = columnL[0];
	sumH[0] = columnH[0];

	for (unsigned i = /**/1 /**/; i < (unsigned) bitWidth; i++)
	{
		assert((columnH[i] >= columnL[i]) && (columnL[i] >= 0));
		sumH[i] = columnH[i] + (sumH[i - 1] / 2);
		sumL[i] = columnL[i] + (sumL[i - 1] / 2);
	}

	// Now the sums counts are all updated. And consistent with each other.

	bool changed = true;
	while (changed)
	{
		changed = false;

		// Make sure each column's sum is consistent with the output.
		for (unsigned i = 0; i < bitWidth; i++)
		{
			if (output.isFixed(i))
			{
				int expected = output.getValue(i) ? 1 : 0;

				// output is true. So the maximum and minimum can only be even.
				if (sumH[i] % 2 != expected)
				{
					sumH[i]--;
					changed = true;
				}
				if (sumL[i] % 2 != expected)
				{
					sumL[i]++;
					changed = true;
				}

				if (changed && ((sumH[i] < sumL[i]) || (sumL[i] < 0)))
					return CONFLICT;
			}
		}

		// update the column counts to make them consistent to the totals.
		for (unsigned i = /**/0 /**/; i < bitWidth; i++)
		{
			if (sumH[i] < columnH[i])
			{
				columnH[i]--;
				changed = true;

				if (columnH[i] < columnL[i])
					return CONFLICT;
			}
		}

		// Go from low to high making each of the sums consistent.
		for (unsigned i = /**/1 /**/; i < bitWidth; i++)
		{
			assert((columnH[i] >= columnL[i]) && (columnL[i] >= 0));
			if (sumH[i] > columnH[i] + (sumH[i - 1] / 2))
			{
				sumH[i] = columnH[i] + (sumH[i - 1] / 2);
				changed = true;
			}
			if (sumL[i] < columnL[i] + (sumL[i - 1] / 2))
			{
				sumL[i] = columnL[i] + (sumL[i - 1] / 2);
				changed = true;
			}

			if (changed && (sumH[i] < sumL[i] || sumL[i] < 0))
				return CONFLICT;

		}

		// go from high to low, making each of the sums consistent.
		for (int i = /**/(int)bitWidth - 1 /**/; i >= 1; i--)
		{
			if ((sumH[i] == sumL[i]))
			{
				stats s = getStats(children, i);

				if (0 == s.unfixed)
				{
					// amount that the prior column needs to contribute.
					int toContribute = (sumH[i] - s.fixedToOne) * 2;

					if (sumH[i - 1] > (toContribute + 1))
					{
						changed = true;
						sumH[i - 1] = toContribute + 1; // plus one because of rounding down.
					}

					if (sumL[i - 1] < toContribute)
					{
						changed = true;
						sumL[i - 1] = toContribute;
					}

					if (sumH[i - 1] < sumL[i - 1])
					{
						return CONFLICT;
					}
				}
			}
		}

		if (add_debug_messages)
		{
			std::cerr << "bottom" << std::endl;
			cerr << "columnL:";
			printArray(columnL, bitWidth);
			cerr << "columnH:";
			printArray(columnH, bitWidth);
			cerr << "sumL:";
			printArray(sumL, bitWidth);
			cerr << "sumH:";
			printArray(sumH, bitWidth);
		}

		for (unsigned column = 0; column < bitWidth; column++)
		{
			if (sumH[column] == sumL[column])
			{
				// (1) If the low and high sum is equal. Then the output is know.
				bool newResult = (sumH[column] % 2 == 0) ? false : true;

				if (!output.isFixed(column))
				{
					output.setFixed(column, true);
					output.setValue(column, newResult);
					changed = true;
				}
				else if (output.isFixed(column) && (output.getValue(column) != newResult))
					return CONFLICT;

				// (2) If this column has some unfixed values. Then we may be able to determine them.
				Result tempResult;
				if (0 == column)
					tempResult = fixIfCanForAddition(children, column, sumH[column], 0, 0);
				else
					tempResult = fixIfCanForAddition(children, column, sumH[column], sumL[column - 1] / 2, sumH[column - 1] / 2);

				if (CONFLICT == tempResult)
					return CONFLICT;

				if (CHANGED == tempResult)
					changed = true;

			}

		}
	}
	return NOT_IMPLEMENTED;
}