Vector element order toggling

To consistently use the instructions generated by vector built-in functions, users need to make all existing Vector Multimedia Extension (VMX) and Vector Scalar Extension (VSX) load and store built-in functions operate on the vectors in registers in the same vector element order, either little endian or big endian element order.

Vector element order

The -maltivec (-qaltivec) option affects the vector element order only in registers when the vectors are operated by a specific set of functions. In registers, the vector layout differs when the computer loads the vector in either big endian element order or little endian element order.

Note: To use the built-in functions enabled by the -maltivec (-qaltivec) option, you must explicitly code #include <altivec.h> in your program.
Big endian element order
Vectors are laid out in vector registers from left to right, so that element 0 is the leftmost element in the register.
Little endian element order
Vectors are laid out in vector registers from right to left, so that element 0 is the rightmost element in the register.

For more information, see Example: Vector layout in the memory and register.

Rules for vector element order toggling

The vector element order is toggled in registers by following these rules:

  • The -maltivec (-qaltivec) option does not affect the vector element order in memory, where the vector elements are always stored in big endian element order.

    For example, in memory, the -maltivec (-qaltivec) option does not affect the vector initialization. The vectors initialized by the union with the non-vectors (such as arrays) are always in big endian element order in memory. When the initialized vector is loaded to registers, the vector element order is always reversed to little endian element order in registers even when -maltivec=be (-qaltivec=be). However, if the vector loading is realized by using the vector built-in function, the vector element order is arranged with respect to the -maltivec (-qaltivec) option.

    The previous rules apply to the vector literals as well. The vector literals are stored always in big endian element order in the memory. When the vector literals are loaded to registers, the vector element order is always reversed to little endian element order in registers.

  • When -maltivec=le (-qaltivec=le) is in effect, the behaviours of functions are as follows:
    • The VMX and VSX load built-in functions load vectors to registers in little endian element order.
    • The VMX and VSX store built-in functions assume that the vectors to be stored are in little endian element order in registers.
    • The nonload and nonstore built-in functions assume that vectors are loaded in registers in little endian element order.
  • When -maltivec=be (-qaltivec=be) is in effect, these functions operate on the vectors in an opposite way of -maltivec=le (-qaltivec=le). The vectors in registers are in big endian element order.
  • Regardless of the -maltivec (-qaltivec) option, the vec_xl_be function loads vectors to registers always in big endian element order and the vec_xst_be function assumes that vectors to be stored are always in big endian element order in registers.

For more information, see Example: The vector built-in functions affected by the -maltivec (-qaltivec) option and Example: The vector initialization by using the union with arrays.

Example: Vector layout in the memory and register

The following example gets the first element of vector va by calling the vec_extract function. The function returning value is different based on the -maltivec (-qaltivec) option that determines whether vec_extract arranges the vector elements in big endian or little endian element order.

int get_first_element(va)
  {
   vector signed int va;
   printf("%i\n", vec_extract(va, 0));
   //vec_extract is affected by the -qaltivec option
   }
   
The following tables show the vector layout in the memory and the register.
Table 1. Vector layout in the memory
Vector element value E0 E1 E2 E3
  • When -maltivec=be (-qaltivec=be), the vector elements are loaded to registers in big endian element order and vector layout looks as follows.

    Table 2. Vector layout in big endian element order
    Vector element number 0 1 2 3
    Vector element value E0 E1 E2 E3

    The elements of vector va are ordered from the first to last, and stored from the left of registers. The get_first_element function gets the first element E0 from the left of registers.

  • When -maltivec=le (-qaltivec=le), the vector elements are loaded to registers in little endian element order and vector layout looks as follows.

    Table 3. Vector layout in little endian element order
    Vector element number 3 2 1 0
    Vector element value E3 E2 E1 E0

    The elements of vector va are ordered from the last to first, and also stored from the left of registers. The get_first_element function gets the first element E0 from the right of registers.

Example: The vector built-in functions affected by the -maltivec (-qaltivec) option

The following program vec_xlw4.C shows that the vec_xlw4 function loads the vector elements in registers in the order specified by the -maltivec (-qaltivec) option.

int main()
{
  vector signed int a4;
  int c4[4] = {0,1,2,3};
  a4 = vec_xlw4(0, c4);  
  //vec_xlw4 is affected by the -qaltivec option
  printf("%i %i %i %i\n", a4[0], a4[1], a4[2], a4[3]);
}
  • Compile the program with -qaltivec=be by running the following command:

    xlC vec_xlw4.C -qaltivec=be

    Ouput:

      0 1 2 3
  • Compile the program with -qaltivec=le by running the following command:

    xlC vec_xlw4.C -qaltivec=le

    Ouput:

      0 1 2 3

Example: The vector initialization by using the union with arrays

The following program example vec_equiv.C contains the vectors initialization by using the union with arrays. The vector loading is not affected by the -maltivec (-qaltivec) option and is loaded to registers always in little endian element order. Therefore, the vector elements extracted by vec_extract function are different between -maltivec=be (-qaltivec=be) and -maltivec=le (-qaltivec=le) .

int main()
{
  union {                           
    vector signed int a4;
    int c4[4];
  };        

  //In the memory, the vector initialization (by using the union)
  //is not affected by the -qaltivec option and the vector is stored in 
  //big endian element order. Then, the initialized vector is loaded 
  //in registers by being reveresed to the little endian element order.

  c4[0] = 0; c4[1] = 1; c4[2] = 2; c4[3] = 3;
  for (int i=0;i<4;i++)
    printf("%i ", vec_extract(a4,i));  
    //vect_extract is affected by the -qaltivec option

  printf("\n");
}
  • Compile the codes with -qaltivec=le by running the following command:

    xlC vec_equiv.C -qaltivec=le

    Ouput:

    0 1 2 3
  • Compile the program with -qaltivec=be by running the following command:

    xlC vec_equiv.C -qaltivec=be

    Ouput:

    3 2 1 0

    The compilation result is different from that of compilation with -qaltivec=le.



Voice your opinion on getting help information Ask IBM compiler experts a technical question in the IBM XL compilers forum Reach out to us