Cómo desintercalar bits de manera eficiente (Morton inverso)

Esta pregunta:Cómo desintercalar bits (¿Desortonando?) tiene una buena respuesta para extraer una de las dos mitades de un número de Morton (solo los bits impares), pero necesito una solución que extraiga ambas partes (los bits impares y los bits pares) en la menor cantidad de operaciones posible.

Para mi uso, necesitaría tomar un int de 32 bits y extraer dos entradas de 16 bits, donde uno son los bits pares y el otro los bits impares desplazados a la derecha en 1 bit, p.

input,  z: 11101101 01010111 11011011 01101110

output, x: 11100001 10110111 // odd bits shifted right by 1
        y: 10111111 11011010 // even bits

Parece que hay muchas soluciones que utilizan turnos y máscaras con números mágicos para generar números de Morton (es decir, bits intercalados), p.Intercalar bits por números mágicos binarios, pero todavía no he encontrado nada para hacer lo contrario (es decir, desintercalar).

ACTUALIZAR

Después de volver a leer la sección de Hacker's Delight sobre shuffles / unshuffles perfectos, encontré algunos ejemplos útiles que adapté de la siguiente manera:

// morton1 - extract even bits

uint32_t morton1(uint32_t x)
{
    x = x & 0x55555555;
    x = (x | (x >> 1)) & 0x33333333;
    x = (x | (x >> 2)) & 0x0F0F0F0F;
    x = (x | (x >> 4)) & 0x00FF00FF;
    x = (x | (x >> 8)) & 0x0000FFFF;
    return x;
}

// morton2 - extract odd and even bits

void morton2(uint32_t *x, uint32_t *y, uint32_t z)
{
    *x = morton1(z);
    *y = morton1(z >> 1);
}

Creo que esto aún se puede mejorar, tanto en su forma escalar actual como también aprovechando SIMD, por lo que todavía estoy interesado en mejores soluciones (ya sea escalar o SIMD).

Respuestas a la pregunta(5)

Su respuesta a la pregunta