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