void copy_32byte_chunks(void const *src, void *dst, int size) {
  asm volatile("emms                             \n\t"
               "xor    %%ecx,%%ecx               \n\t"
               ".align 16                        \n\t"
               "0:                               \n\t"
               "movq   (%%esi,%%ecx,8),%%mm0     \n\t"
               "movq   8(%%esi,%%ecx,8),%%mm1    \n\t"
               "movq   16(%%esi,%%ecx,8),%%mm2   \n\t"
               "movq   24(%%esi,%%ecx,8),%%mm3   \n\t"
               "movntq %%mm0,(%%edi,%%ecx,8)     \n\t"
               "movntq %%mm1,8(%%edi,%%ecx,8)    \n\t"
               "movntq %%mm2,16(%%edi,%%ecx,8)   \n\t"
               "movntq %%mm3,24(%%edi,%%ecx,8)   \n\t"
               "add    $4, %%ecx                 \n\t"
               "dec    %3                        \n\t"
               "jnz    0b                        \n\t"
               "sfence                           \n\t"
               "emms                             \n\t"
               : "=r"(size)
               : "S"(src), "D"(dst), "0"(size)
               : "eax", "ecx", "memory");
}


x86 assembly (clang, -O0):
<copy_32byte_chunks>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    -0x8(%rbp),%rsi
mov    -0x10(%rbp),%rdi
mov    -0x14(%rbp),%edx
emms
xor    %ecx,%ecx
xchg   %ax,%ax
movq   (%esi,%ecx,8),%mm0
movq   0x8(%esi,%ecx,8),%mm1
movq   0x10(%esi,%ecx,8),%mm2
movq   0x18(%esi,%ecx,8),%mm3
movntq %mm0,(%edi,%ecx,8)
movntq %mm1,0x8(%edi,%ecx,8)
movntq %mm2,0x10(%edi,%ecx,8)
movntq %mm3,0x18(%edi,%ecx,8)
add    $0x4,%ecx
dec    %edx
jne    1120 <copy_32byte_chunks+0x20>
sfence
emms
mov    %edx,-0x18(%rbp)
mov    -0x18(%rbp),%eax
mov    %eax,-0x14(%rbp)
pop    %rbp
ret

x86 assembly (clang, -O2):
<copy_32byte_chunks>:
mov    %rsi,%rax
mov    %rdi,%rsi
mov    %rax,%rdi
emms
xor    %ecx,%ecx
nopl   (%rax)
movq   (%esi,%ecx,8),%mm0
movq   0x8(%esi,%ecx,8),%mm1
movq   0x10(%esi,%ecx,8),%mm2
movq   0x18(%esi,%ecx,8),%mm3
movntq %mm0,(%edi,%ecx,8)
movntq %mm1,0x8(%edi,%ecx,8)
movntq %mm2,0x10(%edi,%ecx,8)
movntq %mm3,0x18(%edi,%ecx,8)
add    $0x4,%ecx
dec    %edx
jne    1110 <copy_32byte_chunks+0x10>
sfence
emms
ret

LLVM IR (-O0):
define void @copy_32byte_chunks(i8* %0, i8* %1, i32 %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i32
store i8* %0, i8** %4
store i8* %1, i8** %5
store i32 %2, i32* %6
%7 = load i8*, i8** %4
%8 = load i8*, i8** %5
%9 = load i32, i32* %6
%10 = call i32 asm sideeffect "emms \0A\09xor %ecx,%ecx \0A\09.align 16 \0A\090: \0A\09movq (%esi,%ecx,8),%mm0 \0A\09movq 8(%esi,%ecx,8),%mm1 \0A\09movq 16(%esi,%ecx,8),%mm2 \0A\09movq 24(%esi,%ecx,8),%mm3 \0A\09movntq %mm0,(%edi,%ecx,8) \0A\09movntq %mm1,8(%edi,%ecx,8) \0A\09movntq %mm2,16(%edi,%ecx,8) \0A\09movntq %mm3,24(%edi,%ecx,8) \0A\09add $$4, %ecx \0A\09dec $3 \0A\09jnz 0b \0A\09sfence \0A\09emms \0A\09", "=r,{si},{di},0,~{eax},~{ecx},~{memory},~{dirflag},~{fpsr},~{flags}"(i8* %7, i8* %8, i32 %9)
store i32 %10, i32* %6
ret void
}

LLVM IR (-O2):
define void @copy_32byte_chunks(i8* %0, i8* %1, i32 %2) {
%4 = tail call i32 asm sideeffect "emms \0A\09xor %ecx,%ecx \0A\09.align 16 \0A\090: \0A\09movq (%esi,%ecx,8),%mm0 \0A\09movq 8(%esi,%ecx,8),%mm1 \0A\09movq 16(%esi,%ecx,8),%mm2 \0A\09movq 24(%esi,%ecx,8),%mm3 \0A\09movntq %mm0,(%edi,%ecx,8) \0A\09movntq %mm1,8(%edi,%ecx,8) \0A\09movntq %mm2,16(%edi,%ecx,8) \0A\09movntq %mm3,24(%edi,%ecx,8) \0A\09add $$4, %ecx \0A\09dec $3 \0A\09jnz 0b \0A\09sfence \0A\09emms \0A\09", "=r,{si},{di},0,~{eax},~{ecx},~{memory},~{dirflag},~{fpsr},~{flags}"(i8* %0, i8* %1, i32 %2)
ret void
}