Please forgive my ignorance with the question below. We are supporting GCC 4.8 (and above) and IBM XL C/C++ 12 (and above). We are also supporting big and little-endian on AIX and Linux. The compilers and platforms have made the code fairly messy.
We want to load the constant 1
into a VSX register. This is the code we've been able to craft, but it seems wrong because its so complex. The macros XLC_VERSION
, GCC_VERSION
and LITTLE_ENDIAN
have their customary meanings, so the additional preprocessor macros that lead to them have been omitted.
typedef __vector unsigned char uint8x16_p8;
typedef __vector unsigned long long uint64x2_p8;
#if defined(XLC_VERSION)
typedef uint8x16_p8 VectorType;
#elif defined(GCC_VERSION)
typedef uint64x2_p8 VectorType;
#endif
#if defined(LITTLE_ENDIAN)
const VectorType one = {1};
#else
const VectorType one = (VectorType)((uint64x2_p8){0,1});
#endif
What's not apparent is, XL C/C++ supports all data arrangements and has a rich API set. The IBM compiler is a breeze to work with (when its not producing warnings and errors that are hard to understand).
GCC going back to 4.8 only supports the 64x2 arrangement and it only has a subset of the APIs. For example, GCC is missing IBM APIs for the 8x16 arrangement and GCC does not have vec_reve
(which would make endian reversal easy).
What I really want to do is something like this and have it "just work" everywhere, but it fails to compile:
VectorType one = 1;
Is there a less complex way to load a small constant into a vector register?
You might want to check the BCD_INIT example here. It uses a macro to reverse the vector initialization.
Regarding vec_reve: It's syntactic sugar for vec_perm. You can implement it as an inline function in a header or as a library function and use it for compilers that don't have it.