6.5Operators
Expressions within a kernel function can use many standard C operators. Some operators map to a single DPU intrinsic operation; the Intrinsic operations section below gives an overview of intrinsics, and the Stream Reference Manual gives a detailed description of each intrinsic. For example:
vec int16x2 a, b, x;
x = a + b; // equivalent to x = spi_vadd16i(a, b);
This does just what the programmer expects: it performs two signed 16-bit additions in each lane (one in each halfword of each lane). Because of its SIMD architecture, the DPU performs computations in each lane simultaneously, and therefore the value of a vector expression differs in each lane. This operation requires only a single intrinsic.
Some operators map to multiple intrinsics. For example, the DPU does not support 32-bit by 32-bit multiplication:
vec int32x1 a, b, x;
x = a * b; // requires multiple DPU operations
This generates multiple operations to perform the required multiplication. Similarly, DPU intrinsics for relational operators return all 0 bits or all 1 bits rather than the C relational values of 0 or 1, so
vec int16x2 a, b, x;
x = (a != b); // requires multiple DPU operations
generates multiple operations rather than simply calling intrinsic spi_vne16. See section DPU booleans above for additional information about relational operators and DPU boolean intrinsics.
Kernel functions may not use all C operators. The Kernel intrinsic functions section of the Stream Reference Manual contains additional details about each operator, including argument type information. Supported operators in kernel expressions include:
Operator
|
Description
|
Related intrinsics
|
.
|
member extraction
|
|
[ ]
|
array subscripting
|
|
+ (unary)
|
unary plus
|
|
- (unary)
|
negation
|
spi_vsub
|
+ (binary)
|
addition
|
spi_vadd
|
- (binary)
|
subtraction
|
spi_vsub
|
* (binary)
|
multiplication
|
spi_vmul*
|
/
|
division
|
spi_vdivstep
|
%
|
remainder (modulus)
|
spi_vdivstep
|
<<, >>
|
bitwise shifts
|
spi_vshift, spi_vshifta
|
++, --
|
increment/decrement (prefix and postfix)
|
|
==, !=, <, >, <=, >=
|
relations
|
|
~
|
bitwise complement
|
spi_vnot
|
& (binary), |, ^
|
bitwise operators
|
spi_vand, spi_vor, spi_vxor
|
&&, ||
[N.B.: modified behavior, see below!]
|
logical operators
|
|
!
|
logical negation
|
|
? :
[N.B.: modified behavior, see below!]
|
conditional
|
spi_vselect
|
(type)
|
casts
|
|
=
|
assignment
|
|
In kernel expressions, the ‘&&’ and ‘||’ operators do not use the C evaluation “short circuit” rules; the second argument is always evaluated, regardless of the value of the first argument. Similarly, ternary operator ‘?:’ does not use the C evaluation “short circuit” rule; both the second and third arguments are always evaluated, regardless of the value of the first argument. If ‘?:’ arguments contain side effects (e.g., assignments), the result is undefined.
Some C operators are not supported within kernel functions. These include:
sizeof
|
sizeof
|
->
|
pointer dereference
|
& (unary)
|
address of
|
* (unary)
|
indirection
|
Share with your friends: |