Let's say that data is 1011 1001
and the mask is 0111 0110
, then you have:
input data: 1011 1001
input mask: 0111 0110
apply mask: 0011 0000 (based on `input mask`)
bits selected: -011 -00- (based on `input mask`)
right packed: ---0 1100
expected result: 0000 1100 (set left `8 - popcount('input mask')` bits to zero)
So the final output is 0000 1100
(note that the 3 positions on the left which are unspecified are zero-filled).
You can see that wherever the bits in input mask
is 1 the corresponding value in input data
is selected (in bits selected
above) and then all selected bits are packed contiguously started in the least significant bits of the result (as shown in right packed
above). Finally, any leftmost bits which are left over after the packing are set to 0 (there will be 8 - popcount(mask)
such bits).
Obvious choice is rotate and select but that will consume 5 operations as mask has 5 bits. Can I do this in one step?
Note:
The mask can be anything with arbitrary
n
bitsON
(In above examplen=5
). All you know is the number of bits that areON
in the mask and the mask itself. Mask will keep on changing withn
bitsON
.In above example I have used data and mask of 8-bits but in real usage it can be 8, 16, 32, 64 and 128 bits.