blob: 246f0266c8a1519d19fea7823f700c517d39a910 [file] [log] [blame]
Daniel Dunbarfd089992009-06-26 16:47:03 +00001// This file is distributed under the University of Illinois Open Source
2// License. See LICENSE.TXT for details.
3
Daniel Dunbar7d504782009-10-27 17:49:50 +00004#include "../assembly.h"
5
Daniel Dunbarfd089992009-06-26 16:47:03 +00006// long double __floatundixf(du_int a);
7
8#ifdef __x86_64__
9
Edward O'Callaghan8f40ca32009-11-04 23:52:51 +000010#ifndef __ELF__
Daniel Dunbarfd089992009-06-26 16:47:03 +000011.const
Edward O'Callaghan8f40ca32009-11-04 23:52:51 +000012#endif
Daniel Dunbarfd089992009-06-26 16:47:03 +000013.align 4
14twop64: .quad 0x43f0000000000000
15
16#define REL_ADDR(_a) (_a)(%rip)
17
18.text
19.align 4
Daniel Dunbar9ff93712009-10-27 17:50:21 +000020DEFINE_COMPILERRT_FUNCTION(__floatundixf)
Daniel Dunbarfd089992009-06-26 16:47:03 +000021 movq %rdi, -8(%rsp)
22 fildq -8(%rsp)
23 test %rdi, %rdi
24 js 1f
25 ret
261: 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
39twop52: .quad 0x4330000000000000
40twop84_plus_twop52_neg:
41 .quad 0xc530000000100000
42twop84: .quad 0x4530000000000000
43
44#define REL_ADDR(_a) (_a)(%rip)
45
46.text
47.align 4
Daniel Dunbar9ff93712009-10-27 17:50:21 +000048DEFINE_COMPILERRT_FUNCTION(__floatundixf)
Daniel Dunbarfd089992009-06-26 16:47:03 +000049 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
Edward O'Callaghan8f40ca32009-11-04 23:52:51 +000062*/