Given, struct shared_ptr_struct { unsigned int phase : 24; unsigned short thread : 16; void *addr; };
On the x86_64 (ie, Opteron[tm]) platform, GCC appears to designate the underlying mode of this type as a BLKmode, instead of a TImode. This has implications in terms of the quality of the code that is generated to copy and manipulate 128 bit structures (as defined in the example above). The decision to commit this type to a BLKmode value, originates in this logic in mode_for_size(): if (limit && size > MAX_FIXED_MODE_SIZE) return BLKmode; On the x86 platform, there appears to be no target definition for MAX_FIELD_SIZE. Thus, the default in stor-layout.c applies: #ifndef MAX_FIXED_MODE_SIZE #define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (DImode) #endif Other 64 bit targets define MAX_FIXED_MODE_SIZE along these lines (some line wrapping may occur below): config/i960/i960.h:#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (TImode) config/ia64/ia64.h:#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (TImode) config/mips/mips.h:#define MAX_FIXED_MODE_SIZE LONG_DOUBLE_TYPE_SIZE config/sh/sh.h:#define MAX_FIXED_MODE_SIZE (TARGET_SH5 ? 128 : 64) on MIPS, LONG_DOUBLE_TYPE_SIZE is defined as follows: /* A C expression for the size in bits of the type `long double' on the target machine. If you don't define this, the default is two words. */ #define LONG_DOUBLE_TYPE_SIZE \ (mips_abi == ABI_N32 || mips_abi == ABI_64 ? 128 : 64) In the 'dev' tree, the s390 defines MAX_FIXED_MODE_SIZE as follows: config/s390/s390.h:#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (TARGET_64BIT ? TImode : DImode) (Arguably, the s390 variant might be a better default value to be defined in stor-layout.c) I haven't tried making the suggested change to see if the x86_64 code generator can fully support it. Are there any technical reasons that the x86_64 shouldn't target 128 bit structs into a long double (ie, two 64 bit registers)?