1// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
2// See https://llvm.org/LICENSE.txt for license information.
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5#include "../assembly.h"
6
7// xf_float __floatundixf(du_int a);
8
9#ifdef __x86_64__
10
11CONST_SECTION
12
13 .balign 16
14twop64:
15 .quad 0x43f0000000000000
16
17#define REL_ADDR(_a) (_a)(%rip)
18
19 .text
20
21 .balign 4
22DEFINE_COMPILERRT_FUNCTION(__floatundixf)
23 movq %rdi, -8(%rsp)
24 fildq -8(%rsp)
25 test %rdi, %rdi
26 js 1f
27 ret
281: faddl REL_ADDR(twop64)
29 ret
30END_COMPILERRT_FUNCTION(__floatundixf)
31
32#endif // __x86_64__
33
34
35/* Branch-free implementation is ever so slightly slower, but more beautiful.
36 It is likely superior for inlining, so I kept it around for future reference.
37
38#ifdef __x86_64__
39
40CONST_SECTION
41
42 .balign 4
43twop52:
44 .quad 0x4330000000000000
45twop84_plus_twop52_neg:
46 .quad 0xc530000000100000
47twop84:
48 .quad 0x4530000000000000
49
50#define REL_ADDR(_a) (_a)(%rip)
51
52.text
53.balign 4
54DEFINE_COMPILERRT_FUNCTION(__floatundixf)
55 movl %edi, %esi // low 32 bits of input
56 shrq $32, %rdi // hi 32 bits of input
57 orq REL_ADDR(twop84), %rdi // 2^84 + hi (as a double)
58 orq REL_ADDR(twop52), %rsi // 2^52 + lo (as a double)
59 movq %rdi, -8(%rsp)
60 movq %rsi, -16(%rsp)
61 fldl REL_ADDR(twop84_plus_twop52_neg)
62 faddl -8(%rsp) // hi - 2^52 (as double extended, no rounding occurs)
63 faddl -16(%rsp) // hi + lo (as double extended)
64 ret
65END_COMPILERRT_FUNCTION(__floatundixf)
66
67#endif // __x86_64__
68
69*/
70
71NO_EXEC_STACK_DIRECTIVE
72
73

source code of compiler-rt/lib/builtins/x86_64/floatundixf.S