How do you populate an x86 XMM register with 4 identical floats from another XMM register entry?
c, c++, inline-assembly, sse, x86
Solution
There are two ways:
Use `shufps` exclusively:
__m128 first = ...;
__m128 xxxx = _mm_shuffle_ps(first, first, 0x00); // _MM_SHUFFLE(0, 0, 0, 0)
__m128 yyyy = _mm_shuffle_ps(first, first, 0x55); // _MM_SHUFFLE(1, 1, 1, 1)
__m128 zzzz = _mm_shuffle_ps(first, first, 0xAA); // _MM_SHUFFLE(2, 2, 2, 2)
__m128 wwww = _mm_shuffle_ps(first, first, 0xFF); // _MM_SHUFFLE(3, 3, 3, 3)
Let the compiler choose the best way using `_mm_set1_ps` and `_mm_cvtss_f32`:
__m128 first = ...;
__m128 xxxx = _mm_set1_ps(_mm_cvtss_f32(first));
Note that the 2nd method will produce horrible code on MSVC, as discussed here, and will only produce 'xxxx' as result, unlike the first option.
I'm trying to implement some inline assembler (in C/C++ code) to take advantage of SSE
This is highly unportable. Use intrinsics.
Problem
I'm trying to implement some inline assembler (in C/C++ code) to take advantage of SSE. I'd like to copy and duplicate values (from an XMM register, or from memory) to another XMM register. For example, suppose I have some values {1, 2, 3, 4} in memory. I'd like to copy these values such that xmm1 is populated with {1, 1, 1, 1}, xmm2 with {2, 2, 2, 2}, and so on and so forth. Looking through the Intel reference manuals, I couldn't find an instruction to do this. Do I just need to use a combination of repeated MOVSS and rotates (via PSHUFD?)?