#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 uint64_t;
typedef int uint16_t;

/* Variables and functions */
int ldexp(double, int);
double IEE754_binary64_decode(char out[8]) {
  bool sign = out[0] & 0x80;
  uint16_t exponent = ((out[0] << 4) & 0x7F0) | ((out[1] >> 4) & 0x0F);
  uint64_t fraction =
      ((uint64_t)(out[1] & 0x0F) << 48) | ((uint64_t)(out[2] & 0xFF) << 40) |
      ((uint64_t)(out[3] & 0xFF) << 32) | ((uint64_t)(out[4] & 0xFF) << 24) |
      ((uint64_t)(out[5] & 0xFF) << 16) | ((uint64_t)(out[6] & 0xFF) << 8) |
      (uint64_t)(out[7] & 0xFF) | ((uint64_t)1 << 52);
  double frac = (double)fraction / ((uint64_t)2 << 52);
  if (exponent == 0x7FF) {
    if (fraction == (uint64_t)1 << 52) {
      return sign ? -1.0 / 0.0 : 1.0 / 0.0;
    } else {
      return sign ? 0.0 / 0.0 : -(0.0 / 0.0);
    }
  }
  return ldexp(frac, exponent - 1022) * (sign ? -1 : 1);
}


x86 assembly (clang, -O0):
<IEE754_binary64_decode>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x10(%rbp)
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
and    $0x80,%eax
mov    %eax,-0x14(%rbp)
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
shl    $0x4,%eax
and    $0x7f0,%eax
mov    -0x10(%rbp),%rcx
movsbl 0x1(%rcx),%ecx
sar    $0x4,%ecx
and    $0xf,%ecx
or     %ecx,%eax
mov    %eax,-0x18(%rbp)
mov    -0x10(%rbp),%rax
movsbl 0x1(%rax),%eax
and    $0xf,%eax
mov    $0x30,%ecx
shl    %cl,%eax
mov    -0x10(%rbp),%rcx
movsbl 0x2(%rcx),%edx
and    $0xff,%edx
mov    $0x28,%ecx
shl    %cl,%edx
mov    %edx,%ecx
or     %ecx,%eax
mov    -0x10(%rbp),%rcx
movsbl 0x3(%rcx),%edx
and    $0xff,%edx
mov    $0x20,%ecx
shl    %cl,%edx
mov    %edx,%ecx
or     %ecx,%eax
mov    -0x10(%rbp),%rcx
movsbl 0x4(%rcx),%ecx
and    $0xff,%ecx
shl    $0x18,%ecx
or     %ecx,%eax
mov    -0x10(%rbp),%rcx
movsbl 0x5(%rcx),%ecx
and    $0xff,%ecx
shl    $0x10,%ecx
or     %ecx,%eax
mov    -0x10(%rbp),%rcx
movsbl 0x6(%rcx),%ecx
and    $0xff,%ecx
shl    $0x8,%ecx
or     %ecx,%eax
mov    -0x10(%rbp),%rcx
movsbl 0x7(%rcx),%ecx
and    $0xff,%ecx
or     %ecx,%eax
or     %ecx,%eax
mov    %eax,-0x1c(%rbp)
cvtsi2sdl -0x1c(%rbp),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
cmpl   $0x7ff,-0x18(%rbp)
jne    127f <IEE754_binary64_decode+0x16f>
cmp    %eax,-0x1c(%rbp)
jne    1242 <IEE754_binary64_decode+0x132>
mov    -0x14(%rbp),%eax
movsd  0xe02(%rip),%xmm0
movsd  0xe02(%rip),%xmm1
movsd  %xmm1,-0x38(%rbp)
cmp    $0x0,%eax
movsd  %xmm0,-0x30(%rbp)
jne    1233 <IEE754_binary64_decode+0x123>
movsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12b1 <IEE754_binary64_decode+0x1a1>
cmpl   $0x0,-0x14(%rbp)
je     125e <IEE754_binary64_decode+0x14e>
movsd  0xdb4(%rip),%xmm0
movsd  %xmm0,-0x40(%rbp)
jmp    1270 <IEE754_binary64_decode+0x160>
movsd  0xd9a(%rip),%xmm0
movsd  %xmm0,-0x40(%rbp)
jmp    1270 <IEE754_binary64_decode+0x160>
movsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12b1 <IEE754_binary64_decode+0x1a1>
movsd  -0x28(%rbp),%xmm0
mov    -0x18(%rbp),%edi
sub    $0x3fe,%edi
call   1030 <ldexp@plt>
mov    -0x14(%rbp),%esi
mov    $0x1,%ecx
mov    $0xffffffff,%edx
cmp    $0x0,%esi
cmovne %edx,%ecx
imul   %ecx,%eax
cvtsi2sd %eax,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<IEE754_binary64_decode>:
push   %rbx
movsbl (%rdi),%ebx
mov    %ebx,%eax
and    $0x7f,%eax
shl    $0x4,%eax
movzbl 0x1(%rdi),%edi
shr    $0x4,%edi
or     %eax,%edi
cmp    $0x7ff,%edi
jne    1143 <IEE754_binary64_decode+0x33>
xor    %eax,%eax
test   $0x80,%bl
sete   %al
lea    0xec4(%rip),%rcx
movsd  (%rcx,%rax,8),%xmm0
pop    %rbx
ret
add    $0xfffffc02,%edi
call   1030 <ldexp@plt>
mov    %eax,%ecx
neg    %ecx
test   $0x80,%bl
cmove  %eax,%ecx
cvtsi2sd %ecx,%xmm0
pop    %rbx
ret

LLVM IR (-O0):
define double @IEE754_binary64_decode(i8* %0) {
%2 = alloca double
%3 = alloca i8*
%4 = alloca i32
%5 = alloca i32
%6 = alloca i32
%7 = alloca double
store i8* %0, i8** %3
%8 = load i8*, i8** %3
%9 = getelementptr inbounds i8, i8* %8, i64 0
%10 = load i8, i8* %9
%11 = sext i8 %10 to i32
%12 = and i32 %11, 128
store i32 %12, i32* %4
%13 = load i8*, i8** %3
%14 = getelementptr inbounds i8, i8* %13, i64 0
%15 = load i8, i8* %14
%16 = sext i8 %15 to i32
%17 = shl i32 %16, 4
%18 = and i32 %17, 2032
%19 = load i8*, i8** %3
%20 = getelementptr inbounds i8, i8* %19, i64 1
%21 = load i8, i8* %20
%22 = sext i8 %21 to i32
%23 = ashr i32 %22, 4
%24 = and i32 %23, 15
%25 = or i32 %18, %24
store i32 %25, i32* %5
%26 = load i8*, i8** %3
%27 = getelementptr inbounds i8, i8* %26, i64 1
%28 = load i8, i8* %27
%29 = sext i8 %28 to i32
%30 = and i32 %29, 15
%31 = shl i32 %30, 48
%32 = load i8*, i8** %3
%33 = getelementptr inbounds i8, i8* %32, i64 2
%34 = load i8, i8* %33
%35 = sext i8 %34 to i32
%36 = and i32 %35, 255
%37 = shl i32 %36, 40
%38 = or i32 %31, %37
%39 = load i8*, i8** %3
%40 = getelementptr inbounds i8, i8* %39, i64 3
%41 = load i8, i8* %40
%42 = sext i8 %41 to i32
%43 = and i32 %42, 255
%44 = shl i32 %43, 32
%45 = or i32 %38, %44
%46 = load i8*, i8** %3
%47 = getelementptr inbounds i8, i8* %46, i64 4
%48 = load i8, i8* %47
%49 = sext i8 %48 to i32
%50 = and i32 %49, 255
%51 = shl i32 %50, 24
%52 = or i32 %45, %51
%53 = load i8*, i8** %3
%54 = getelementptr inbounds i8, i8* %53, i64 5
%55 = load i8, i8* %54
%56 = sext i8 %55 to i32
%57 = and i32 %56, 255
%58 = shl i32 %57, 16
%59 = or i32 %52, %58
%60 = load i8*, i8** %3
%61 = getelementptr inbounds i8, i8* %60, i64 6
%62 = load i8, i8* %61
%63 = sext i8 %62 to i32
%64 = and i32 %63, 255
%65 = shl i32 %64, 8
%66 = or i32 %59, %65
%67 = load i8*, i8** %3
%68 = getelementptr inbounds i8, i8* %67, i64 7
%69 = load i8, i8* %68
%70 = sext i8 %69 to i32
%71 = and i32 %70, 255
%72 = or i32 %66, %71
%73 = or i32 %72, poison
store i32 %73, i32* %6
%74 = load i32, i32* %6
%75 = sitofp i32 %74 to double
%76 = fdiv double %75, poison
store double %76, double* %7
%77 = load i32, i32* %5
%78 = icmp eq i32 %77, 2047
br i1 %78, label %79, label %94
79: ; preds = %1
%80 = load i32, i32* %6
%81 = icmp eq i32 %80, poison
br i1 %81, label %82, label %87
82: ; preds = %79
%83 = load i32, i32* %4
%84 = icmp ne i32 %83, 0
%85 = zext i1 %84 to i64
%86 = select i1 %84, double 0xFFF0000000000000, double 0x7FF0000000000000
store double %86, double* %2
br label %105
87: ; preds = %79
%88 = load i32, i32* %4
%89 = icmp ne i32 %88, 0
br i1 %89, label %90, label %91
90: ; preds = %87
br label %92
91: ; preds = %87
br label %92
92: ; preds = %91, %90
%93 = phi double [ 0x7FF8000000000000, %90 ], [ 0xFFF8000000000000, %91 ]
store double %93, double* %2
br label %105
94: ; preds = %1
%95 = load double, double* %7
%96 = load i32, i32* %5
%97 = sub nsw i32 %96, 1022
%98 = call i32 @ldexp(double %95, i32 %97)
%99 = load i32, i32* %4
%100 = icmp ne i32 %99, 0
%101 = zext i1 %100 to i64
%102 = select i1 %100, i32 -1, i32 1
%103 = mul nsw i32 %98, %102
%104 = sitofp i32 %103 to double
store double %104, double* %2
br label %105
105: ; preds = %94, %92, %82
%106 = load double, double* %2
ret double %106
}

LLVM IR (-O2):
define double @IEE754_binary64_decode(i8* nocapture %0) {
%2 = load i8, i8* %0
%3 = sext i8 %2 to i32
%4 = and i32 %3, 128
%5 = shl nsw i32 %3, 4
%6 = and i32 %5, 2032
%7 = getelementptr inbounds i8, i8* %0, i64 1
%8 = load i8, i8* %7
%9 = lshr i8 %8, 4
%10 = zext i8 %9 to i32
%11 = or i32 %6, %10
%12 = icmp eq i32 %11, 2047
br i1 %12, label %13, label %16
13: ; preds = %1
%14 = icmp eq i32 %4, 0
%15 = select i1 %14, double 0xFFF8000000000000, double 0x7FF8000000000000
br label %23
16: ; preds = %1
%17 = add nsw i32 %11, -1022
%18 = tail call i32 @ldexp(double poison, i32 %17)
%19 = icmp eq i32 %4, 0
%20 = sub nsw i32 0, %18
%21 = select i1 %19, i32 %18, i32 %20
%22 = sitofp i32 %21 to double
br label %23
23: ; preds = %16, %13
%24 = phi double [ %15, %13 ], [ %22, %16 ]
ret double %24
}