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.
This commit is contained in:
Bruce Evans 2008-01-17 16:39:07 +00:00
parent a4b679d859
commit d2012f3333
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=175402
3 changed files with 24 additions and 3 deletions

View file

@ -36,6 +36,11 @@ union IEEEl2bits {
unsigned int junkl :16;
unsigned int junkh :32;
} bits;
struct {
unsigned long man :64;
unsigned int expsign :16;
unsigned long junk :48;
} xbits;
};
#define LDBL_NBIT 0x80000000

View file

@ -35,6 +35,11 @@ union IEEEl2bits {
unsigned int sign :1;
unsigned int junk :16;
} bits;
struct {
unsigned long long man :64;
unsigned int expsign :16;
unsigned int junk :16;
} xbits;
};
#define LDBL_NBIT 0x80000000

View file

@ -46,6 +46,17 @@ union IEEEl2bits {
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