#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 */

/* Variables and functions */
int /*<<< orphan*/ aes_cipher(int const, char const *, char const *, char *);
short aes_pkcs7padding(char const *, size_t const, char *);
void aes_ofbenc(const int bits, const char *in, const size_t length,
                const char *key, const char *iv, char *out) {
  const char *vector = iv;
  char blk[16];
  for (size_t d = 0; d + 15 < length; d += 16) {
    aes_cipher(bits, vector, key, out + d);
    vector = out + d;
  }
  short quot = aes_pkcs7padding(in, length, blk);
  aes_cipher(bits, vector, key, out + length - quot);
  for (size_t d = 0; d < ((length >> 4) << 4); d++)
    *(out + d) ^= *(in + d);
  for (short i = 0; i < 16; i++)
    *(out + length - quot + i) ^= blk[i];
}


x86 assembly (clang, -O0):
<aes_ofbenc>:
push   %rbp
mov    %rsp,%rbp
sub    $0x70,%rsp
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
mov    %r9,-0x30(%rbp)
mov    -0x28(%rbp),%rax
mov    %rax,-0x38(%rbp)
movq   $0x0,-0x58(%rbp)
mov    -0x58(%rbp),%rax
add    $0xf,%rax
cmp    -0x18(%rbp),%rax
jae    1196 <aes_ofbenc+0x76>
mov    -0x4(%rbp),%edi
mov    -0x38(%rbp),%rsi
mov    -0x20(%rbp),%rdx
mov    -0x30(%rbp),%rcx
add    -0x58(%rbp),%rcx
call   1040 <aes_cipher@plt>
mov    -0x30(%rbp),%rax
add    -0x58(%rbp),%rax
mov    %rax,-0x38(%rbp)
mov    -0x58(%rbp),%rax
add    $0x10,%rax
mov    %rax,-0x58(%rbp)
jmp    114f <aes_ofbenc+0x2f>
mov    -0x10(%rbp),%rdi
mov    -0x18(%rbp),%rsi
lea    -0x50(%rbp),%rdx
call   1030 <aes_pkcs7padding@plt>
mov    %ax,-0x5a(%rbp)
mov    -0x4(%rbp),%edi
mov    -0x38(%rbp),%rsi
mov    -0x20(%rbp),%rdx
mov    -0x30(%rbp),%rcx
add    -0x18(%rbp),%rcx
movswl -0x5a(%rbp),%eax
movslq %eax,%r8
xor    %eax,%eax
sub    %r8,%rax
add    %rax,%rcx
call   1040 <aes_cipher@plt>
movq   $0x0,-0x68(%rbp)
mov    -0x68(%rbp),%rax
mov    -0x18(%rbp),%rcx
shr    $0x4,%rcx
shl    $0x4,%rcx
cmp    %rcx,%rax
jae    1221 <aes_ofbenc+0x101>
mov    -0x10(%rbp),%rax
mov    -0x68(%rbp),%rcx
movsbl (%rax,%rcx,1),%esi
mov    -0x30(%rbp),%rax
mov    -0x68(%rbp),%rcx
movsbl (%rax,%rcx,1),%edx
xor    %esi,%edx
mov    %dl,(%rax,%rcx,1)
mov    -0x68(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x68(%rbp)
jmp    11da <aes_ofbenc+0xba>
movw   $0x0,-0x6a(%rbp)
movswl -0x6a(%rbp),%eax
cmp    $0x10,%eax
jge    1276 <aes_ofbenc+0x156>
movswq -0x6a(%rbp),%rax
movsbl -0x50(%rbp,%rax,1),%esi
mov    -0x30(%rbp),%rax
add    -0x18(%rbp),%rax
movswl -0x5a(%rbp),%ecx
movslq %ecx,%rdx
xor    %ecx,%ecx
sub    %rdx,%rcx
add    %rcx,%rax
movswl -0x6a(%rbp),%ecx
movslq %ecx,%rcx
movsbl (%rax,%rcx,1),%edx
xor    %esi,%edx
mov    %dl,(%rax,%rcx,1)
mov    -0x6a(%rbp),%ax
add    $0x1,%ax
mov    %ax,-0x6a(%rbp)
jmp    1227 <aes_ofbenc+0x107>
add    $0x70,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<aes_ofbenc>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x38,%rsp
mov    %r9,%r15
mov    %r8,%r12
mov    %rcx,%rbp
mov    %rdx,%r14
mov    %rsi,%rbx
cmp    $0x10,%rdx
mov    %edi,0x4(%rsp)
jb     11bd <aes_ofbenc+0x9d>
mov    %rbx,0x18(%rsp)
mov    %rbp,0x10(%rsp)
mov    $0xf,%r13d
xor    %ebp,%ebp
mov    %r15,%rbx
mov    %r15,0x8(%rsp)
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
mov    %r14,%r15
mov    0x8(%rsp),%rax
lea    (%rax,%rbp,1),%r14
mov    0x4(%rsp),%edi
mov    %r12,%rsi
mov    0x10(%rsp),%rdx
mov    %rbx,%rcx
call   1040 <aes_cipher@plt>
add    $0x10,%rbp
add    $0x10,%rbx
add    $0x10,%r13
mov    %r14,%r12
mov    %r15,%r14
cmp    %r15,%r13
jb     1170 <aes_ofbenc+0x50>
add    $0xfffffffffffffff0,%rbx
mov    %rbx,%r12
mov    0x18(%rsp),%rbx
mov    0x8(%rsp),%r15
mov    0x10(%rsp),%rbp
lea    0x20(%rsp),%rdx
mov    %rbx,%rdi
mov    %r14,%rsi
call   1030 <aes_pkcs7padding@plt>
lea    (%r15,%r14,1),%r13
movswq %ax,%rax
sub    %rax,%r13
mov    0x4(%rsp),%edi
mov    %r12,%rsi
mov    %rbp,%rdx
mov    %r13,%rcx
call   1040 <aes_cipher@plt>
mov    %r14,%rax
and    $0xfffffffffffffff0,%rax
je     12b1 <aes_ofbenc+0x191>
lea    (%rbx,%rax,1),%rcx
cmp    %r15,%rcx
jbe    1241 <aes_ofbenc+0x121>
lea    (%r15,%rax,1),%rcx
cmp    %rbx,%rcx
jbe    1241 <aes_ofbenc+0x121>
xor    %ecx,%ecx
nopl   0x0(%rax,%rax,1)
movzbl (%rbx,%rcx,1),%edx
xor    %dl,(%r15,%rcx,1)
movzbl 0x1(%rbx,%rcx,1),%edx
xor    %dl,0x1(%r15,%rcx,1)
movzbl 0x2(%rbx,%rcx,1),%edx
xor    %dl,0x2(%r15,%rcx,1)
movzbl 0x3(%rbx,%rcx,1),%edx
xor    %dl,0x3(%r15,%rcx,1)
add    $0x4,%rcx
cmp    %rcx,%rax
jne    1210 <aes_ofbenc+0xf0>
jmp    12b1 <aes_ofbenc+0x191>
cmp    $0x20,%rax
jae    124b <aes_ofbenc+0x12b>
xor    %ecx,%ecx
jmp    12a0 <aes_ofbenc+0x180>
and    $0x10,%r14d
mov    %rax,%rcx
sub    %r14,%rcx
xor    %edx,%edx
nopw   0x0(%rax,%rax,1)
movups (%rbx,%rdx,1),%xmm0
movups 0x10(%rbx,%rdx,1),%xmm1
movups (%r15,%rdx,1),%xmm2
xorps  %xmm0,%xmm2
movups 0x10(%r15,%rdx,1),%xmm0
xorps  %xmm1,%xmm0
movups %xmm2,(%r15,%rdx,1)
movups %xmm0,0x10(%r15,%rdx,1)
add    $0x20,%rdx
cmp    %rdx,%rcx
jne    1260 <aes_ofbenc+0x140>
test   %r14,%r14
je     12b1 <aes_ofbenc+0x191>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
mov    (%rbx,%rcx,1),%rdx
xor    %rdx,(%r15,%rcx,1)
add    $0x8,%rcx
cmp    %rcx,%rax
jne    12a0 <aes_ofbenc+0x180>
movups 0x0(%r13),%xmm0
xorps  0x20(%rsp),%xmm0
movups %xmm0,0x0(%r13)
add    $0x38,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @aes_ofbenc(i32 %0, i8* %1, i64 %2, i8* %3, i8* %4, i8* %5) {
%7 = alloca i32
%8 = alloca i8*
%9 = alloca i64
%10 = alloca i8*
%11 = alloca i8*
%12 = alloca i8*
%13 = alloca i8*
%14 = alloca [16 x i8]
%15 = alloca i64
%16 = alloca i16
%17 = alloca i64
%18 = alloca i16
store i32 %0, i32* %7
store i8* %1, i8** %8
store i64 %2, i64* %9
store i8* %3, i8** %10
store i8* %4, i8** %11
store i8* %5, i8** %12
%19 = load i8*, i8** %11
store i8* %19, i8** %13
store i64 0, i64* %15
br label %20
20: ; preds = %36, %6
%21 = load i64, i64* %15
%22 = add i64 %21, 15
%23 = load i64, i64* %9
%24 = icmp ult i64 %22, %23
br i1 %24, label %25, label %39
25: ; preds = %20
%26 = load i32, i32* %7
%27 = load i8*, i8** %13
%28 = load i8*, i8** %10
%29 = load i8*, i8** %12
%30 = load i64, i64* %15
%31 = getelementptr inbounds i8, i8* %29, i64 %30
%32 = call i32 @aes_cipher(i32 %26, i8* %27, i8* %28, i8* %31)
%33 = load i8*, i8** %12
%34 = load i64, i64* %15
%35 = getelementptr inbounds i8, i8* %33, i64 %34
store i8* %35, i8** %13
br label %36
36: ; preds = %25
%37 = load i64, i64* %15
%38 = add i64 %37, 16
store i64 %38, i64* %15
br label %20
39: ; preds = %20
%40 = load i8*, i8** %8
%41 = load i64, i64* %9
%42 = getelementptr inbounds [16 x i8], [16 x i8]* %14, i64 0, i64 0
%43 = call signext i16 @aes_pkcs7padding(i8* %40, i64 %41, i8* %42)
store i16 %43, i16* %16
%44 = load i32, i32* %7
%45 = load i8*, i8** %13
%46 = load i8*, i8** %10
%47 = load i8*, i8** %12
%48 = load i64, i64* %9
%49 = getelementptr inbounds i8, i8* %47, i64 %48
%50 = load i16, i16* %16
%51 = sext i16 %50 to i32
%52 = sext i32 %51 to i64
%53 = sub i64 0, %52
%54 = getelementptr inbounds i8, i8* %49, i64 %53
%55 = call i32 @aes_cipher(i32 %44, i8* %45, i8* %46, i8* %54)
store i64 0, i64* %17
br label %56
56: ; preds = %75, %39
%57 = load i64, i64* %17
%58 = load i64, i64* %9
%59 = lshr i64 %58, 4
%60 = shl i64 %59, 4
%61 = icmp ult i64 %57, %60
br i1 %61, label %62, label %78
62: ; preds = %56
%63 = load i8*, i8** %8
%64 = load i64, i64* %17
%65 = getelementptr inbounds i8, i8* %63, i64 %64
%66 = load i8, i8* %65
%67 = sext i8 %66 to i32
%68 = load i8*, i8** %12
%69 = load i64, i64* %17
%70 = getelementptr inbounds i8, i8* %68, i64 %69
%71 = load i8, i8* %70
%72 = sext i8 %71 to i32
%73 = xor i32 %72, %67
%74 = trunc i32 %73 to i8
store i8 %74, i8* %70
br label %75
75: ; preds = %62
%76 = load i64, i64* %17
%77 = add i64 %76, 1
store i64 %77, i64* %17
br label %56
78: ; preds = %56
store i16 0, i16* %18
br label %79
79: ; preds = %105, %78
%80 = load i16, i16* %18
%81 = sext i16 %80 to i32
%82 = icmp slt i32 %81, 16
br i1 %82, label %83, label %108
83: ; preds = %79
%84 = load i16, i16* %18
%85 = sext i16 %84 to i64
%86 = getelementptr inbounds [16 x i8], [16 x i8]* %14, i64 0, i64 %85
%87 = load i8, i8* %86
%88 = sext i8 %87 to i32
%89 = load i8*, i8** %12
%90 = load i64, i64* %9
%91 = getelementptr inbounds i8, i8* %89, i64 %90
%92 = load i16, i16* %16
%93 = sext i16 %92 to i32
%94 = sext i32 %93 to i64
%95 = sub i64 0, %94
%96 = getelementptr inbounds i8, i8* %91, i64 %95
%97 = load i16, i16* %18
%98 = sext i16 %97 to i32
%99 = sext i32 %98 to i64
%100 = getelementptr inbounds i8, i8* %96, i64 %99
%101 = load i8, i8* %100
%102 = sext i8 %101 to i32
%103 = xor i32 %102, %88
%104 = trunc i32 %103 to i8
store i8 %104, i8* %100
br label %105
105: ; preds = %83
%106 = load i16, i16* %18
%107 = add i16 %106, 1
store i16 %107, i16* %18
br label %79
108: ; preds = %79
ret void
}

LLVM IR (-O2):
define void @aes_ofbenc(i32 %0, i8* %1, i64 %2, i8* %3, i8* %4, i8* %5) {
%7 = alloca <16 x i8>
%8 = getelementptr inbounds <16 x i8>, <16 x i8>* %7, i64 0, i64 0
%9 = icmp ugt i64 %2, 15
br i1 %9, label %67, label %10
10: ; preds = %67, %6
%11 = phi i8* [ %4, %6 ], [ %70, %67 ]
%12 = call signext i16 @aes_pkcs7padding(i8* %1, i64 %2, i8* %8)
%13 = getelementptr inbounds i8, i8* %5, i64 %2
%14 = sext i16 %12 to i64
%15 = sub nsw i64 0, %14
%16 = getelementptr inbounds i8, i8* %13, i64 %15
%17 = call i32 @aes_cipher(i32 %0, i8* %11, i8* %3, i8* %16)
%18 = and i64 %2, -16
%19 = icmp eq i64 %18, 0
br i1 %19, label %75, label %20
20: ; preds = %10
%21 = getelementptr i8, i8* %5, i64 %18
%22 = getelementptr i8, i8* %1, i64 %18
%23 = icmp ugt i8* %22, %5
%24 = icmp ugt i8* %21, %1
%25 = and i1 %23, %24
br i1 %25, label %81, label %26
26: ; preds = %20
%27 = icmp ult i64 %18, 32
br i1 %27, label %53, label %28
28: ; preds = %26
%29 = and i64 %2, 16
%30 = sub i64 %18, %29
br label %31
31: ; preds = %31, %28
%32 = phi i64 [ 0, %28 ], [ %49, %31 ]
%33 = getelementptr inbounds i8, i8* %1, i64 %32
%34 = bitcast i8* %33 to <16 x i8>*
%35 = load <16 x i8>, <16 x i8>* %34
%36 = getelementptr inbounds i8, i8* %33, i64 16
%37 = bitcast i8* %36 to <16 x i8>*
%38 = load <16 x i8>, <16 x i8>* %37
%39 = getelementptr inbounds i8, i8* %5, i64 %32
%40 = bitcast i8* %39 to <16 x i8>*
%41 = load <16 x i8>, <16 x i8>* %40
%42 = getelementptr inbounds i8, i8* %39, i64 16
%43 = bitcast i8* %42 to <16 x i8>*
%44 = load <16 x i8>, <16 x i8>* %43
%45 = xor <16 x i8> %41, %35
%46 = xor <16 x i8> %44, %38
%47 = bitcast i8* %39 to <16 x i8>*
store <16 x i8> %45, <16 x i8>* %47
%48 = bitcast i8* %42 to <16 x i8>*
store <16 x i8> %46, <16 x i8>* %48
%49 = add nuw i64 %32, 32
%50 = icmp eq i64 %49, %30
br i1 %50, label %51, label %31
51: ; preds = %31
%52 = icmp eq i64 %29, 0
br i1 %52, label %75, label %53
53: ; preds = %51, %26
%54 = phi i64 [ %30, %51 ], [ 0, %26 ]
br label %55
55: ; preds = %53, %55
%56 = phi i64 [ %65, %55 ], [ %54, %53 ]
%57 = getelementptr inbounds i8, i8* %1, i64 %56
%58 = bitcast i8* %57 to <8 x i8>*
%59 = load <8 x i8>, <8 x i8>* %58
%60 = getelementptr inbounds i8, i8* %5, i64 %56
%61 = bitcast i8* %60 to <8 x i8>*
%62 = load <8 x i8>, <8 x i8>* %61
%63 = xor <8 x i8> %62, %59
%64 = bitcast i8* %60 to <8 x i8>*
store <8 x i8> %63, <8 x i8>* %64
%65 = add nuw i64 %56, 8
%66 = icmp eq i64 %65, %18
br i1 %66, label %75, label %55
67: ; preds = %6, %67
%68 = phi i8* [ %70, %67 ], [ %4, %6 ]
%69 = phi i64 [ %72, %67 ], [ 0, %6 ]
%70 = getelementptr inbounds i8, i8* %5, i64 %69
%71 = tail call i32 @aes_cipher(i32 %0, i8* %68, i8* %3, i8* %70)
%72 = add i64 %69, 16
%73 = or i64 %72, 15
%74 = icmp ult i64 %73, %2
br i1 %74, label %67, label %10
75: ; preds = %55, %81, %51, %10
%76 = load <16 x i8>, <16 x i8>* %7
%77 = bitcast i8* %16 to <16 x i8>*
%78 = load <16 x i8>, <16 x i8>* %77
%79 = xor <16 x i8> %78, %76
%80 = bitcast i8* %16 to <16 x i8>*
store <16 x i8> %79, <16 x i8>* %80
ret void
81: ; preds = %20, %81
%82 = phi i64 [ %106, %81 ], [ 0, %20 ]
%83 = getelementptr inbounds i8, i8* %1, i64 %82
%84 = load i8, i8* %83
%85 = getelementptr inbounds i8, i8* %5, i64 %82
%86 = load i8, i8* %85
%87 = xor i8 %86, %84
store i8 %87, i8* %85
%88 = or i64 %82, 1
%89 = getelementptr inbounds i8, i8* %1, i64 %88
%90 = load i8, i8* %89
%91 = getelementptr inbounds i8, i8* %5, i64 %88
%92 = load i8, i8* %91
%93 = xor i8 %92, %90
store i8 %93, i8* %91
%94 = or i64 %82, 2
%95 = getelementptr inbounds i8, i8* %1, i64 %94
%96 = load i8, i8* %95
%97 = getelementptr inbounds i8, i8* %5, i64 %94
%98 = load i8, i8* %97
%99 = xor i8 %98, %96
store i8 %99, i8* %97
%100 = or i64 %82, 3
%101 = getelementptr inbounds i8, i8* %1, i64 %100
%102 = load i8, i8* %101
%103 = getelementptr inbounds i8, i8* %5, i64 %100
%104 = load i8, i8* %103
%105 = xor i8 %104, %102
store i8 %105, i8* %103
%106 = add nuw i64 %82, 4
%107 = icmp eq i64 %106, %18
br i1 %107, label %75, label %81
}