How to move 128-bit immediates to XMM registers
assembly, simd, sse, x86
Solution
You can do it like this, with just one `movaps` instruction:
.section .rodata # put your constants in the read-only data section
.p2align 4 # align to 16 = 1<<4
LC0:
.long 1082130432
.long 1077936128
.long 1073741824
.long 1065353216
.text
foo:
movaps LC0(%rip), %xmm0
Loading it with a data load is usually preferable to embedding it in the instruction stream, especially because of how many instructions it takes. That's several extra uops for the CPU to execute, for an arbitrary constant that can't be generated from all-ones with a couple shifts.
If it's easier, you can put constants right before or after a function that you jit-compile, instead of in a separate section. But since CPUs have split L1d / L1i caches and TLBs, it's generally best to group constants together separate from instructions.
If both halves of your constant are the same, you can broadcast-load it with SSE3 `movddup (m64), %xmm0`.
Problem
There already is a question on this, but it was closed as "ambiguous" so I'm opening a new one - I've found the answer, maybe it will help others too. The question is: how do you write a sequence of assembly code to initialize an XMM register with a 128-bit immediate (constant) value?