Занумеруйте все биты от 0 до 16. Потом транспонируйте эту матрицу. Потом посмотрите на разность результата и конца. Вот эти вот числа - это на сколько бит надо сдвинуть исходные биты, чтобы они встали на нужное место.
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
0 4 8 12
1 5 9 13
2 6 10 13
3 7 11 15
0 -3 -6 -9
3 0 -3 -6
...
Все биты с одинаковым смещением можно подсчитать за 3 операции: Сдвиг, битовая маска и побитовое или в ответ.
Я тут вижу 7 разных чисел -9,-6,-3,0,3,6,9.
Например, для 0 и 3 у вас будет
answer = (source & 0x1248) | ((source << 3) | 0x2480) | ...
Это не 8 пока еще операций, а аж 20. Возможно можно как-то еще их сгруппировать.
Edit: Возможно, еще подход с таблицей будет быстрее. Для каждого из 16 возможных значений строк выдавайте битовое число - столбец, где эти 4 бита на позициях 0, 4, 8,12. Тогда ответ будет table[source&0xf0] | (table[(source>>4)&0xf] << 1) | (table[(source>>8)&0xf] << 2) | (table[(source>>12)&0xf] << 3).
Тут 13 битовых операций и 4 чтения из памяти.