#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 uint16_t;

/* Variables and functions */
int /*<<< orphan*/ assert(int);
int strlen(char const *);
void vc4_parse_string16(const char *p, uint16_t *bitsp, uint16_t *maskp) {
  uint16_t mask, val, fval;
  assert(strlen(p) >= 16);
  mask = 0x8000;
  val = fval = 0;
  while (mask) {
    if (*p == '0') {
      fval |= mask;
    } else if (*p == '1') {
      val |= mask;
      fval |= mask;
    } else {
    }
    mask >>= 1;
    p++;
  }
  *bitsp = val;
  *maskp = fval;
}


x86 assembly (clang, -O0):
<vc4_parse_string16>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x8(%rbp),%rdi
call   1030 <strlen@plt>
cmp    $0x10,%eax
setge  %al
and    $0x1,%al
movzbl %al,%edi
call   1040 <assert@plt>
movl   $0x8000,-0x1c(%rbp)
movl   $0x0,-0x24(%rbp)
movl   $0x0,-0x20(%rbp)
cmpl   $0x0,-0x1c(%rbp)
je     11d5 <vc4_parse_string16+0xb5>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x30,%eax
jne    118a <vc4_parse_string16+0x6a>
mov    -0x1c(%rbp),%eax
or     -0x24(%rbp),%eax
mov    %eax,-0x24(%rbp)
jmp    11bb <vc4_parse_string16+0x9b>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x31,%eax
jne    11b1 <vc4_parse_string16+0x91>
mov    -0x1c(%rbp),%eax
or     -0x20(%rbp),%eax
mov    %eax,-0x20(%rbp)
mov    -0x1c(%rbp),%eax
or     -0x24(%rbp),%eax
mov    %eax,-0x24(%rbp)
jmp    11b6 <vc4_parse_string16+0x96>
jmp    11b6 <vc4_parse_string16+0x96>
jmp    11bb <vc4_parse_string16+0x9b>
mov    -0x1c(%rbp),%eax
sar    $0x1,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
jmp    1162 <vc4_parse_string16+0x42>
mov    -0x20(%rbp),%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x24(%rbp),%ecx
mov    -0x18(%rbp),%rax
mov    %ecx,(%rax)
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<vc4_parse_string16>:
push   %r15
push   %r14
push   %rbx
mov    %rdx,%r14
mov    %rsi,%r15
mov    %rdi,%rbx
call   1030 <strlen@plt>
xor    %edi,%edi
cmp    $0x10,%eax
setge  %dil
call   1040 <assert@plt>
mov    (%rbx),%cl
cmp    $0x31,%cl
je     1153 <vc4_parse_string16+0x33>
xor    %eax,%eax
cmp    $0x30,%cl
je     1158 <vc4_parse_string16+0x38>
xor    %ecx,%ecx
jmp    115d <vc4_parse_string16+0x3d>
mov    $0x8000,%eax
mov    $0x8000,%ecx
mov    0x1(%rbx),%dl
cmp    $0x30,%dl
je     116f <vc4_parse_string16+0x4f>
cmp    $0x31,%dl
jne    1175 <vc4_parse_string16+0x55>
or     $0x4000,%eax
or     $0x4000,%ecx
mov    0x2(%rbx),%dl
cmp    $0x30,%dl
je     1187 <vc4_parse_string16+0x67>
cmp    $0x31,%dl
jne    118d <vc4_parse_string16+0x6d>
or     $0x2000,%eax
or     $0x2000,%ecx
mov    0x3(%rbx),%dl
cmp    $0x30,%dl
je     119f <vc4_parse_string16+0x7f>
cmp    $0x31,%dl
jne    11a5 <vc4_parse_string16+0x85>
or     $0x1000,%eax
or     $0x1000,%ecx
mov    0x4(%rbx),%dl
cmp    $0x30,%dl
je     11b7 <vc4_parse_string16+0x97>
cmp    $0x31,%dl
jne    11bd <vc4_parse_string16+0x9d>
or     $0x800,%eax
or     $0x800,%ecx
mov    0x5(%rbx),%dl
cmp    $0x30,%dl
je     11cf <vc4_parse_string16+0xaf>
cmp    $0x31,%dl
jne    11d5 <vc4_parse_string16+0xb5>
or     $0x400,%eax
or     $0x400,%ecx
mov    0x6(%rbx),%dl
cmp    $0x30,%dl
je     11e7 <vc4_parse_string16+0xc7>
cmp    $0x31,%dl
jne    11ed <vc4_parse_string16+0xcd>
or     $0x200,%eax
or     $0x200,%ecx
mov    0x7(%rbx),%dl
cmp    $0x30,%dl
je     11ff <vc4_parse_string16+0xdf>
cmp    $0x31,%dl
jne    1205 <vc4_parse_string16+0xe5>
or     $0x100,%eax
or     $0x100,%ecx
mov    0x8(%rbx),%dl
cmp    $0x30,%dl
je     1217 <vc4_parse_string16+0xf7>
cmp    $0x31,%dl
jne    121d <vc4_parse_string16+0xfd>
or     $0x80,%eax
or     $0x80,%ecx
mov    0x9(%rbx),%dl
cmp    $0x30,%dl
je     122d <vc4_parse_string16+0x10d>
cmp    $0x31,%dl
jne    1230 <vc4_parse_string16+0x110>
or     $0x40,%eax
or     $0x40,%ecx
mov    0xa(%rbx),%dl
cmp    $0x30,%dl
je     1240 <vc4_parse_string16+0x120>
cmp    $0x31,%dl
jne    1243 <vc4_parse_string16+0x123>
or     $0x20,%eax
or     $0x20,%ecx
mov    0xb(%rbx),%dl
cmp    $0x30,%dl
je     1253 <vc4_parse_string16+0x133>
cmp    $0x31,%dl
jne    1256 <vc4_parse_string16+0x136>
or     $0x10,%eax
or     $0x10,%ecx
mov    0xc(%rbx),%dl
cmp    $0x30,%dl
je     1266 <vc4_parse_string16+0x146>
cmp    $0x31,%dl
jne    1269 <vc4_parse_string16+0x149>
or     $0x8,%eax
or     $0x8,%ecx
mov    0xd(%rbx),%dl
cmp    $0x30,%dl
je     1279 <vc4_parse_string16+0x159>
cmp    $0x31,%dl
jne    127c <vc4_parse_string16+0x15c>
or     $0x4,%eax
or     $0x4,%ecx
mov    0xe(%rbx),%dl
cmp    $0x30,%dl
je     128c <vc4_parse_string16+0x16c>
cmp    $0x31,%dl
jne    128f <vc4_parse_string16+0x16f>
or     $0x2,%eax
or     $0x2,%ecx
mov    0xf(%rbx),%dl
cmp    $0x30,%dl
je     129f <vc4_parse_string16+0x17f>
cmp    $0x31,%dl
jne    12a2 <vc4_parse_string16+0x182>
or     $0x1,%eax
or     $0x1,%ecx
mov    %eax,(%r15)
mov    %ecx,(%r14)
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
define void @vc4_parse_string16(i8* %0, i32* %1, i32* %2) {
%4 = alloca i8*
%5 = alloca i32*
%6 = alloca i32*
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
store i8* %0, i8** %4
store i32* %1, i32** %5
store i32* %2, i32** %6
%10 = load i8*, i8** %4
%11 = call i32 @strlen(i8* %10)
%12 = icmp sge i32 %11, 16
%13 = zext i1 %12 to i32
%14 = call i32 @assert(i32 %13)
store i32 32768, i32* %7
store i32 0, i32* %9
store i32 0, i32* %8
br label %15
15: ; preds = %41, %3
%16 = load i32, i32* %7
%17 = icmp ne i32 %16, 0
br i1 %17, label %18, label %46
18: ; preds = %15
%19 = load i8*, i8** %4
%20 = load i8, i8* %19
%21 = sext i8 %20 to i32
%22 = icmp eq i32 %21, 48
br i1 %22, label %23, label %27
23: ; preds = %18
%24 = load i32, i32* %7
%25 = load i32, i32* %9
%26 = or i32 %25, %24
store i32 %26, i32* %9
br label %41
27: ; preds = %18
%28 = load i8*, i8** %4
%29 = load i8, i8* %28
%30 = sext i8 %29 to i32
%31 = icmp eq i32 %30, 49
br i1 %31, label %32, label %39
32: ; preds = %27
%33 = load i32, i32* %7
%34 = load i32, i32* %8
%35 = or i32 %34, %33
store i32 %35, i32* %8
%36 = load i32, i32* %7
%37 = load i32, i32* %9
%38 = or i32 %37, %36
store i32 %38, i32* %9
br label %40
39: ; preds = %27
br label %40
40: ; preds = %39, %32
br label %41
41: ; preds = %40, %23
%42 = load i32, i32* %7
%43 = ashr i32 %42, 1
store i32 %43, i32* %7
%44 = load i8*, i8** %4
%45 = getelementptr inbounds i8, i8* %44, i32 1
store i8* %45, i8** %4
br label %15
46: ; preds = %15
%47 = load i32, i32* %8
%48 = load i32*, i32** %5
store i32 %47, i32* %48
%49 = load i32, i32* %9
%50 = load i32*, i32** %6
store i32 %49, i32* %50
ret void
}

LLVM IR (-O2):
define void @vc4_parse_string16(i8* %0, i32* nocapture writeonly %1, i32* nocapture writeonly %2) {
%4 = tail call i32 @strlen(i8* %0)
%5 = icmp sgt i32 %4, 15
%6 = zext i1 %5 to i32
%7 = tail call i32 @assert(i32 %6)
%8 = load i8, i8* %0
switch i8 %8, label %11 [
i8 48, label %9
i8 49, label %10
]
9: ; preds = %3
br label %11
10: ; preds = %3
br label %11
11: ; preds = %3, %10, %9
%12 = phi i32 [ 0, %9 ], [ 32768, %10 ], [ 0, %3 ]
%13 = phi i32 [ 32768, %9 ], [ 32768, %10 ], [ 0, %3 ]
%14 = getelementptr inbounds i8, i8* %0, i64 1
%15 = load i8, i8* %14
switch i8 %15, label %21 [
i8 48, label %19
i8 49, label %16
]
16: ; preds = %11
%17 = or i32 %12, 16384
%18 = or i32 %13, 16384
br label %21
19: ; preds = %11
%20 = or i32 %13, 16384
br label %21
21: ; preds = %19, %16, %11
%22 = phi i32 [ %12, %19 ], [ %17, %16 ], [ %12, %11 ]
%23 = phi i32 [ %20, %19 ], [ %18, %16 ], [ %13, %11 ]
%24 = getelementptr inbounds i8, i8* %0, i64 2
%25 = load i8, i8* %24
switch i8 %25, label %31 [
i8 48, label %29
i8 49, label %26
]
26: ; preds = %21
%27 = or i32 %22, 8192
%28 = or i32 %23, 8192
br label %31
29: ; preds = %21
%30 = or i32 %23, 8192
br label %31
31: ; preds = %29, %26, %21
%32 = phi i32 [ %22, %29 ], [ %27, %26 ], [ %22, %21 ]
%33 = phi i32 [ %30, %29 ], [ %28, %26 ], [ %23, %21 ]
%34 = getelementptr inbounds i8, i8* %0, i64 3
%35 = load i8, i8* %34
switch i8 %35, label %41 [
i8 48, label %39
i8 49, label %36
]
36: ; preds = %31
%37 = or i32 %32, 4096
%38 = or i32 %33, 4096
br label %41
39: ; preds = %31
%40 = or i32 %33, 4096
br label %41
41: ; preds = %39, %36, %31
%42 = phi i32 [ %32, %39 ], [ %37, %36 ], [ %32, %31 ]
%43 = phi i32 [ %40, %39 ], [ %38, %36 ], [ %33, %31 ]
%44 = getelementptr inbounds i8, i8* %0, i64 4
%45 = load i8, i8* %44
switch i8 %45, label %51 [
i8 48, label %49
i8 49, label %46
]
46: ; preds = %41
%47 = or i32 %42, 2048
%48 = or i32 %43, 2048
br label %51
49: ; preds = %41
%50 = or i32 %43, 2048
br label %51
51: ; preds = %49, %46, %41
%52 = phi i32 [ %42, %49 ], [ %47, %46 ], [ %42, %41 ]
%53 = phi i32 [ %50, %49 ], [ %48, %46 ], [ %43, %41 ]
%54 = getelementptr inbounds i8, i8* %0, i64 5
%55 = load i8, i8* %54
switch i8 %55, label %61 [
i8 48, label %59
i8 49, label %56
]
56: ; preds = %51
%57 = or i32 %52, 1024
%58 = or i32 %53, 1024
br label %61
59: ; preds = %51
%60 = or i32 %53, 1024
br label %61
61: ; preds = %59, %56, %51
%62 = phi i32 [ %52, %59 ], [ %57, %56 ], [ %52, %51 ]
%63 = phi i32 [ %60, %59 ], [ %58, %56 ], [ %53, %51 ]
%64 = getelementptr inbounds i8, i8* %0, i64 6
%65 = load i8, i8* %64
switch i8 %65, label %71 [
i8 48, label %69
i8 49, label %66
]
66: ; preds = %61
%67 = or i32 %62, 512
%68 = or i32 %63, 512
br label %71
69: ; preds = %61
%70 = or i32 %63, 512
br label %71
71: ; preds = %69, %66, %61
%72 = phi i32 [ %62, %69 ], [ %67, %66 ], [ %62, %61 ]
%73 = phi i32 [ %70, %69 ], [ %68, %66 ], [ %63, %61 ]
%74 = getelementptr inbounds i8, i8* %0, i64 7
%75 = load i8, i8* %74
switch i8 %75, label %81 [
i8 48, label %79
i8 49, label %76
]
76: ; preds = %71
%77 = or i32 %72, 256
%78 = or i32 %73, 256
br label %81
79: ; preds = %71
%80 = or i32 %73, 256
br label %81
81: ; preds = %79, %76, %71
%82 = phi i32 [ %72, %79 ], [ %77, %76 ], [ %72, %71 ]
%83 = phi i32 [ %80, %79 ], [ %78, %76 ], [ %73, %71 ]
%84 = getelementptr inbounds i8, i8* %0, i64 8
%85 = load i8, i8* %84
switch i8 %85, label %91 [
i8 48, label %89
i8 49, label %86
]
86: ; preds = %81
%87 = or i32 %82, 128
%88 = or i32 %83, 128
br label %91
89: ; preds = %81
%90 = or i32 %83, 128
br label %91
91: ; preds = %89, %86, %81
%92 = phi i32 [ %82, %89 ], [ %87, %86 ], [ %82, %81 ]
%93 = phi i32 [ %90, %89 ], [ %88, %86 ], [ %83, %81 ]
%94 = getelementptr inbounds i8, i8* %0, i64 9
%95 = load i8, i8* %94
switch i8 %95, label %101 [
i8 48, label %99
i8 49, label %96
]
96: ; preds = %91
%97 = or i32 %92, 64
%98 = or i32 %93, 64
br label %101
99: ; preds = %91
%100 = or i32 %93, 64
br label %101
101: ; preds = %99, %96, %91
%102 = phi i32 [ %92, %99 ], [ %97, %96 ], [ %92, %91 ]
%103 = phi i32 [ %100, %99 ], [ %98, %96 ], [ %93, %91 ]
%104 = getelementptr inbounds i8, i8* %0, i64 10
%105 = load i8, i8* %104
switch i8 %105, label %111 [
i8 48, label %109
i8 49, label %106
]
106: ; preds = %101
%107 = or i32 %102, 32
%108 = or i32 %103, 32
br label %111
109: ; preds = %101
%110 = or i32 %103, 32
br label %111
111: ; preds = %109, %106, %101
%112 = phi i32 [ %102, %109 ], [ %107, %106 ], [ %102, %101 ]
%113 = phi i32 [ %110, %109 ], [ %108, %106 ], [ %103, %101 ]
%114 = getelementptr inbounds i8, i8* %0, i64 11
%115 = load i8, i8* %114
switch i8 %115, label %121 [
i8 48, label %119
i8 49, label %116
]
116: ; preds = %111
%117 = or i32 %112, 16
%118 = or i32 %113, 16
br label %121
119: ; preds = %111
%120 = or i32 %113, 16
br label %121
121: ; preds = %119, %116, %111
%122 = phi i32 [ %112, %119 ], [ %117, %116 ], [ %112, %111 ]
%123 = phi i32 [ %120, %119 ], [ %118, %116 ], [ %113, %111 ]
%124 = getelementptr inbounds i8, i8* %0, i64 12
%125 = load i8, i8* %124
switch i8 %125, label %131 [
i8 48, label %129
i8 49, label %126
]
126: ; preds = %121
%127 = or i32 %122, 8
%128 = or i32 %123, 8
br label %131
129: ; preds = %121
%130 = or i32 %123, 8
br label %131
131: ; preds = %129, %126, %121
%132 = phi i32 [ %122, %129 ], [ %127, %126 ], [ %122, %121 ]
%133 = phi i32 [ %130, %129 ], [ %128, %126 ], [ %123, %121 ]
%134 = getelementptr inbounds i8, i8* %0, i64 13
%135 = load i8, i8* %134
switch i8 %135, label %141 [
i8 48, label %139
i8 49, label %136
]
136: ; preds = %131
%137 = or i32 %132, 4
%138 = or i32 %133, 4
br label %141
139: ; preds = %131
%140 = or i32 %133, 4
br label %141
141: ; preds = %139, %136, %131
%142 = phi i32 [ %132, %139 ], [ %137, %136 ], [ %132, %131 ]
%143 = phi i32 [ %140, %139 ], [ %138, %136 ], [ %133, %131 ]
%144 = getelementptr inbounds i8, i8* %0, i64 14
%145 = load i8, i8* %144
switch i8 %145, label %151 [
i8 48, label %149
i8 49, label %146
]
146: ; preds = %141
%147 = or i32 %142, 2
%148 = or i32 %143, 2
br label %151
149: ; preds = %141
%150 = or i32 %143, 2
br label %151
151: ; preds = %149, %146, %141
%152 = phi i32 [ %142, %149 ], [ %147, %146 ], [ %142, %141 ]
%153 = phi i32 [ %150, %149 ], [ %148, %146 ], [ %143, %141 ]
%154 = getelementptr inbounds i8, i8* %0, i64 15
%155 = load i8, i8* %154
switch i8 %155, label %161 [
i8 48, label %159
i8 49, label %156
]
156: ; preds = %151
%157 = or i32 %152, 1
%158 = or i32 %153, 1
br label %161
159: ; preds = %151
%160 = or i32 %153, 1
br label %161
161: ; preds = %159, %156, %151
%162 = phi i32 [ %152, %159 ], [ %157, %156 ], [ %152, %151 ]
%163 = phi i32 [ %160, %159 ], [ %158, %156 ], [ %153, %151 ]
store i32 %162, i32* %1
store i32 %163, i32* %2
ret void
}