12.5 SIMD Variables

The 8-bit unsigned integer data and Q15 fractional data are packed in a single 32-bit register, and the new instructions operate simultaneously on the multiple data in the register in Single Instruction, Multiple Data (SIMD) fashion. This feature provides computation parallelism for increased application performance.

You can directly take advantage of SIMD parallelism by declaring SIMD data types as described here. In addition, the compiler may automatically take advantage of SIMD parallelism using auto-vectorization as described in the Auto-vectorization section below.

To declare SIMD data types, typedefs with special vector_size attributes are required. For example,

  typedef signed char v4i8 __attribute__ ((vector_size(4)));
  typedef signed char v4q7 __attribute__ ((vector_size(4)));
  typedef short v2i16 __attribute__ ((vector_size(4)));
  typedef short v2q15 __attribute__ ((vector_size(4)));

v4i8, v4q7, v2i16, and v2q15 are SIMD data types that consist of 4, 4, 2, and 2 elements of 8 bits, 8 bits, 16 bits, and 16 bits respectively in a single variable/register.

SIMD data types are powerful and can be applied to fixed-point data types as well. For example:

  typedef _Sat unsigned short _Fract
    sat_v4uqq __attribute__ ((vector_size(4)));
  typedef _Sat unsigned _Fract 
    sat_v2uhq __attribute__ ((vector_size(4)));
  typedef _Sat unsigned short _Accum
    sat_v2uha __attribute__ ((vector_size(4)));
  typedef _Sat _Fract 
    sat_v2hq __attribute__ ((vector_size(4)));
  typedef _Sat short _Accum 
    sat_v2ha __attribute__ ((vector_size(4)));

To initialize SIMD variables is similar to initializing aggregate data. The following examples show how to initialize SIMD variables.

Example:
  /* v4i8 Example */
  v4i8 a = {1, 2, 3, 4};
  v4i8 b;
  b = (v4i8) {5, 6, 7, 8};
  /* ------------------------------------------------------ */
  Ex: /* v2q15 Example */
  v2q15 a = {0x0fcb, 0x3a75};
  v2q15 b;
  b = (v2q15) {0.1234 * 32768.0, 0.4567 * 32768.0};

Data is stored from the right-to-left location of a register. For the example of v4i8 a = {1, 2, 3, 4}, the register stores 1, 2, 3, and 4 from the right-to-left location as shown below.

a[3]=4 a[2]=3 a[1]=2 a[0]=1
Bit 31 Bit 0

Most arithmetic operations will simply work on the SIMD operands in the register irrespective of their right-to-left location within the register. However, you must be aware of such instructions that directly refer to the left or right portions of a register. For example, MAQ_SA.W.PHL.