예제 #1
0
char *
btor_add_unbounded_const (BtorMemMgr * mm, const char *a, const char *b)
{
  char *res, *r, c, x, y, s, *tmp;
  int alen, blen, rlen;
  const char *p, *q;

  assert (mm != NULL);
  assert (a != NULL);
  assert (b != NULL);
  assert (is_valid_const (a));
  assert (is_valid_const (b));

  a = strip_zeroes (a);
  b = strip_zeroes (b);

  if (!*a)
    return btor_strdup (mm, b);

  if (!*b)
    return btor_strdup (mm, a);

  alen = (int) strlen (a);
  blen = (int) strlen (b);
  rlen = (alen < blen) ? blen : alen;
  rlen++;

  BTOR_NEWN (mm, res, rlen + 1);

  p = a + alen;
  q = b + blen;

  c = '0';

  r = res + rlen;
  *r = 0;

  while (res < r)
    {
      x = (a < p) ? *--p : '0';
      y = (b < q) ? *--q : '0';
      s = x ^ y ^ c;
      c = (x & y) | (x & c) | (y & c);
      *--r = s;
    }

  p = strip_zeroes (res);
  if ((p != res))
    {
      tmp = btor_copy_const (mm, p);
      btor_delete_const (mm, res);
      res = tmp;
    }

  return res;
}
예제 #2
0
static void
dump_const_value_aux_smt (BtorSMTDumpContext * sdc, char * bits)
{
  assert (sdc);
  assert (bits);

  int base;
  FILE *file;
  char *val;
  const char *fmt;
  BtorPtrHashBucket *b;

  base = sdc->btor->options.output_number_format.val;
  file = sdc->file;

  /* converting consts to decimal/hex is costly. we now always dump the value of
   * constants. in order to avoid computing the same value again we cache
   * the result of the first computation and print the cached value in
   * subsequent calls. */
  if (base == BTOR_OUTPUT_BASE_DEC)
    {
      if ((b = btor_find_in_ptr_hash_table (sdc->const_cache, bits)))
        {
          val = b->data.asStr;
          assert (val);
        }
      else
        {
          val = btor_const_to_decimal (sdc->btor->mm, bits);
          btor_insert_in_ptr_hash_table (sdc->const_cache,
              btor_strdup (sdc->btor->mm, bits))->data.asStr = val;
        }
      fmt = "(_ bv%s %d)";
      fprintf (file, fmt, val, strlen (bits));
    }
  else if (base == BTOR_OUTPUT_BASE_HEX && strlen (bits) % 4 == 0)
    {
      if ((b = btor_find_in_ptr_hash_table (sdc->const_cache, bits)))
        {
          val = b->data.asStr;
          assert (val);
        }
      else
        {
          val = btor_const_to_hex (sdc->btor->mm, bits);
          btor_insert_in_ptr_hash_table (sdc->const_cache,
              btor_strdup (sdc->btor->mm, bits))->data.asStr = val;
        }
      fprintf (file, "#x%s", val);
    }
  else
    btor_dump_const_value_smt (sdc->btor, bits, base, file);
}
예제 #3
0
char *
btor_decimal_to_const_n (BtorMemMgr * mem, const char *str, int len)
{
  const char *end, *p;
  char *res, *tmp;

  assert (mem != NULL);
  assert (str != NULL);
  assert (len >= 0);

  res = btor_strdup (mem, "");

  end = str + len;
  for (p = str; p < end; p++)
    {
      tmp = btor_mult_unbounded_const (mem, res, "1010");       /* *10 */
      btor_delete_const (mem, res);
      res = tmp;

      tmp = btor_add_unbounded_const (mem, res, digit2const (*p));
      btor_delete_const (mem, res);
      res = tmp;
    }

  assert (strip_zeroes (res) == res);

  return res;
}
예제 #4
0
char *
btor_copy_const (BtorMemMgr * mm, const char *c)
{
  assert (mm != NULL);
  assert (c != NULL);
  assert (is_valid_const_3vl (c));

  return btor_strdup (mm, c);
}
예제 #5
0
char *
btor_const_to_hex (BtorMemMgr * mem, const char *c)
{
  int clen, rlen, i, j, tmp;
  char *res, ch;

  assert (mem != NULL);
  assert (c != NULL);
  assert (is_valid_const (c));

  clen = (int) strlen (c);
  rlen = (clen + 3) / 4;

  if (rlen)
    {
      BTOR_NEWN (mem, res, rlen + 1);

      i = clen - 1;
      j = rlen;

      res[j--] = 0;

      while (i >= 0)
        {
          tmp = (c[i--] == '1');
          if (i >= 0)
            {
              tmp |= (c[i--] == '1') << 1;
              if (i >= 0)
                {
                  tmp |= (c[i--] == '1') << 2;
                  if (i >= 0)
                    tmp |= (c[i--] == '1') << 3;
                }
            }

          if (tmp < 10)
            ch = '0' + tmp;
          else
            ch = 'a' + (tmp - 10);

          res[j--] = ch;
        }
    }
  else
    res = btor_strdup (mem, "0");

  return res;
}
예제 #6
0
static char *
btor_srl_n_bits_const (BtorMemMgr * mm, const char *a, int n)
{
  char *result;
  int len, i;

  assert (mm != NULL);
  assert (a != NULL);
  assert (is_valid_const_3vl (a));
  assert (n >= 0);
  assert (n < (int) strlen (a));

  len = (int) strlen (a);
  if (len == 0)
    return btor_strdup (mm, a);
  BTOR_NEWN (mm, result, len + 1);
  for (i = 0; i < n; i++)
    result[i] = '0';
  for (i = n; i < len; i++)
    result[i] = a[i - n];
  result[len] = '\0';
  return result;
}
예제 #7
0
파일: btorbtor.c 프로젝트: hellok/kint
static BtorNode *
parse_constd (BtorBTORParser * parser, int len)
{
  char ch, *tmp, * extended;
  BtorNode *res;
  int clen;

  if (parse_space (parser))
    return 0;

  assert (BTOR_EMPTY_STACK (parser->constant));

  ch = btor_nextch_btor (parser);
  if (!isdigit (ch))
    {
      (void) btor_perr_btor (parser, "expected digit");
      return 0;
    }

  BTOR_PUSH_STACK (parser->mem, parser->constant, ch);

  if (ch == '0')
    {
      ch = btor_nextch_btor (parser);

      if (isdigit (ch))
	{
	  (void) btor_perr_btor (parser, "digit after '0'");
	  return 0;
	}

      tmp = btor_strdup (parser->mem, "");
    }
  else
    {
      while (isdigit (ch = btor_nextch_btor (parser)))
	BTOR_PUSH_STACK (parser->mem, parser->constant, ch);

      clen = BTOR_COUNT_STACK (parser->constant);

      tmp = btor_decimal_to_const_n (parser->mem,
				     parser->constant.start, clen);
    }

  BTOR_PUSH_STACK (parser->mem, parser->constant, 0);
  BTOR_RESET_STACK (parser->constant);

  btor_savech_btor (parser, ch);

  clen = (int) strlen (tmp);
  if (clen > len)
    {
      (void) btor_perr_btor (parser,
			  "decimal constant '%s' exceeds bit width %d",
			  parser->constant.start, len);
      btor_freestr (parser->mem, tmp);
      return 0;
    }

  if (clen < len)
    {
      extended = btor_uext_const (parser->mem, tmp, len - clen);
      btor_delete_const (parser->mem, tmp);
      tmp = extended;
    }

  assert (len == (int) strlen (tmp));
  res = btor_const_exp (parser->btor, tmp);
  btor_delete_const (parser->mem, tmp);

  assert (btor_get_exp_len (parser->btor, res) == len);

  return res;
}
예제 #8
0
char *
btor_sub_unbounded_const (BtorMemMgr * mem, const char *a, const char *b)
{
  char *res, *tmp, *r, c, x, y, s;
  int alen, blen, rlen;
  const char *p, *q;

  assert (mem != NULL);
  assert (a != NULL);
  assert (b != NULL);
  assert (is_valid_const (a));
  assert (is_valid_const (b));
  assert (btor_cmp_const (b, a) <= 0);

  a = strip_zeroes (a);
  b = strip_zeroes (b);
  if (!*b)
    return btor_strdup (mem, a);

  alen = (int) strlen (a);
  blen = (int) strlen (b);

  assert (alen >= blen);
  rlen = alen;

  BTOR_NEWN (mem, res, rlen + 1);

  p = a + alen;
  q = b + blen;

  c = '0';
  r = res + rlen;
  *r = 0;

  while (res < r)
    {
      assert (a < p);
      x = *--p;

      y = (b < q) ? *--q : '0';

      s = x ^ y ^ c;
      c = ((1 ^ x) & c) | ((1 ^ x) & y) | (y & c);

      *--r = s;
    }

  assert (c == '0');

#ifndef NDEBUG
  {
    tmp = btor_add_unbounded_const (mem, res, b);
    assert (!btor_cmp_const (tmp, a));
    btor_freestr (mem, tmp);
  }
#endif

  tmp = btor_strdup (mem, strip_zeroes (res));
  btor_freestr (mem, res);
  res = tmp;

  return res;
}
예제 #9
0
char *
btor_mult_unbounded_const (BtorMemMgr * mm, const char *a, const char *b)
{
  char *res, *r, c, x, y, s, m;
  int alen, blen, rlen, i;
  const char *p;

  assert (mm != NULL);
  assert (a != NULL);
  assert (b != NULL);
  assert (is_valid_const (a));
  assert (is_valid_const (b));

  a = strip_zeroes (a);

  if (!*a)
    return btor_strdup (mm, "");

  if (a[0] == '1' && !a[1])
    return btor_strdup (mm, b);

  b = strip_zeroes (b);

  if (!*b)
    return btor_strdup (mm, "");

  if (b[0] == '1' && !b[1])
    return btor_strdup (mm, a);

  alen = (int) strlen (a);
  blen = (int) strlen (b);
  rlen = alen + blen;
  BTOR_NEWN (mm, res, rlen + 1);
  res[rlen] = 0;

  for (r = res; r < res + blen; r++)
    *r = '0';

  for (p = a; p < a + alen; p++)
    *r++ = *p;

  assert (r == res + rlen);

  for (i = 0; i < alen; i++)
    {
      m = res[rlen - 1];
      c = '0';

      if (m == '1')
        {
          p = b + blen;
          r = res + blen;

          while (res < r)
            {
              x = *--p;
              y = *--r;
              s = x ^ y ^ c;
              c = (x & y) | (x & c) | (y & c);
              *r = s;
            }
        }

      memmove (res + 1, res, rlen - 1);
      res[0] = c;
    }

  return res;
}
예제 #10
0
char *
btor_hex_to_const_n (BtorMemMgr * mem, const char *str, int hlen)
{
  const char *p, *end;
  char *tmp, *res, *q;
  int len;

  assert (mem != NULL);
  assert (str != NULL);
  assert (hlen >= 0);

  len = 4 * hlen;
  BTOR_NEWN (mem, tmp, len + 1);
  q = tmp;

  end = str + hlen;
  for (p = str; p < end; p++)
    switch (*p)
      {
      case '0':
        *q++ = '0';
        *q++ = '0';
        *q++ = '0';
        *q++ = '0';
        break;
      case '1':
        *q++ = '0';
        *q++ = '0';
        *q++ = '0';
        *q++ = '1';
        break;
      case '2':
        *q++ = '0';
        *q++ = '0';
        *q++ = '1';
        *q++ = '0';
        break;
      case '3':
        *q++ = '0';
        *q++ = '0';
        *q++ = '1';
        *q++ = '1';
        break;
      case '4':
        *q++ = '0';
        *q++ = '1';
        *q++ = '0';
        *q++ = '0';
        break;
      case '5':
        *q++ = '0';
        *q++ = '1';
        *q++ = '0';
        *q++ = '1';
        break;
      case '6':
        *q++ = '0';
        *q++ = '1';
        *q++ = '1';
        *q++ = '0';
        break;
      case '7':
        *q++ = '0';
        *q++ = '1';
        *q++ = '1';
        *q++ = '1';
        break;
      case '8':
        *q++ = '1';
        *q++ = '0';
        *q++ = '0';
        *q++ = '0';
        break;
      case '9':
        *q++ = '1';
        *q++ = '0';
        *q++ = '0';
        *q++ = '1';
        break;
      case 'A':
      case 'a':
        *q++ = '1';
        *q++ = '0';
        *q++ = '1';
        *q++ = '0';
        break;
      case 'B':
      case 'b':
        *q++ = '1';
        *q++ = '0';
        *q++ = '1';
        *q++ = '1';
        break;
      case 'C':
      case 'c':
        *q++ = '1';
        *q++ = '1';
        *q++ = '0';
        *q++ = '0';
        break;
      case 'D':
      case 'd':
        *q++ = '1';
        *q++ = '1';
        *q++ = '0';
        *q++ = '1';
        break;
      case 'E':
      case 'e':
        *q++ = '1';
        *q++ = '1';
        *q++ = '1';
        *q++ = '0';
        break;
      case 'F':
      case 'f':
      default:
        assert (*p == 'f' || *p == 'F');
        *q++ = '1';
        *q++ = '1';
        *q++ = '1';
        *q++ = '1';
        break;
      }

  assert (tmp + len == q);
  *q++ = 0;

  res = btor_strdup (mem, strip_zeroes (tmp));
  btor_freestr (mem, tmp);

  return res;
}
예제 #11
0
char *
btor_udiv_unbounded_const (BtorMemMgr * mem,
                           const char *dividend, const char *divisor,
                           char **rem_ptr)
{
  char *quotient, *rest, *extended_divisor, *tmp;
  int delta, plen, qlen;
  const char *p, *q;

  assert (mem != NULL);
  assert (dividend != NULL);
  assert (divisor != NULL);
  assert (is_valid_const (dividend));
  assert (is_valid_const (divisor));

  dividend = strip_zeroes (dividend);
  divisor = strip_zeroes (divisor);

  for (p = dividend; *p && *p == '0'; p++)
    ;

  for (q = divisor; *q && *q == '0'; q++)
    ;

  assert (*q);                  /* in any case even if 'dividend == 0' */

  if (!*p || btor_cmp_const (p, q) < 0)
    {
      if (rem_ptr)
        *rem_ptr = btor_strdup (mem, p);        /* copy divident */

      return btor_strdup (mem, "");
    }

  plen = (int) strlen (p);
  qlen = (int) strlen (q);
  delta = plen - qlen;
  assert (delta >= 0);

  BTOR_NEWN (mem, extended_divisor, plen + 1);
  memset (extended_divisor, '0', delta);
  strcpy (extended_divisor + delta, divisor);

  udiv_urem_const (mem, dividend, extended_divisor, &quotient, &rest);

  btor_delete_const (mem, extended_divisor);

  tmp = btor_strdup (mem, strip_zeroes (quotient));
  btor_delete_const (mem, quotient);
  quotient = tmp;

  tmp = btor_strdup (mem, strip_zeroes (rest));
  btor_delete_const (mem, rest);
  rest = tmp;

  assert (btor_cmp_const (rest, divisor) < 0);
#ifndef NDEBUG
  {
    char *tmp1 = btor_mult_unbounded_const (mem, quotient, divisor);
    char *tmp2 = btor_add_unbounded_const (mem, tmp1, rest);
    assert (!btor_cmp_const (dividend, tmp2));
    btor_freestr (mem, tmp1);
    btor_freestr (mem, tmp2);
  }
#endif
  if (rem_ptr)
    *rem_ptr = rest;
  else
    btor_delete_const (mem, rest);

  return quotient;
}