Something went wrong. Try again.
Cider Isn't Darwin Emulation, Really
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
/* * modf.s * * by Steve Canon (scanon) * * Copyright (c) 2008 Apple Inc. All Rights Reserved. * * Rewritten by Steve Canon in December '08 to fix * behavior of small signaling nans and to get the * sign of a zero fractional part correct. */
// double modf(double x, double *iptr);//// breaks x into integral and fractional parts, each of which has the same sign as the argument.// the fractional part is returned, and iptr holds the integral part.//// Special Cases://// Input Fractional Part Integral Part// +-inf +-0 +-inf// NaN NaN NaN
#if defined __i386__
.text.align 4.globl _modf_modf: movl 8(%esp), %eax // high word of x andl $0x7fffffff, %eax // high word of |x| subl $0x3ff00000, %eax // subtract off exponent bias movsd 4(%esp), %xmm0 // x pcmpeqb %xmm3, %xmm3 psllq $63, %xmm3 movapd %xmm3, %xmm4 // set aside signbit mask for later use andpd %xmm0, %xmm3 // signbit(x) cmpl $0x03400000, %eax // compare to unbiased 2**52 jae 1f // 1.0 <= |x| < 2**52 shrl $20, %eax // unbiased exponent of x movl $52, %edx subl %eax, %edx movd %edx, %xmm2 // 52 - unbiased exponent of x pcmpeqb %xmm1, %xmm1 psllq %xmm2, %xmm1 // mask for integral bits of x andpd %xmm0, %xmm1 // trunc(x) subsd %xmm1, %xmm0 // fractional part, except that sign of zero may be wrong andnpd %xmm0, %xmm4 // |fractional part| orpd %xmm3, %xmm4 // copysign(fractional part, x) movl 12(%esp), %ecx // iptr movsd %xmm4, 4(%esp) movsd %xmm1, (%ecx) // store integral part to iptr fldl 4(%esp) // return fraction part on the x87 stack retl 1: movl 12(%esp), %ecx // iptr jge 2f
// |x| < 1.0 movsd %xmm3, (%ecx) // *iptr = copysign(0.0, x) fldl 4(%esp) // fractional part = x retl 2: ucomisd %xmm0, %xmm0 // check for NaN jp 3f
// |x| >= 2**52 movsd %xmm3, 4(%esp) // fractional part = copysign(0.0, x)3: movsd %xmm0, (%ecx) // *iptr = x fldl 4(%esp) retl #else // __x86_64__
.const.align 4absmask: .quad 0x7fffffffffffffffone: .quad 0x3ff0000000000000
.text.align 4.globl _modf_modf: movsd absmask(%rip), %xmm1 andpd %xmm0, %xmm1 // |x| movd %xmm1, %rax xorpd %xmm0, %xmm1 // copysign(0.0, x) subq one(%rip), %rax // subtract off exponent bias movq $52, %rcx sarq %cl, %rax cmpq %rcx, %rax // compare exponent of x to 52 jae 1f // 1.0 <= |x| < 2**52 subq %rax, %rcx // 52 - unbiased exponent of x pcmpeqb %xmm2, %xmm2 movd %rcx, %xmm3 psllq %xmm3, %xmm2 // mask for integral bits of x andpd %xmm0, %xmm2 // trunc(x) subsd %xmm2, %xmm0 // fractional part, except sign of zero may be wrong andpd absmask(%rip), %xmm0 // |fractional part| orpd %xmm1, %xmm0 // copysign(fractional part, x) movsd %xmm2, (%rdi) // *iptr = trunc(x) retq 1: jge 2f // |x| < 1.0 movsd %xmm1, (%rdi) // *iptr = copysign(0.0, x) retq 2: ucomisd %xmm0, %xmm0 // check for NaN jp 3f // |x| >= 2**52 movsd %xmm0, (%rdi) // *iptr = x movapd %xmm1, %xmm0 // fractional part = copysign(0.0, x) retq 3: movsd %xmm0, (%rdi) // *iptr = x retq
#endif // __ARCH__