long double modfl(long double value, long double *iptr) {
  long double int_part = 0.0L;
  asm("subq $8, %%rsp\n"
      "fnstcw 4(%%rsp)\n"
      "movzwl 4(%%rsp), %%eax\n"
      "orb $12, %%ah\n"
      "movw %%ax, (%%rsp)\n"
      "fldcw (%%rsp)\n"
      "frndint\n"
      "fldcw 4(%%rsp)\n"
      "addq $8, %%rsp\n"
      : "=t"(int_part)
      : "0"(value));
  if (iptr)
    *iptr = int_part;
  return (isinf(value) ? 0.0L : value - int_part);
}


x86 assembly (clang, -O0):
<modfl>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
fldt   0x10(%rbp)
fstpt  -0x10(%rbp)
mov    %rdi,-0x18(%rbp)
fldz
fstpt  -0x30(%rbp)
fldt   -0x10(%rbp)
sub    $0x8,%rsp
fnstcw 0x4(%rsp)
movzwl 0x4(%rsp),%eax
or     $0xc,%ah
mov    %ax,(%rsp)
fldcw  (%rsp)
frndint
fldcw  0x4(%rsp)
add    $0x8,%rsp
fstpt  -0x30(%rbp)
cmpq   $0x0,-0x18(%rbp)
je     1162 <modfl+0x52>
fldt   -0x30(%rbp)
mov    -0x18(%rbp),%rax
fstpt  (%rax)
fldt   -0x10(%rbp)
mov    %rsp,%rax
fstpt  (%rax)
xor    %eax,%eax
call   1030 <isinf@plt>
cmp    $0x0,%eax
je     1184 <modfl+0x74>
fldz
fstpt  -0x3c(%rbp)
jmp    118f <modfl+0x7f>
fldt   -0x10(%rbp)
fldt   -0x30(%rbp)
fsubrp %st,%st(1)
fstpt  -0x3c(%rbp)
fldt   -0x3c(%rbp)
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<modfl>:
sub    $0x28,%rsp
fldt   0x30(%rsp)
fld    %st(0)
sub    $0x8,%rsp
fnstcw 0x4(%rsp)
movzwl 0x4(%rsp),%eax
or     $0xc,%ah
mov    %ax,(%rsp)
fldcw  (%rsp)
frndint
fldcw  0x4(%rsp)
add    $0x8,%rsp
test   %rdi,%rdi
je     1144 <modfl+0x34>
fld    %st(0)
fstpt  (%rdi)
fld    %st(1)
fstpt  (%rsp)
xor    %eax,%eax
fxch   %st(1)
fstpt  0x1c(%rsp)
fstpt  0x10(%rsp)
call   1030 <isinf@plt>
test   %eax,%eax
fldt   0x1c(%rsp)
fldt   0x10(%rsp)
fsubrp %st,%st(1)
fldz
fcmove %st(1),%st
fstp   %st(1)
add    $0x28,%rsp
ret

LLVM IR (-O0):
define x86_fp80 @modfl(x86_fp80 %0, x86_fp80* %1) {
%3 = alloca x86_fp80
%4 = alloca x86_fp80*
%5 = alloca x86_fp80
store x86_fp80 %0, x86_fp80* %3
store x86_fp80* %1, x86_fp80** %4
store x86_fp80 0xK00000000000000000000, x86_fp80* %5
%6 = load x86_fp80, x86_fp80* %3
%7 = call x86_fp80 asm "subq $$8, %rsp\0Afnstcw 4(%rsp)\0Amovzwl 4(%rsp), %eax\0Aorb $$12, %ah\0Amovw %ax, (%rsp)\0Afldcw (%rsp)\0Afrndint\0Afldcw 4(%rsp)\0Aaddq $$8, %rsp\0A", "={st},0,~{dirflag},~{fpsr},~{flags}"(x86_fp80 %6)
store x86_fp80 %7, x86_fp80* %5
%8 = load x86_fp80*, x86_fp80** %4
%9 = icmp ne x86_fp80* %8, null
br i1 %9, label %10, label %13
10: ; preds = %2
%11 = load x86_fp80, x86_fp80* %5
%12 = load x86_fp80*, x86_fp80** %4
store x86_fp80 %11, x86_fp80* %12
br label %13
13: ; preds = %10, %2
%14 = load x86_fp80, x86_fp80* %3
%15 = call i32 (x86_fp80, ...) bitcast (i32 (...)* @isinf to i32 (x86_fp80, ...)*)(x86_fp80 %14)
%16 = icmp ne i32 %15, 0
br i1 %16, label %17, label %18
17: ; preds = %13
br label %22
18: ; preds = %13
%19 = load x86_fp80, x86_fp80* %3
%20 = load x86_fp80, x86_fp80* %5
%21 = fsub x86_fp80 %19, %20
br label %22
22: ; preds = %18, %17
%23 = phi x86_fp80 [ 0xK00000000000000000000, %17 ], [ %21, %18 ]
ret x86_fp80 %23
}

LLVM IR (-O2):
define x86_fp80 @modfl(x86_fp80 %0, x86_fp80* writeonly %1) {
%3 = tail call x86_fp80 asm "subq $$8, %rsp\0Afnstcw 4(%rsp)\0Amovzwl 4(%rsp), %eax\0Aorb $$12, %ah\0Amovw %ax, (%rsp)\0Afldcw (%rsp)\0Afrndint\0Afldcw 4(%rsp)\0Aaddq $$8, %rsp\0A", "={st},0,~{dirflag},~{fpsr},~{flags}"(x86_fp80 %0)
%4 = icmp eq x86_fp80* %1, null
br i1 %4, label %6, label %5
5: ; preds = %2
store x86_fp80 %3, x86_fp80* %1
br label %6
6: ; preds = %5, %2
%7 = tail call i32 (x86_fp80, ...) bitcast (i32 (...)* @isinf to i32 (x86_fp80, ...)*)(x86_fp80 %0)
%8 = icmp eq i32 %7, 0
%9 = fsub x86_fp80 %0, %3
%10 = select i1 %8, x86_fp80 %9, x86_fp80 0xK00000000000000000000
ret x86_fp80 %10
}