LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/util - bitvector.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 196 197 99.5 %
Date: 2026-05-13 10:48:54 Functions: 44 44 100.0 %
Branches: 120 283 42.4 %

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * This file is part of the cvc5 project.
       3                 :            :  *
       4                 :            :  * Copyright (c) 2009-2026 by the authors listed in the file AUTHORS
       5                 :            :  * in the top-level source directory and their institutional affiliations.
       6                 :            :  * All rights reserved.  See the file COPYING in the top-level source
       7                 :            :  * directory for licensing information.
       8                 :            :  * ****************************************************************************
       9                 :            :  *
      10                 :            :  * A fixed-size bit-vector, implemented as a wrapper around Integer.
      11                 :            :  */
      12                 :            : 
      13                 :            : #include "util/bitvector.h"
      14                 :            : 
      15                 :            : #include "base/check.h"
      16                 :            : #include "util/hash.h"
      17                 :            : 
      18                 :            : namespace cvc5::internal {
      19                 :            : 
      20                 :     129528 : BitVector::BitVector(const std::string& num, uint32_t base)
      21                 :            : {
      22 [ +  + ][ +  + ]:     129528 :   Assert(base == 2 || base == 10 || base == 16);
         [ +  + ][ +  - ]
         [ -  + ][ -  + ]
                 [ -  - ]
      23 [ -  + ][ -  + ]:     129528 :   Assert(num[0] != '-');
                 [ -  - ]
      24                 :     129528 :   d_value = Integer(num, base);
      25 [ -  + ][ -  + ]:     129528 :   Assert(d_value == d_value.abs());
                 [ -  - ]
      26                 :            :   // Compute the length, *without* any negative sign.
      27    [ +  + ][ + ]:     129528 :   switch (base)
      28                 :            :   {
      29                 :          1 :     case 10: d_size = d_value.length(); break;
      30                 :          2 :     case 16: d_size = num.size() * 4; break;
      31                 :     129525 :     default: d_size = num.size();
      32                 :            :   }
      33                 :     129528 : }
      34                 :            : 
      35                 :   90782738 : uint32_t BitVector::getSize() const { return d_size; }
      36                 :            : 
      37                 :   66174599 : const Integer& BitVector::getValue() const { return d_value; }
      38                 :            : 
      39                 :      41699 : Integer BitVector::toInteger() const { return d_value; }
      40                 :            : 
      41                 :    3527007 : Integer BitVector::toSignedInteger() const
      42                 :            : {
      43                 :    3527007 :   uint32_t size = d_size;
      44                 :    3527007 :   Integer sign_bit = d_value.extractBitRange(1, size - 1);
      45                 :    3527007 :   Integer val = d_value.extractBitRange(size - 1, 0);
      46                 :    7054014 :   Integer res = Integer(-1) * sign_bit.multiplyByPow2(size - 1) + val;
      47                 :    7054014 :   return res;
      48                 :    3527007 : }
      49                 :            : 
      50                 :      73849 : std::string BitVector::toString(uint32_t base) const
      51                 :            : {
      52                 :      73849 :   std::string str = d_value.toString(base);
      53 [ +  + ][ +  + ]:      73849 :   if (base == 2 && d_size > str.size())
                 [ +  + ]
      54                 :            :   {
      55                 :      36153 :     std::string zeroes;
      56         [ +  + ]:     573926 :     for (uint32_t i = 0; i < d_size - str.size(); ++i)
      57                 :            :     {
      58                 :     537773 :       zeroes.append("0");
      59                 :            :     }
      60                 :      36153 :     return zeroes + str;
      61                 :      36153 :   }
      62                 :            :   else
      63                 :            :   {
      64                 :      37696 :     return str;
      65                 :            :   }
      66                 :      73849 : }
      67                 :            : 
      68                 :    4946567 : size_t BitVector::hash() const
      69                 :            : {
      70                 :            :   PairHashFunction<size_t, size_t> h;
      71                 :    4946567 :   return h(std::make_pair(d_value.hash(), d_size));
      72                 :            : }
      73                 :            : 
      74                 :       2344 : BitVector& BitVector::setBit(uint32_t i, bool value)
      75                 :            : {
      76 [ -  + ][ -  + ]:       2344 :   Assert(i < d_size);
                 [ -  - ]
      77                 :       2344 :   d_value.setBit(i, value);
      78                 :       2344 :   return *this;
      79                 :            : }
      80                 :            : 
      81                 :     151438 : bool BitVector::isBitSet(uint32_t i) const
      82                 :            : {
      83 [ -  + ][ -  + ]:     151438 :   Assert(i < d_size);
                 [ -  - ]
      84                 :     151438 :   return d_value.isBitSet(i);
      85                 :            : }
      86                 :            : 
      87                 :     195986 : unsigned BitVector::isPow2() const { return d_value.isPow2(); }
      88                 :            : 
      89                 :          2 : bool BitVector::is_one() const { return d_value == Integer(1); }
      90                 :            : 
      91                 :            : /* -----------------------------------------------------------------------
      92                 :            :  * Operators
      93                 :            :  * ----------------------------------------------------------------------- */
      94                 :            : 
      95                 :            : /* String Operations ----------------------------------------------------- */
      96                 :            : 
      97                 :     304937 : BitVector BitVector::concat(const BitVector& other) const
      98                 :            : {
      99                 :     304937 :   return BitVector(d_size + other.d_size,
     100                 :     609874 :                    (d_value.multiplyByPow2(other.d_size)) + other.d_value);
     101                 :            : }
     102                 :            : 
     103                 :     897646 : BitVector BitVector::extract(uint32_t high, uint32_t low) const
     104                 :            : {
     105 [ -  + ][ -  + ]:     897646 :   Assert(high < d_size);
                 [ -  - ]
     106 [ -  + ][ -  + ]:     897646 :   Assert(low <= high);
                 [ -  - ]
     107                 :     897646 :   return BitVector(high - low + 1,
     108                 :    1795292 :                    d_value.extractBitRange(high - low + 1, low));
     109                 :            : }
     110                 :            : 
     111                 :            : /* (Dis)Equality --------------------------------------------------------- */
     112                 :            : 
     113                 :   20011105 : bool operator==(const BitVector& a, const BitVector& b)
     114                 :            : {
     115         [ -  + ]:   20011105 :   if (a.getSize() != b.getSize()) return false;
     116                 :   20011105 :   return a.getValue() == b.getValue();
     117                 :            : }
     118                 :            : 
     119                 :    1212592 : bool operator!=(const BitVector& a, const BitVector& b)
     120                 :            : {
     121         [ -  + ]:    1212592 :   if (a.getSize() != b.getSize()) return true;
     122                 :    1212592 :   return a.getValue() != b.getValue();
     123                 :            : }
     124                 :            : 
     125                 :            : /* Unsigned Inequality --------------------------------------------------- */
     126                 :            : 
     127                 :       1336 : bool operator<(const BitVector& a, const BitVector& b)
     128                 :            : {
     129                 :       1336 :   return a.getValue() < b.getValue();
     130                 :            : }
     131                 :            : 
     132                 :       2667 : bool operator<=(const BitVector& a, const BitVector& b)
     133                 :            : {
     134                 :       2667 :   return a.getValue() <= b.getValue();
     135                 :            : }
     136                 :            : 
     137                 :        474 : bool operator>(const BitVector& a, const BitVector& b)
     138                 :            : {
     139                 :        474 :   return a.getValue() > b.getValue();
     140                 :            : }
     141                 :            : 
     142                 :       1028 : bool operator>=(const BitVector& a, const BitVector& b)
     143                 :            : {
     144                 :       1028 :   return a.getValue() >= b.getValue();
     145                 :            : }
     146                 :            : 
     147                 :      58592 : bool BitVector::unsignedLessThan(const BitVector& y) const
     148                 :            : {
     149 [ -  + ][ -  + ]:      58592 :   Assert(d_size == y.d_size);
                 [ -  - ]
     150 [ -  + ][ -  + ]:      58592 :   Assert(d_value >= 0);
                 [ -  - ]
     151 [ -  + ][ -  + ]:      58592 :   Assert(y.d_value >= 0);
                 [ -  - ]
     152                 :      58592 :   return d_value < y.d_value;
     153                 :            : }
     154                 :            : 
     155                 :      13761 : bool BitVector::unsignedLessThanEq(const BitVector& y) const
     156                 :            : {
     157 [ -  + ][ -  + ]:      13761 :   Assert(d_size == y.d_size);
                 [ -  - ]
     158 [ -  + ][ -  + ]:      13761 :   Assert(d_value >= 0);
                 [ -  - ]
     159 [ -  + ][ -  + ]:      13761 :   Assert(y.d_value >= 0);
                 [ -  - ]
     160                 :      13761 :   return d_value <= y.d_value;
     161                 :            : }
     162                 :            : 
     163                 :            : /* Signed Inequality ----------------------------------------------------- */
     164                 :            : 
     165                 :      75487 : bool BitVector::signedLessThan(const BitVector& y) const
     166                 :            : {
     167 [ -  + ][ -  + ]:      75487 :   Assert(d_size == y.d_size);
                 [ -  - ]
     168 [ -  + ][ -  + ]:      75487 :   Assert(d_value >= 0);
                 [ -  - ]
     169 [ -  + ][ -  + ]:      75487 :   Assert(y.d_value >= 0);
                 [ -  - ]
     170                 :      75487 :   Integer a = (*this).toSignedInteger();
     171                 :      75487 :   Integer b = y.toSignedInteger();
     172                 :            : 
     173                 :     150974 :   return a < b;
     174                 :      75487 : }
     175                 :            : 
     176                 :    1687986 : bool BitVector::signedLessThanEq(const BitVector& y) const
     177                 :            : {
     178 [ -  + ][ -  + ]:    1687986 :   Assert(d_size == y.d_size);
                 [ -  - ]
     179 [ -  + ][ -  + ]:    1687986 :   Assert(d_value >= 0);
                 [ -  - ]
     180 [ -  + ][ -  + ]:    1687986 :   Assert(y.d_value >= 0);
                 [ -  - ]
     181                 :    1687986 :   Integer a = (*this).toSignedInteger();
     182                 :    1687986 :   Integer b = y.toSignedInteger();
     183                 :            : 
     184                 :    3375972 :   return a <= b;
     185                 :    1687986 : }
     186                 :            : 
     187                 :            : /* Bit-wise operations --------------------------------------------------- */
     188                 :            : 
     189                 :       3383 : BitVector operator^(const BitVector& a, const BitVector& b)
     190                 :            : {
     191 [ -  + ][ -  + ]:       3383 :   Assert(a.getSize() == b.getSize());
                 [ -  - ]
     192                 :       6766 :   return BitVector(a.getSize(), a.getValue().bitwiseXor(b.getValue()));
     193                 :            : }
     194                 :            : 
     195                 :     328769 : BitVector operator|(const BitVector& a, const BitVector& b)
     196                 :            : {
     197 [ -  + ][ -  + ]:     328769 :   Assert(a.getSize() == b.getSize());
                 [ -  - ]
     198                 :     657538 :   return BitVector(a.getSize(), a.getValue().bitwiseOr(b.getValue()));
     199                 :            : }
     200                 :            : 
     201                 :     662683 : BitVector operator&(const BitVector& a, const BitVector& b)
     202                 :            : {
     203 [ -  + ][ -  + ]:     662683 :   Assert(a.getSize() == b.getSize());
                 [ -  - ]
     204                 :    1325366 :   return BitVector(a.getSize(), a.getValue().bitwiseAnd(b.getValue()));
     205                 :            : }
     206                 :            : 
     207                 :    4996942 : BitVector operator~(const BitVector& a)
     208                 :            : {
     209                 :    9993884 :   return BitVector(a.getSize(), a.getValue().bitwiseNot());
     210                 :            : }
     211                 :            : 
     212                 :            : /* Arithmetic operations ------------------------------------------------- */
     213                 :            : 
     214                 :    7742604 : BitVector operator+(const BitVector& a, const BitVector& b)
     215                 :            : {
     216 [ -  + ][ -  + ]:    7742604 :   Assert(a.getSize() == b.getSize());
                 [ -  - ]
     217                 :    7742604 :   Integer sum = a.getValue() + b.getValue();
     218                 :   15485208 :   return BitVector(a.getSize(), sum);
     219                 :    7742604 : }
     220                 :            : 
     221                 :    2838574 : BitVector operator-(const BitVector& a, const BitVector& b)
     222                 :            : {
     223 [ -  + ][ -  + ]:    2838574 :   Assert(a.getSize() == b.getSize());
                 [ -  - ]
     224                 :            :   // to maintain the invariant that we are only adding BitVectors of the
     225                 :            :   // same size
     226                 :    2838574 :   BitVector one(a.getSize(), Integer(1));
     227                 :    8515722 :   return a + ~b + one;
     228                 :    2838574 : }
     229                 :            : 
     230                 :    1802437 : BitVector operator-(const BitVector& a)
     231                 :            : {
     232                 :    1802437 :   BitVector one(a.getSize(), Integer(1));
     233                 :    5407311 :   return ~a + one;
     234                 :    1802437 : }
     235                 :            : 
     236                 :     476454 : BitVector operator*(const BitVector& a, const BitVector& b)
     237                 :            : {
     238 [ -  + ][ -  + ]:     476454 :   Assert(a.getSize() == b.getSize());
                 [ -  - ]
     239                 :     476454 :   Integer prod = a.getValue() * b.getValue();
     240                 :     952908 :   return BitVector(a.getSize(), prod);
     241                 :     476454 : }
     242                 :            : 
     243                 :      62483 : BitVector BitVector::unsignedDivTotal(const BitVector& y) const
     244                 :            : {
     245 [ -  + ][ -  + ]:      62483 :   Assert(d_size == y.d_size);
                 [ -  - ]
     246                 :            :   /* d_value / 0 = -1 = 2^d_size - 1 */
     247         [ +  + ]:      62483 :   if (y.d_value == 0)
     248                 :            :   {
     249                 :      16316 :     return BitVector(d_size, Integer(1).oneExtend(1, d_size - 1));
     250                 :            :   }
     251 [ -  + ][ -  + ]:      54325 :   Assert(d_value >= 0);
                 [ -  - ]
     252 [ -  + ][ -  + ]:      54325 :   Assert(y.d_value > 0);
                 [ -  - ]
     253                 :     108650 :   return BitVector(d_size, d_value.floorDivideQuotient(y.d_value));
     254                 :            : }
     255                 :            : 
     256                 :      67376 : BitVector BitVector::unsignedRemTotal(const BitVector& y) const
     257                 :            : {
     258 [ -  + ][ -  + ]:      67376 :   Assert(d_size == y.d_size);
                 [ -  - ]
     259         [ +  + ]:      67376 :   if (y.d_value == 0)
     260                 :            :   {
     261                 :       8135 :     return BitVector(d_size, d_value);
     262                 :            :   }
     263 [ -  + ][ -  + ]:      59241 :   Assert(d_value >= 0);
                 [ -  - ]
     264 [ -  + ][ -  + ]:      59241 :   Assert(y.d_value > 0);
                 [ -  - ]
     265                 :     118482 :   return BitVector(d_size, d_value.floorDivideRemainder(y.d_value));
     266                 :            : }
     267                 :            : 
     268                 :            : /* Extend operations ----------------------------------------------------- */
     269                 :            : 
     270                 :     591092 : BitVector BitVector::zeroExtend(uint32_t n) const
     271                 :            : {
     272                 :     591092 :   return BitVector(d_size + n, d_value);
     273                 :            : }
     274                 :            : 
     275                 :    1597854 : BitVector BitVector::signExtend(uint32_t n) const
     276                 :            : {
     277                 :    1597854 :   Integer sign_bit = d_value.extractBitRange(1, d_size - 1);
     278         [ +  + ]:    1597854 :   if (sign_bit == Integer(0))
     279                 :            :   {
     280                 :      91127 :     return BitVector(d_size + n, d_value);
     281                 :            :   }
     282                 :    1506727 :   Integer val = d_value.oneExtend(d_size, n);
     283                 :    1506727 :   return BitVector(d_size + n, val);
     284                 :    1597854 : }
     285                 :            : 
     286                 :            : /* Shift operations ------------------------------------------------------ */
     287                 :            : 
     288                 :    2342868 : BitVector BitVector::leftShift(const BitVector& y) const
     289                 :            : {
     290         [ +  + ]:    2342868 :   if (y.d_value > Integer(d_size))
     291                 :            :   {
     292                 :      22262 :     return BitVector(d_size, Integer(0));
     293                 :            :   }
     294         [ +  + ]:    2331737 :   if (y.d_value == 0)
     295                 :            :   {
     296                 :     182548 :     return *this;
     297                 :            :   }
     298                 :            :   // making sure we don't lose information casting
     299 [ -  + ][ -  + ]:    2149189 :   Assert(y.d_value < Integer(1).multiplyByPow2(32));
                 [ -  - ]
     300                 :    2149189 :   uint32_t amount = y.d_value.toUnsignedInt();
     301                 :    2149189 :   Integer res = d_value.multiplyByPow2(amount);
     302                 :    2149189 :   return BitVector(d_size, res);
     303                 :    2149189 : }
     304                 :            : 
     305                 :      57962 : BitVector BitVector::logicalRightShift(const BitVector& y) const
     306                 :            : {
     307         [ +  + ]:      57962 :   if (y.d_value > Integer(d_size))
     308                 :            :   {
     309                 :          2 :     return BitVector(d_size, Integer(0));
     310                 :            :   }
     311                 :            :   // making sure we don't lose information casting
     312 [ -  + ][ -  + ]:      57961 :   Assert(y.d_value < Integer(1).multiplyByPow2(32));
                 [ -  - ]
     313                 :      57961 :   uint32_t amount = y.d_value.toUnsignedInt();
     314                 :      57961 :   Integer res = d_value.divByPow2(amount);
     315                 :      57961 :   return BitVector(d_size, res);
     316                 :      57961 : }
     317                 :            : 
     318                 :      20758 : BitVector BitVector::arithRightShift(const BitVector& y) const
     319                 :            : {
     320                 :      20758 :   Integer sign_bit = d_value.extractBitRange(1, d_size - 1);
     321         [ +  + ]:      20758 :   if (y.d_value > Integer(d_size))
     322                 :            :   {
     323         [ +  + ]:        983 :     if (sign_bit == Integer(0))
     324                 :            :     {
     325                 :       1336 :       return BitVector(d_size, Integer(0));
     326                 :            :     }
     327                 :            :     else
     328                 :            :     {
     329                 :        630 :       return BitVector(d_size, Integer(d_size).multiplyByPow2(d_size) - 1);
     330                 :            :     }
     331                 :            :   }
     332                 :            : 
     333         [ +  + ]:      19775 :   if (y.d_value == 0)
     334                 :            :   {
     335                 :        755 :     return *this;
     336                 :            :   }
     337                 :            : 
     338                 :            :   // making sure we don't lose information casting
     339 [ -  + ][ -  + ]:      19020 :   Assert(y.d_value < Integer(1).multiplyByPow2(32));
                 [ -  - ]
     340                 :            : 
     341                 :      19020 :   uint32_t amount = y.d_value.toUnsignedInt();
     342                 :      19020 :   Integer rest = d_value.divByPow2(amount);
     343                 :            : 
     344         [ +  + ]:      19020 :   if (sign_bit == Integer(0))
     345                 :            :   {
     346                 :      12865 :     return BitVector(d_size, rest);
     347                 :            :   }
     348                 :       6155 :   Integer res = rest.oneExtend(d_size - amount, amount);
     349                 :       6155 :   return BitVector(d_size, res);
     350                 :      20758 : }
     351                 :            : 
     352                 :            : /* -----------------------------------------------------------------------
     353                 :            :  * Static helpers.
     354                 :            :  * ----------------------------------------------------------------------- */
     355                 :            : 
     356                 :         41 : BitVector BitVector::mkZero(uint32_t size)
     357                 :            : {
     358 [ -  + ][ -  + ]:         41 :   Assert(size > 0);
                 [ -  - ]
     359                 :         41 :   return BitVector(size);
     360                 :            : }
     361                 :            : 
     362                 :         45 : BitVector BitVector::mkOne(uint32_t size)
     363                 :            : {
     364 [ -  + ][ -  + ]:         45 :   Assert(size > 0);
                 [ -  - ]
     365                 :         45 :   return BitVector(size, 1u);
     366                 :            : }
     367                 :            : 
     368                 :    1398605 : BitVector BitVector::mkOnes(uint32_t size)
     369                 :            : {
     370 [ -  + ][ -  + ]:    1398605 :   Assert(size > 0);
                 [ -  - ]
     371                 :    2797210 :   return BitVector(1, Integer(1)).signExtend(size - 1);
     372                 :            : }
     373                 :            : 
     374                 :        127 : BitVector BitVector::mkMinSigned(uint32_t size)
     375                 :            : {
     376 [ -  + ][ -  + ]:        127 :   Assert(size > 0);
                 [ -  - ]
     377                 :        127 :   BitVector res(size);
     378                 :        127 :   res.setBit(size - 1, true);
     379                 :        127 :   return res;
     380                 :          0 : }
     381                 :            : 
     382                 :         39 : BitVector BitVector::mkMaxSigned(uint32_t size)
     383                 :            : {
     384 [ -  + ][ -  + ]:         39 :   Assert(size > 0);
                 [ -  - ]
     385                 :         78 :   return ~BitVector::mkMinSigned(size);
     386                 :            : }
     387                 :            : 
     388                 :          2 : BitVector BitVector::mkRandom(uint32_t size)
     389                 :            : {
     390 [ -  + ][ -  + ]:          2 :   Assert(size > 0);
                 [ -  - ]
     391                 :          4 :   return BitVector(size, Integer::mkRandom(size));
     392                 :            : }
     393                 :            : 
     394                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14