#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 */
double log(double);
unsigned long myDoubleToUlong(double);
scalar_t__ myUlongToDouble(unsigned long);
double pow(double, double);
void double_to_ieee_80(double val, unsigned char *p) {
  char sign = 0;
  short exp = 0;
  unsigned long mant1 = 0;
  unsigned long mant0 = 0;
  if (val < 0.0) {
    sign = 1;
    val = -val;
  }
  if (val != 0.0) {
    exp = (short)(log(val) / log(2.0) + 16383.0);
    val *= pow(2.0, 31.0 + 16383.0 - (double)exp);
    mant1 = myDoubleToUlong(val);
    val -= myUlongToDouble(mant1);
    val *= pow(2.0, 32.0);
    mant0 = myDoubleToUlong(val);
  }
  *p++ = ((sign << 7) | (exp >> 8));
  *p++ = 0xFF & exp;
  *p++ = (char)(0xFF & (mant1 >> 24));
  *p++ = (char)(0xFF & (mant1 >> 16));
  *p++ = (char)(0xFF & (mant1 >> 8));
  *p++ = (char)(0xFF & (mant1));
  *p++ = (char)(0xFF & (mant0 >> 24));
  *p++ = (char)(0xFF & (mant0 >> 16));
  *p++ = (char)(0xFF & (mant0 >> 8));
  *p++ = (char)(0xFF & (mant0));
}


x86 assembly (clang, -O0):
<double_to_ieee_80>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
movsd  %xmm0,-0x8(%rbp)
mov    %rdi,-0x10(%rbp)
movb   $0x0,-0x11(%rbp)
movw   $0x0,-0x14(%rbp)
movq   $0x0,-0x20(%rbp)
movq   $0x0,-0x28(%rbp)
xorps  %xmm0,%xmm0
ucomisd -0x8(%rbp),%xmm0
jbe    119e <double_to_ieee_80+0x5e>
movb   $0x1,-0x11(%rbp)
movsd  -0x8(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    11bb <double_to_ieee_80+0x7b>
jp     11bb <double_to_ieee_80+0x7b>
jmp    1279 <double_to_ieee_80+0x139>
movsd  -0x8(%rbp),%xmm0
call   1050 <log@plt>
movsd  %xmm0,-0x30(%rbp)
movsd  0xe2e(%rip),%xmm0
call   1050 <log@plt>
movaps %xmm0,%xmm1
movsd  -0x30(%rbp),%xmm0
divsd  %xmm1,%xmm0
movsd  0xe2d(%rip),%xmm1
addsd  %xmm1,%xmm0
cvttsd2si %xmm0,%eax
mov    %ax,-0x14(%rbp)
movswl -0x14(%rbp),%eax
cvtsi2sd %eax,%xmm0
movsd  0xe09(%rip),%xmm1
subsd  %xmm0,%xmm1
movsd  0xded(%rip),%xmm0
call   1060 <pow@plt>
mulsd  -0x8(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
call   1030 <myDoubleToUlong@plt>
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rdi
call   1040 <myUlongToDouble@plt>
cvtsi2sd %rax,%xmm1
movsd  -0x8(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  0xdac(%rip),%xmm0
movsd  0xdac(%rip),%xmm1
call   1060 <pow@plt>
mulsd  -0x8(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
call   1030 <myDoubleToUlong@plt>
mov    %rax,-0x28(%rbp)
movsbl -0x11(%rbp),%eax
shl    $0x7,%eax
movswl -0x14(%rbp),%ecx
sar    $0x8,%ecx
or     %ecx,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
movswl -0x14(%rbp),%eax
and    $0xff,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x20(%rbp),%rax
shr    $0x18,%rax
and    $0xff,%rax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x20(%rbp),%rax
shr    $0x10,%rax
and    $0xff,%rax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x20(%rbp),%rax
shr    $0x8,%rax
and    $0xff,%rax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x20(%rbp),%rax
and    $0xff,%rax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x28(%rbp),%rax
shr    $0x18,%rax
and    $0xff,%rax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x28(%rbp),%rax
shr    $0x10,%rax
and    $0xff,%rax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x28(%rbp),%rax
shr    $0x8,%rax
and    $0xff,%rax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x28(%rbp),%rax
and    $0xff,%rax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<double_to_ieee_80>:
push   %rbp
push   %r14
push   %rbx
sub    $0x20,%rsp
mov    %rdi,%rbx
movapd %xmm0,%xmm1
movapd 0xea9(%rip),%xmm3
xorpd  %xmm0,%xmm3
xorpd  %xmm2,%xmm2
cmpltsd %xmm2,%xmm0
andpd  %xmm0,%xmm3
andnpd %xmm1,%xmm0
orpd   %xmm3,%xmm0
ucomisd %xmm2,%xmm0
jne    117c <double_to_ieee_80+0x3c>
jnp    1206 <double_to_ieee_80+0xc6>
movapd %xmm1,0x10(%rsp)
movapd %xmm0,(%rsp)
call   1060 <log@plt>
divsd  0xe7c(%rip),%xmm0
addsd  0xe7c(%rip),%xmm0
cvttsd2si %xmm0,%eax
movswl %ax,%ebp
xorps  %xmm1,%xmm1
cvtsi2sd %ebp,%xmm1
movsd  0xe6e(%rip),%xmm0
subsd  %xmm1,%xmm0
call   1030 <exp2@plt>
mulsd  (%rsp),%xmm0
movsd  %xmm0,(%rsp)
call   1040 <myDoubleToUlong@plt>
mov    %rax,%r14
mov    %rax,%rdi
call   1050 <myUlongToDouble@plt>
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
movsd  (%rsp),%xmm1
subsd  %xmm0,%xmm1
mulsd  0xe3a(%rip),%xmm1
movapd %xmm1,%xmm0
call   1040 <myDoubleToUlong@plt>
xorpd  %xmm2,%xmm2
movapd 0x10(%rsp),%xmm1
movzwl %bp,%ecx
jmp    120d <double_to_ieee_80+0xcd>
xor    %ecx,%ecx
xor    %r14d,%r14d
xor    %eax,%eax
xor    %edx,%edx
ucomisd %xmm1,%xmm2
seta   %dl
shl    $0x7,%edx
mov    %ecx,%esi
shr    $0x8,%esi
or     %edx,%esi
mov    %sil,(%rbx)
mov    %cl,0x1(%rbx)
mov    %r14,%rdx
mov    %r14,%rcx
shr    $0x18,%rcx
mov    %cl,0x2(%rbx)
mov    %r14,%rcx
shr    $0x10,%rcx
mov    %cl,0x3(%rbx)
mov    %dh,0x4(%rbx)
mov    %dl,0x5(%rbx)
mov    %rax,%rcx
shr    $0x18,%rcx
mov    %cl,0x6(%rbx)
mov    %rax,%rcx
shr    $0x10,%rcx
mov    %cl,0x7(%rbx)
mov    %ah,0x8(%rbx)
mov    %al,0x9(%rbx)
add    $0x20,%rsp
pop    %rbx
pop    %r14
pop    %rbp
ret

LLVM IR (-O0):
define void @double_to_ieee_80(double %0, i8* %1) {
%3 = alloca double
%4 = alloca i8*
%5 = alloca i8
%6 = alloca i16
%7 = alloca i64
%8 = alloca i64
store double %0, double* %3
store i8* %1, i8** %4
store i8 0, i8* %5
store i16 0, i16* %6
store i64 0, i64* %7
store i64 0, i64* %8
%9 = load double, double* %3
%10 = fcmp olt double %9, 0.000000e+00
br i1 %10, label %11, label %14
11: ; preds = %2
store i8 1, i8* %5
%12 = load double, double* %3
%13 = fneg double %12
store double %13, double* %3
br label %14
14: ; preds = %11, %2
%15 = load double, double* %3
%16 = fcmp une double %15, 0.000000e+00
br i1 %16, label %17, label %42
17: ; preds = %14
%18 = load double, double* %3
%19 = call double @log(double %18)
%20 = call double @log(double 2.000000e+00)
%21 = fdiv double %19, %20
%22 = fadd double %21, 1.638300e+04
%23 = fptosi double %22 to i16
store i16 %23, i16* %6
%24 = load i16, i16* %6
%25 = sitofp i16 %24 to double
%26 = fsub double 1.641400e+04, %25
%27 = call double @pow(double 2.000000e+00, double %26)
%28 = load double, double* %3
%29 = fmul double %28, %27
store double %29, double* %3
%30 = load double, double* %3
%31 = call i64 @myDoubleToUlong(double %30)
store i64 %31, i64* %7
%32 = load i64, i64* %7
%33 = call i64 @myUlongToDouble(i64 %32)
%34 = sitofp i64 %33 to double
%35 = load double, double* %3
%36 = fsub double %35, %34
store double %36, double* %3
%37 = call double @pow(double 2.000000e+00, double 3.200000e+01)
%38 = load double, double* %3
%39 = fmul double %38, %37
store double %39, double* %3
%40 = load double, double* %3
%41 = call i64 @myDoubleToUlong(double %40)
store i64 %41, i64* %8
br label %42
42: ; preds = %17, %14
%43 = load i8, i8* %5
%44 = sext i8 %43 to i32
%45 = shl i32 %44, 7
%46 = load i16, i16* %6
%47 = sext i16 %46 to i32
%48 = ashr i32 %47, 8
%49 = or i32 %45, %48
%50 = trunc i32 %49 to i8
%51 = load i8*, i8** %4
%52 = getelementptr inbounds i8, i8* %51, i32 1
store i8* %52, i8** %4
store i8 %50, i8* %51
%53 = load i16, i16* %6
%54 = sext i16 %53 to i32
%55 = and i32 255, %54
%56 = trunc i32 %55 to i8
%57 = load i8*, i8** %4
%58 = getelementptr inbounds i8, i8* %57, i32 1
store i8* %58, i8** %4
store i8 %56, i8* %57
%59 = load i64, i64* %7
%60 = lshr i64 %59, 24
%61 = and i64 255, %60
%62 = trunc i64 %61 to i8
%63 = load i8*, i8** %4
%64 = getelementptr inbounds i8, i8* %63, i32 1
store i8* %64, i8** %4
store i8 %62, i8* %63
%65 = load i64, i64* %7
%66 = lshr i64 %65, 16
%67 = and i64 255, %66
%68 = trunc i64 %67 to i8
%69 = load i8*, i8** %4
%70 = getelementptr inbounds i8, i8* %69, i32 1
store i8* %70, i8** %4
store i8 %68, i8* %69
%71 = load i64, i64* %7
%72 = lshr i64 %71, 8
%73 = and i64 255, %72
%74 = trunc i64 %73 to i8
%75 = load i8*, i8** %4
%76 = getelementptr inbounds i8, i8* %75, i32 1
store i8* %76, i8** %4
store i8 %74, i8* %75
%77 = load i64, i64* %7
%78 = and i64 255, %77
%79 = trunc i64 %78 to i8
%80 = load i8*, i8** %4
%81 = getelementptr inbounds i8, i8* %80, i32 1
store i8* %81, i8** %4
store i8 %79, i8* %80
%82 = load i64, i64* %8
%83 = lshr i64 %82, 24
%84 = and i64 255, %83
%85 = trunc i64 %84 to i8
%86 = load i8*, i8** %4
%87 = getelementptr inbounds i8, i8* %86, i32 1
store i8* %87, i8** %4
store i8 %85, i8* %86
%88 = load i64, i64* %8
%89 = lshr i64 %88, 16
%90 = and i64 255, %89
%91 = trunc i64 %90 to i8
%92 = load i8*, i8** %4
%93 = getelementptr inbounds i8, i8* %92, i32 1
store i8* %93, i8** %4
store i8 %91, i8* %92
%94 = load i64, i64* %8
%95 = lshr i64 %94, 8
%96 = and i64 255, %95
%97 = trunc i64 %96 to i8
%98 = load i8*, i8** %4
%99 = getelementptr inbounds i8, i8* %98, i32 1
store i8* %99, i8** %4
store i8 %97, i8* %98
%100 = load i64, i64* %8
%101 = and i64 255, %100
%102 = trunc i64 %101 to i8
%103 = load i8*, i8** %4
%104 = getelementptr inbounds i8, i8* %103, i32 1
store i8* %104, i8** %4
store i8 %102, i8* %103
ret void
}

LLVM IR (-O2):
define void @double_to_ieee_80(double %0, i8* nocapture writeonly %1) {
%3 = fcmp olt double %0, 0.000000e+00
%4 = fneg double %0
%5 = select i1 %3, double %4, double %0
%6 = fcmp une double %5, 0.000000e+00
br i1 %6, label %7, label %23
7: ; preds = %2
%8 = tail call double @log(double %5)
%9 = fdiv double %8, 0x3FE62E42FEFA39EF
%10 = fadd double %9, 1.638300e+04
%11 = fptosi double %10 to i16
%12 = sitofp i16 %11 to double
%13 = fsub double 1.641400e+04, %12
%14 = tail call double @exp2(double %13)
%15 = fmul double %5, %14
%16 = tail call i64 @myDoubleToUlong(double %15)
%17 = tail call i64 @myUlongToDouble(i64 %16)
%18 = sitofp i64 %17 to double
%19 = fsub double %15, %18
%20 = fmul double %19, 0x41F0000000000000
%21 = tail call i64 @myDoubleToUlong(double %20)
%22 = zext i16 %11 to i32
br label %23
23: ; preds = %7, %2
%24 = phi i32 [ %22, %7 ], [ 0, %2 ]
%25 = phi i64 [ %16, %7 ], [ 0, %2 ]
%26 = phi i64 [ %21, %7 ], [ 0, %2 ]
%27 = select i1 %3, i32 128, i32 0
%28 = lshr i32 %24, 8
%29 = or i32 %28, %27
%30 = trunc i32 %29 to i8
%31 = getelementptr inbounds i8, i8* %1, i64 1
store i8 %30, i8* %1
%32 = trunc i32 %24 to i8
%33 = getelementptr inbounds i8, i8* %1, i64 2
store i8 %32, i8* %31
%34 = lshr i64 %25, 24
%35 = trunc i64 %34 to i8
%36 = getelementptr inbounds i8, i8* %1, i64 3
store i8 %35, i8* %33
%37 = lshr i64 %25, 16
%38 = trunc i64 %37 to i8
%39 = getelementptr inbounds i8, i8* %1, i64 4
store i8 %38, i8* %36
%40 = lshr i64 %25, 8
%41 = trunc i64 %40 to i8
%42 = getelementptr inbounds i8, i8* %1, i64 5
store i8 %41, i8* %39
%43 = trunc i64 %25 to i8
%44 = getelementptr inbounds i8, i8* %1, i64 6
store i8 %43, i8* %42
%45 = lshr i64 %26, 24
%46 = trunc i64 %45 to i8
%47 = getelementptr inbounds i8, i8* %1, i64 7
store i8 %46, i8* %44
%48 = lshr i64 %26, 16
%49 = trunc i64 %48 to i8
%50 = getelementptr inbounds i8, i8* %1, i64 8
store i8 %49, i8* %47
%51 = lshr i64 %26, 8
%52 = trunc i64 %51 to i8
%53 = getelementptr inbounds i8, i8* %1, i64 9
store i8 %52, i8* %50
%54 = trunc i64 %26 to i8
store i8 %54, i8* %53
ret void
}