Something went wrong. Try again.
Cider Isn't Darwin Emulation, Really
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
/* * modff.s * * by Ian Ollmann * * Copyright (c) 2007 Apple Inc. All Rights Reserved. */
#include <machine/asm.h>#include "abi.h"
#if defined( __i386__ ) #define RESULT_P %eax#else #define RESULT_P %rdi#endif
ENTRY( modff )#if defined( __i386__ ) movl FRAME_SIZE( STACKP ), %ecx //load x#else movd %xmm0, %ecx#endif movl %ecx, %edx // x andl $0x7fffffff, %ecx // |x| xorl %ecx, %edx // sign of x addl $0x35000000, %ecx // add 128-22 to exponent. This forces Inf, NaN, numbers >= 2**23 to be negative cmpl $0x74800000, %ecx // values with exponents less than 128-22 are fractional numbers only jl 1f // branch for all exceptional conditions //we presume that the common case is 1.0 <= x < 2**23#if defined( __i386__ ) movss FRAME_SIZE( STACKP ), %xmm0 // load x#endif movd %edx, %xmm2 // load signof( x ) to xmm shrl $23, %ecx subl $(127+128-22), %ecx movl $0xff800000, %eax sarl %cl, %eax movd %eax, %xmm1#if defined( __i386__ ) movl 4+FRAME_SIZE( STACKP), RESULT_P#endif andps %xmm0, %xmm1 // find trunc(x) subss %xmm1, %xmm0 // fract = x - trunc(x) orps %xmm2, %xmm0 // fract = copysign( fract, x )#if defined( __i386__ ) movss %xmm0, (RESULT_P) flds (RESULT_P)#endif movss %xmm1, (RESULT_P) ret 1: jae 2f // Inf, NaN, big numbers go to 2 // |x| < 1.0#if defined( __i386__ ) movl 4+FRAME_SIZE( STACKP), RESULT_P#endif movl %edx, (RESULT_P)#if defined( __i386__ ) flds FRAME_SIZE( STACKP )#endif ret 2: cmp $0xb4800000, %ecx ja 3f //do NaNs elsewhere
// |x| >= 2**23#if defined( __i386__ ) movl 4+FRAME_SIZE( STACKP), RESULT_P movl %edx, (RESULT_P) flds (RESULT_P) movl FRAME_SIZE( STACKP ), %edx movl %edx, (RESULT_P)#else movss %xmm0, (RESULT_P) movd %edx, %xmm0#endif ret 3: //Nan#if defined( __i386__) movl 4+FRAME_SIZE( STACKP), RESULT_P flds FRAME_SIZE( STACKP ) // { x } fld %st(0) fstpl (RESULT_P)#else movss %xmm0, (RESULT_P)#endif ret