this repo has no description
1// long double rintl(long double x)
2//
3// returns the argument rounded to an integral value using the prevailing
4// rounding mode. rintf is allowed to raise the "inexact" flag if the result
5// differs from the argument (C99 7.12.9.4).
6//
7// -- Stephen Canon, January 2010
8
9#if defined __i386__
10
11 #define input 4(%esp)
12 #define exponent 12(%esp)
13
14#elif defined __x86_64__
15
16 #define input 8(%rsp)
17 #define exponent 16(%rsp)
18
19#else
20 #error "this implementation only supports 32- and 64-bit intel."
21#endif
22
23.text
24.align 4
25.globl _rintl
26_rintl:
27 movswl exponent, %eax
28 fldt input
29 mov %eax, %edx
30 and $0x7fff, %eax // biased exponent of x
31 and $0x80000000, %edx // signbit of x
32 sub $16383, %eax // unbiased exponent of x
33 cmp $63, %eax // if |x| < 1.0 or |x| >= 0x1.0p63 or isnan(x)
34 jae 1f
35
36 or $0x5f000000, %edx // copysignf( 0x1.0p63f, x )
37 mov %edx, input
38 flds input
39 fadd %st(0), %st(1) // x + copysign(0x1.0p63f, x)
40 fsubrp // rintl(x)
41 ret
42
431: jge 2f
44 fistps input
45 or $0x3f800000, %edx // copysignf(1.0f,x)
46 filds input // rintl(x), up to sign of zero
47 mov %edx, input
48 fabs
49 fmuls input // restore sign of zero
50
512: ret