#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 */
char _base64_get_index(char);
int base64_stream_decode(char *dst, char *src, int src_len, int *left) {
  char *p = dst;
  char *s = src;
  int in_len = 0;
  int out_len = 0;
  int i, k, effect_len = 0;
  char prev = 0;
  for (i = 0; i < src_len; i++) {
    char v = *(s++);
    k = effect_len % 4;
    char ch = _base64_get_index(v);
    if ((('z') + 1) == ch) {
      if (v == '\r' || v == '\n' || v == ' ' || v == '\t')
        continue;
      ch = 0;
    } else if ((('z') + 2) == ch) {
      *left = src_len - i - 1;
      *p = '\0';
      return p - dst;
    }
    effect_len++;
    switch (k) {
    case 0:
      break;
    case 1:
      *(p++) = ((prev << 2) & 0xfc) | ((ch >> 4) & 0x03);
      break;
    case 2:
      *(p++) = ((prev << 4) & 0xf0) | ((ch >> 2) & 0x0f);
      break;
    case 3:
      *(p++) = ((prev << 6) & 0xc0) | (ch & 0x03f);
      in_len += 4;
      out_len += 3;
      break;
    }
    prev = ch;
  }
  *p = '\0';
  *left = 0;
  return out_len;
}


x86 assembly (clang, -O0):
<base64_stream_decode>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %edx,-0x1c(%rbp)
mov    %rcx,-0x28(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x18(%rbp),%rax
mov    %rax,-0x38(%rbp)
movl   $0x0,-0x3c(%rbp)
movl   $0x0,-0x40(%rbp)
movl   $0x0,-0x4c(%rbp)
movb   $0x0,-0x4d(%rbp)
movl   $0x0,-0x44(%rbp)
mov    -0x44(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jge    1304 <base64_stream_decode+0x1f4>
mov    -0x38(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x38(%rbp)
mov    (%rax),%al
mov    %al,-0x4e(%rbp)
mov    -0x4c(%rbp),%eax
mov    $0x4,%ecx
cltd
idiv   %ecx
mov    %edx,-0x48(%rbp)
movsbl -0x4e(%rbp),%edi
call   1030 <_base64_get_index@plt>
mov    %al,-0x4f(%rbp)
movsbl -0x4f(%rbp),%ecx
mov    $0x7b,%eax
cmp    %ecx,%eax
jne    11e4 <base64_stream_decode+0xd4>
movsbl -0x4e(%rbp),%eax
cmp    $0xd,%eax
je     11d6 <base64_stream_decode+0xc6>
movsbl -0x4e(%rbp),%eax
cmp    $0xa,%eax
je     11d6 <base64_stream_decode+0xc6>
movsbl -0x4e(%rbp),%eax
cmp    $0x20,%eax
je     11d6 <base64_stream_decode+0xc6>
movsbl -0x4e(%rbp),%eax
cmp    $0x9,%eax
jne    11db <base64_stream_decode+0xcb>
jmp    12f6 <base64_stream_decode+0x1e6>
movb   $0x0,-0x4f(%rbp)
jmp    1223 <base64_stream_decode+0x113>
movsbl -0x4f(%rbp),%ecx
mov    $0x7c,%eax
cmp    %ecx,%eax
jne    121e <base64_stream_decode+0x10e>
mov    -0x1c(%rbp),%ecx
sub    -0x44(%rbp),%ecx
sub    $0x1,%ecx
mov    -0x28(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x30(%rbp),%rax
movb   $0x0,(%rax)
mov    -0x30(%rbp),%rax
mov    -0x10(%rbp),%rcx
sub    %rcx,%rax
mov    %eax,-0x4(%rbp)
jmp    131b <base64_stream_decode+0x20b>
jmp    1223 <base64_stream_decode+0x113>
mov    -0x4c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x4c(%rbp)
mov    -0x48(%rbp),%eax
mov    %rax,-0x58(%rbp)
sub    $0x3,%rax
ja     12f0 <base64_stream_decode+0x1e0>
mov    -0x58(%rbp),%rax
lea    0xdb8(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
jmp    12f0 <base64_stream_decode+0x1e0>
movsbl -0x4d(%rbp),%eax
shl    $0x2,%eax
and    $0xfc,%eax
movsbl -0x4f(%rbp),%ecx
sar    $0x4,%ecx
and    $0x3,%ecx
or     %ecx,%eax
mov    %al,%cl
mov    -0x30(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x30(%rbp)
mov    %cl,(%rax)
jmp    12f0 <base64_stream_decode+0x1e0>
movsbl -0x4d(%rbp),%eax
shl    $0x4,%eax
and    $0xf0,%eax
movsbl -0x4f(%rbp),%ecx
sar    $0x2,%ecx
and    $0xf,%ecx
or     %ecx,%eax
mov    %al,%cl
mov    -0x30(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x30(%rbp)
mov    %cl,(%rax)
jmp    12f0 <base64_stream_decode+0x1e0>
movsbl -0x4d(%rbp),%eax
shl    $0x6,%eax
and    $0xc0,%eax
movsbl -0x4f(%rbp),%ecx
and    $0x3f,%ecx
or     %ecx,%eax
mov    %al,%cl
mov    -0x30(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x30(%rbp)
mov    %cl,(%rax)
mov    -0x3c(%rbp),%eax
add    $0x4,%eax
mov    %eax,-0x3c(%rbp)
mov    -0x40(%rbp),%eax
add    $0x3,%eax
mov    %eax,-0x40(%rbp)
mov    -0x4f(%rbp),%al
mov    %al,-0x4d(%rbp)
mov    -0x44(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x44(%rbp)
jmp    1157 <base64_stream_decode+0x47>
mov    -0x30(%rbp),%rax
movb   $0x0,(%rax)
mov    -0x28(%rbp),%rax
movl   $0x0,(%rax)
mov    -0x40(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<base64_stream_decode>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x28,%rsp
mov    %rcx,0x8(%rsp)
mov    %rsi,0x20(%rsp)
test   %edx,%edx
jle    121d <base64_stream_decode+0x10d>
mov    %edx,0x4(%rsp)
mov    %edx,%eax
mov    %rax,0x18(%rsp)
xor    %r14d,%r14d
xor    %r13d,%r13d
xor    %r12d,%r12d
mov    %rdi,%rax
mov    %rdi,0x10(%rsp)
mov    %rdi,%rbp
movl   $0x0,(%rsp)
jmp    1182 <base64_stream_decode+0x72>
shl    $0x6,%r13b
mov    %eax,%ecx
and    $0x3f,%cl
or     %r13b,%cl
mov    %cl,0x0(%rbp)
add    $0x1,%rbp
addl   $0x3,(%rsp)
nop
add    $0x1,%r14
mov    %eax,%r13d
cmp    %r14d,0x18(%rsp)
je     1227 <base64_stream_decode+0x117>
mov    0x20(%rsp),%rax
movzbl (%rax,%r14,1),%ebx
lea    0x3(%r12),%r15d
test   %r12d,%r12d
cmovns %r12d,%r15d
movsbl %bl,%edi
call   1030 <_base64_get_index@plt>
cmp    $0x7b,%al
je     11e0 <base64_stream_decode+0xd0>
cmp    $0x7c,%al
je     123b <base64_stream_decode+0x12b>
and    $0xfffffffc,%r15d
mov    %r12d,%ecx
sub    %r15d,%ecx
add    $0x1,%r12d
cmp    $0x3,%ecx
je     1158 <base64_stream_decode+0x48>
cmp    $0x2,%ecx
je     1202 <base64_stream_decode+0xf2>
cmp    $0x1,%ecx
jne    1170 <base64_stream_decode+0x60>
shl    $0x2,%r13b
mov    %eax,%ecx
shr    $0x4,%cl
and    $0x3,%cl
jmp    120e <base64_stream_decode+0xfe>
nopw   0x0(%rax,%rax,1)
xor    %eax,%eax
cmp    $0x20,%bl
ja     11ac <base64_stream_decode+0x9c>
movzbl %bl,%ecx
movabs $0x100002600,%rdx
bt     %rcx,%rdx
jae    11ac <base64_stream_decode+0x9c>
mov    %r13d,%eax
jmp    1170 <base64_stream_decode+0x60>
shl    $0x4,%r13b
mov    %eax,%ecx
shr    $0x2,%cl
and    $0xf,%cl
or     %r13b,%cl
mov    %cl,0x0(%rbp)
add    $0x1,%rbp
jmp    1170 <base64_stream_decode+0x60>
movl   $0x0,(%rsp)
mov    %rdi,%rbp
movb   $0x0,0x0(%rbp)
mov    0x8(%rsp),%rax
movl   $0x0,(%rax)
mov    (%rsp),%eax
jmp    1255 <base64_stream_decode+0x145>
not    %r14d
add    0x4(%rsp),%r14d
mov    0x8(%rsp),%rax
mov    %r14d,(%rax)
movb   $0x0,0x0(%rbp)
sub    0x10(%rsp),%ebp
mov    %ebp,%eax
add    $0x28,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define i32 @base64_stream_decode(i8* %0, i8* %1, i32 %2, i32* %3) {
%5 = alloca i32
%6 = alloca i8*
%7 = alloca i8*
%8 = alloca i32
%9 = alloca i32*
%10 = alloca i8*
%11 = alloca i8*
%12 = alloca i32
%13 = alloca i32
%14 = alloca i32
%15 = alloca i32
%16 = alloca i32
%17 = alloca i8
%18 = alloca i8
%19 = alloca i8
store i8* %0, i8** %6
store i8* %1, i8** %7
store i32 %2, i32* %8
store i32* %3, i32** %9
%20 = load i8*, i8** %6
store i8* %20, i8** %10
%21 = load i8*, i8** %7
store i8* %21, i8** %11
store i32 0, i32* %12
store i32 0, i32* %13
store i32 0, i32* %16
store i8 0, i8* %17
store i32 0, i32* %14
br label %22
22: ; preds = %122, %4
%23 = load i32, i32* %14
%24 = load i32, i32* %8
%25 = icmp slt i32 %23, %24
br i1 %25, label %26, label %125
26: ; preds = %22
%27 = load i8*, i8** %11
%28 = getelementptr inbounds i8, i8* %27, i32 1
store i8* %28, i8** %11
%29 = load i8, i8* %27
store i8 %29, i8* %18
%30 = load i32, i32* %16
%31 = srem i32 %30, 4
store i32 %31, i32* %15
%32 = load i8, i8* %18
%33 = call signext i8 @_base64_get_index(i8 signext %32)
store i8 %33, i8* %19
%34 = load i8, i8* %19
%35 = sext i8 %34 to i32
%36 = icmp eq i32 123, %35
br i1 %36, label %37, label %55
37: ; preds = %26
%38 = load i8, i8* %18
%39 = sext i8 %38 to i32
%40 = icmp eq i32 %39, 13
br i1 %40, label %53, label %41
41: ; preds = %37
%42 = load i8, i8* %18
%43 = sext i8 %42 to i32
%44 = icmp eq i32 %43, 10
br i1 %44, label %53, label %45
45: ; preds = %41
%46 = load i8, i8* %18
%47 = sext i8 %46 to i32
%48 = icmp eq i32 %47, 32
br i1 %48, label %53, label %49
49: ; preds = %45
%50 = load i8, i8* %18
%51 = sext i8 %50 to i32
%52 = icmp eq i32 %51, 9
br i1 %52, label %53, label %54
53: ; preds = %49, %45, %41, %37
br label %122
54: ; preds = %49
store i8 0, i8* %19
br label %73
55: ; preds = %26
%56 = load i8, i8* %19
%57 = sext i8 %56 to i32
%58 = icmp eq i32 124, %57
br i1 %58, label %59, label %72
59: ; preds = %55
%60 = load i32, i32* %8
%61 = load i32, i32* %14
%62 = sub nsw i32 %60, %61
%63 = sub nsw i32 %62, 1
%64 = load i32*, i32** %9
store i32 %63, i32* %64
%65 = load i8*, i8** %10
store i8 0, i8* %65
%66 = load i8*, i8** %10
%67 = load i8*, i8** %6
%68 = ptrtoint i8* %66 to i64
%69 = ptrtoint i8* %67 to i64
%70 = sub i64 %68, %69
%71 = trunc i64 %70 to i32
store i32 %71, i32* %5
br label %129
72: ; preds = %55
br label %73
73: ; preds = %72, %54
%74 = load i32, i32* %16
%75 = add nsw i32 %74, 1
store i32 %75, i32* %16
%76 = load i32, i32* %15
switch i32 %76, label %120 [
i32 0, label %77
i32 1, label %78
i32 2, label %91
i32 3, label %104
]
77: ; preds = %73
br label %120
78: ; preds = %73
%79 = load i8, i8* %17
%80 = sext i8 %79 to i32
%81 = shl i32 %80, 2
%82 = and i32 %81, 252
%83 = load i8, i8* %19
%84 = sext i8 %83 to i32
%85 = ashr i32 %84, 4
%86 = and i32 %85, 3
%87 = or i32 %82, %86
%88 = trunc i32 %87 to i8
%89 = load i8*, i8** %10
%90 = getelementptr inbounds i8, i8* %89, i32 1
store i8* %90, i8** %10
store i8 %88, i8* %89
br label %120
91: ; preds = %73
%92 = load i8, i8* %17
%93 = sext i8 %92 to i32
%94 = shl i32 %93, 4
%95 = and i32 %94, 240
%96 = load i8, i8* %19
%97 = sext i8 %96 to i32
%98 = ashr i32 %97, 2
%99 = and i32 %98, 15
%100 = or i32 %95, %99
%101 = trunc i32 %100 to i8
%102 = load i8*, i8** %10
%103 = getelementptr inbounds i8, i8* %102, i32 1
store i8* %103, i8** %10
store i8 %101, i8* %102
br label %120
104: ; preds = %73
%105 = load i8, i8* %17
%106 = sext i8 %105 to i32
%107 = shl i32 %106, 6
%108 = and i32 %107, 192
%109 = load i8, i8* %19
%110 = sext i8 %109 to i32
%111 = and i32 %110, 63
%112 = or i32 %108, %111
%113 = trunc i32 %112 to i8
%114 = load i8*, i8** %10
%115 = getelementptr inbounds i8, i8* %114, i32 1
store i8* %115, i8** %10
store i8 %113, i8* %114
%116 = load i32, i32* %12
%117 = add nsw i32 %116, 4
store i32 %117, i32* %12
%118 = load i32, i32* %13
%119 = add nsw i32 %118, 3
store i32 %119, i32* %13
br label %120
120: ; preds = %73, %104, %91, %78, %77
%121 = load i8, i8* %19
store i8 %121, i8* %17
br label %122
122: ; preds = %120, %53
%123 = load i32, i32* %14
%124 = add nsw i32 %123, 1
store i32 %124, i32* %14
br label %22
125: ; preds = %22
%126 = load i8*, i8** %10
store i8 0, i8* %126
%127 = load i32*, i32** %9
store i32 0, i32* %127
%128 = load i32, i32* %13
store i32 %128, i32* %5
br label %129
129: ; preds = %125, %59
%130 = load i32, i32* %5
ret i32 %130
}

LLVM IR (-O2):
define i32 @base64_stream_decode(i8* %0, i8* nocapture %1, i32 %2, i32* nocapture writeonly %3) {
%5 = icmp sgt i32 %2, 0
br i1 %5, label %6, label %53
6: ; preds = %4, %46
%7 = phi i8 [ %50, %46 ], [ 0, %4 ]
%8 = phi i32 [ %49, %46 ], [ 0, %4 ]
%9 = phi i8* [ %48, %46 ], [ %0, %4 ]
%10 = phi i32 [ %51, %46 ], [ 0, %4 ]
%11 = phi i32 [ %47, %46 ], [ 0, %4 ]
%12 = phi i8* [ %13, %46 ], [ %1, %4 ]
%13 = getelementptr inbounds i8, i8* %12, i64 1
%14 = load i8, i8* %12
%15 = srem i32 %8, 4
%16 = tail call signext i8 @_base64_get_index(i8 signext %14)
switch i8 %16, label %18 [
i8 123, label %17
i8 124, label %39
]
17: ; preds = %6
switch i8 %14, label %18 [
i8 32, label %46
i8 13, label %46
i8 10, label %46
i8 9, label %46
]
18: ; preds = %6, %17
%19 = phi i8 [ 0, %17 ], [ %16, %6 ]
%20 = add nsw i32 %8, 1
switch i32 %15, label %46 [
i32 3, label %33
i32 1, label %21
i32 2, label %27
]
21: ; preds = %18
%22 = shl i8 %7, 2
%23 = lshr i8 %19, 4
%24 = and i8 %23, 3
%25 = or i8 %24, %22
%26 = getelementptr inbounds i8, i8* %9, i64 1
store i8 %25, i8* %9
br label %46
27: ; preds = %18
%28 = shl i8 %7, 4
%29 = lshr i8 %19, 2
%30 = and i8 %29, 15
%31 = or i8 %30, %28
%32 = getelementptr inbounds i8, i8* %9, i64 1
store i8 %31, i8* %9
br label %46
33: ; preds = %18
%34 = shl i8 %7, 6
%35 = and i8 %19, 63
%36 = or i8 %35, %34
%37 = getelementptr inbounds i8, i8* %9, i64 1
store i8 %36, i8* %9
%38 = add nsw i32 %11, 3
br label %46
39: ; preds = %6
%40 = xor i32 %10, -1
%41 = add i32 %40, %2
store i32 %41, i32* %3
store i8 0, i8* %9
%42 = ptrtoint i8* %9 to i64
%43 = ptrtoint i8* %0 to i64
%44 = sub i64 %42, %43
%45 = trunc i64 %44 to i32
br label %56
46: ; preds = %17, %17, %17, %17, %18, %33, %27, %21
%47 = phi i32 [ %38, %33 ], [ %11, %21 ], [ %11, %27 ], [ %11, %18 ], [ %11, %17 ], [ %11, %17 ], [ %11, %17 ], [ %11, %17 ]
%48 = phi i8* [ %37, %33 ], [ %26, %21 ], [ %32, %27 ], [ %9, %18 ], [ %9, %17 ], [ %9, %17 ], [ %9, %17 ], [ %9, %17 ]
%49 = phi i32 [ %20, %33 ], [ %20, %21 ], [ %20, %27 ], [ %20, %18 ], [ %8, %17 ], [ %8, %17 ], [ %8, %17 ], [ %8, %17 ]
%50 = phi i8 [ %19, %33 ], [ %19, %21 ], [ %19, %27 ], [ %19, %18 ], [ %7, %17 ], [ %7, %17 ], [ %7, %17 ], [ %7, %17 ]
%51 = add nuw nsw i32 %10, 1
%52 = icmp eq i32 %51, %2
br i1 %52, label %53, label %6
53: ; preds = %46, %4
%54 = phi i32 [ 0, %4 ], [ %47, %46 ]
%55 = phi i8* [ %0, %4 ], [ %48, %46 ]
store i8 0, i8* %55
store i32 0, i32* %3
br label %56
56: ; preds = %39, %53
%57 = phi i32 [ %45, %39 ], [ %54, %53 ]
ret i32 %57
}