vconvert ( from-type to-type -- quot )
SIMD vector conversion


Vocabulary
math.vectors.conversion

Inputs
from-typea SIMD type
to-typea SIMD type


Outputs
None

Word description
Converts SIMD vectors of from-type to to-type. The number of inputs and outputs depends on the relationship of the two types:
If to-type is a floating-point vector type with the same byte length and element count as the integer vector type from-type (for example, from int-4 to float-4 or from longlong-2 to double-2), vconvert takes one vector of from-type and converts its elements to floating-point, outputting one vector of to-type.
Likewise, if to-type is an integer vector type with the same byte length and element count as the floating-point vector type from-type, vconvert takes one vector of from-type and truncates its elements to integers, outputting one vector of to-type.
If to-type is a vector type with the same byte length as and twice the element count of the vector type from-type (for example, from int-4 to ushort-8, from double-2 to float-4, or from short-8 to char-16), vconvert takes two vectors of from-type and packs them into one vector of to-type, saturating values too large or small to be representable as elements of to-type.
If to-type is a vector type with the same byte length as and half the element count of the vector type from-type (for example, from ushort-8 to int-4, from float-4 to double-2, or from char-16 to short-8), vconvert takes one vector of from-type and unpacks it into two vectors of to-type.

from-type and to-type must adhere to the following restrictions; a bad-vconvert error will be thrown otherwise:
from-type and to-type must have the same byte length. You cannot currently convert between 128- and 256-bit vector types.
For conversions between floating-point and integer vectors, from-type and to-type must have the same element length.
For packing conversions, from-type and to-type must be both floating-point or both integer types. Integer types can be packed from signed to unsigned or from unsigned to unsigned types. Unsigned to signed packing is invalid.
For unpacking conversions, from-type and to-type must be both floating-point or both integer types. Integer types can be unpacked from unsigned to signed or from unsigned to unsigned types. Signed to unsigned unpacking is invalid.


Examples
Conversion between integer and float vectors:
USING: alien.c-types math.vectors.conversion math.vectors.simd prettyprint ; int-4{ 0 1 2 3 } int-4 float-4 vconvert . double-2{ 1.25 3.75 } double-2 longlong-2 vconvert .
float-4{ 0.0 1.0 2.0 3.0 } longlong-2{ 1 3 }

Packing conversions:
USING: alien.c-types math.vectors.conversion math.vectors.simd prettyprint ; int-4{ -8 70000 6000 50 } int-4{ 4 3 2 -1 } int-4 ushort-8 vconvert . double-2{ 0.0 1.0e100 } double-2{ -1.0e100 0.0 } double-2 float-4 vconvert .
ushort-8{ 0 65535 6000 50 4 3 2 0 } float-4{ 0.0 1/0. -1/0. 0.0 }

Unpacking conversions:
USING: alien.c-types kernel math.vectors.conversion math.vectors.simd prettyprint ; uchar-16{ 8 70 60 50 4 30 200 1 9 10 110 102 133 143 115 0 } uchar-16 short-8 vconvert [ . ] bi@
short-8{ 8 70 60 50 4 30 200 1 } short-8{ 9 10 110 102 133 143 115 0 }


Definition


MACRO:: vconvert ( from-type to-type -- quot )
from-type new [ simd-element-type ] [ byte-length ] bi
:> ( from-element from-length ) to-type new
[ simd-element-type ] [ byte-length ] bi
:> ( to-element to-length ) from-element heap-size
:> from-size to-element heap-size :> to-size from-length
to-length = [ from-type to-type bad-vconvert ] unless
from-element to-element from-size to-size from-type to-type
{
{ [ from-size to-size < ] [ [vunpack] ] }
{ [ from-size to-size = ] [ [vconvert] ] }
{ [ from-size to-size > ] [ [vpack] ] }
} cond ;