xref: /freebsd/contrib/llvm-project/compiler-rt/lib/builtins/x86_64/floatundixf.S (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
10b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
20b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
30b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
40b57cec5SDimitry Andric
50b57cec5SDimitry Andric#include "../assembly.h"
60b57cec5SDimitry Andric
7*5f757f3fSDimitry Andric// xf_float __floatundixf(du_int a);
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric#ifdef __x86_64__
100b57cec5SDimitry Andric
110b57cec5SDimitry AndricCONST_SECTION
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric	.balign 16
140b57cec5SDimitry Andrictwop64:
150b57cec5SDimitry Andric	.quad 0x43f0000000000000
160b57cec5SDimitry Andric
170b57cec5SDimitry Andric#define REL_ADDR(_a)	(_a)(%rip)
180b57cec5SDimitry Andric
190b57cec5SDimitry Andric	.text
200b57cec5SDimitry Andric
210b57cec5SDimitry Andric	.balign 4
220b57cec5SDimitry AndricDEFINE_COMPILERRT_FUNCTION(__floatundixf)
230b57cec5SDimitry Andric	movq	%rdi,	 -8(%rsp)
240b57cec5SDimitry Andric	fildq	-8(%rsp)
250b57cec5SDimitry Andric	test	%rdi,		%rdi
260b57cec5SDimitry Andric	js		1f
270b57cec5SDimitry Andric	ret
280b57cec5SDimitry Andric1:	faddl	REL_ADDR(twop64)
290b57cec5SDimitry Andric	ret
300b57cec5SDimitry AndricEND_COMPILERRT_FUNCTION(__floatundixf)
310b57cec5SDimitry Andric
320b57cec5SDimitry Andric#endif // __x86_64__
330b57cec5SDimitry Andric
340b57cec5SDimitry Andric
350b57cec5SDimitry Andric/* Branch-free implementation is ever so slightly slower, but more beautiful.
360b57cec5SDimitry Andric   It is likely superior for inlining, so I kept it around for future reference.
370b57cec5SDimitry Andric
380b57cec5SDimitry Andric#ifdef __x86_64__
390b57cec5SDimitry Andric
400b57cec5SDimitry AndricCONST_SECTION
410b57cec5SDimitry Andric
420b57cec5SDimitry Andric	.balign 4
430b57cec5SDimitry Andrictwop52:
440b57cec5SDimitry Andric	.quad 0x4330000000000000
450b57cec5SDimitry Andrictwop84_plus_twop52_neg:
460b57cec5SDimitry Andric	.quad 0xc530000000100000
470b57cec5SDimitry Andrictwop84:
480b57cec5SDimitry Andric	.quad 0x4530000000000000
490b57cec5SDimitry Andric
500b57cec5SDimitry Andric#define REL_ADDR(_a)	(_a)(%rip)
510b57cec5SDimitry Andric
520b57cec5SDimitry Andric.text
530b57cec5SDimitry Andric.balign 4
540b57cec5SDimitry AndricDEFINE_COMPILERRT_FUNCTION(__floatundixf)
550b57cec5SDimitry Andric	movl	%edi,				%esi			// low 32 bits of input
560b57cec5SDimitry Andric	shrq	$32,				%rdi			// hi 32 bits of input
570b57cec5SDimitry Andric	orq		REL_ADDR(twop84),	%rdi			// 2^84 + hi (as a double)
580b57cec5SDimitry Andric	orq		REL_ADDR(twop52),	%rsi			// 2^52 + lo (as a double)
590b57cec5SDimitry Andric	movq	%rdi,			 -8(%rsp)
600b57cec5SDimitry Andric	movq	%rsi,			-16(%rsp)
610b57cec5SDimitry Andric	fldl	REL_ADDR(twop84_plus_twop52_neg)
620b57cec5SDimitry Andric	faddl	-8(%rsp)	// hi - 2^52 (as double extended, no rounding occurs)
630b57cec5SDimitry Andric	faddl	-16(%rsp)	// hi + lo (as double extended)
640b57cec5SDimitry Andric	ret
650b57cec5SDimitry AndricEND_COMPILERRT_FUNCTION(__floatundixf)
660b57cec5SDimitry Andric
670b57cec5SDimitry Andric#endif // __x86_64__
680b57cec5SDimitry Andric
690b57cec5SDimitry Andric*/
700b57cec5SDimitry Andric
710b57cec5SDimitry AndricNO_EXEC_STACK_DIRECTIVE
720b57cec5SDimitry Andric
73