예제 #1
0
void setUnsignedMinMax(const FixedBits& v, CBV min, CBV max)
{
  CONSTANTBV::BitVector_Fill(max);
  CONSTANTBV::BitVector_Empty(min);

  for (unsigned i = 0; i < v.getWidth(); i++)
  {
    if (v.isFixed(i))
    {
      if (v.getValue(i)) // if it's on. It's on.

      {
        // CONSTANTBV::BitVector_Bit_On(max, i);
        CONSTANTBV::BitVector_Bit_On(min, i);
      }
      else
      {
        CONSTANTBV::BitVector_Bit_Off(max, i);
        // CONSTANTBV::BitVector_Bit_Off(min, i);
      }
    }
    // else // not fixed. Just set the max.
    //{
    //	CONSTANTBV::BitVector_Bit_On(max, i);
    //	CONSTANTBV::BitVector_Bit_Off(min, i);
    //}
  }
  assert(CONSTANTBV::BitVector_Lexicompare(min, max) <= 0);
}
예제 #2
0
    // If the bits are totally fixed, then return a new matching ASTNode.
    ASTNode
    bitsToNode(const ASTNode& node, const FixedBits& bits)
    {
      ASTNode result;
      STPMgr & beev = *node.GetSTPMgr();

      assert (bits.isTotallyFixed());
      assert (!node.isConstant()); // Peformance. Shouldn't waste time calling it on constants.

      if (node.GetType() == BOOLEAN_TYPE)
        {
          if (bits.getValue(0))
            {
              result = beev.CreateNode(TRUE);
            }
          else
            {
              result = beev.CreateNode(FALSE);
            }
        }
      else if (node.GetType() == BITVECTOR_TYPE)
        {
          result = beev.CreateBVConst(bits.GetBVConst(), node.GetValueWidth());
        }
      else
        FatalError("sadf234s");

      assert(result.isConstant());
      return result;
    }
예제 #3
0
    FixedBits*
    ConstantBitPropagation::getUpdatedFixedBits(const ASTNode& n)
    {
      FixedBits* output = getCurrentFixedBits(n);
      const Kind k = n.GetKind();

      if (n.isConstant())
        {
          assert(output->isTotallyFixed());
          return output;
        }

      if (SYMBOL == k)
        return output; // No transfer functions for these.

      vector<FixedBits*> children;
      const int numberOfChildren = n.GetChildren().size();
      children.reserve(numberOfChildren);

      for (int i = 0; i < numberOfChildren; i++)
        {
          children.push_back(getCurrentFixedBits(n.GetChildren()[i]));
        }

      assert(status != CONFLICT);
      status = dispatchToTransferFunctions(k, children, *output, n, msm);
      //result = dispatchToMaximallyPrecise(k, children, *output, n,msm);

      assert(((unsigned)output->getWidth()) == n.GetValueWidth() || output->getWidth() ==1);

      return output;
    }
예제 #4
0
void setValue(FixedBits& a, const int i, bool v)
{
  if (a.isFixed(i))
      return;

  a.setFixed(i,true);
  a.setValue(i,v);
}
Result bvConcatBothWays(vector<FixedBits*>& children, FixedBits& output)
{
  Result r = NO_CHANGE;
  const size_t numberOfChildren = children.size();
  unsigned current = 0;
  for (int i = (int)numberOfChildren - 1; i >= 0;
       i--) // least significant is last.
  {
    FixedBits& child = *children[i];
    for (unsigned j = 0; j < child.getWidth(); j++)
    {
      // values are different. Bad.
      if (output.isFixed(current) && child.isFixed(j) &&
          (output.getValue(current) != child.getValue(j)))
        return CONFLICT;

      if (output.isFixed(current) && !child.isFixed(j))
      {
        // only output is fixed.
        child.setFixed(j, true);
        child.setValue(j, output.getValue(current));
        r = CHANGED;
      }
      else if (!output.isFixed(current) && child.isFixed(j))
      {
        // only input is fixed.
        output.setFixed(current, true);
        output.setValue(current, child.getValue(j));
        r = CHANGED;
      }
      current++;
    }
  }
  return r;
}
Result bvZeroExtendBothWays(vector<FixedBits*>& children, FixedBits& output)
{
  assert(children.size() == 2);
  // The second argument is a junk size arugment.

  FixedBits& input = *children[0];
  const int inputBitWidth = input.getWidth();
  const int outputBitWidth = output.getWidth();

  Result result = makeEqual(input, output, 0, inputBitWidth);
  if (CONFLICT == result)
    return CONFLICT;

  // Fix all the topmost bits of the output to zero.
  for (int i = inputBitWidth; i < outputBitWidth; i++)
  {
    if (output.isFixed(i) && output.getValue(i))
      return CONFLICT; // set to one. Never right.
    else if (!output.isFixed(i))
    {
      output.setFixed(i, true);
      output.setValue(i, false);
      result = CHANGED;
    }
  }
  return result;
}
Result bvSignExtendBothWays(vector<FixedBits*>& children, FixedBits& output)
{
  assert(children.size() == 2);
  // The second argument is a junk size arugment.

  FixedBits& input = *children[0];
  const int inputBitWidth = input.getWidth();
  const int outputBitWidth = output.getWidth();
  assert(inputBitWidth <= outputBitWidth);

  Result result = makeEqual(input, output, 0, inputBitWidth);
  if (CONFLICT == result)
    return CONFLICT;

  // If any of the topmost bits of the output are fixed. Then they all should
  // be.
  // They should all be fixed to the same value.
  bool found = false;
  bool setTo;
  for (int i = inputBitWidth - /**/ 1 /**/; i < outputBitWidth; i++)
  {
    if (output.isFixed(i))
    {
      setTo = output.getValue(i);
      found = true;
      break;
    }
  }

  if (found)
  {
    for (int i = inputBitWidth - 1; i < outputBitWidth; i++)
    {
      if (output.isFixed(i) && (output.getValue(i) != setTo))
        return CONFLICT; // if any are set to the wrong value! bad.
      else if (!output.isFixed(i))
      {
        output.setFixed(i, true);
        output.setValue(i, setTo);
        result = CHANGED;
      }
    }

    Result result2 = makeEqual(input, output, 0, inputBitWidth);
    if (CONFLICT == result2)
      return CONFLICT;
  }
  return result;
}
예제 #8
0
void setSignedMinMax(FixedBits& v, CBV min, CBV max)
{
  const unsigned int msb = v.getWidth() - 1;

  for (unsigned i = 0; i < (unsigned)v.getWidth(); i++)
  {
    if (v.isFixed(i))
    {
      if (v.getValue(i)) // if it's on. It's on.

      {
        CONSTANTBV::BitVector_Bit_On(max, i);
        CONSTANTBV::BitVector_Bit_On(min, i);
      }
      else
      {
        CONSTANTBV::BitVector_Bit_Off(max, i);
        CONSTANTBV::BitVector_Bit_Off(min, i);
      }
    }
    else
    {
      if (i != msb)
      { // not fixed. Make the maximum Maximum.
        CONSTANTBV::BitVector_Bit_On(max, i);
        CONSTANTBV::BitVector_Bit_Off(min, i);
      }
      else
      { // except for the msb. Where we reduce the min.
        CONSTANTBV::BitVector_Bit_On(min, i);
        CONSTANTBV::BitVector_Bit_Off(max, i);
      }
    }
  }
  assert(CONSTANTBV::BitVector_Compare(min, max) <= 0);
}
Result bvExtractBothWays(vector<FixedBits*>& children, FixedBits& output)
{
  const size_t numberOfChildren = children.size();
  const unsigned outputBitWidth = output.getWidth();

  Result result = NO_CHANGE;

  assert(3 == numberOfChildren);

  unsigned top = children[1]->getUnsignedValue();
  unsigned bottom = children[2]->getUnsignedValue();

  FixedBits& input = *(children[0]);

  assert(top >= bottom);
  assert(top - bottom + 1 == outputBitWidth);
  assert(top < input.getWidth());

  for (unsigned outputPosition = 0; outputPosition < outputBitWidth;
       outputPosition++)
  {
    unsigned inputPosition = outputPosition + bottom;

    if (input.isFixed(inputPosition) && output.isFixed(outputPosition))
      if (input.getValue(inputPosition) ^ output.getValue(outputPosition))
        return CONFLICT;

    if (input.isFixed(inputPosition) ^ output.isFixed(outputPosition))
    {
      if (input.isFixed(inputPosition))
      {
        output.setFixed(outputPosition, true);
        output.setValue(outputPosition, input.getValue(inputPosition));
        result = CHANGED;
      }
      else
      {
        input.setFixed(inputPosition, true);
        input.setValue(inputPosition, output.getValue(outputPosition));
        result = CHANGED;
      }
    }
  }

  // cerr << "extract[" << top << ":" << bottom << "]" << input << "=" <<
  // output<< endl;

  return result;
}
예제 #10
0
    // get the current value from the map. If no value is in the map. Make a new value.
    FixedBits*
    ConstantBitPropagation::getCurrentFixedBits(const ASTNode& n)
    {
      assert (NULL != fixedMap);

      NodeToFixedBitsMap::NodeToFixedBitsMapType::iterator it = fixedMap->map->find(n);
      if (it != fixedMap->map->end())
        {
          return it->second;
        }

      int bw;
      if (0 == n.GetValueWidth())
        {
          bw = 1;
        }
      else
        {
          bw = n.GetValueWidth();
        }

      FixedBits* output = new FixedBits(bw, (BOOLEAN_TYPE == n.GetType()));

      if (BVCONST == n.GetKind() || BITVECTOR == n.GetKind())
        {
          // the CBV doesn't leak. it is a copy of the cbv inside the node.
          CBV cbv = n.GetBVConst();

          for (unsigned int j = 0; j < n.GetValueWidth(); j++)
            {
              output->setFixed(j, true);
              output->setValue(j, CONSTANTBV::BitVector_bit_test(cbv, j));
            }
        }
      else if (TRUE == n.GetKind())
        {
          output->setFixed(0, true);
          output->setValue(0, true);
        }
      else if (FALSE == n.GetKind())
        {
          output->setFixed(0, true);
          output->setValue(0, false);
        }

       fixedMap->map->insert(pair<ASTNode, FixedBits*> (n, output));
      return output;
    }
예제 #11
0
Result bvXorBothWays(vector<FixedBits*>& operands, FixedBits& output)
{
  Result result = NO_CHANGE;
  const int bitWidth = output.getWidth();

  for (int i = 0; i < bitWidth; i++)
  {
    const stats status = getStats(operands, i);

    if (status.unfixed == 0) // if they are all fixed. We know the answer.
    {
      bool answer = (status.fixedToOne % 2) != 0;

      if (!output.isFixed(i))
      {
        output.setFixed(i, true);
        output.setValue(i, answer);
        result = CHANGED;
      }
      else if (output.getValue(i) != answer)
        return CONFLICT;
    }
    else if (status.unfixed == 1 && output.isFixed(i))
    {
      // If there is just one unfixed, and we have the answer --> We know the
      // value.
      bool soFar = ((status.fixedToOne % 2) != 0);
      if (soFar != output.getValue(i))
      { // result needs to be flipped.
        fixUnfixedTo(operands, i, true);
      }
      else
        fixUnfixedTo(operands, i, false);
      result = CHANGED;
    }
  }
  return result;
}
// If the guard is fixed, make equal the appropriate input and output.
// If one input can not possibly be the output. Then set the guard to make it
// the other one.
// If both values are the same. Set the output to that value.
Result bvITEBothWays(vector<FixedBits*>& children, FixedBits& output)
{
  Result result = NO_CHANGE;

  assert(3 == children.size());
  const int bitWidth = output.getWidth();
  FixedBits& guard = *children[0];
  FixedBits& c1 = *children[1];
  FixedBits& c2 = *children[2];

  assert(c1.getWidth() == c2.getWidth());
  assert(output.getWidth() == c2.getWidth());

  if (guard.isFixed(0) && guard.getValue(0))
  { // guard fixed to true. So make (first arg == output)
    result = makeEqual(output, c1, 0, bitWidth);
    if (CONFLICT == result)
      return CONFLICT;
  }
  else if (guard.isFixed(0) && !guard.getValue(0))
  {
    result = makeEqual(output, c2, 0, bitWidth);
    if (CONFLICT == result)
      return CONFLICT;
  }
  else
  {
    for (int i = 0; i < bitWidth; i++)
    {
      if (c1.isFixed(i) && c2.isFixed(i) && (c1.getValue(i) == c2.getValue(i)))
      {

        if (output.isFixed(i) && (output.getValue(i) != c1.getValue(i)))
          return CONFLICT;

        if (!output.isFixed(i))
        {
          output.setFixed(i, true);
          output.setValue(i, c1.getValue(i));
          result = CHANGED;
        }
      }
    }
  }

  bool changed = false;
  if (CHANGED == result)
    changed = true;

  for (int i = 0; i < bitWidth; i++)
  {
    if (output.isFixed(i))
    {
      if (c1.isFixed(i) && (c1.getValue(i) != output.getValue(i)))
      {
        // c1 is fixed to a value that's not the same as the output.
        if (!guard.isFixed(0))
        {
          guard.setFixed(0, true);
          guard.setValue(0, false);
          result = bvITEBothWays(children, output);
          if (CONFLICT == result)
            return CONFLICT;
          changed = true;
        }
        else if (guard.getValue(0))
          return CONFLICT;
      }

      if (c2.isFixed(i) && (c2.getValue(i) != output.getValue(i)))
      {
        // c2 is fixed to a value that's not the same as the output.
        if (!guard.isFixed(0))
        {
          guard.setFixed(0, true);
          guard.setValue(0, true);
          result = bvITEBothWays(children, output);
          if (CONFLICT == result)
            return CONFLICT;
          changed = true;
        }
        else if (!guard.getValue(0))
          return CONFLICT;
      }
    }
  }

  if (result == CONFLICT)
    return CONFLICT;
  if (changed)
    return CHANGED;

  return result;
}
// if a==b then fix the result to true.
// if a!=b then fix the result to false.
Result bvEqualsBothWays(FixedBits& a, FixedBits& b, FixedBits& output)
{
  assert(a.getWidth() == b.getWidth());
  assert(1 == output.getWidth());

  const int childWidth = a.getWidth();

  Result r = NO_CHANGE;

  bool allSame = true;
  bool definatelyFalse = false;

  for (int i = 0; i < childWidth; i++)
  {
    // if both fixed
    if (a.isFixed(i) && b.isFixed(i))
    {
      // And have different values.
      if (a.getValue(i) != b.getValue(i))
      {
        definatelyFalse = true;
        break;
      }
      else
      {
        allSame &= true;
        continue;
      }
    }
    allSame &= false;
  }

  if (definatelyFalse)
  {
    if (output.isFixed(0) && output.getValue(0))
    {
      return CONFLICT;
    }
    else if (!output.isFixed(0))
    {
      output.setFixed(0, true);
      output.setValue(0, false);
      r = CHANGED;
    }
  }
  else if (allSame)
  {
    if (output.isFixed(0) && !output.getValue(0))
    {
      return CONFLICT;
    }
    else if (!output.isFixed(0))
    {
      output.setFixed(0, true);
      output.setValue(0, true);
      r = CHANGED;
    }
  }

  if (output.isFixed(0) && output.getValue(0)) // all should be the same.
  {
    for (int i = 0; i < childWidth; i++)
    {
      if (a.isFixed(i) && b.isFixed(i))
      {
        if (a.getValue(i) != b.getValue(i))
        {
          return CONFLICT;
        }
      }
      else if (a.isFixed(i) != b.isFixed(i)) // both same but only one is fixed.
      {
        if (a.isFixed(i))
        {
          b.setFixed(i, true);
          b.setValue(i, a.getValue(i));
          r = CHANGED;
        }
        else
        {
          a.setFixed(i, true);
          a.setValue(i, b.getValue(i));
          r = CHANGED;
        }
      }
    }
  }

  // if the result is fixed to false, there is a single unspecied value, and all
  // the rest are the same. Fix it to the opposite.
  if (output.isFixed(0) && !output.getValue(0))
  {
    int unknown = 0;

    for (int i = 0; i < childWidth && unknown < 2; i++)
    {
      if (!a.isFixed(i))
        unknown++;
      if (!b.isFixed(i))
        unknown++;
      else if (a.isFixed(i) && b.isFixed(i) && a.getValue(i) != b.getValue(i))
      {
        unknown = 10; // hack, don't do the next loop.
        break;
      }
    }

    if (1 == unknown)
    {
      for (int i = 0; i < childWidth; i++)
      {
        if (!a.isFixed(i))
        {
          a.setFixed(i, true);
          a.setValue(i, !b.getValue(i));
          r = CHANGED;
        }
        if (!b.isFixed(i))
        {
          b.setFixed(i, true);
          b.setValue(i, !a.getValue(i));
          r = CHANGED;
        }
      }
    }
  }
  return r;
}
예제 #14
0
Result makeEqual(FixedBits& a, FixedBits& b, unsigned from, unsigned to)
{
  assert(to >= from);
  assert(from <= a.getWidth());
  assert(from <= b.getWidth());

  Result result = NO_CHANGE;
  for (unsigned i = from; i < to; i++)
  {
    if (a.isFixed(i) && !b.isFixed(i))
    {
      b.setFixed(i, true);
      b.setValue(i, a.getValue(i));
      result = CHANGED;
    }
    else if (b.isFixed(i) && !a.isFixed(i))
    {
      a.setFixed(i, true);
      a.setValue(i, b.getValue(i));
      result = CHANGED;
    }
    else if (b.isFixed(i) && a.isFixed(i))
    {
      if (a.getValue(i) != b.getValue(i))
        return CONFLICT;
    }
  }
  return result;
}
예제 #15
0
Result bvOrBothWays(vector<FixedBits*>& children, FixedBits& output)
{
  Result r = NO_CHANGE;
  const int numberOfChildren = children.size();
  const int bitWidth = output.getWidth();

  for (int i = 0; i < bitWidth; i++)
  {
    bool answerKnown = output.isFixed(i);
    bool answer = false;
    if (answerKnown)
      answer = output.getValue(i);

    int unks = 0;
    int ones = 0;
    int zeroes = 0;

    for (int j = 0; j < numberOfChildren; j++)
    {
      assert(output.getWidth() == children[j]->getWidth());

      if (!children[j]->isFixed(i))
        unks++;
      else if (children[j]->getValue(i))
        ones++;
      else
        zeroes++;
    }

    if (ones > 0) // Atleast a single one found!

    {
      if (answerKnown && !answer)
        return CONFLICT;

      if (!answerKnown)
      {
        output.setFixed(i, true);
        output.setValue(i, true);
        r = CHANGED;
      }
    }

    if (zeroes == numberOfChildren) // all zeroes.

    {
      if (answerKnown && answer)
        return CONFLICT;

      if (!answerKnown)
      {
        r = CHANGED;
        output.setFixed(i, true);
        output.setValue(i, false);
      }
    }

    if (answerKnown && !answer) // known false

    {
      if (ones > 0)
        return CONFLICT;

      // set all the column to false.

      for (int j = 0; j < numberOfChildren; j++)
      {
        if (!children[j]->isFixed(i))
        {
          r = CHANGED;
          children[j]->setFixed(i, true);
          children[j]->setValue(i, false);
        }
      }
    }

    if (unks == 1 && answerKnown && answer &&
        (zeroes == (numberOfChildren - 1)))
    {
      // A single unknown, everything else is false. The answer is true. So the
      // unknown is true.

      for (int j = 0; j < numberOfChildren; j++)
      {
        if (!children[j]->isFixed(i))
        {
          r = CHANGED;
          children[j]->setFixed(i, true);
          children[j]->setValue(i, true);
        }
      }
    }
  }
  return r;
}
예제 #16
0
Result bvImpliesBothWays(vector<FixedBits*>& children, FixedBits& result)
{

  FixedBits& a = (*children[0]);
  FixedBits& b = (*children[1]);

  assert(a.getWidth() == result.getWidth());
  const int bitWidth = a.getWidth();
  assert(bitWidth == 1);

  Result r = NO_CHANGE;

  int i = 0;

  //  (false -> something) is always true.
  //  (something -> true ) is always true.
  if (a.isFixedToZero(i) || b.isFixedToOne(i))
  {
    if (!result.isFixed(i))
    {
      result.setFixed(i, true);
      result.setValue(i, true);
      r = CHANGED;
    }
    else if (result.isFixedToZero(i))
      return CONFLICT;
  }

  // If the result is false. it must be (true -> false)
  if (result.isFixedToZero(i))
  {
    if (a.isFixedToZero(i) || b.isFixedToOne(i))
      return CONFLICT;

    if (!a.isFixed(i))
    {
      a.setFixed(i, true);
      a.setValue(i, true);
      r = CHANGED;
    }
    if (!b.isFixed(i))
    {
      b.setFixed(i, true);
      b.setValue(i, false);
      r = CHANGED;
    }
  }

  if (result.isFixedToOne(i))
  {
    if (a.isFixedToOne(i))
    {
      if (!b.isFixed(i))
      {
        b.setFixed(i, true);
        b.setValue(i, true);
        r = CHANGED;
      }
      else if (b.isFixedToZero(i))
        return CONFLICT;
    }

    if (b.isFixedToZero(i))
    {
      if (!a.isFixed(i))
      {
        a.setFixed(i, true);
        a.setValue(i, false);
        r = CHANGED;
      }
    }
  }

  if (a.isFixedToOne(i) && b.isFixedToZero(i))
  {
    if (result.isFixedToOne(i))
      return CONFLICT;
    if (!result.isFixed(i))
    {
      result.setFixed(i, true);
      result.setValue(i, false);
      r = CHANGED;
    }
  }

  return r;
}
예제 #17
0
Result bvNotBothWays(FixedBits& a, FixedBits& output)
{
  assert(a.getWidth() == output.getWidth());
  const int bitWidth = a.getWidth();

  Result result = NO_CHANGE;

  for (int i = 0; i < bitWidth; i++)
  {
    // error if they are the same.
    if (a.isFixed(i) && output.isFixed(i) &&
        (a.getValue(i) == output.getValue(i)))
    {
      return CONFLICT;
    }

    if (a.isFixed(i) && !output.isFixed(i))
    {
      output.setFixed(i, true);
      output.setValue(i, !a.getValue(i));
      result = CHANGED;
    }

    if (output.isFixed(i) && !a.isFixed(i))
    {
      a.setFixed(i, true);
      a.setValue(i, !output.getValue(i));
      result = CHANGED;
    }
  }
  return result;
}
예제 #18
0
// Specialisation for two operands.
    Result
    bvAddBothWays(FixedBits& x, FixedBits& y, FixedBits& output)
    {
      const int bitWidth = output.getWidth();
      FixedBits carry(bitWidth + 1, false);
      carry.setFixed(0, true);
      carry.setValue(0, false);

      //cerr << "input" << x << y << output << endl;

      for (int i = 0; i < bitWidth; i++)
        {
        //cerr << i << ":"<< x[i] << y[i] << carry[i] << "=" << output[i]<< endl;

        int lb = (x[i] == '1' ? 1 : 0) + (y[i] == '1' ? 1 : 0) + (carry[i] == '1' ? 1 : 0);
        int ub = (x[i] == '0' ? 0 : 1) + (y[i] == '0' ? 0 : 1) + (carry[i] == '0' ? 0 : 1);

        const int lb_initial = lb;
        const int ub_initial = ub;

        if (carry[i+1] == '1') // carry out is true.
          lb = std::max(2, lb);

        if (carry[i+1] == '0') // carry out is false.
          ub = std::min(1, ub);

        const char output_i = output[i];
        if (output_i == '1' && (lb % 2 == 0))
          lb++;

        if (output_i == '0' && (lb % 2 == 1))
          lb++;

        if (output_i == '1' && (ub % 2 == 0))
          ub--;

        if (output_i == '0' && (ub % 2 == 1))
          ub--;

        if (lb >= 2)
          setValue(carry, i+1, true);

        if (ub <= 1)
          setValue(carry, i+1, false);

        if (ub < lb)
          return CONFLICT;

        if (lb == ub)
          {
            setValue(output, i, ((lb % 2) == 1));

            if (lb_initial  ==lb)
              {
                if (!x.isFixed(i))
                  setValue(x, i, false);
                if (!y.isFixed(i))
                  setValue(y, i, false);
                if (!carry.isFixed(i))
                  {
                  setValue(carry, i, false);
                  i = std::max(i-2,-1); // go back to the prior column.
                  continue;
                  }
              }

            if (ub_initial ==lb)
              {
                if (!x.isFixed(i))
                  setValue(x, i, true);
                if (!y.isFixed(i))
                  setValue(y, i, true);
                if (!carry.isFixed(i))
                  {
                  setValue(carry, i, true);
                  i = std::max(i-2,-1); // go back to the prior column.
                  continue;
                  }

              }
          }
        //cerr << i << "[" << ub << ":" << lb << "]" << endl;
        }

      return NOT_IMPLEMENTED;
    }
예제 #19
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;
}
예제 #20
0
// if output bit is true. Fix all the operands.
// if all the operands are fixed. Fix the output.
// given 1,1,1,- == 0, fix - to 0.
Result bvAndBothWays(vector<FixedBits*>& operands, FixedBits& output)
{
  Result result = NO_CHANGE;
  const int bitWidth = output.getWidth();

  for (int i = 0; i < bitWidth; i++)
  {
    const stats status = getStats(operands, i);

    // output is fixed to one. But an input value is false!
    if (output.isFixed(i) && output.getValue(i) && status.fixedToZero > 0)
      return CONFLICT;

    // output is fixed to one. But an input value is false!
    if (output.isFixed(i) && !output.getValue(i) && status.fixedToZero == 0 &&
        status.unfixed == 0)
      return CONFLICT;

    // output is fixed to one. So all should be one.
    if (output.isFixed(i) && output.getValue(i) && status.unfixed > 0)
    {
      fixUnfixedTo(operands, i, true);
      result = CHANGED;
    }

    // The output is unfixed. At least one input is false.
    if (!output.isFixed(i) && status.fixedToZero > 0)
    {
      output.setFixed(i, true);
      output.setValue(i, false);
      result = CHANGED;
    }

    // Everything is fixed to one!
    if (!output.isFixed(i) && status.fixedToZero == 0 && status.unfixed == 0)
    {
      output.setFixed(i, true);
      output.setValue(i, true);
      result = CHANGED;
    }

    // If the output is false, and there is a single unfixed value with
    // everything else true..
    if (output.isFixed(i) && !output.getValue(i) && status.fixedToZero == 0 &&
        status.unfixed == 1)
    {
      fixUnfixedTo(operands, i, false);
      result = CHANGED;
    }
  }
  return result;
}