19ad441ffec97db647fee3725b3424284fb913e14Howard Hinnant// This file is dual licensed under the MIT and the University of Illinois Open
29ad441ffec97db647fee3725b3424284fb913e14Howard Hinnant// Source Licenses. See LICENSE.TXT for details.
3b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
419336a2d6b9b375ac106125950f4ff09742d1aecDaniel Dunbar#include "../assembly.h"
519336a2d6b9b375ac106125950f4ff09742d1aecDaniel Dunbar
6b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar// long double __floatundixf(du_int a);
7b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
8b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#ifdef __x86_64__
9b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
10eed1300f303841d026f0769e489d7c3df6e0e87fEdward O'Callaghan#ifndef __ELF__
11b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar.const
12eed1300f303841d026f0769e489d7c3df6e0e87fEdward O'Callaghan#endif
13b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar.align 4
14b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbartwop64: .quad 0x43f0000000000000
15b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
16b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#define REL_ADDR(_a)	(_a)(%rip)
17b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
18b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar.text
19b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar.align 4
20b4b1e8c5085cf83a50242057775a33ae4323d402Daniel DunbarDEFINE_COMPILERRT_FUNCTION(__floatundixf)
21b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar	movq	%rdi,	 -8(%rsp)
22b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar	fildq	-8(%rsp)
23b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar	test	%rdi,		%rdi
24b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar	js		1f
25b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar	ret
26b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar1:	faddl	REL_ADDR(twop64)
27b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar	ret
28b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
29b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#endif // __x86_64__
30b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
31b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
32b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar/* Branch-free implementation is ever so slightly slower, but more beautiful.
33b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar   It is likely superior for inlining, so I kept it around for future reference.
34b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
35b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#ifdef __x86_64__
36b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
37b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar.const
38b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar.align 4
39b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbartwop52: .quad 0x4330000000000000
40b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbartwop84_plus_twop52_neg:
41b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar		.quad 0xc530000000100000
42b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbartwop84: .quad 0x4530000000000000
43b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
44b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#define REL_ADDR(_a)	(_a)(%rip)
45b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
46b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar.text
47b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar.align 4
48b4b1e8c5085cf83a50242057775a33ae4323d402Daniel DunbarDEFINE_COMPILERRT_FUNCTION(__floatundixf)
49b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar	movl	%edi,				%esi			// low 32 bits of input
50b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar	shrq	$32,				%rdi			// hi 32 bits of input
51b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar	orq		REL_ADDR(twop84),	%rdi			// 2^84 + hi (as a double)
52b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar	orq		REL_ADDR(twop52),	%rsi			// 2^52 + lo (as a double)
53b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar	movq	%rdi,			 -8(%rsp)
54b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar	movq	%rsi,			-16(%rsp)
55b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar	fldl	REL_ADDR(twop84_plus_twop52_neg)
56b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar	faddl	-8(%rsp)	// hi - 2^52 (as double extended, no rounding occurs)
57b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar	faddl	-16(%rsp)	// hi + lo (as double extended)
58b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar	ret
59b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
60b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#endif // __x86_64__
61b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
62eed1300f303841d026f0769e489d7c3df6e0e87fEdward O'Callaghan*/
63