1276789Sdim//===-- floatundidf.S - Implement __floatundidf for i386 ------------------===//
2276789Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6276789Sdim//
7276789Sdim//===----------------------------------------------------------------------===//
8276789Sdim//
9276789Sdim// This file implements __floatundidf for the compiler_rt library.
10276789Sdim//
11276789Sdim//===----------------------------------------------------------------------===//
12276789Sdim
13276789Sdim#include "../assembly.h"
14276789Sdim
15276789Sdim// double __floatundidf(du_int a);
16276789Sdim
17276789Sdim#ifdef __i386__
18276789Sdim
19276789SdimCONST_SECTION
20276789Sdim
21276789Sdim	.balign 16
22276789Sdimtwop52:
23276789Sdim	.quad 0x4330000000000000
24276789Sdim
25276789Sdim	.balign 16
26276789Sdimtwop84_plus_twop52:
27276789Sdim	.quad 0x4530000000100000
28276789Sdim
29276789Sdim	.balign 16
30276789Sdimtwop84:
31276789Sdim	.quad 0x4530000000000000
32276789Sdim
33276789Sdim#define REL_ADDR(_a)	(_a)-0b(%eax)
34276789Sdim
35276789Sdim.text
36276789Sdim.balign 4
37276789SdimDEFINE_COMPILERRT_FUNCTION(__floatundidf)
38276789Sdim	movss	8(%esp),						%xmm1 // high 32 bits of a
39276789Sdim	movss	4(%esp),						%xmm0 // low 32 bits of a
40276789Sdim	calll	0f
41276789Sdim0:	popl	%eax
42276789Sdim	orpd	REL_ADDR(twop84),				%xmm1 // 0x1p84 + a_hi (no rounding occurs)
43276789Sdim	subsd	REL_ADDR(twop84_plus_twop52),	%xmm1 // a_hi - 0x1p52 (no rounding occurs)
44276789Sdim	orpd	REL_ADDR(twop52),				%xmm0 // 0x1p52 + a_lo (no rounding occurs)
45276789Sdim	addsd	%xmm1,							%xmm0 // a_hi + a_lo   (round happens here)
46276789Sdim	movsd	%xmm0,						   4(%esp)
47276789Sdim	fldl   4(%esp)
48276789Sdim	ret
49276789SdimEND_COMPILERRT_FUNCTION(__floatundidf)
50276789Sdim
51276789Sdim#endif // __i386__
52309124Sdim
53309124SdimNO_EXEC_STACK_DIRECTIVE
54309124Sdim
55