fixdfdi.c revision 285830
10Sstevel@tonic-gate/* ===-- fixdfdi.c - Implement __fixdfdi -----------------------------------===
20Sstevel@tonic-gate *
30Sstevel@tonic-gate *                     The LLVM Compiler Infrastructure
40Sstevel@tonic-gate *
50Sstevel@tonic-gate * This file is dual licensed under the MIT and the University of Illinois Open
60Sstevel@tonic-gate * Source Licenses. See LICENSE.TXT for details.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * ===----------------------------------------------------------------------===
90Sstevel@tonic-gate *
100Sstevel@tonic-gate * This file implements __fixdfdi for the compiler_rt library.
110Sstevel@tonic-gate *
120Sstevel@tonic-gate * ===----------------------------------------------------------------------===
130Sstevel@tonic-gate */
140Sstevel@tonic-gate
150Sstevel@tonic-gate#include "int_lib.h"
160Sstevel@tonic-gate
170Sstevel@tonic-gate/* Returns: convert a to a signed long long, rounding toward zero. */
180Sstevel@tonic-gate
190Sstevel@tonic-gate/* Assumption: double is a IEEE 64 bit floating point type
200Sstevel@tonic-gate *            su_int is a 32 bit integral type
210Sstevel@tonic-gate *            value in double is representable in di_int (no range checking performed)
220Sstevel@tonic-gate */
230Sstevel@tonic-gate
240Sstevel@tonic-gate/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
250Sstevel@tonic-gate
260Sstevel@tonic-gateARM_EABI_FNALIAS(d2lz, fixdfdi)
270Sstevel@tonic-gate
280Sstevel@tonic-gateCOMPILER_RT_ABI di_int
290Sstevel@tonic-gate__fixdfdi(double a)
300Sstevel@tonic-gate{
310Sstevel@tonic-gate    double_bits fb;
320Sstevel@tonic-gate    fb.f = a;
330Sstevel@tonic-gate    int e = ((fb.u.s.high & 0x7FF00000) >> 20) - 1023;
340Sstevel@tonic-gate    if (e < 0)
350Sstevel@tonic-gate        return 0;
360Sstevel@tonic-gate    di_int s = (si_int)(fb.u.s.high & 0x80000000) >> 31;
370Sstevel@tonic-gate    dwords r;
380Sstevel@tonic-gate    r.s.high = (fb.u.s.high & 0x000FFFFF) | 0x00100000;
390Sstevel@tonic-gate    r.s.low = fb.u.s.low;
400Sstevel@tonic-gate    if (e > 52)
410Sstevel@tonic-gate        r.all <<= (e - 52);
420Sstevel@tonic-gate    else
430Sstevel@tonic-gate        r.all >>= (52 - e);
440Sstevel@tonic-gate    return (r.all ^ s) - s;
450Sstevel@tonic-gate}
460Sstevel@tonic-gate