This question is related to this.
Let x
be an 8 bit integer. I will number bits from left to right because that's how we read. If I want to get the third and fifth bits and put them in the first and second bits, with everything else as zero, I can have f(x) = (5*x) & 0b11000000
. More concisely:
00a0b000 -> ab000000 | f_0b00101000(x) = (5*x) & 0b11000000
However if I want the fifth, sixth and eighth bits to be in the first three bits, f(x)
is different:
000ab0cd -> abcd0000 | f_0b00011011(x) = ((x << 3) & 0b11000000) | (x << 4)
Note that the n
in f_n(x)
indicates which bits I care about. n
could have any 8 bit value. Is there some common function of x
(and a few arguments) that will push all the required bits to the left? Also, this is supposed to be fast so I would prefer to only use bitwise operations.
Let's say instead I'm dealing with 3 bit integers.
000 -> 000 | f_0(x) = (1*x) & 0
00a -> a00 | f_1(x) = (4*x) & 4
0a0 -> a00 | f_2(x) = (2*x) & 4
0ab -> ab0 | f_3(x) = (2*x) & 6
a00 -> a00 | f_4(x) = (1*x) & 4
a0b -> ab0 | f_5(x) = (3*x) & 6
ab0 -> ab0 | f_6(x) = (1*x) & 6
abc -> abc | f_7(x) = (1*x) & 7
These functions can all be combined into f(x, m, a) = (m*x) & a
, and I could create a lookup table which I could index to get the values of m
and a
from n
:
t = [(1, 0), (4, 4), (2, 4), (2, 6), (1, 4), (3, 6), (1, 6), (1, 7)]
So f_n(x)
becomes f(x, *t[n])
. I think f(x, m, a) = (m*x) & a
is optimal for 3 bits. The naive version for 3 bits is:
f(x, a, b, c, d, e, f) = ((x & a) << b) |
((x & c) << d) |
((x & e) << f)
The operation count is 8 for the naive function, and 2 for the optimal (?) one. Now the naive function for 8 bits is:
f(x, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) = ((x & a) << b) |
((x & c) << d) |
((x & e) << f) |
((x & g) << h) |
((x & i) << j) |
((x & k) << l) |
((x & m) << n) |
((x & o) << p)
There are 25 operations in this instruction. Is it possible to get that down to around 7 or 8, or even lower?