#include <stdint.h>
#include <stdio.h>

void format_binary(uint64_t x, char *buf)
{
    int i = 0;
    while(x){
        char b = x % 2;
        buf[i] = b + '0';
        x /= 2;
        i++;
    }
    int m = i / 2;
    for(int j = 0; j < m; j++){
        char tmp = buf[j];
        buf[j] = buf[i - 1 - j];
        buf[i - 1 - j] = tmp;
    }
    buf[i] = '\0';
}

static inline uint64_t interleave64(uint32_t xlo, uint32_t ylo) {
    static const uint64_t B[] = {0x5555555555555555ULL, 0x3333333333333333ULL,
                                 0x0F0F0F0F0F0F0F0FULL, 0x00FF00FF00FF00FFULL,
                                 0x0000FFFF0000FFFFULL};
    char bf[200];
    for(int i = 0; i < 5; i++){
        format_binary(B[i], bf);
        printf("B[%d]=(%lx)%s\n", i, B[i], bf);
    }
    static const unsigned int S[] = {1, 2, 4, 8, 16};

    uint64_t x = xlo;
    uint64_t y = ylo;
    format_binary(x, bf);
    printf("x (%lx)%s \n", x, bf);
    format_binary(y, bf);
    printf("y (%lx)%s \n", y, bf);

    x = (x | (x << S[4])) & B[4];
    y = (y | (y << S[4])) & B[4];
    format_binary(x, bf);
    printf("S 4: x (%lx)%s \n", x, bf);
    format_binary(y, bf);
    printf("S 4: y (%lx)%s \n", y, bf);

    x = (x | (x << S[3])) & B[3];
    y = (y | (y << S[3])) & B[3];
    format_binary(x, bf);
    printf("S 3: x (%lx)%s \n", x, bf);
    format_binary(y, bf);
    printf("S 3: y (%lx)%s \n", y, bf);

    x = (x | (x << S[2])) & B[2];
    y = (y | (y << S[2])) & B[2];
    format_binary(x, bf);
    printf("S 2: x (%lx)%s \n", x, bf);
    format_binary(y, bf);
    printf("S 2: y (%lx)%s \n", y, bf);

    x = (x | (x << S[1])) & B[1];
    y = (y | (y << S[1])) & B[1];
    format_binary(x, bf);
    printf("S 1: x (%lx)%s \n", x, bf);
    format_binary(y, bf);
    printf("S 1: y (%lx)%s \n", y, bf);

    x = (x | (x << S[0])) & B[0];
    y = (y | (y << S[0])) & B[0];
    format_binary(x, bf);
    printf("S 0: x (%lx)%s \n", x, bf);
    format_binary(y, bf);
    printf("S 0: y (%lx)%s \n", y, bf);

    return x | (y << 1);
}

int main(){
	interleave64(0xffffffff, 0);
}