floatunditf_ieee754.c revision 1.1.4.2 1 1.1.4.2 yamt /* $NetBSD: floatunditf_ieee754.c,v 1.1.4.2 2014/05/22 11:36:52 yamt Exp $ */
2 1.1.4.2 yamt
3 1.1.4.2 yamt /*-
4 1.1.4.2 yamt * Copyright (c) 2014 Joerg Sonnenberger <joerg (at) NetBSD.org>.
5 1.1.4.2 yamt * All rights reserved.
6 1.1.4.2 yamt *
7 1.1.4.2 yamt * Redistribution and use in source and binary forms, with or without
8 1.1.4.2 yamt * modification, are permitted provided that the following conditions
9 1.1.4.2 yamt * are met:
10 1.1.4.2 yamt *
11 1.1.4.2 yamt * 1. Redistributions of source code must retain the above copyright
12 1.1.4.2 yamt * notice, this list of conditions and the following disclaimer.
13 1.1.4.2 yamt * 2. Redistributions in binary form must reproduce the above copyright
14 1.1.4.2 yamt * notice, this list of conditions and the following disclaimer in
15 1.1.4.2 yamt * the documentation and/or other materials provided with the
16 1.1.4.2 yamt * distribution.
17 1.1.4.2 yamt *
18 1.1.4.2 yamt * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 1.1.4.2 yamt * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 1.1.4.2 yamt * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 1.1.4.2 yamt * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 1.1.4.2 yamt * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 1.1.4.2 yamt * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 1.1.4.2 yamt * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 1.1.4.2 yamt * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 1.1.4.2 yamt * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 1.1.4.2 yamt * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
28 1.1.4.2 yamt * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 1.1.4.2 yamt * SUCH DAMAGE.
30 1.1.4.2 yamt */
31 1.1.4.2 yamt
32 1.1.4.2 yamt #include <sys/cdefs.h>
33 1.1.4.2 yamt __RCSID("$NetBSD: floatunditf_ieee754.c,v 1.1.4.2 2014/05/22 11:36:52 yamt Exp $");
34 1.1.4.2 yamt
35 1.1.4.2 yamt #include <math.h>
36 1.1.4.2 yamt #include <machine/ieee.h>
37 1.1.4.2 yamt #include <limits.h>
38 1.1.4.2 yamt
39 1.1.4.2 yamt #ifdef __HAVE_LONG_DOUBLE
40 1.1.4.2 yamt
41 1.1.4.2 yamt long double __floatunditf(uint64_t x);
42 1.1.4.2 yamt
43 1.1.4.2 yamt /*
44 1.1.4.2 yamt * Convert uint64_t to long double.
45 1.1.4.2 yamt */
46 1.1.4.2 yamt long double
47 1.1.4.2 yamt __floatunditf(uint64_t x)
48 1.1.4.2 yamt {
49 1.1.4.2 yamt int exponent, zeros;
50 1.1.4.2 yamt union ieee_ext_u ux;
51 1.1.4.2 yamt
52 1.1.4.2 yamt /* Use the easier conversion routine for uint32_t if possible. */
53 1.1.4.2 yamt if (x <= UINT32_MAX)
54 1.1.4.2 yamt return (long double)(uint32_t)x;
55 1.1.4.2 yamt
56 1.1.4.2 yamt zeros = __builtin_clzll(x);
57 1.1.4.2 yamt #ifdef LDBL_IMPLICIT_NBIT
58 1.1.4.2 yamt exponent = 64 - zeros;
59 1.1.4.2 yamt x <<= zeros + 1;
60 1.1.4.2 yamt #else
61 1.1.4.2 yamt exponent = 63 - zeros;
62 1.1.4.2 yamt x <<= zeros;
63 1.1.4.2 yamt #endif
64 1.1.4.2 yamt
65 1.1.4.2 yamt ux.extu_exp = EXT_EXP_BIAS + exponent;
66 1.1.4.2 yamt ux.extu_frach = (x >> (64 - EXT_FRACHBITS));
67 1.1.4.2 yamt x <<= EXT_FRACHBITS;
68 1.1.4.2 yamt #ifdef EXT_FRACHMBITS
69 1.1.4.2 yamt ux.extu_frachm = (x >> (64 - EXT_FRACHMBITS));
70 1.1.4.2 yamt x <<= EXT_FRACHMBITS;
71 1.1.4.2 yamt #endif
72 1.1.4.2 yamt #ifdef EXT_FRACLMBITS
73 1.1.4.2 yamt ux.extu_fraclm = (x >> (64 - EXT_FRACLMBITS));
74 1.1.4.2 yamt x <<= EXT_FRACLMBITS;
75 1.1.4.2 yamt #endif
76 1.1.4.2 yamt ux.extu_fracl = (x >> (64 - EXT_FRACLBITS));
77 1.1.4.2 yamt ux.extu_sign = 0;
78 1.1.4.2 yamt
79 1.1.4.2 yamt return ux.extu_ld;
80 1.1.4.2 yamt }
81 1.1.4.2 yamt #endif /* __HAVE_LONG_DOUBLE */
82