Author: | Wojciech Muła |
---|---|
Added on: | 2010-04-01 |
This is continuation of the subproblem from the previous post: we have a word (byte, dword, whatever) and want to fill it with the selected bit.
mask bit:
[10111010] => [00010000]
clone word:
a=[00010000], b=[00010000]
shift bit in first word to MSB, and to LSB in second word:
a=[10000000], b=[00000001]
subtract c = a - b:
c=[01111111]
add missing MSB c = c OR a:
c=[11111111]
uint32_t fill1(uint32_t a, int bit) { uint32_t b; b = a = a & (1 << bit); a <<= 31 - bit; b >>= bit; return (a - b) | a; }
shift bit to MSB:
a=[10000000]
arithmetic shift right:
a=[11111111]
uint32_t fill2(uint32_t a, int bit) { a <<= 31 - bit; return (int32_t)(a) >> 31; }
On processors 386+ we can clone the carry flag (CF) with sbb reg, reg and with bt reg, reg copy the selected bit from a reg to CF.
uint32_t fill386(uint32_t a, int bit) { uint32_t result; __asm__ __volatile__ ( "bt %1, %0\n" "sbb %0, %0\n" : "=r" (result) : "r" (bit), "0" (a) ); return result; }