1*0a6a1f1dSLionel Sambuc//===-- floatundidf.S - Implement __floatundidf for i386 ------------------===// 2*0a6a1f1dSLionel Sambuc// 3*0a6a1f1dSLionel Sambuc// The LLVM Compiler Infrastructure 4*0a6a1f1dSLionel Sambuc// 5*0a6a1f1dSLionel Sambuc// This file is dual licensed under the MIT and the University of Illinois Open 6*0a6a1f1dSLionel Sambuc// Source Licenses. See LICENSE.TXT for details. 7*0a6a1f1dSLionel Sambuc// 8*0a6a1f1dSLionel Sambuc//===----------------------------------------------------------------------===// 9*0a6a1f1dSLionel Sambuc// 10*0a6a1f1dSLionel Sambuc// This file implements __floatundidf for the compiler_rt library. 11*0a6a1f1dSLionel Sambuc// 12*0a6a1f1dSLionel Sambuc//===----------------------------------------------------------------------===// 13*0a6a1f1dSLionel Sambuc 14*0a6a1f1dSLionel Sambuc#include "../assembly.h" 15*0a6a1f1dSLionel Sambuc 16*0a6a1f1dSLionel Sambuc// double __floatundidf(du_int a); 17*0a6a1f1dSLionel Sambuc 18*0a6a1f1dSLionel Sambuc#ifdef __i386__ 19*0a6a1f1dSLionel Sambuc 20*0a6a1f1dSLionel Sambuc#if defined(__APPLE__) 21*0a6a1f1dSLionel Sambuc .const 22*0a6a1f1dSLionel Sambuc#elif defined(__ELF__) 23*0a6a1f1dSLionel Sambuc .section .rodata 24*0a6a1f1dSLionel Sambuc#else 25*0a6a1f1dSLionel Sambuc .section .rdata,"rd" 26*0a6a1f1dSLionel Sambuc#endif 27*0a6a1f1dSLionel Sambuc 28*0a6a1f1dSLionel Sambuc .balign 16 29*0a6a1f1dSLionel Sambuctwop52: 30*0a6a1f1dSLionel Sambuc .quad 0x4330000000000000 31*0a6a1f1dSLionel Sambuc 32*0a6a1f1dSLionel Sambuc .balign 16 33*0a6a1f1dSLionel Sambuctwop84_plus_twop52: 34*0a6a1f1dSLionel Sambuc .quad 0x4530000000100000 35*0a6a1f1dSLionel Sambuc 36*0a6a1f1dSLionel Sambuc .balign 16 37*0a6a1f1dSLionel Sambuctwop84: 38*0a6a1f1dSLionel Sambuc .quad 0x4530000000000000 39*0a6a1f1dSLionel Sambuc 40*0a6a1f1dSLionel Sambuc#define REL_ADDR(_a) (_a)-0b(%eax) 41*0a6a1f1dSLionel Sambuc 42*0a6a1f1dSLionel Sambuc.text 43*0a6a1f1dSLionel Sambuc.balign 4 44*0a6a1f1dSLionel SambucDEFINE_COMPILERRT_FUNCTION(__floatundidf) 45*0a6a1f1dSLionel Sambuc movss 8(%esp), %xmm1 // high 32 bits of a 46*0a6a1f1dSLionel Sambuc movss 4(%esp), %xmm0 // low 32 bits of a 47*0a6a1f1dSLionel Sambuc calll 0f 48*0a6a1f1dSLionel Sambuc0: popl %eax 49*0a6a1f1dSLionel Sambuc orpd REL_ADDR(twop84), %xmm1 // 0x1p84 + a_hi (no rounding occurs) 50*0a6a1f1dSLionel Sambuc subsd REL_ADDR(twop84_plus_twop52), %xmm1 // a_hi - 0x1p52 (no rounding occurs) 51*0a6a1f1dSLionel Sambuc orpd REL_ADDR(twop52), %xmm0 // 0x1p52 + a_lo (no rounding occurs) 52*0a6a1f1dSLionel Sambuc addsd %xmm1, %xmm0 // a_hi + a_lo (round happens here) 53*0a6a1f1dSLionel Sambuc movsd %xmm0, 4(%esp) 54*0a6a1f1dSLionel Sambuc fldl 4(%esp) 55*0a6a1f1dSLionel Sambuc ret 56*0a6a1f1dSLionel SambucEND_COMPILERRT_FUNCTION(__floatundidf) 57*0a6a1f1dSLionel Sambuc 58*0a6a1f1dSLionel Sambuc#endif // __i386__ 59