1214152Sed//===-- floatundidf.S - Implement __floatundidf for x86_64 ----------------===//
2214152Sed//
3214152Sed//                     The LLVM Compiler Infrastructure
4214152Sed//
5222656Sed// This file is dual licensed under the MIT and the University of Illinois Open
6222656Sed// Source Licenses. See LICENSE.TXT for details.
7214152Sed//
8214152Sed//===----------------------------------------------------------------------===//
9214152Sed//
10214152Sed// This file implements __floatundidf for the compiler_rt library.
11214152Sed//
12214152Sed//===----------------------------------------------------------------------===//
13214152Sed
14214152Sed#include "../assembly.h"
15214152Sed
16214152Sed// double __floatundidf(du_int a);
17214152Sed
18214152Sed#ifdef __x86_64__
19214152Sed
20214152Sed#ifndef __ELF__
21214152Sed.const
22214152Sed#endif
23214152Sed.align 4
24214152Sedtwop52: .quad 0x4330000000000000
25214152Sedtwop84_plus_twop52:
26214152Sed		.quad 0x4530000000100000
27214152Sedtwop84: .quad 0x4530000000000000
28214152Sed
29214152Sed#define REL_ADDR(_a)	(_a)(%rip)
30214152Sed
31214152Sed.text
32214152Sed.align 4
33214152SedDEFINE_COMPILERRT_FUNCTION(__floatundidf)
34214152Sed	movd	%edi,							%xmm0 // low 32 bits of a
35214152Sed	shrq	$32,							%rdi  // high 32 bits of a
36214152Sed	orq		REL_ADDR(twop84),				%rdi  // 0x1p84 + a_hi (no rounding occurs)
37214152Sed	orpd	REL_ADDR(twop52),				%xmm0 // 0x1p52 + a_lo (no rounding occurs)
38214152Sed	movd	%rdi,							%xmm1
39214152Sed	subsd	REL_ADDR(twop84_plus_twop52),	%xmm1 // a_hi - 0x1p52 (no rounding occurs)
40214152Sed	addsd	%xmm1,							%xmm0 // a_hi + a_lo   (round happens here)
41214152Sed	ret
42214152Sed
43214152Sed#endif // __x86_64__
44