Using the Stream Address Generator

Similar to the SE, once the stream address generator (SA) has been configured, a corresponding SA can be opened and used. The following API is provided to facilitate this, which takes the parameter template as input:

The Stream Address Generators are accessed using the following API. Note that for Stream Address Generators, the base address is given as an input to the read operation, and the return value is a pointer to the location that is then used by a memory load or memory store operation. This is because, unlike the SE, an SA simply provides an offset added to the given base address. The given type is used to cast the type of the data loaded or stored through the SA.

Stream Address Generators are closed using the corresponding close API:

When the accessor APIs shown above are used by themselves, the compiler will match a basic load or store operation for them, depending on whether they are on the left-hand-side (LHS) or right-hand-side (RHS) of an assignment operator.

The following is an example of an SA-returned pointer dereferenced by itself on both the LHS and RHS to copy data from one location to another. Because the SA returns a pointer, dereferencing it on the RHS generates a load, and dereferencing it on the LHS generates a store.

// OPEN THE STREAMS, SA0 AND SA1 __SA0_OPEN(params); __SA1_OPEN(params); // COPY DATA FROM *(src_addr+SA1) TO *(dst_addr+SA0) for (I0 = 0; I0 < 8; I0++) { // COMPILER MATCHES VECTOR LOAD AND STORE FOR FOUR WORD DATA *__SA0ADV(uint8, dst_addr) = *__SA1ADV(uint8, src_addr); } // CLOSE THE STREAMS __SA0_CLOSE(); __SA1_CLOSE();

However, the SA accessor APIs can also be given as input to a load or store intrinsic, as in the following example. In this case, since the SA simply returns a pointer that is not dereferenced, the compiler will not attempt to match a corresponding basic vector load or store and will instead use the load or store indicated by the intrinsic.

// OPEN THE STREAMS, SA0 AND SA1 __SA0_OPEN(params); __SA1_OPEN(params); // COPY DATA (WITH UNPACK + PACK) FROM *(src_addr+SA1) TO *(dst_addr+SA0) for (I0 = 0; I0 < 8; I0++) { ulong8 data = __vload_unpack_long(__SA1ADV(uint8, src_addr)); __vstore_packl(__SA0ADV(uint8, dst_addr), data); } // CLOSE THE STREAMS __SA0_CLOSE(); __SA1_CLOSE();

NOTE

If the Stream Address Generator is used with a base pointer that is flagged as restrict, then derivations based on that pointer (base + offset), as calculated by the SA, are also assumed to be restrict. This means that SA-generated pointers, and all loads and stores that use them, are not assumed to alias other memory pointers.

Therefore, using the SA based on restrict base pointers implies a contract in which the program promises never or modify the data in any area of memory that can be reached by that stream address generator during its lifetime.