Convert _mm_shuffle_epi32 to C expression for permutation?

I am working on an SSE2 port for NEON. The port is at an early stage and it is giving incorrect results. Part of the reason for the incorrect results is _mm_shuffle_epi32the NEON commands that I selected.

The documentation for _mm_shuffle_epi32is onshore from Microsoft . Intel's documentation is better, but it’s not clear to me what some kind of pseudo code is doing.

SELECT4(src, control)
{
    CASE(control[1:0])
        0: tmp[31:0] := src[31:0]
        1: tmp[31:0] := src[63:32]
        2: tmp[31:0] := src[95:64]
        3: tmp[31:0] := src[127:96]
    ESAC
    RETURN tmp[31:0]
}

dst[31:0] := SELECT4(a[127:0], imm8[1:0])
dst[63:32] := SELECT4(a[127:0], imm8[3:2])
dst[95:64] := SELECT4(a[127:0], imm8[5:4])
dst[127:96] := SELECT4(a[127:0], imm8[7:6])

I need help representing what I'm doing _mm_shuffle_epi32. Or rather, a permutation applied directly to a value. I think I need to see it as basic C and AND and OR.

Using C statements and macros, for example:

v2 = _mm_shuffle_epi32(v1, _MM_SHUFFLE(i1,i2,i3,i4));

What does the resulting C expression look like when it is expanded into the basic C statements?

+4
2

AND/OR, 8- , 2- .

_MM_SHUFFLE, , .

-

// dst = _mm_shuffle_epi32(src, _MM_SHUFFLE(d,c,b,a))
void pshufd(int dst[4], int src[4], int d,int c,int b,int a)
{   // note that the _MM_SHUFFLE args are high-element-first order
    dst[0] = src[a];
    dst[1] = src[b];
    dst[2] = src[c];
    dst[3] = src[d];
}

= 0. - , , , [ 3 2 1 0 ]. (, psrldq) .

_mm_set_epi32(3, 2, 1, 0) int foo[] = { 0, 1, 2, 3 };.

+4

, , :

int x[] = {0,1,2,3}, y[4];
__m128i s = _mm_shuffle_epi32(_mm_loadu_si128((__m128i*)x), _MM_SHUFFLE(2, 3, 0, 1));
_mm_store_si128((__m128i*)y, s);
printf("{%d,%d,%d,%d} => {%d,%d,%d,%d}\n", x[0], x[1], x[2], x[3], y[0], y[1], y[2], y[3]);

:

{0,1,2,3} = > {1,0,3,2}

0

All Articles