Add ieee754 versions of the compiler runtime functions

__fixuns{sf,df,tf}{si,di}.
Add an ieee754 version of the compiler runtime function __floatuntfdi
This commit is contained in:
matt 2011-07-09 02:30:27 +00:00
parent e17674a5a4
commit cee1c10ee1
8 changed files with 542 additions and 2 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile.inc,v 1.10 2011/01/26 01:18:48 pooka Exp $
# $NetBSD: Makefile.inc,v 1.11 2011/07/09 02:30:27 matt Exp $
.include <bsd.own.mk>
@ -9,6 +9,15 @@ CPPFLAGS.assym.h+=-D__LIBC12_SOURCE__
.if ${MKSOFTFLOAT} != "no"
.include <softfloat/Makefile.inc>
CPPFLAGS+= -DSOFTFLOAT_NEED_FIXUNS
CPPFLAGS+= -DSOFTFLOAT
SRCS+= fixunsgen_ieee754.c fixunssfsi_ieee754.c fixunsdfsi_ieee754.c
SRCS+= fixunsgen64_ieee754.c #fixunssfdi.c fixunsdfdi.c
.if ${MACHINE_ARCH} == "mips64eb" || ${MACHINE_ARCH} == "mips64el"
SRCS+= fixunstfsi_ieee754.c fixunstfdi_ieee754.c
.endif
.endif
.if ${MACHINE_ARCH} == "mips64eb" || ${MACHINE_ARCH} == "mips64el"
SRCS+= floatunditf_ieee754.c
.endif

View File

@ -0,0 +1,65 @@
/* $NetBSD: fixunsdfsi_ieee754.c,v 1.1 2011/07/09 02:30:27 matt Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matt Thomas of 3am Software Foundry.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: fixunsdfsi_ieee754.c,v 1.1 2011/07/09 02:30:27 matt Exp $");
#endif /* LIBC_SCCS and not lint */
#include <stdbool.h>
#include <stdint.h>
#include <float.h>
#include <machine/ieee.h>
uint32_t __fixunsgen32(int, bool, size_t, size_t, const uint32_t *);
uint32_t __fixunsdfsi(double);
/*
* Convert double to (unsigned) int. All operations are done module 2^32.
*/
uint32_t
__fixunsdfsi(double x)
{
const union ieee_double_u dblu = { .dblu_d = x };
const uint32_t frac[(DBL_FRACBITS + 31)/32 + 1] = {
[0] = 0,
[1] = dblu.dblu_dbl.dbl_fracl,
[2] = dblu.dblu_dbl.dbl_frach,
};
return __fixunsgen32(
dblu.dblu_dbl.dbl_exp - DBL_EXP_BIAS,
dblu.dblu_dbl.dbl_sign != 0,
DBL_MANT_DIG,
DBL_FRACHBITS,
&frac[__arraycount(frac)-1]);
}

View File

@ -0,0 +1,45 @@
/* $NetBSD: fixunsgen64_ieee754.c,v 1.1 2011/07/09 02:30:27 matt Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: fixunsgen64_ieee754.c,v 1.1 2011/07/09 02:30:27 matt Exp $");
#endif /* LIBC_SCCS and not lint */
#define FIXUNSNAME(n) n##64
#define UINTXX_T uint64_t
#include "fixunsgen_ieee754.c"

View File

@ -0,0 +1,110 @@
/* $NetBSD: fixunsgen_ieee754.c,v 1.1 2011/07/09 02:30:27 matt Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if !defined(FIXUNSNAME) && defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: fixunsgen_ieee754.c,v 1.1 2011/07/09 02:30:27 matt Exp $");
#endif /* LIBC_SCCS and not lint */
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <float.h>
#ifndef FIXUNSNAME
#define FIXUNSNAME(n) n##32
#define UINTXX_T uint32_t
#endif
__dso_hidden UINTXX_T
FIXUNSNAME(__fixunsgen)(int, bool, size_t, size_t, const uint32_t *);
/*
* Convert double to (unsigned) int. All operations are done module 2^32.
*/
UINTXX_T
FIXUNSNAME(__fixunsgen)(int exp, bool sign, size_t mant_dig, size_t fracbits,
const uint32_t *frac)
{
UINTXX_T tmp;
/*
* If it's less than 1 (negative exponent), it's going to round
* to zero. If the exponent is so large that it is a multiple of
* 2^N, then x module 2^N will be 0.
*/
if (__predict_false(exp < 0 || exp - mant_dig > sizeof(UINTXX_T)*8-1))
return 0;
/*
* This is simplier than it seems. Basically we are constructing
* fixed binary representation of the floating point number tossing
* away bits that wont be in the modulis we return.
*/
tmp = 1;
for (size_t ebits = exp;;) {
if (ebits <= fracbits) {
/*
* The current fraction has more bits than we need.
* Shift the current value over and insert the bits
* we want. We're done.
*/
tmp <<= ebits;
tmp |= *frac >> (fracbits - ebits);
break;
}
if (fracbits == sizeof(tmp)*4) {
/*
* Shifts must be < sizeof(type). If it's going to be
* sizeof(type), just replace the value.
*/
tmp = *frac--;
} else {
tmp <<= fracbits;
tmp |= *frac--;
}
ebits -= fracbits;
fracbits = sizeof(frac[0]) * 4;
}
/*
* If the input was negative, make tmp negative module 2^32.
*/
if (sign)
tmp = -tmp;
return tmp;
}

View File

@ -0,0 +1,64 @@
/* $NetBSD: fixunssfsi_ieee754.c,v 1.1 2011/07/09 02:30:27 matt Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matt Thomas of 3am Software Foundry.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: fixunssfsi_ieee754.c,v 1.1 2011/07/09 02:30:27 matt Exp $");
#endif /* LIBC_SCCS and not lint */
#include <stdbool.h>
#include <stdint.h>
#include <float.h>
#include <machine/ieee.h>
uint32_t __fixunsgen32(int, bool, size_t, size_t, const uint32_t *);
uint32_t __fixunssfsi(float);
/*
* Convert float to (unsigned) int. All operations are done module 2^32.
*/
uint32_t
__fixunssfsi(float x)
{
const union ieee_single_u sngu = { .sngu_f = x };
const uint32_t frac[(SNG_FRACBITS + 31)/32 + 1] = {
[0] = 0,
[1] = sngu.sngu_sng.sng_frac,
};
return __fixunsgen32(
sngu.sngu_sng.sng_exp - SNG_EXP_BIAS,
sngu.sngu_sng.sng_sign != 0,
FLT_MANT_DIG,
SNG_FRACBITS,
&frac[__arraycount(frac)-1]);
}

View File

@ -0,0 +1,72 @@
/* $NetBSD: fixunstfdi_ieee754.c,v 1.1 2011/07/09 02:30:27 matt Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matt Thomas of 3am Software Foundry.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: fixunstfdi_ieee754.c,v 1.1 2011/07/09 02:30:27 matt Exp $");
#endif /* LIBC_SCCS and not lint */
#include <stdbool.h>
#include <stdint.h>
#include <float.h>
#include <machine/ieee.h>
#if defined(__x86_64__) || defined(__i486__)
#define FIXUNS __fixunsxfdi
#else
#define FIXUNS __fixunstfdi
#endif
uint64_t __fixunsgen64(int, bool, size_t, size_t, const uint32_t *);
uint64_t FIXUNS(long double);
/*
* Convert long double to uint64_t. All operations are done module 2^64.
*/
uint64_t
FIXUNS(long double x)
{
const union ieee_ext_u extu = { .extu_ld = x };
uint32_t frac[(EXT_FRACBITS + 31)/32 + 2];
frac[0] = 0;
frac[1] = 0;
EXT_TO_ARRAY32(extu, &frac[2]);
return __fixunsgen64(
extu.extu_ext.ext_exp - EXT_EXP_BIAS,
extu.extu_ext.ext_sign != 0,
LDBL_MANT_DIG,
EXT_FRACHBITS,
&frac[__arraycount(frac)-1]);
}

View File

@ -0,0 +1,71 @@
/* $NetBSD: fixunstfsi_ieee754.c,v 1.1 2011/07/09 02:30:27 matt Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matt Thomas of 3am Software Foundry.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: fixunstfsi_ieee754.c,v 1.1 2011/07/09 02:30:27 matt Exp $");
#endif /* LIBC_SCCS and not lint */
#include <stdbool.h>
#include <stdint.h>
#include <float.h>
#include <machine/ieee.h>
#if defined(__x86_64__) || defined(__i486__)
#define FIXUNS __fixunsxfsi
#else
#define FIXUNS __fixunstfsi
#endif
uint32_t __fixunsgen32(int, bool, size_t, size_t, const uint32_t *);
uint32_t FIXUNS(long double);
/*
* Convert long double to (unsigned) int. All operations are done module 2^32.
*/
uint32_t
FIXUNS(long double x)
{
const union ieee_ext_u extu = { .extu_ld = x };
uint32_t frac[(EXT_FRACBITS + 31)/32 + 1];
frac[0] = 0;
EXT_TO_ARRAY32(extu, &frac[1]);
return __fixunsgen32(
extu.extu_ext.ext_exp - EXT_EXP_BIAS,
extu.extu_ext.ext_sign != 0,
LDBL_MANT_DIG,
EXT_FRACHBITS,
&frac[__arraycount(frac)-1]);
}

View File

@ -0,0 +1,104 @@
/* $NetBSD: floatunditf_ieee754.c,v 1.1 2011/07/09 02:30:27 matt Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)floatunsdidf.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: floatunditf_ieee754.c,v 1.1 2011/07/09 02:30:27 matt Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
#include "quad.h"
#ifdef __vax__
#error vax does not support a distinct long double
#endif
#include <machine/ieee.h>
/*
* Convert (unsigned) quad to long double.
* This is exactly like floatdidf.c except that negatives never occur.
*/
long double
__floatunditf(u_quad_t x)
{
#if 0
long double ld;
union uu u;
u.uq = x;
ld = (long double)u.ul[H] * (((int)1 << (INT_BITS - 2)) * 4.0);
ld += u.ul[L];
return (ld);
#else
union ieee_ext_u extu;
if (x == 0)
return 0.0L;
if (x == 1)
return 1.0L;
quad_t tmp = x; /* must be signed */
size_t width = 64;
size_t bit = 0;
quad_t mask = ~(quad_t)0;
while (mask != 0 && (tmp >= 0)) {
width >>= 1;
mask <<= width;
if ((tmp & mask) == 0) {
tmp <<= width;
bit += width;
}
}
x <<= (bit + 1);
extu.extu_sign = 0;
extu.extu_exp = EXT_EXP_BIAS + (64 - (bit + 1));
extu.extu_frach = x >> (64 - EXT_FRACHBITS);
x <<= EXT_FRACHBITS;
#ifdef EXT_FRACHMBITS
extu.extu_frachm = x >> (64 - EXT_FRACHMBITS);
x <<= EXT_FRACHMBITS;
#endif
#ifdef EXT_FRACLMBITS
extu.extu_fraclm = x >> (64 - EXT_FRACLMBITS);
x <<= EXT_FRACLMBITS;
#endif
extu.extu_fracl = x >> (64 - EXT_FRACLBITS);
return extu.extu_ld;
#endif
}