SPRUIG8J January 2018 – March 2024
The Streaming Address Generators (SA) may be configured to cause the generation of SA vector predicates containing 0s that may be used to mask part of a load or store. When the SA is configured this way and a load or store is based on the SA, it is unspecified whether vector predication will be applied to the operation unless vector predication is explicitly specified in the program source code.
The following definitions apply to the code examples for SA and memory operations in this section:
Given these definitions, predicated operations are actually a super-set of unpredicated operations, because all unpredicated operations can be represented as predicated operations.
A pointer P1 is defined as based
on another pointer P2 if the value of P1 is derived from P2. For example, if
ptr = __SA0()
, then ptr
is based on SA0.
Similarly, if ptr1 = __SA0()
and ptr2 = (ptr1 +
0)
, both ptr1
and ptr2
are based on SA0.
The following C examples show various store and load operations. For each operation type, examples that produce well-defined or unspecified behavior are shown for SA configurations that either require unpredicated operations or allow predicated operations.
Store operations
*__SA0ADV(int16, baseptr) = data; // Normal store
__vstore_packl(__SA0ADV(int8, baseptr), data); // Specialized store
int16 *ptr = __SA0ADV(int16, baseptr);
*ptr = data;
None, because the SA is configured for unpredicated operations only. The predicated store operations shown below are also well-defined with this configuration, although they may be slower.
__vpred vp = __SA0_VPRED(int16);
int16 *ptr = __SA0ADV(int16, baseptr);
__vstore_pred(vp, ptr, data); // Normal store with explicit predication
__vpred vp = __SA0_VPRED(int8);
int8 *ptr = __SA0ADV(int8, baseptr);
__vstore_pred_packl(vp, ptr, data); // Specialized store with explicit predication
*__SA0ADV(int16, baseptr) = data; // May be predicated
__vstore_packl(__SA0ADV(int8, baseptr), data); // May be predicated
int16 *ptr = __SA0ADV(int16, baseptr);
*ptr = data; // May be predicated
Load operations
int16 x = *__SA0ADV(int16, baseptr); // Normal load
ushort32 x = __vload_unpack_short(__SA0ADV(uchar32, baseptr); // Specialized load
int16 *ptr = __SA0ADV(int16, baseptr);
int16 x = *ptr;
None, because the SA is configured for unpredicated operations. The predicated load operations shown below are also well-defined with this configuration, although they may be slower.
__vpred vp = __SA0_VPRED(int16);
int16 x = *__SA0ADV(int16, baseptr); // Normal load
x = select(vp, x, (int16)(0)); // Apply predication
__vpred vp = __SA0_VPRED(int16);
int16 *ptr = __SA0ADV(int16, baseptr);
int16 x = __vload_pred(vp, ptr); // Normal load, explicit predication
__vpred vp = __SA0_VPRED(uchar32);
uchar32 *ptr = __SA0ADV(uchar32, baseptr);
ushort32 x = __vload_pred_unpack_short(vp, ptr); // Specialized load, explicit predication
int16 x = *__SA0ADV(int16, baseptr); // May be predicated
ushort32 x = __vload_unpack_short(__SA0ADV(uchar32, baseptr); // May be predicated
int16 *ptr = __SA0ADV(int16, baseptr);
int16 x = *ptr // May be predicated