Add vsplit and vconcat instructions.
Add support for two new type variable functions: half_vector() and double_vector(). Use these two instructions to break down unsupported SIMD types and build them up again.
This commit is contained in:
@@ -264,6 +264,40 @@ fill = Instruction(
|
||||
# Vector operations
|
||||
#
|
||||
|
||||
x = Operand('x', TxN, doc='Vector to split')
|
||||
lo = Operand('lo', TxN.half_vector(), doc='Low-numbered lanes of `x`')
|
||||
hi = Operand('hi', TxN.half_vector(), doc='High-numbered lanes of `x`')
|
||||
|
||||
vsplit = Instruction(
|
||||
'vsplit', r"""
|
||||
Split a vector into two halves.
|
||||
|
||||
Split the vector `x` into two separate values, each containing half of
|
||||
the lanes from ``x``. The result may be two scalars if ``x`` only had
|
||||
two lanes.
|
||||
""",
|
||||
ins=x, outs=(lo, hi))
|
||||
|
||||
Any128 = TypeVar(
|
||||
'Any128', 'Any scalar or vector type with as most 128 lanes',
|
||||
ints=True, floats=True, bools=True, scalars=True, simd=(1, 128))
|
||||
x = Operand('x', Any128, doc='Low-numbered lanes')
|
||||
y = Operand('y', Any128, doc='High-numbered lanes')
|
||||
a = Operand('a', Any128.double_vector(), doc='Concatenation of `x` and `y`')
|
||||
|
||||
vconcat = Instruction(
|
||||
'vconcat', r"""
|
||||
Vector concatenation.
|
||||
|
||||
Return a vector formed by concatenating ``x`` and ``y``. The resulting
|
||||
vector type has twice as many lanes as each of the inputs. The lanes of
|
||||
``x`` appear as the low-numbered lanes, and the lanes of ``y`` become
|
||||
the high-numbered lanes of ``a``.
|
||||
|
||||
It is possible to form a vector by concatenating two scalars.
|
||||
""",
|
||||
ins=(x, y), outs=a)
|
||||
|
||||
c = Operand('c', TxN.as_bool(), doc='Controlling vector')
|
||||
x = Operand('x', TxN, doc='Value to use where `c` is true')
|
||||
y = Operand('y', TxN, doc='Value to use where `c` is false')
|
||||
|
||||
@@ -315,6 +315,8 @@ class TypeVar(object):
|
||||
ASBOOL = 'as_bool'
|
||||
HALFWIDTH = 'half_width'
|
||||
DOUBLEWIDTH = 'double_width'
|
||||
HALFVECTOR = 'half_vector'
|
||||
DOUBLEVECTOR = 'double_vector'
|
||||
|
||||
@staticmethod
|
||||
def derived(base, derived_func):
|
||||
@@ -396,6 +398,30 @@ class TypeVar(object):
|
||||
|
||||
return TypeVar.derived(self, self.DOUBLEWIDTH)
|
||||
|
||||
def half_vector(self):
|
||||
# type: () -> TypeVar
|
||||
"""
|
||||
Return a derived type variable that has half the number of vector lanes
|
||||
as this one, with the same lane type.
|
||||
"""
|
||||
if not self.is_derived:
|
||||
ts = self.type_set
|
||||
assert ts.min_lanes > 1, "Can't halve a scalar type"
|
||||
|
||||
return TypeVar.derived(self, self.HALFVECTOR)
|
||||
|
||||
def double_vector(self):
|
||||
# type: () -> TypeVar
|
||||
"""
|
||||
Return a derived type variable that has twice the number of vector
|
||||
lanes as this one, with the same lane type.
|
||||
"""
|
||||
if not self.is_derived:
|
||||
ts = self.type_set
|
||||
assert ts.max_lanes < 256, "Can't double 256 lanes."
|
||||
|
||||
return TypeVar.derived(self, self.DOUBLEVECTOR)
|
||||
|
||||
def free_typevar(self):
|
||||
# type: () -> TypeVar
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user