xref: /openbsd-src/gnu/llvm/compiler-rt/lib/builtins/i386/floatdidf.S (revision 1f9cb04fc6f537ca6cf5a53c28927340cba218a2)
13cab2bb3Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
23cab2bb3Spatrick// See https://llvm.org/LICENSE.txt for license information.
33cab2bb3Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
43cab2bb3Spatrick
53cab2bb3Spatrick#include "../assembly.h"
63cab2bb3Spatrick
7*1f9cb04fSpatrick// double __floatdidf(du_int a);
83cab2bb3Spatrick
93cab2bb3Spatrick#ifdef __i386__
103cab2bb3Spatrick
113cab2bb3SpatrickCONST_SECTION
123cab2bb3Spatrick
133cab2bb3Spatrick	.balign 16
143cab2bb3Spatricktwop52:
153cab2bb3Spatrick	.quad 0x4330000000000000
163cab2bb3Spatrick
173cab2bb3Spatrick	.balign 16
183cab2bb3Spatricktwop32:
193cab2bb3Spatrick	.quad 0x41f0000000000000
203cab2bb3Spatrick
213cab2bb3Spatrick#define REL_ADDR(_a)	(_a)-0b(%eax)
223cab2bb3Spatrick
233cab2bb3Spatrick.text
243cab2bb3Spatrick.balign 4
253cab2bb3SpatrickDEFINE_COMPILERRT_FUNCTION(__floatdidf)
263cab2bb3Spatrick	cvtsi2sd	8(%esp),			%xmm1
273cab2bb3Spatrick	movss		4(%esp),			%xmm0 // low 32 bits of a
283cab2bb3Spatrick	calll		0f
293cab2bb3Spatrick0:	popl		%eax
303cab2bb3Spatrick	mulsd		REL_ADDR(twop32),	%xmm1 // a_hi as a double (without rounding)
313cab2bb3Spatrick	movsd		REL_ADDR(twop52),	%xmm2 // 0x1.0p52
323cab2bb3Spatrick	subsd		%xmm2,				%xmm1 // a_hi - 0x1p52 (no rounding occurs)
333cab2bb3Spatrick	orpd		%xmm2,				%xmm0 // 0x1p52 + a_lo (no rounding occurs)
343cab2bb3Spatrick	addsd		%xmm1,				%xmm0 // a_hi + a_lo   (round happens here)
353cab2bb3Spatrick	movsd		%xmm0,			   4(%esp)
363cab2bb3Spatrick	fldl	   4(%esp)
373cab2bb3Spatrick	ret
383cab2bb3SpatrickEND_COMPILERRT_FUNCTION(__floatdidf)
393cab2bb3Spatrick
403cab2bb3Spatrick#endif // __i386__
413cab2bb3Spatrick
423cab2bb3SpatrickNO_EXEC_STACK_DIRECTIVE
433cab2bb3Spatrick
44