void aesni256_encrypt(unsigned char *ctx, const unsigned char *in,
                      unsigned char *out) {
  void *p1, *p2;
  asm volatile("movdqu (%2), %%xmm1\n\t"
               "pxor (%3), %%xmm1\n\t"
               "aesenc 0x10(%3), %%xmm1\n\t"
               "aesenc 0x20(%3), %%xmm1\n\t"
               "aesenc 0x30(%3), %%xmm1\n\t"
               "aesenc 0x40(%3), %%xmm1\n\t"
               "aesenc 0x50(%3), %%xmm1\n\t"
               "aesenc 0x60(%3), %%xmm1\n\t"
               "aesenc 0x70(%3), %%xmm1\n\t"
               "aesenc 0x80(%3), %%xmm1\n\t"
               "aesenc 0x90(%3), %%xmm1\n\t"
               "aesenc 0xa0(%3), %%xmm1\n\t"
               "aesenc 0xb0(%3), %%xmm1\n\t"
               "aesenc 0xc0(%3), %%xmm1\n\t"
               "aesenc 0xd0(%3), %%xmm1\n\t"
               "aesenclast 0xe0(%3), %%xmm1\n\t"
               "movdqu %%xmm1, (%4)\n\t"
               : "=r"(p1), "=r"(p2)
               : "0r"(in), "r"(ctx), "1r"(out)
               : "%xmm1", "memory");
}


x86 assembly (clang, -O0):
<aesni256_encrypt>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x8(%rbp),%rcx
mov    -0x18(%rbp),%rdx
movdqu (%rax),%xmm1
pxor   (%rcx),%xmm1
aesenc 0x10(%rcx),%xmm1
aesenc 0x20(%rcx),%xmm1
aesenc 0x30(%rcx),%xmm1
aesenc 0x40(%rcx),%xmm1
aesenc 0x50(%rcx),%xmm1
aesenc 0x60(%rcx),%xmm1
aesenc 0x70(%rcx),%xmm1
aesenc 0x80(%rcx),%xmm1
aesenc 0x90(%rcx),%xmm1
aesenc 0xa0(%rcx),%xmm1
aesenc 0xb0(%rcx),%xmm1
aesenc 0xc0(%rcx),%xmm1
aesenc 0xd0(%rcx),%xmm1
aesenclast 0xe0(%rcx),%xmm1
movdqu %xmm1,(%rdx)
mov    %rcx,-0x20(%rbp)
mov    %rax,-0x28(%rbp)
pop    %rbp
ret

x86 assembly (clang, -O2):
<aesni256_encrypt>:
movdqu (%rsi),%xmm1
pxor   (%rdi),%xmm1
aesenc 0x10(%rdi),%xmm1
aesenc 0x20(%rdi),%xmm1
aesenc 0x30(%rdi),%xmm1
aesenc 0x40(%rdi),%xmm1
aesenc 0x50(%rdi),%xmm1
aesenc 0x60(%rdi),%xmm1
aesenc 0x70(%rdi),%xmm1
aesenc 0x80(%rdi),%xmm1
aesenc 0x90(%rdi),%xmm1
aesenc 0xa0(%rdi),%xmm1
aesenc 0xb0(%rdi),%xmm1
aesenc 0xc0(%rdi),%xmm1
aesenc 0xd0(%rdi),%xmm1
aesenclast 0xe0(%rdi),%xmm1
movdqu %xmm1,(%rdx)
ret

LLVM IR (-O0):
define void @aesni256_encrypt(i8* %0, i8* %1, i8* %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i8*
%7 = alloca i8*
%8 = alloca i8*
store i8* %0, i8** %4
store i8* %1, i8** %5
store i8* %2, i8** %6
%9 = load i8*, i8** %5
%10 = load i8*, i8** %4
%11 = load i8*, i8** %6
%12 = call { i8*, i8* } asm sideeffect "movdqu ($2), %xmm1\0A\09pxor ($3), %xmm1\0A\09aesenc 0x10($3), %xmm1\0A\09aesenc 0x20($3), %xmm1\0A\09aesenc 0x30($3), %xmm1\0A\09aesenc 0x40($3), %xmm1\0A\09aesenc 0x50($3), %xmm1\0A\09aesenc 0x60($3), %xmm1\0A\09aesenc 0x70($3), %xmm1\0A\09aesenc 0x80($3), %xmm1\0A\09aesenc 0x90($3), %xmm1\0A\09aesenc 0xa0($3), %xmm1\0A\09aesenc 0xb0($3), %xmm1\0A\09aesenc 0xc0($3), %xmm1\0A\09aesenc 0xd0($3), %xmm1\0A\09aesenclast 0xe0($3), %xmm1\0A\09movdqu %xmm1, ($4)\0A\09", "=r,=r,0r,r,1r,~{xmm1},~{memory},~{dirflag},~{fpsr},~{flags}"(i8* %9, i8* %10, i8* %11)
%13 = extractvalue { i8*, i8* } %12, 0
%14 = extractvalue { i8*, i8* } %12, 1
store i8* %13, i8** %7
store i8* %14, i8** %8
ret void
}

LLVM IR (-O2):
define void @aesni256_encrypt(i8* %0, i8* %1, i8* %2) {
%4 = tail call { i8*, i8* } asm sideeffect "movdqu ($2), %xmm1\0A\09pxor ($3), %xmm1\0A\09aesenc 0x10($3), %xmm1\0A\09aesenc 0x20($3), %xmm1\0A\09aesenc 0x30($3), %xmm1\0A\09aesenc 0x40($3), %xmm1\0A\09aesenc 0x50($3), %xmm1\0A\09aesenc 0x60($3), %xmm1\0A\09aesenc 0x70($3), %xmm1\0A\09aesenc 0x80($3), %xmm1\0A\09aesenc 0x90($3), %xmm1\0A\09aesenc 0xa0($3), %xmm1\0A\09aesenc 0xb0($3), %xmm1\0A\09aesenc 0xc0($3), %xmm1\0A\09aesenc 0xd0($3), %xmm1\0A\09aesenclast 0xe0($3), %xmm1\0A\09movdqu %xmm1, ($4)\0A\09", "=r,=r,0r,r,1r,~{xmm1},~{memory},~{dirflag},~{fpsr},~{flags}"(i8* %1, i8* %0, i8* %2)
ret void
}