1*0b57cec5SDimitry Andric//===-- floatundidf.S - Implement __floatundidf for i386 ------------------===// 2*0b57cec5SDimitry Andric// 3*0b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric// 7*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric// 9*0b57cec5SDimitry Andric// This file implements __floatundidf for the compiler_rt library. 10*0b57cec5SDimitry Andric// 11*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric#include "../assembly.h" 14*0b57cec5SDimitry Andric 15*0b57cec5SDimitry Andric// double __floatundidf(du_int a); 16*0b57cec5SDimitry Andric 17*0b57cec5SDimitry Andric#ifdef __i386__ 18*0b57cec5SDimitry Andric 19*0b57cec5SDimitry AndricCONST_SECTION 20*0b57cec5SDimitry Andric 21*0b57cec5SDimitry Andric .balign 16 22*0b57cec5SDimitry Andrictwop52: 23*0b57cec5SDimitry Andric .quad 0x4330000000000000 24*0b57cec5SDimitry Andric 25*0b57cec5SDimitry Andric .balign 16 26*0b57cec5SDimitry Andrictwop84_plus_twop52: 27*0b57cec5SDimitry Andric .quad 0x4530000000100000 28*0b57cec5SDimitry Andric 29*0b57cec5SDimitry Andric .balign 16 30*0b57cec5SDimitry Andrictwop84: 31*0b57cec5SDimitry Andric .quad 0x4530000000000000 32*0b57cec5SDimitry Andric 33*0b57cec5SDimitry Andric#define REL_ADDR(_a) (_a)-0b(%eax) 34*0b57cec5SDimitry Andric 35*0b57cec5SDimitry Andric.text 36*0b57cec5SDimitry Andric.balign 4 37*0b57cec5SDimitry AndricDEFINE_COMPILERRT_FUNCTION(__floatundidf) 38*0b57cec5SDimitry Andric movss 8(%esp), %xmm1 // high 32 bits of a 39*0b57cec5SDimitry Andric movss 4(%esp), %xmm0 // low 32 bits of a 40*0b57cec5SDimitry Andric calll 0f 41*0b57cec5SDimitry Andric0: popl %eax 42*0b57cec5SDimitry Andric orpd REL_ADDR(twop84), %xmm1 // 0x1p84 + a_hi (no rounding occurs) 43*0b57cec5SDimitry Andric subsd REL_ADDR(twop84_plus_twop52), %xmm1 // a_hi - 0x1p52 (no rounding occurs) 44*0b57cec5SDimitry Andric orpd REL_ADDR(twop52), %xmm0 // 0x1p52 + a_lo (no rounding occurs) 45*0b57cec5SDimitry Andric addsd %xmm1, %xmm0 // a_hi + a_lo (round happens here) 46*0b57cec5SDimitry Andric movsd %xmm0, 4(%esp) 47*0b57cec5SDimitry Andric fldl 4(%esp) 48*0b57cec5SDimitry Andric ret 49*0b57cec5SDimitry AndricEND_COMPILERRT_FUNCTION(__floatundidf) 50*0b57cec5SDimitry Andric 51*0b57cec5SDimitry Andric#endif // __i386__ 52*0b57cec5SDimitry Andric 53*0b57cec5SDimitry AndricNO_EXEC_STACK_DIRECTIVE 54*0b57cec5SDimitry Andric 55