XL C/C++ supports the programming model of AltiVec technology through
non-orthogonal language extensions. AltiVec data types are referred to
as vector types. The IBM implementation of the AltiVec
Programming Interface specification is an extended syntax that allows type
qualifiers and storage class specifiers to precede the keyword vector
(or its alternate spelling, __vector) in a declaration.
The keyword vector is recognized in a declaration context only when used as a type specifier and when the program is compiled with the option -qaltivec. The other AltiVec keywords, pixel and bool, are recognized as valid type specifiers only when preceded by the keyword vector. To keep your source code maximally portable, avoid using vector, pixel, or bool as keywords or identifiers in your program. Use the underscore versions of the specifiers vector and pixel (__vector and __pixel) in declarations.
Most of the legal forms of the syntax are captured in the following diagram. Some variations have been omitted from the diagram for the sake of clarity: type qualifiers such as const and storage class specifiers such as static can appear in any order within the declaration, as long as neither immediately follows the keyword vector (or __vector).
.-----------------------------. V | >>---+-------------------------+-+------------------------------> +-type_qualifier----------+ '-storage_class_specifier-' >--+-vector---+-+-+-bool-----+--+-char-----------+-+----------->< '-__vector-' | +-signed---+ +-short--+-----+-+ | | '-unsigned-' | '-int-' | | | +-int------------+ | | '-long--+-----+--' | | '-int-' | +-pixel----------------------------+ +-__pixel--------------------------+ '-float----------------------------'
Notes:
A typedef name as a type specifier is not allowed in a vector declaration context. However, a vector type can be used in a typedef declaration, and the resulting typedef name can be used in the usual way.
All vector types are aligned on a 16-byte boundary. An aggregate that contains one or more vector types is aligned on a 16-byte boundary, and padded, if necessary, so that each member of vector type is also 16-byte aligned.
The indirection operator * has been extended to handle pointer to vector types. A vector pointer should point to a memory location that has 16-byte alignment. However, the compiler does not enforce this constraint. Dereferencing a vector pointer maintains the vector type and its 16-byte alignment. If a program dereferences a vector pointer that does not contain a 16-byte aligned address, the behavior is undefined.
Pointer arithmetic is defined for pointer to vector types. Given:
vector unsigned int *v;
the expression v + 1 represents a pointer to the vector following v.
Vector types can be cast to other vector types. The cast does not perform a conversion: it preserves the 128-bit pattern, but not necessarily the value. A cast between a vector type and a scalar type is not allowed.
Vector pointers and pointers to non-vector types can be cast back and forth to each other. When a pointer to a non-vector type is cast to a vector pointer, the address should be 16-byte aligned. The referenced object of the pointer to a non-vector type can be aligned on a sixteen-byte boundary by using either the __align specifier or __attribute__((aligned(16))). Only vector types have a natural 16-byte alignment.
A vector type is initialized by a vector literal or any expression having the same vector type. For example:
vector unsigned int v1; vector unsigned int v2 = (vector unsigned int)(10); v1 = v2;
A vector type can be initialized by an initializer list. The number of
elements in a braced initializer list must be less than or equal to the number
of elements of the vector type. Any uninitialized element will be
initialized to zero.
Examples:
vector unsigned int v1 = {1}; // initialize the first 4 bytes of v1 with 1 and the remaining 12 bytes with zeros vector unsigned int v2 = {1,2}; // initialize the first 8 bytes of v1 with 1 and 2 and the remaining 8 bytes with zeros vector unsigned int v3 = {1,2,3,4}; // equivalent to the vector literal (vector unsigned int) (1,2,3,4)
Unlike vector literals, the elements in the initializer list do not have to be constant expressions unless the initialized vector variable is static. Thus, the following is legal:
int i=1; int foo() { return 2; } int main() { vector unsigned int v1 = {i, foo()}; return 0; }
Related References