]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/compiler-rt/lib/x86_64/floatundixf.S
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / compiler-rt / lib / x86_64 / floatundixf.S
1 // This file is dual licensed under the MIT and the University of Illinois Open
2 // Source Licenses. See LICENSE.TXT for details.
3
4 #include "../assembly.h"
5
6 // long double __floatundixf(du_int a);
7
8 #ifdef __x86_64__
9
10 #ifndef __ELF__
11 .const
12 #endif
13 .align 4
14 twop64: .quad 0x43f0000000000000
15
16 #define REL_ADDR(_a)    (_a)(%rip)
17
18 .text
19 .align 4
20 DEFINE_COMPILERRT_FUNCTION(__floatundixf)
21         movq    %rdi,    -8(%rsp)
22         fildq   -8(%rsp)
23         test    %rdi,           %rdi
24         js              1f
25         ret
26 1:      faddl   REL_ADDR(twop64)
27         ret
28
29 #endif // __x86_64__
30
31
32 /* Branch-free implementation is ever so slightly slower, but more beautiful.
33    It is likely superior for inlining, so I kept it around for future reference.
34
35 #ifdef __x86_64__
36
37 .const
38 .align 4
39 twop52: .quad 0x4330000000000000
40 twop84_plus_twop52_neg:
41                 .quad 0xc530000000100000
42 twop84: .quad 0x4530000000000000
43
44 #define REL_ADDR(_a)    (_a)(%rip)
45
46 .text
47 .align 4
48 DEFINE_COMPILERRT_FUNCTION(__floatundixf)
49         movl    %edi,                           %esi                    // low 32 bits of input
50         shrq    $32,                            %rdi                    // hi 32 bits of input
51         orq             REL_ADDR(twop84),       %rdi                    // 2^84 + hi (as a double)
52         orq             REL_ADDR(twop52),       %rsi                    // 2^52 + lo (as a double)
53         movq    %rdi,                    -8(%rsp)
54         movq    %rsi,                   -16(%rsp)
55         fldl    REL_ADDR(twop84_plus_twop52_neg)        
56         faddl   -8(%rsp)        // hi - 2^52 (as double extended, no rounding occurs)
57         faddl   -16(%rsp)       // hi + lo (as double extended)
58         ret
59
60 #endif // __x86_64__
61
62 */