void copy_32byte_chunks(void const *src, void *dst, int size) {
  asm volatile("emms                             \n\t"
               "xor    %%rcx,%%rcx               \n\t"
               ".align 16                        \n\t"
               "0:                               \n\t"
               "movq   (%%rsi,%%rcx,8),%%mm0     \n\t"
               "movq   8(%%rsi,%%rcx,8),%%mm1    \n\t"
               "movq   16(%%rsi,%%rcx,8),%%mm2   \n\t"
               "movq   24(%%rsi,%%rcx,8),%%mm3   \n\t"
               "movntq %%mm0,(%%rdi,%%rcx,8)     \n\t"
               "movntq %%mm1,8(%%rdi,%%rcx,8)    \n\t"
               "movntq %%mm2,16(%%rdi,%%rcx,8)   \n\t"
               "movntq %%mm3,24(%%rdi,%%rcx,8)   \n\t"
               "add    $0x4, %%rcx               \n\t"
               "dec    %3                        \n\t"
               "jnz    0b                        \n\t"
               "sfence                           \n\t"
               "emms                             \n\t"
               : "=r"(size)
               : "S"(src), "D"(dst), "0"(size)
               : "rax", "rcx", "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    %rcx,%rcx
nop
movq   (%rsi,%rcx,8),%mm0
movq   0x8(%rsi,%rcx,8),%mm1
movq   0x10(%rsi,%rcx,8),%mm2
movq   0x18(%rsi,%rcx,8),%mm3
movntq %mm0,(%rdi,%rcx,8)
movntq %mm1,0x8(%rdi,%rcx,8)
movntq %mm2,0x10(%rdi,%rcx,8)
movntq %mm3,0x18(%rdi,%rcx,8)
add    $0x4,%rcx
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    %rcx,%rcx
xchg   %ax,%ax
movq   (%rsi,%rcx,8),%mm0
movq   0x8(%rsi,%rcx,8),%mm1
movq   0x10(%rsi,%rcx,8),%mm2
movq   0x18(%rsi,%rcx,8),%mm3
movntq %mm0,(%rdi,%rcx,8)
movntq %mm1,0x8(%rdi,%rcx,8)
movntq %mm2,0x10(%rdi,%rcx,8)
movntq %mm3,0x18(%rdi,%rcx,8)
add    $0x4,%rcx
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 %rcx,%rcx \0A\09.align 16 \0A\090: \0A\09movq (%rsi,%rcx,8),%mm0 \0A\09movq 8(%rsi,%rcx,8),%mm1 \0A\09movq 16(%rsi,%rcx,8),%mm2 \0A\09movq 24(%rsi,%rcx,8),%mm3 \0A\09movntq %mm0,(%rdi,%rcx,8) \0A\09movntq %mm1,8(%rdi,%rcx,8) \0A\09movntq %mm2,16(%rdi,%rcx,8) \0A\09movntq %mm3,24(%rdi,%rcx,8) \0A\09add $$0x4, %rcx \0A\09dec $3 \0A\09jnz 0b \0A\09sfence \0A\09emms \0A\09", "=r,{si},{di},0,~{rax},~{rcx},~{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 %rcx,%rcx \0A\09.align 16 \0A\090: \0A\09movq (%rsi,%rcx,8),%mm0 \0A\09movq 8(%rsi,%rcx,8),%mm1 \0A\09movq 16(%rsi,%rcx,8),%mm2 \0A\09movq 24(%rsi,%rcx,8),%mm3 \0A\09movntq %mm0,(%rdi,%rcx,8) \0A\09movntq %mm1,8(%rdi,%rcx,8) \0A\09movntq %mm2,16(%rdi,%rcx,8) \0A\09movntq %mm3,24(%rdi,%rcx,8) \0A\09add $$0x4, %rcx \0A\09dec $3 \0A\09jnz 0b \0A\09sfence \0A\09emms \0A\09", "=r,{si},{di},0,~{rax},~{rcx},~{memory},~{dirflag},~{fpsr},~{flags}"(i8* %0, i8* %1, i32 %2)
ret void
}