SPRUI04F july 2015 – april 2023
Through the use of MUST_ITERATE and _nassert, you can guarantee that a loop executes a certain number of times.
This example tells the compiler that the loop is guaranteed to run exactly 10 times:
#pragma MUST_ITERATE(10,10);
for (I = 0; I < trip_count; I++) { ...
MUST_ITERATE can also be used to specify a range for the trip count as well as a factor of the trip count. For example:
#pragma MUST_ITERATE(8,48,8);
for (I = 0; I < trip; I++) { ...
This example tells the compiler that the loop executes between 8 and 48 times and that the trip variable is a multiple of 8 (8, 16, 24, 32, 40, 48). The compiler can now use all this information to generate the best loop possible by unrolling better even when the --interrupt_thresholdn option is used to specify that interrupts do occur every n cycles.
The TMS320C6000 Programmer's Guide states that one of the ways to refine C/C++ code is to use word accesses to operate on 16-bit data stored in the high and low parts of a 32-bit register. Examples using casts to int pointers are shown with the use of intrinsics to use certain instructions like _mpyh. This can be automated by using the _nassert(); intrinsic to specify that 16-bit short arrays are aligned on a 32-bit (word) boundary.
The following examples generate the same assembly code:
int dot_product(short *x, short *y, short z)
{
int *w_x = (int *)x;
int *w_y = (int *)y;
int sum1 = 0, sum2 = 0, I;
for (I = 0; I < z/2; I++)
{
sum1 += _mpy(w_x[i], w_y[i]);
sum2 += _mpyh(w_x[i], w_y[i]);
}
return (sum1 + sum2);
}
int dot_product(short *x, short *y, short z)
{
int sum = 0, I;
_nassert (((int)(x) & 0x3) == 0);
_nassert (((int)(y) & 0x3) == 0);
#pragma MUST_ITERATE(20, , 4);
for (I = 0; I < z; I++) sum += x[i] * y[i];
return sum;
}
In C++ code, _nassert is part of the standard namespace. Thus, the correct syntax is std::_nassert().