1 // This file is dual licensed under the MIT and the University of Illinois Open 2 // Source Licenses. See LICENSE.TXT for details. 3 4 #include "../assembly.h" 5 6 // long double __floatundixf(du_int a); 7 8 #ifdef __x86_64__ 9 10 #if defined(__APPLE__) 11 .const 12 #elif defined(__ELF__) 13 .rodata 14 #else 15 .section .rdata,"rd" 16 #endif 17 .balign 4 18 twop64: 19 .quad 0x43f0000000000000 20 21 #define REL_ADDR(_a) (_a)(%rip) 22 23 .text 24 25 .balign 4 26 DEFINE_COMPILERRT_FUNCTION(__floatundixf) 27 movq %rdi, -8(%rsp) 28 fildq -8(%rsp) 29 test %rdi, %rdi 30 js 1f 31 ret 32 1: faddl REL_ADDR(twop64) 33 ret 34 END_COMPILERRT_FUNCTION(__floatundixf) 35 36 #endif // __x86_64__ 37 38 39 /* Branch-free implementation is ever so slightly slower, but more beautiful. 40 It is likely superior for inlining, so I kept it around for future reference. 41 42 #ifdef __x86_64__ 43 44 #if defined(__APPLE__) 45 .const 46 #elif defined(__ELF__) 47 .rdata 48 #else 49 .section .rdata,"rd" 50 #endif 51 .balign 4 52 twop52: 53 .quad 0x4330000000000000 54 twop84_plus_twop52_neg: 55 .quad 0xc530000000100000 56 twop84: 57 .quad 0x4530000000000000 58 59 #define REL_ADDR(_a) (_a)(%rip) 60 61 .text 62 .balign 4 63 DEFINE_COMPILERRT_FUNCTION(__floatundixf) 64 movl %edi, %esi // low 32 bits of input 65 shrq $32, %rdi // hi 32 bits of input 66 orq REL_ADDR(twop84), %rdi // 2^84 + hi (as a double) 67 orq REL_ADDR(twop52), %rsi // 2^52 + lo (as a double) 68 movq %rdi, -8(%rsp) 69 movq %rsi, -16(%rsp) 70 fldl REL_ADDR(twop84_plus_twop52_neg) 71 faddl -8(%rsp) // hi - 2^52 (as double extended, no rounding occurs) 72 faddl -16(%rsp) // hi + lo (as double extended) 73 ret 74 END_COMPILERRT_FUNCTION(__floatundixf) 75 76 #endif // __x86_64__ 77 78 */ 79