Fill word with selected bit

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.

The most general algorithm

  1. mask bit:

    [10111010] => [00010000]
    
  2. clone word:

    a=[00010000], b=[00010000]
    
  3. shift bit in first word to MSB, and to LSB in second word:

    a=[10000000], b=[00000001]
    
  4. subtract c = a - b:

    c=[01111111]
    
  5. 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;
}

If arithmetic shifts are supported

  1. shift bit to MSB:

    a=[10000000]
    
  2. arithmetic shift right:

    a=[11111111]
    
uint32_t fill2(uint32_t a, int bit) {
        a <<= 31 - bit;
        return (int32_t)(a) >> 31;
}

386 processor specific

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;
}