void sincos(double __x, double *p_sin, double *p_cos) {
  long double c, s;
  __asm__ __volatile__("fsincos\n\t"
                       "fnstsw    %%ax\n\t"
                       "testl     $0x400, %%eax\n\t"
                       "jz        1f\n\t"
                       "fldpi\n\t"
                       "fadd      %%st(0)\n\t"
                       "fxch      %%st(1)\n\t"
                       "2: fprem1\n\t"
                       "fnstsw    %%ax\n\t"
                       "testl     $0x400, %%eax\n\t"
                       "jnz       2b\n\t"
                       "fstp      %%st(1)\n\t"
                       "fsincos\n\t"
                       "1:"
                       : "=t"(c), "=u"(s)
                       : "0"(__x)
                       : "eax");
  *p_sin = (double)s;
  *p_cos = (double)c;
}


x86 assembly (clang, -O0):
<sincos>:
push   %rbp
mov    %rsp,%rbp
movsd  %xmm0,-0x8(%rbp)
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
fldl   -0x8(%rbp)
fsincos
fnstsw %ax
test   $0x400,%eax
je     113c <sincos+0x3c>
fldpi
fadd   %st(0),%st
fxch   %st(1)
fprem1
fnstsw %ax
test   $0x400,%eax
jne    1129 <sincos+0x29>
fstp   %st(1)
fsincos
fstpt  -0x30(%rbp)
fstpt  -0x40(%rbp)
fldt   -0x40(%rbp)
mov    -0x10(%rbp),%rax
fstpl  (%rax)
fldt   -0x30(%rbp)
fstpl  -0x48(%rbp)
movsd  -0x48(%rbp),%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<sincos>:
movsd  %xmm0,-0x8(%rsp)
fldl   -0x8(%rsp)
fsincos
fnstsw %ax
test   $0x400,%eax
je     112a <sincos+0x2a>
fldpi
fadd   %st(0),%st
fxch   %st(1)
fprem1
fnstsw %ax
test   $0x400,%eax
jne    111b <sincos+0x1b>
fstp   %st(1)
fsincos
fxch   %st(1)
fstpl  (%rdi)
fstpl  (%rsi)
ret

LLVM IR (-O0):
define void @sincos(double %0, double* %1, double* %2) {
%4 = alloca double
%5 = alloca double*
%6 = alloca double*
%7 = alloca x86_fp80
%8 = alloca x86_fp80
store double %0, double* %4
store double* %1, double** %5
store double* %2, double** %6
%9 = load double, double* %4
%10 = fpext double %9 to x86_fp80
%11 = call { x86_fp80, x86_fp80 } asm sideeffect "fsincos\0A\09fnstsw %ax\0A\09testl $$0x400, %eax\0A\09jz 1f\0A\09fldpi\0A\09fadd %st(0)\0A\09fxch %st(1)\0A\092: fprem1\0A\09fnstsw %ax\0A\09testl $$0x400, %eax\0A\09jnz 2b\0A\09fstp %st(1)\0A\09fsincos\0A\091:", "={st},={st(1)},0,~{eax},~{dirflag},~{fpsr},~{flags}"(x86_fp80 %10)
%12 = extractvalue { x86_fp80, x86_fp80 } %11, 0
%13 = extractvalue { x86_fp80, x86_fp80 } %11, 1
store x86_fp80 %12, x86_fp80* %7
store x86_fp80 %13, x86_fp80* %8
%14 = load x86_fp80, x86_fp80* %8
%15 = fptrunc x86_fp80 %14 to double
%16 = load double*, double** %5
store double %15, double* %16
%17 = load x86_fp80, x86_fp80* %7
%18 = fptrunc x86_fp80 %17 to double
%19 = load double*, double** %6
store double %18, double* %19
ret void
}

LLVM IR (-O2):
define void @sincos(double %0, double* nocapture writeonly %1, double* nocapture writeonly %2) {
%4 = fpext double %0 to x86_fp80
%5 = tail call { x86_fp80, x86_fp80 } asm sideeffect "fsincos\0A\09fnstsw %ax\0A\09testl $$0x400, %eax\0A\09jz 1f\0A\09fldpi\0A\09fadd %st(0)\0A\09fxch %st(1)\0A\092: fprem1\0A\09fnstsw %ax\0A\09testl $$0x400, %eax\0A\09jnz 2b\0A\09fstp %st(1)\0A\09fsincos\0A\091:", "={st},={st(1)},0,~{eax},~{dirflag},~{fpsr},~{flags}"(x86_fp80 %4)
%6 = extractvalue { x86_fp80, x86_fp80 } %5, 0
%7 = extractvalue { x86_fp80, x86_fp80 } %5, 1
%8 = fptrunc x86_fp80 %7 to double
store double %8, double* %1
%9 = fptrunc x86_fp80 %6 to double
store double %9, double* %2
ret void
}