#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
typedef int uint8_t;
typedef int /*<<< orphan*/ pt;
typedef int /*<<< orphan*/ ct;

/* Variables and functions */
int /*<<< orphan*/ AES_128_decrypt_asm(int *, int *, int *);
int /*<<< orphan*/ AES_128_encrypt_asm(int *, int *, int *);
int /*<<< orphan*/ AES_128_generate_tables();
int /*<<< orphan*/ AES_128_key_exp_dec_asm(int *, int *);
int /*<<< orphan*/ AES_128_key_exp_enc_asm(int *, int *);
scalar_t__ memcmp(int *, int *, int);
int /*<<< orphan*/ printf(char *);
int /*<<< orphan*/ printx(int *, int);
int main(int argc, char *argv[]) {
  (void)argc;
  (void)argv;
  uint8_t key[(128 / 8)] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                            0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
  uint8_t pt[(128 / 8)] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
                           0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
  uint8_t ct[(128 / 8)] = {0x69, 0xC4, 0xE0, 0xD8, 0x6A, 0x7B, 0x04, 0x30,
                           0xD8, 0xCD, 0xB7, 0x80, 0x70, 0xB4, 0xC5, 0x5A};
  uint8_t oute[(128 / 8)] = {0x00};
  uint8_t outd[(128 / 8)] = {0x00};
  uint8_t kxe[(11 * 16)] = {0x00};
  uint8_t kxd[(11 * 16)] = {0x00};
  AES_128_generate_tables();
  AES_128_key_exp_enc_asm(key, kxe);
  AES_128_encrypt_asm(pt, oute, kxe);
  if (memcmp(oute, ct, sizeof(ct)) == 0) {
    printf("ENCRYPT TEST PASSED: ");
  } else {
    printf("ENCRYPT TEST FAILED: ");
  }
  printx(oute, (128 / 8));
  printf(" vs. ");
  printx(ct, (128 / 8));
  printf("\r\n");
  AES_128_key_exp_dec_asm(key, kxd);
  AES_128_decrypt_asm(ct, outd, kxd);
  if (memcmp(outd, pt, sizeof(pt)) == 0) {
    printf("DECRYPT TEST PASSED: ");
  } else {
    printf("DECRYPT TEST FAILED: ");
  }
  printx(outd, (128 / 8));
  printf(" vs. ");
  printx(pt, (128 / 8));
  printf("\r\n");
  return 0;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x6d0,%rsp
movl   $0x0,-0x4(%rbp)
mov    %edi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
lea    -0x50(%rbp),%rdi
lea    0xe3c(%rip),%rsi
mov    $0x40,%edx
call   1080 <memcpy@plt>
lea    -0x90(%rbp),%rdi
lea    0xe64(%rip),%rsi
mov    $0x40,%edx
call   1080 <memcpy@plt>
lea    -0xd0(%rbp),%rdi
lea    0xe8c(%rip),%rsi
mov    $0x40,%edx
call   1080 <memcpy@plt>
lea    -0x110(%rbp),%rdi
xor    %esi,%esi
mov    $0x40,%edx
call   1060 <memset@plt>
lea    -0x150(%rbp),%rdi
xor    %esi,%esi
mov    $0x40,%edx
call   1060 <memset@plt>
lea    -0x410(%rbp),%rdi
xor    %esi,%esi
mov    $0x2c0,%edx
call   1060 <memset@plt>
lea    -0x6d0(%rbp),%rdi
xor    %esi,%esi
mov    $0x2c0,%edx
call   1060 <memset@plt>
mov    $0x0,%al
call   1090 <AES_128_generate_tables@plt>
lea    -0x50(%rbp),%rdi
lea    -0x410(%rbp),%rsi
call   10b0 <AES_128_key_exp_enc_asm@plt>
lea    -0x90(%rbp),%rdi
lea    -0x110(%rbp),%rsi
lea    -0x410(%rbp),%rdx
call   10c0 <AES_128_encrypt_asm@plt>
lea    -0x110(%rbp),%rdi
lea    -0xd0(%rbp),%rsi
mov    $0x40,%edx
call   1070 <memcmp@plt>
cmp    $0x0,%rax
jne    12ae <main+0x10e>
lea    0xe1c(%rip),%rdi
call   1050 <printf@plt>
jmp    12ba <main+0x11a>
lea    0xe21(%rip),%rdi
call   1050 <printf@plt>
lea    -0x110(%rbp),%rdi
mov    $0x10,%esi
call   1030 <printx@plt>
lea    0xe1a(%rip),%rdi
call   1050 <printf@plt>
lea    -0xd0(%rbp),%rdi
mov    $0x10,%esi
call   1030 <printx@plt>
lea    0xe03(%rip),%rdi
call   1050 <printf@plt>
lea    -0x50(%rbp),%rdi
lea    -0x6d0(%rbp),%rsi
call   10a0 <AES_128_key_exp_dec_asm@plt>
lea    -0xd0(%rbp),%rdi
lea    -0x150(%rbp),%rsi
lea    -0x6d0(%rbp),%rdx
call   1040 <AES_128_decrypt_asm@plt>
lea    -0x150(%rbp),%rdi
lea    -0x90(%rbp),%rsi
mov    $0x40,%edx
call   1070 <memcmp@plt>
cmp    $0x0,%rax
jne    1351 <main+0x1b1>
lea    0xdae(%rip),%rdi
call   1050 <printf@plt>
jmp    135d <main+0x1bd>
lea    0xdb3(%rip),%rdi
call   1050 <printf@plt>
lea    -0x150(%rbp),%rdi
mov    $0x10,%esi
call   1030 <printx@plt>
lea    0xd77(%rip),%rdi
call   1050 <printf@plt>
lea    -0x90(%rbp),%rdi
mov    $0x10,%esi
call   1030 <printx@plt>
lea    0xd60(%rip),%rdi
call   1050 <printf@plt>
xor    %eax,%eax
add    $0x6d0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x6c8,%rsp
movaps 0xe78(%rip),%xmm0
movaps %xmm0,0x70(%rsp)
movaps 0xe5c(%rip),%xmm0
movaps %xmm0,0x60(%rsp)
movaps 0xe40(%rip),%xmm0
movaps %xmm0,0x50(%rsp)
movaps 0xe24(%rip),%xmm0
movaps %xmm0,0x40(%rsp)
movaps 0xe88(%rip),%xmm0
movaps %xmm0,0x30(%rsp)
movaps 0xe6c(%rip),%xmm0
movaps %xmm0,0x20(%rsp)
movaps 0xe50(%rip),%xmm0
movaps %xmm0,0x10(%rsp)
movaps 0xe34(%rip),%xmm0
movaps %xmm0,(%rsp)
movaps 0xe99(%rip),%xmm0
movaps %xmm0,0x130(%rsp)
movaps 0xe7a(%rip),%xmm0
movaps %xmm0,0x120(%rsp)
movaps 0xe5b(%rip),%xmm0
movaps %xmm0,0x110(%rsp)
movaps 0xe3c(%rip),%xmm0
movaps %xmm0,0x100(%rsp)
xorps  %xmm0,%xmm0
movaps %xmm0,0xf0(%rsp)
movaps %xmm0,0xe0(%rsp)
movaps %xmm0,0xd0(%rsp)
movaps %xmm0,0xc0(%rsp)
movaps %xmm0,0xb0(%rsp)
movaps %xmm0,0xa0(%rsp)
movaps %xmm0,0x90(%rsp)
movaps %xmm0,0x80(%rsp)
lea    0x400(%rsp),%rbx
mov    $0x2c0,%edx
mov    %rbx,%rdi
xor    %esi,%esi
call   1070 <memset@plt>
lea    0x140(%rsp),%r12
mov    $0x2c0,%edx
mov    %r12,%rdi
xor    %esi,%esi
call   1070 <memset@plt>
xor    %eax,%eax
call   1090 <AES_128_generate_tables@plt>
lea    0x40(%rsp),%rdi
mov    %rbx,%rsi
call   10b0 <AES_128_key_exp_enc_asm@plt>
mov    %rsp,%rdi
lea    0xc0(%rsp),%rbp
mov    %rbp,%rsi
mov    %rbx,%rdx
call   10c0 <AES_128_encrypt_asm@plt>
lea    0x100(%rsp),%r14
mov    %rbp,%rdi
mov    %r14,%rsi
mov    $0x40,%edx
call   1080 <memcmp@plt>
test   %rax,%rax
lea    0xdb7(%rip),%rax
lea    0xdc6(%rip),%rdi
cmove  %rax,%rdi
call   1060 <printf@plt>
mov    %rbp,%rdi
mov    $0x10,%esi
call   1030 <printx@plt>
lea    0xdbf(%rip),%r13
mov    %r13,%rdi
call   1060 <printf@plt>
mov    %r14,%rdi
mov    $0x10,%esi
call   1030 <printx@plt>
lea    0xdd5(%rip),%r15
mov    %r15,%rdi
call   1040 <puts@plt>
lea    0x40(%rsp),%rdi
mov    %r12,%rsi
call   10a0 <AES_128_key_exp_dec_asm@plt>
lea    0x80(%rsp),%rbp
mov    %r14,%rdi
mov    %rbp,%rsi
mov    %r12,%rdx
call   1050 <AES_128_decrypt_asm@plt>
mov    %rbp,%rdi
mov    %rsp,%rbx
mov    %rbx,%rsi
mov    $0x40,%edx
call   1080 <memcmp@plt>
test   %rax,%rax
lea    0xd61(%rip),%rax
lea    0xd70(%rip),%rdi
cmove  %rax,%rdi
call   1060 <printf@plt>
mov    %rbp,%rdi
mov    $0x10,%esi
call   1030 <printx@plt>
mov    %r13,%rdi
call   1060 <printf@plt>
mov    %rbx,%rdi
mov    $0x10,%esi
call   1030 <printx@plt>
mov    %r15,%rdi
call   1040 <puts@plt>
xor    %eax,%eax
add    $0x6c8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@__const.main.key = [16 x i32] [i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15]
@__const.main.pt = [16 x i32] [i32 0, i32 17, i32 34, i32 51, i32 68, i32 85, i32 102, i32 119, i32 136, i32 153, i32 170, i32 187, i32 204, i32 221, i32 238, i32 255]
@__const.main.ct = [16 x i32] [i32 105, i32 196, i32 224, i32 216, i32 106, i32 123, i32 4, i32 48, i32 216, i32 205, i32 183, i32 128, i32 112, i32 180, i32 197, i32 90]
@.str = [22 x i8] c"ENCRYPT TEST PASSED: \00"
@.str.1 = [22 x i8] c"ENCRYPT TEST FAILED: \00"
@.str.2 = [6 x i8] c" vs. \00"
@.str.3 = [3 x i8] c"\0D\0A\00"
@.str.4 = [22 x i8] c"DECRYPT TEST PASSED: \00"
@.str.5 = [22 x i8] c"DECRYPT TEST FAILED: \00"
define i32 @main(i32 %0, i8** %1) {
%3 = alloca i32
%4 = alloca i32
%5 = alloca i8**
%6 = alloca [16 x i32]
%7 = alloca [16 x i32]
%8 = alloca [16 x i32]
%9 = alloca [16 x i32]
%10 = alloca [16 x i32]
%11 = alloca [176 x i32]
%12 = alloca [176 x i32]
store i32 0, i32* %3
store i32 %0, i32* %4
store i8** %1, i8*** %5
%13 = load i32, i32* %4
%14 = load i8**, i8*** %5
%15 = bitcast [16 x i32]* %6 to i8*
%16 = bitcast [16 x i32]* %7 to i8*
%17 = bitcast [16 x i32]* %8 to i8*
%18 = bitcast [16 x i32]* %9 to i8*
%19 = bitcast [16 x i32]* %10 to i8*
%20 = bitcast [176 x i32]* %11 to i8*
%21 = bitcast [176 x i32]* %12 to i8*
%22 = call i32 (...) @AES_128_generate_tables()
%23 = getelementptr inbounds [16 x i32], [16 x i32]* %6, i64 0, i64 0
%24 = getelementptr inbounds [176 x i32], [176 x i32]* %11, i64 0, i64 0
%25 = call i32 @AES_128_key_exp_enc_asm(i32* %23, i32* %24)
%26 = getelementptr inbounds [16 x i32], [16 x i32]* %7, i64 0, i64 0
%27 = getelementptr inbounds [16 x i32], [16 x i32]* %9, i64 0, i64 0
%28 = getelementptr inbounds [176 x i32], [176 x i32]* %11, i64 0, i64 0
%29 = call i32 @AES_128_encrypt_asm(i32* %26, i32* %27, i32* %28)
%30 = getelementptr inbounds [16 x i32], [16 x i32]* %9, i64 0, i64 0
%31 = getelementptr inbounds [16 x i32], [16 x i32]* %8, i64 0, i64 0
%32 = call i64 @memcmp(i32* %30, i32* %31, i32 64)
%33 = icmp eq i64 %32, 0
br i1 %33, label %34, label %36
34: ; preds = %2
%35 = call i32 @printf(i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str, i64 0, i64 0))
br label %38
36: ; preds = %2
%37 = call i32 @printf(i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str.1, i64 0, i64 0))
br label %38
38: ; preds = %36, %34
%39 = getelementptr inbounds [16 x i32], [16 x i32]* %9, i64 0, i64 0
%40 = call i32 @printx(i32* %39, i32 16)
%41 = call i32 @printf(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.2, i64 0, i64 0))
%42 = getelementptr inbounds [16 x i32], [16 x i32]* %8, i64 0, i64 0
%43 = call i32 @printx(i32* %42, i32 16)
%44 = call i32 @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.3, i64 0, i64 0))
%45 = getelementptr inbounds [16 x i32], [16 x i32]* %6, i64 0, i64 0
%46 = getelementptr inbounds [176 x i32], [176 x i32]* %12, i64 0, i64 0
%47 = call i32 @AES_128_key_exp_dec_asm(i32* %45, i32* %46)
%48 = getelementptr inbounds [16 x i32], [16 x i32]* %8, i64 0, i64 0
%49 = getelementptr inbounds [16 x i32], [16 x i32]* %10, i64 0, i64 0
%50 = getelementptr inbounds [176 x i32], [176 x i32]* %12, i64 0, i64 0
%51 = call i32 @AES_128_decrypt_asm(i32* %48, i32* %49, i32* %50)
%52 = getelementptr inbounds [16 x i32], [16 x i32]* %10, i64 0, i64 0
%53 = getelementptr inbounds [16 x i32], [16 x i32]* %7, i64 0, i64 0
%54 = call i64 @memcmp(i32* %52, i32* %53, i32 64)
%55 = icmp eq i64 %54, 0
br i1 %55, label %56, label %58
56: ; preds = %38
%57 = call i32 @printf(i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str.4, i64 0, i64 0))
br label %60
58: ; preds = %38
%59 = call i32 @printf(i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str.5, i64 0, i64 0))
br label %60
60: ; preds = %58, %56
%61 = getelementptr inbounds [16 x i32], [16 x i32]* %10, i64 0, i64 0
%62 = call i32 @printx(i32* %61, i32 16)
%63 = call i32 @printf(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.2, i64 0, i64 0))
%64 = getelementptr inbounds [16 x i32], [16 x i32]* %7, i64 0, i64 0
%65 = call i32 @printx(i32* %64, i32 16)
%66 = call i32 @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.3, i64 0, i64 0))
ret i32 0
}

LLVM IR (-O2):
@__const.main.key = [16 x i32] [i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15]
@__const.main.pt = [16 x i32] [i32 0, i32 17, i32 34, i32 51, i32 68, i32 85, i32 102, i32 119, i32 136, i32 153, i32 170, i32 187, i32 204, i32 221, i32 238, i32 255]
@__const.main.ct = [16 x i32] [i32 105, i32 196, i32 224, i32 216, i32 106, i32 123, i32 4, i32 48, i32 216, i32 205, i32 183, i32 128, i32 112, i32 180, i32 197, i32 90]
@.str = [22 x i8] c"ENCRYPT TEST PASSED: \00"
@.str.1 = [22 x i8] c"ENCRYPT TEST FAILED: \00"
@.str.2 = [6 x i8] c" vs. \00"
@.str.4 = [22 x i8] c"DECRYPT TEST PASSED: \00"
@.str.5 = [22 x i8] c"DECRYPT TEST FAILED: \00"
@str.6 = [2 x i8] c"\0D\00"
define i32 @main(i32 %0, i8** nocapture readnone %1) {
%3 = alloca [16 x i32]
%4 = alloca [16 x i32]
%5 = alloca [16 x i32]
%6 = alloca [16 x i32]
%7 = alloca [16 x i32]
%8 = alloca [176 x i32]
%9 = alloca [176 x i32]
%10 = bitcast [16 x i32]* %3 to i8*
%11 = bitcast [16 x i32]* %4 to i8*
%12 = bitcast [16 x i32]* %5 to i8*
%13 = bitcast [16 x i32]* %6 to i8*
%14 = bitcast [16 x i32]* %7 to i8*
%15 = bitcast [176 x i32]* %8 to i8*
%16 = bitcast [176 x i32]* %9 to i8*
%17 = tail call i32 (...) @AES_128_generate_tables()
%18 = getelementptr inbounds [16 x i32], [16 x i32]* %3, i64 0, i64 0
%19 = getelementptr inbounds [176 x i32], [176 x i32]* %8, i64 0, i64 0
%20 = call i32 @AES_128_key_exp_enc_asm(i32* %18, i32* %19)
%21 = getelementptr inbounds [16 x i32], [16 x i32]* %4, i64 0, i64 0
%22 = getelementptr inbounds [16 x i32], [16 x i32]* %6, i64 0, i64 0
%23 = call i32 @AES_128_encrypt_asm(i32* %21, i32* %22, i32* %19)
%24 = getelementptr inbounds [16 x i32], [16 x i32]* %5, i64 0, i64 0
%25 = call i64 @memcmp(i32* %22, i32* %24, i32 64)
%26 = icmp eq i64 %25, 0
%27 = select i1 %26, i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str.1, i64 0, i64 0)
%28 = call i32 @printf(i8* dereferenceable(1) %27)
%29 = call i32 @printx(i32* %22, i32 16)
%30 = call i32 @printf(i8* dereferenceable(1) getelementptr inbounds ([6 x i8], [6 x i8]* @.str.2, i64 0, i64 0))
%31 = call i32 @printx(i32* %24, i32 16)
%32 = call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([2 x i8], [2 x i8]* @str.6, i64 0, i64 0))
%33 = getelementptr inbounds [176 x i32], [176 x i32]* %9, i64 0, i64 0
%34 = call i32 @AES_128_key_exp_dec_asm(i32* %18, i32* %33)
%35 = getelementptr inbounds [16 x i32], [16 x i32]* %7, i64 0, i64 0
%36 = call i32 @AES_128_decrypt_asm(i32* %24, i32* %35, i32* %33)
%37 = call i64 @memcmp(i32* %35, i32* %21, i32 64)
%38 = icmp eq i64 %37, 0
%39 = select i1 %38, i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str.4, i64 0, i64 0), i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str.5, i64 0, i64 0)
%40 = call i32 @printf(i8* dereferenceable(1) %39)
%41 = call i32 @printx(i32* %35, i32 16)
%42 = call i32 @printf(i8* dereferenceable(1) getelementptr inbounds ([6 x i8], [6 x i8]* @.str.2, i64 0, i64 0))
%43 = call i32 @printx(i32* %21, i32 16)
%44 = call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([2 x i8], [2 x i8]* @str.6, i64 0, i64 0))
ret i32 0
}