freebsd-skq/lib/libc/ia64/_fpmath.h
bde c553ad248f Add an alternative view of the bits in an 80-bit long double (64+16
instead of 32+32+15+1) on all arches that have such long doubles (amd64,
ia64 and i386).  Large objects should be be accessed in large units,
and the 32+32+15+1[+padding] decomposition asks for almost the opposite
of that, sometimes resulting in very slow accesses depending on how
well the compiler ignores what we ask for and converts to the best
units for the given machine.  E.g., on Athlons, there is a 10-20 cycle
penalty for accessing the middle 32-bit word immediately after an
80-bit store.

Whether actually using the alternative view is better is very machine-
dependent.  A 32+32+16 view is probably best with old 32-bit systems
and gcc through 4.2.1.  The compiler should mostly avoid the view and
generate best accesses, but gcc-4.2.1 is far from doing that.  I think
64+16 is best for now.  Similarly for doubles -- they should be using
64+0 especially on 64-bit machines, but fdlibm uses 32+32 extensively
for them.  Fortunately, in 64-bit mode for doubles, gcc already ignores
the 32+32-bit view and generates best accesses in many cases.
2008-01-17 16:39:07 +00:00

83 lines
2.7 KiB
C

/*-
* Copyright (c) 2003 Mike Barcroft <mike@FreeBSD.org>
* Copyright (c) 2002, 2003 David Schultz <das@FreeBSD.ORG>
* All rights reserved.
*
* 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 AUTHOR 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 AUTHOR 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.
*
* $FreeBSD$
*/
#include <sys/endian.h>
union IEEEl2bits {
long double e;
struct {
#if _BYTE_ORDER == _LITTLE_ENDIAN
unsigned int manl :32;
unsigned int manh :32;
unsigned int exp :15;
unsigned int sign :1;
unsigned long junk :48;
#else /* _BIG_ENDIAN */
unsigned long junk :48;
unsigned int sign :1;
unsigned int exp :15;
unsigned int manh :32;
unsigned int manl :32;
#endif
} bits;
struct {
#if _BYTE_ORDER == _LITTLE_ENDIAN
unsigned long man :64;
unsigned int expsign :16;
unsigned long junk :48;
#else /* _BIG_ENDIAN */
unsigned long junk :48;
unsigned int expsign :16;
unsigned long man :64;
#endif
} xbits;
};
#if _BYTE_ORDER == _LITTLE_ENDIAN
#define LDBL_NBIT 0x80000000
#define mask_nbit_l(u) ((u).bits.manh &= ~LDBL_NBIT)
#else /* _BIG_ENDIAN */
/*
* XXX This doesn't look right. Very few machines have a different
* endianness for integers and floating-point, and in nextafterl()
* we assume that none do. If you have an environment for testing
* this, please let me know. --das
*/
#define LDBL_NBIT 0x80
#define mask_nbit_l(u) ((u).bits.manh &= ~LDBL_NBIT)
#endif
#define LDBL_MANH_SIZE 32
#define LDBL_MANL_SIZE 32
#define LDBL_TO_ARRAY32(u, a) do { \
(a)[0] = (uint32_t)(u).bits.manl; \
(a)[1] = (uint32_t)(u).bits.manh; \
} while (0)