#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 uintptr_t uint64_t;
typedef uintptr_t uint32_t;
typedef uintptr_t uint16_t;
typedef uintptr_t int64_t;
typedef uintptr_t int32_t;
typedef uintptr_t int16_t;

/* Variables and functions */
int /*<<< orphan*/ abort();
uintptr_t readULEB128(int const **);
uint64_t readEncodedPointer(const uint8_t **data, uint8_t encoding) {
  const uint8_t *p = *data;
  uint64_t result = 0;
  if (encoding == 0xff)
    return 0;
  switch (encoding & 0x0F) {
  case 0x00:
    result = *((uintptr_t *)p);
    p += sizeof(uintptr_t);
    break;
  case 0x01:
    result = readULEB128(&p);
    break;
  case 0x02:
    result = *((uint16_t *)p);
    p += sizeof(uint16_t);
    break;
  case 0x03:
    result = *((uint32_t *)p);
    p += sizeof(uint32_t);
    break;
  case 0x04:
    result = *((uint64_t *)p);
    p += sizeof(uint64_t);
    break;
  case 0x0A:
    result = *((int16_t *)p);
    p += sizeof(int16_t);
    break;
  case 0x0B:
    result = *((int32_t *)p);
    p += sizeof(int32_t);
    break;
  case 0x0C:
    result = *((int64_t *)p);
    p += sizeof(int64_t);
    break;
  case 0x09:
  default:
    abort();
    break;
  }
  switch (encoding & 0x70) {
  case 0x00:
    break;
  case 0x10:
    result += (uintptr_t)(*data);
    break;
  case 0x20:
  case 0x30:
  case 0x40:
  case 0x50:
  default:
    abort();
    break;
  }
  if (encoding & 0x80) {
    result = *((uintptr_t *)result);
  }
  *data = p;
  return result;
}


x86 assembly (clang, -O0):
<readEncodedPointer>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    -0x10(%rbp),%rax
mov    (%rax),%rax
mov    %rax,-0x20(%rbp)
movq   $0x0,-0x28(%rbp)
cmpl   $0xff,-0x14(%rbp)
jne    115c <readEncodedPointer+0x3c>
movq   $0x0,-0x8(%rbp)
jmp    1322 <readEncodedPointer+0x202>
mov    -0x14(%rbp),%eax
and    $0xf,%eax
mov    %rax,-0x30(%rbp)
sub    $0xc,%eax
ja     125e <readEncodedPointer+0x13e>
mov    -0x30(%rbp),%rax
lea    0xe86(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
mov    -0x20(%rbp),%rax
mov    (%rax),%rax
mov    %rax,-0x28(%rbp)
mov    -0x20(%rbp),%rax
add    $0x20,%rax
mov    %rax,-0x20(%rbp)
jmp    1265 <readEncodedPointer+0x145>
lea    -0x20(%rbp),%rdi
call   1040 <readULEB128@plt>
mov    %rax,-0x28(%rbp)
jmp    1265 <readEncodedPointer+0x145>
mov    -0x20(%rbp),%rax
mov    (%rax),%rax
mov    %rax,-0x28(%rbp)
mov    -0x20(%rbp),%rax
add    $0x20,%rax
mov    %rax,-0x20(%rbp)
jmp    1265 <readEncodedPointer+0x145>
mov    -0x20(%rbp),%rax
mov    (%rax),%rax
mov    %rax,-0x28(%rbp)
mov    -0x20(%rbp),%rax
add    $0x20,%rax
mov    %rax,-0x20(%rbp)
jmp    1265 <readEncodedPointer+0x145>
mov    -0x20(%rbp),%rax
mov    (%rax),%rax
mov    %rax,-0x28(%rbp)
mov    -0x20(%rbp),%rax
add    $0x20,%rax
mov    %rax,-0x20(%rbp)
jmp    1265 <readEncodedPointer+0x145>
mov    -0x20(%rbp),%rax
mov    (%rax),%rax
mov    %rax,-0x28(%rbp)
mov    -0x20(%rbp),%rax
add    $0x20,%rax
mov    %rax,-0x20(%rbp)
jmp    1265 <readEncodedPointer+0x145>
mov    -0x20(%rbp),%rax
mov    (%rax),%rax
mov    %rax,-0x28(%rbp)
mov    -0x20(%rbp),%rax
add    $0x20,%rax
mov    %rax,-0x20(%rbp)
jmp    1265 <readEncodedPointer+0x145>
mov    -0x20(%rbp),%rax
mov    (%rax),%rax
mov    %rax,-0x28(%rbp)
mov    -0x20(%rbp),%rax
add    $0x20,%rax
mov    %rax,-0x20(%rbp)
jmp    1265 <readEncodedPointer+0x145>
jmp    125e <readEncodedPointer+0x13e>
mov    $0x0,%al
call   1030 <abort@plt>
mov    -0x14(%rbp),%eax
and    $0x70,%eax
mov    %eax,-0x34(%rbp)
je     12ce <readEncodedPointer+0x1ae>
jmp    1279 <readEncodedPointer+0x159>
mov    -0x34(%rbp),%eax
sub    $0x10,%eax
je     12d3 <readEncodedPointer+0x1b3>
jmp    128a <readEncodedPointer+0x16a>
mov    -0x34(%rbp),%eax
sub    $0x20,%eax
je     12e7 <readEncodedPointer+0x1c7>
jmp    129b <readEncodedPointer+0x17b>
mov    -0x34(%rbp),%eax
sub    $0x30,%eax
je     12e7 <readEncodedPointer+0x1c7>
jmp    12ac <readEncodedPointer+0x18c>
mov    -0x34(%rbp),%eax
sub    $0x40,%eax
je     12e7 <readEncodedPointer+0x1c7>
jmp    12bd <readEncodedPointer+0x19d>
mov    -0x34(%rbp),%eax
sub    $0x50,%eax
je     12e7 <readEncodedPointer+0x1c7>
jmp    12ec <readEncodedPointer+0x1cc>
jmp    12f3 <readEncodedPointer+0x1d3>
mov    -0x10(%rbp),%rax
mov    (%rax),%rax
add    -0x28(%rbp),%rax
mov    %rax,-0x28(%rbp)
jmp    12f3 <readEncodedPointer+0x1d3>
jmp    12ec <readEncodedPointer+0x1cc>
mov    $0x0,%al
call   1030 <abort@plt>
mov    -0x14(%rbp),%eax
and    $0x80,%eax
cmp    $0x0,%eax
je     130f <readEncodedPointer+0x1ef>
mov    -0x28(%rbp),%rax
mov    (%rax),%rax
mov    %rax,-0x28(%rbp)
mov    -0x20(%rbp),%rcx
mov    -0x10(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x28(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<readEncodedPointer>:
push   %rbp
push   %rbx
push   %rax
mov    (%rdi),%rcx
mov    %rcx,(%rsp)
cmp    $0xff,%esi
jne    1136 <readEncodedPointer+0x16>
xor    %eax,%eax
jmp    1182 <readEncodedPointer+0x62>
mov    %esi,%ebp
mov    %esi,%eax
and    $0xf,%eax
cmp    $0xc,%eax
ja     1193 <readEncodedPointer+0x73>
mov    %rdi,%rbx
lea    0xeb4(%rip),%rdx
movslq (%rdx,%rax,4),%rax
add    %rdx,%rax
jmp    *%rax
mov    (%rcx),%rax
add    $0x20,%rcx
mov    %rcx,(%rsp)
mov    %ebp,%ecx
shr    $0x4,%ecx
and    $0x7,%ecx
je     1172 <readEncodedPointer+0x52>
cmp    $0x1,%ecx
jne    1193 <readEncodedPointer+0x73>
add    (%rbx),%rax
test   $0x80,%bpl
je     117b <readEncodedPointer+0x5b>
mov    (%rax),%rax
mov    (%rsp),%rcx
mov    %rcx,(%rbx)
add    $0x8,%rsp
pop    %rbx
pop    %rbp
ret
mov    %rsp,%rdi
call   1040 <readULEB128@plt>
jmp    1160 <readEncodedPointer+0x40>
xor    %eax,%eax
call   1030 <abort@plt>

LLVM IR (-O0):
define i64 @readEncodedPointer(i32** %0, i32 %1) {
%3 = alloca i64
%4 = alloca i32**
%5 = alloca i32
%6 = alloca i32*
%7 = alloca i64
store i32** %0, i32*** %4
store i32 %1, i32* %5
%8 = load i32**, i32*** %4
%9 = load i32*, i32** %8
store i32* %9, i32** %6
store i64 0, i64* %7
%10 = load i32, i32* %5
%11 = icmp eq i32 %10, 255
br i1 %11, label %12, label %13
12: ; preds = %2
store i64 0, i64* %3
br label %88
13: ; preds = %2
%14 = load i32, i32* %5
%15 = and i32 %14, 15
switch i32 %15, label %61 [
i32 0, label %16
i32 1, label %22
i32 2, label %24
i32 3, label %30
i32 4, label %36
i32 10, label %42
i32 11, label %48
i32 12, label %54
i32 9, label %60
]
16: ; preds = %13
%17 = load i32*, i32** %6
%18 = bitcast i32* %17 to i64*
%19 = load i64, i64* %18
store i64 %19, i64* %7
%20 = load i32*, i32** %6
%21 = getelementptr inbounds i32, i32* %20, i64 8
store i32* %21, i32** %6
br label %63
22: ; preds = %13
%23 = call i64 @readULEB128(i32** %6)
store i64 %23, i64* %7
br label %63
24: ; preds = %13
%25 = load i32*, i32** %6
%26 = bitcast i32* %25 to i64*
%27 = load i64, i64* %26
store i64 %27, i64* %7
%28 = load i32*, i32** %6
%29 = getelementptr inbounds i32, i32* %28, i64 8
store i32* %29, i32** %6
br label %63
30: ; preds = %13
%31 = load i32*, i32** %6
%32 = bitcast i32* %31 to i64*
%33 = load i64, i64* %32
store i64 %33, i64* %7
%34 = load i32*, i32** %6
%35 = getelementptr inbounds i32, i32* %34, i64 8
store i32* %35, i32** %6
br label %63
36: ; preds = %13
%37 = load i32*, i32** %6
%38 = bitcast i32* %37 to i64*
%39 = load i64, i64* %38
store i64 %39, i64* %7
%40 = load i32*, i32** %6
%41 = getelementptr inbounds i32, i32* %40, i64 8
store i32* %41, i32** %6
br label %63
42: ; preds = %13
%43 = load i32*, i32** %6
%44 = bitcast i32* %43 to i64*
%45 = load i64, i64* %44
store i64 %45, i64* %7
%46 = load i32*, i32** %6
%47 = getelementptr inbounds i32, i32* %46, i64 8
store i32* %47, i32** %6
br label %63
48: ; preds = %13
%49 = load i32*, i32** %6
%50 = bitcast i32* %49 to i64*
%51 = load i64, i64* %50
store i64 %51, i64* %7
%52 = load i32*, i32** %6
%53 = getelementptr inbounds i32, i32* %52, i64 8
store i32* %53, i32** %6
br label %63
54: ; preds = %13
%55 = load i32*, i32** %6
%56 = bitcast i32* %55 to i64*
%57 = load i64, i64* %56
store i64 %57, i64* %7
%58 = load i32*, i32** %6
%59 = getelementptr inbounds i32, i32* %58, i64 8
store i32* %59, i32** %6
br label %63
60: ; preds = %13
br label %61
61: ; preds = %13, %60
%62 = call i32 (...) @abort()
unreachable
63: ; preds = %54, %48, %42, %36, %30, %24, %22, %16
%64 = load i32, i32* %5
%65 = and i32 %64, 112
switch i32 %65, label %74 [
i32 0, label %66
i32 16, label %67
i32 32, label %73
i32 48, label %73
i32 64, label %73
i32 80, label %73
]
66: ; preds = %63
br label %76
67: ; preds = %63
%68 = load i32**, i32*** %4
%69 = load i32*, i32** %68
%70 = ptrtoint i32* %69 to i64
%71 = load i64, i64* %7
%72 = add i64 %71, %70
store i64 %72, i64* %7
br label %76
73: ; preds = %63, %63, %63, %63
br label %74
74: ; preds = %63, %73
%75 = call i32 (...) @abort()
unreachable
76: ; preds = %67, %66
%77 = load i32, i32* %5
%78 = and i32 %77, 128
%79 = icmp ne i32 %78, 0
br i1 %79, label %80, label %84
80: ; preds = %76
%81 = load i64, i64* %7
%82 = inttoptr i64 %81 to i64*
%83 = load i64, i64* %82
store i64 %83, i64* %7
br label %84
84: ; preds = %80, %76
%85 = load i32*, i32** %6
%86 = load i32**, i32*** %4
store i32* %85, i32** %86
%87 = load i64, i64* %7
store i64 %87, i64* %3
br label %88
88: ; preds = %84, %12
%89 = load i64, i64* %3
ret i64 %89
}

LLVM IR (-O2):
define i64 @readEncodedPointer(i32** nocapture %0, i32 %1) {
%3 = alloca i32*
%4 = bitcast i32** %3 to i8*
%5 = load i32*, i32** %0
store i32* %5, i32** %3
%6 = icmp eq i32 %1, 255
br i1 %6, label %61, label %7
7: ; preds = %2
%8 = and i32 %1, 15
switch i32 %8, label %39 [
i32 0, label %9
i32 1, label %13
i32 2, label %15
i32 3, label %19
i32 4, label %23
i32 10, label %27
i32 11, label %31
i32 12, label %35
]
9: ; preds = %7
%10 = bitcast i32* %5 to i64*
%11 = load i64, i64* %10
%12 = getelementptr inbounds i32, i32* %5, i64 8
store i32* %12, i32** %3
br label %41
13: ; preds = %7
%14 = call i64 @readULEB128(i32** %3)
br label %41
15: ; preds = %7
%16 = bitcast i32* %5 to i64*
%17 = load i64, i64* %16
%18 = getelementptr inbounds i32, i32* %5, i64 8
store i32* %18, i32** %3
br label %41
19: ; preds = %7
%20 = bitcast i32* %5 to i64*
%21 = load i64, i64* %20
%22 = getelementptr inbounds i32, i32* %5, i64 8
store i32* %22, i32** %3
br label %41
23: ; preds = %7
%24 = bitcast i32* %5 to i64*
%25 = load i64, i64* %24
%26 = getelementptr inbounds i32, i32* %5, i64 8
store i32* %26, i32** %3
br label %41
27: ; preds = %7
%28 = bitcast i32* %5 to i64*
%29 = load i64, i64* %28
%30 = getelementptr inbounds i32, i32* %5, i64 8
store i32* %30, i32** %3
br label %41
31: ; preds = %7
%32 = bitcast i32* %5 to i64*
%33 = load i64, i64* %32
%34 = getelementptr inbounds i32, i32* %5, i64 8
store i32* %34, i32** %3
br label %41
35: ; preds = %7
%36 = bitcast i32* %5 to i64*
%37 = load i64, i64* %36
%38 = getelementptr inbounds i32, i32* %5, i64 8
store i32* %38, i32** %3
br label %41
39: ; preds = %7
%40 = tail call i32 (...) @abort()
unreachable
41: ; preds = %35, %31, %27, %23, %19, %15, %13, %9
%42 = phi i64 [ %37, %35 ], [ %33, %31 ], [ %29, %27 ], [ %25, %23 ], [ %21, %19 ], [ %17, %15 ], [ %14, %13 ], [ %11, %9 ]
%43 = lshr i32 %1, 4
%44 = and i32 %43, 7
switch i32 %44, label %49 [
i32 0, label %51
i32 1, label %45
]
45: ; preds = %41
%46 = load i32*, i32** %0
%47 = ptrtoint i32* %46 to i64
%48 = add i64 %42, %47
br label %51
49: ; preds = %41
%50 = call i32 (...) @abort()
unreachable
51: ; preds = %45, %41
%52 = phi i64 [ %48, %45 ], [ %42, %41 ]
%53 = and i32 %1, 128
%54 = icmp eq i32 %53, 0
br i1 %54, label %58, label %55
55: ; preds = %51
%56 = inttoptr i64 %52 to i64*
%57 = load i64, i64* %56
br label %58
58: ; preds = %55, %51
%59 = phi i64 [ %57, %55 ], [ %52, %51 ]
%60 = load i32*, i32** %3
store i32* %60, i32** %0
br label %61
61: ; preds = %2, %58
%62 = phi i64 [ %59, %58 ], [ 0, %2 ]
ret i64 %62
}