long double frexpd(long double x, int *e) {
  int *lPtr = (int *)&x;
  if (x == 0.0) {
    *e = 0;
    return 0.0;
  }
  *e = (lPtr[1] >> 20) & 0x7ff;
  *e = *e - 1022;
  lPtr[1] = (lPtr[1] & 0x800fffff) | (1022 << 20);
  return x;
}


x86 assembly (clang, -O0):
<frexpd>:
push   %rbp
mov    %rsp,%rbp
fldt   0x10(%rbp)
fstpt  -0x20(%rbp)
mov    %rdi,-0x28(%rbp)
lea    -0x20(%rbp),%rax
mov    %rax,-0x30(%rbp)
fldt   -0x20(%rbp)
fldz
fxch   %st(1)
fucomip %st(1),%st
fstp   %st(0)
jne    1146 <frexpd+0x46>
jp     1146 <frexpd+0x46>
jmp    1132 <frexpd+0x32>
mov    -0x28(%rbp),%rax
movl   $0x0,(%rax)
fldz
fstpt  -0x10(%rbp)
jmp    1186 <frexpd+0x86>
mov    -0x30(%rbp),%rax
mov    0x4(%rax),%ecx
shr    $0x14,%ecx
and    $0x7ff,%ecx
mov    -0x28(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x28(%rbp),%rax
mov    (%rax),%ecx
add    $0xfffffc02,%ecx
mov    %ecx,(%rax)
mov    -0x30(%rbp),%rax
mov    0x4(%rax),%ecx
and    $0x800fffff,%ecx
or     $0x3fe00000,%ecx
mov    %ecx,0x4(%rax)
fldt   -0x20(%rbp)
fstpt  -0x10(%rbp)
fldt   -0x10(%rbp)
pop    %rbp
ret

x86 assembly (clang, -O2):
<frexpd>:
fldt   0x8(%rsp)
fldz
fxch   %st(1)
fucomi %st(1),%st
jne    1117 <frexpd+0x17>
jp     1117 <frexpd+0x17>
fstp   %st(0)
movl   $0x0,(%rdi)
ret
fstp   %st(1)
fstpt  -0x18(%rsp)
mov    -0x10(%rsp),%eax
mov    -0x18(%rsp),%rcx
mov    %rcx,%rdx
mov    %ecx,%esi
shr    $0x20,%rcx
shr    $0x34,%rdx
and    $0x7ff,%edx
add    $0xfffffc02,%edx
mov    %edx,(%rdi)
and    $0x800fffff,%ecx
or     $0x3fe00000,%ecx
shl    $0x20,%rcx
or     %rcx,%rsi
mov    %ax,-0x20(%rsp)
mov    %rsi,-0x28(%rsp)
fldt   -0x28(%rsp)
ret

LLVM IR (-O0):
define x86_fp80 @frexpd(x86_fp80 %0, i32* %1) {
%3 = alloca x86_fp80
%4 = alloca x86_fp80
%5 = alloca i32*
%6 = alloca i32*
store x86_fp80 %0, x86_fp80* %4
store i32* %1, i32** %5
%7 = bitcast x86_fp80* %4 to i32*
store i32* %7, i32** %6
%8 = load x86_fp80, x86_fp80* %4
%9 = fcmp oeq x86_fp80 %8, 0xK00000000000000000000
br i1 %9, label %10, label %12
10: ; preds = %2
%11 = load i32*, i32** %5
store i32 0, i32* %11
store x86_fp80 0xK00000000000000000000, x86_fp80* %3
br label %31
12: ; preds = %2
%13 = load i32*, i32** %6
%14 = getelementptr inbounds i32, i32* %13, i64 1
%15 = load i32, i32* %14
%16 = ashr i32 %15, 20
%17 = and i32 %16, 2047
%18 = load i32*, i32** %5
store i32 %17, i32* %18
%19 = load i32*, i32** %5
%20 = load i32, i32* %19
%21 = sub nsw i32 %20, 1022
%22 = load i32*, i32** %5
store i32 %21, i32* %22
%23 = load i32*, i32** %6
%24 = getelementptr inbounds i32, i32* %23, i64 1
%25 = load i32, i32* %24
%26 = and i32 %25, -2146435073
%27 = or i32 %26, 1071644672
%28 = load i32*, i32** %6
%29 = getelementptr inbounds i32, i32* %28, i64 1
store i32 %27, i32* %29
%30 = load x86_fp80, x86_fp80* %4
store x86_fp80 %30, x86_fp80* %3
br label %31
31: ; preds = %12, %10
%32 = load x86_fp80, x86_fp80* %3
ret x86_fp80 %32
}

LLVM IR (-O2):
define x86_fp80 @frexpd(x86_fp80 %0, i32* nocapture writeonly %1) {
%3 = fcmp oeq x86_fp80 %0, 0xK00000000000000000000
br i1 %3, label %4, label %5
4: ; preds = %2
store i32 0, i32* %1
br label %19
5: ; preds = %2
%6 = bitcast x86_fp80 %0 to i80
%7 = lshr i80 %6, 32
%8 = trunc i80 %7 to i32
%9 = lshr i32 %8, 20
%10 = and i32 %9, 2047
%11 = add nsw i32 %10, -1022
store i32 %11, i32* %1
%12 = and i32 %8, -2146435073
%13 = or i32 %12, 1071644672
%14 = zext i32 %13 to i80
%15 = shl nuw nsw i80 %14, 32
%16 = and i80 %6, -18446744069414584321
%17 = or i80 %15, %16
%18 = bitcast i80 %17 to x86_fp80
br label %19
19: ; preds = %5, %4
%20 = phi x86_fp80 [ 0xK00000000000000000000, %4 ], [ %18, %5 ]
ret x86_fp80 %20
}