@@ -68,6 +68,19 @@ struct BitUtil {
6868 return res;
6969 }
7070
71+ static W getBitsByMask (const W& word, const W& mask) noexcept {
72+ W res = 0 ;
73+ unsigned idx = 0 ;
74+ for (auto i = 0 ; i < NUM_BITS ; ++i) {
75+ if (getBit (mask, i)) {
76+ W temp = getBit (word, i);
77+ res = res | (temp << idx);
78+ ++idx;
79+ }
80+ }
81+ return res;
82+ }
83+
7184 static W setBitRange (const W& word, size_t lo, size_t hi) noexcept {
7285 checkBitRange (lo, hi);
7386 return (word | genMask (lo, hi));
@@ -88,6 +101,17 @@ struct BitUtil {
88101 return ret;
89102 }
90103
104+ static W setBitsByMask (const W& word, const W& mask) noexcept {
105+ W ret = word;
106+
107+ for (auto i = 0 ; i < NUM_BITS ; ++i) {
108+ if (getBit (mask, i)) {
109+ ret = setBit (ret, i);
110+ }
111+ }
112+ return ret;
113+ }
114+
91115 static W clearBitRange (const W& word, size_t lo, size_t hi) noexcept {
92116 checkBitRange (lo, hi);
93117 return word & ~genMask (lo, hi);
@@ -154,6 +178,26 @@ struct BitUtil {
154178 return ret;
155179 }
156180
181+ static W removeBitsByMask (const W& word, const W& mask) noexcept {
182+ W res = word;
183+ size_t shiftAmt = 0 ;
184+ for (auto i = 0 ; i < NUM_BITS ; ++i) {
185+ if (getBit (mask, i)) {
186+ res = removeBit (res, i);
187+ /*
188+ * since bitIndices are sorted, removing a lower order bit changes the
189+ * positions of higher order bits, so higher bitIndices are off by 1
190+ * So, we left shift by 1 to make higher bitIndices valid, but ++shiftAmt to
191+ * remember how many zeros we added on the right and remove them
192+ */
193+ res <<= 1 ;
194+ ++shiftAmt;
195+ }
196+ }
197+ res >>= shiftAmt; // remove the zeroes we added to adjust for higher bitIndices
198+ return res;
199+ }
200+
157201 /* *
158202 * assumes that bitIndices are sorted low to high idx
159203 */
@@ -197,6 +241,16 @@ struct BitUtil {
197241 return insertBitRange (word, idx, idx + 1 );
198242 }
199243
244+ static W insertBitsByMask (const W& word, const W& mask) noexcept {
245+ W ret = word;
246+ for (auto i = 0 ; i < NUM_BITS ; ++i) {
247+ if (getBit (mask, i)) {
248+ ret = insertBit (ret, i);
249+ }
250+ }
251+ return ret;
252+ }
253+
200254 // This does the opposite of removeBitsByInnerBits. It uses each element of innerBitIndices to
201255 // capture the right set of bits from word and shift them appropriately to insert bits at
202256 // the right locations.
@@ -253,6 +307,19 @@ struct BitUtil {
253307 }
254308 return ret;
255309 }
310+
311+ static W replaceBitsByMask (const W& word, const W& mask, const W& newVal) noexcept {
312+ W ret = word;
313+ W nval = newVal;
314+
315+ for (auto i = 0 ; i < NUM_BITS ; ++i) {
316+ if (getBit (mask, i)) {
317+ ret = replaceBit (ret, i, getLSB (nval));
318+ nval >>= 1 ;
319+ }
320+ }
321+ return ret;
322+ }
256323};
257324
258325template <typename T>
@@ -306,6 +373,10 @@ class BitUtil<T*> {
306373 return toPtr (IntBitUtil::getBits (toInt (ptr), bitIndices));
307374 }
308375
376+ static P getBitsByMask (const P& ptr, Int mask) noexcept {
377+ return toPtr (IntBitUtil::getBitsByMask (toInt (ptr), mask));
378+ }
379+
309380 static P setBit (const P& ptr, size_t idx) noexcept {
310381 return toPtr (IntBitUtil::setBit (toInt (ptr), idx));
311382 }
@@ -319,6 +390,10 @@ class BitUtil<T*> {
319390 return toPtr (IntBitUtil::setBits (toInt (ptr), bitIndices));
320391 }
321392
393+ static P setBitsByMask (const P& ptr, Int mask) noexcept {
394+ return toPtr (IntBitUtil::setBits (toInt (ptr), mask));
395+ }
396+
322397 static P clearBit (const P& ptr, size_t idx) noexcept {
323398 return toPtr (IntBitUtil::clearBit (toInt (ptr), idx));
324399 }
@@ -345,6 +420,10 @@ class BitUtil<T*> {
345420 return toPtr (IntBitUtil::replaceBits (toInt (ptr), bitIndices, toInt (newVal)));
346421 }
347422
423+ static P replaceBitsByMask (const P& ptr, Int mask, const P& newVal) noexcept {
424+ return toPtr (IntBitUtil::replaceBitsByMask (toInt (ptr), mask, toInt (newVal)));
425+ }
426+
348427 static P removeBit (const P& ptr, size_t idx) noexcept {
349428 return toPtr (IntBitUtil::removeBit (toInt (ptr), idx));
350429 }
@@ -357,6 +436,10 @@ class BitUtil<T*> {
357436 static P removeBits (const P& ptr, const V& bitIndices) noexcept {
358437 return toPtr (IntBitUtil::removeBits (toInt (ptr), bitIndices));
359438 }
439+
440+ static P removeBitsByMask (const P& ptr, Int mask) noexcept {
441+ return toPtr (IntBitUtil::removeBitsByMask (toInt (ptr), mask));
442+ }
360443
361444 template <typename V>
362445 static P removeBitsByInnerBits (const P& ptr, const V& innerBitIndices) noexcept {
@@ -376,6 +459,10 @@ class BitUtil<T*> {
376459 return toPtr (IntBitUtil::insertBits (toInt (ptr), bitIndices));
377460 }
378461
462+ static P insertBitsByMask (const P& ptr, Int mask) noexcept {
463+ return toPtr (IntBitUtil::insertBitsByMask (toInt (ptr), mask));
464+ }
465+
379466 template <typename V>
380467 static P insertBitsByInnerBits (const P& ptr, const V& innerBitIndices) noexcept {
381468 return toPtr (IntBitUtil::insertBitsByInnerBits (toInt (ptr), innerBitIndices));
0 commit comments