this repo has no description
1
2/*
3 * modff.s
4 *
5 * by Ian Ollmann
6 *
7 * Copyright (c) 2007 Apple Inc. All Rights Reserved.
8 */
9
10#include <machine/asm.h>
11#include "abi.h"
12
13#if defined( __i386__ )
14 #define RESULT_P %eax
15#else
16 #define RESULT_P %rdi
17#endif
18
19
20ENTRY( modff )
21#if defined( __i386__ )
22 movl FRAME_SIZE( STACKP ), %ecx //load x
23#else
24 movd %xmm0, %ecx
25#endif
26 movl %ecx, %edx // x
27 andl $0x7fffffff, %ecx // |x|
28 xorl %ecx, %edx // sign of x
29 addl $0x35000000, %ecx // add 128-22 to exponent. This forces Inf, NaN, numbers >= 2**23 to be negative
30 cmpl $0x74800000, %ecx // values with exponents less than 128-22 are fractional numbers only
31 jl 1f // branch for all exceptional conditions
32
33 //we presume that the common case is 1.0 <= x < 2**23
34#if defined( __i386__ )
35 movss FRAME_SIZE( STACKP ), %xmm0 // load x
36#endif
37 movd %edx, %xmm2 // load signof( x ) to xmm
38 shrl $23, %ecx
39 subl $(127+128-22), %ecx
40 movl $0xff800000, %eax
41 sarl %cl, %eax
42 movd %eax, %xmm1
43#if defined( __i386__ )
44 movl 4+FRAME_SIZE( STACKP), RESULT_P
45#endif
46 andps %xmm0, %xmm1 // find trunc(x)
47 subss %xmm1, %xmm0 // fract = x - trunc(x)
48 orps %xmm2, %xmm0 // fract = copysign( fract, x )
49#if defined( __i386__ )
50 movss %xmm0, (RESULT_P)
51 flds (RESULT_P)
52#endif
53 movss %xmm1, (RESULT_P)
54 ret
55
561: jae 2f // Inf, NaN, big numbers go to 2
57 // |x| < 1.0
58#if defined( __i386__ )
59 movl 4+FRAME_SIZE( STACKP), RESULT_P
60#endif
61 movl %edx, (RESULT_P)
62#if defined( __i386__ )
63 flds FRAME_SIZE( STACKP )
64#endif
65 ret
66
672: cmp $0xb4800000, %ecx
68 ja 3f //do NaNs elsewhere
69
70 // |x| >= 2**23
71#if defined( __i386__ )
72 movl 4+FRAME_SIZE( STACKP), RESULT_P
73 movl %edx, (RESULT_P)
74 flds (RESULT_P)
75 movl FRAME_SIZE( STACKP ), %edx
76 movl %edx, (RESULT_P)
77#else
78 movss %xmm0, (RESULT_P)
79 movd %edx, %xmm0
80#endif
81 ret
82
833: //Nan
84#if defined( __i386__)
85 movl 4+FRAME_SIZE( STACKP), RESULT_P
86 flds FRAME_SIZE( STACKP ) // { x }
87 fld %st(0)
88 fstpl (RESULT_P)
89#else
90 movss %xmm0, (RESULT_P)
91#endif
92 ret
93