Casting intrinsic functions (
as_[Type]()) allow casting between vector types or scalar types of the
same size. The casting can work on accumulator vector types too. Generally, using
the smallest data type possible will reduce register spillage and improve
performance. For example, if a 48-bit accumulator (acc48) can meet the design
requirements then it is preferable to use that instead of a larger 80-bit
acc80vector data type occupies two neighboring 48-bit lanes.
Standard C casts can be also used and works identically in almost all cases as shown in the following example.
v8int16 iv; v4cint16 cv=as_v4cint16(iv); v4cint16 cv2=*(v4cint16*)&iv; v8acc80 cas_iv; v8cacc48 cas_cv=as_v8cacc48(cas_iv);
There is hardware support built-in for floating-point to fixed-point
float2fix()) and fixed-point to floating-point
fix2float()) conversions. For example, the
fixed-point square root, inverse square root, and inverse are implemented with
floating point precision and the
float2fix() conversions are used before and
after the function.
The scalar engine is used in this example because the square root and inverse functions are not vectorizable. This can be verified by looking at the function prototype's input data types:
float _sqrtf(float a) //scalar float operation int sqrt(int a,...) //scalar integer operation
Note that the input data types are scalar types (int) and not vector types (vint).
The conversion functions (
float2fix) can be handled by either the vector
or scalar engines depending on the function called. Note the difference in data
return type and data argument types:
float fix2float(int n,...) //Uses the scalar engine v8float fix2float(v8int32 ivec,...) //Uses the vector engine
float2fix, there are two types of implementations,
float2fix_safeimplementation offering a more strict data type check. You can define the macro