""" Cretonne meta language module. This module provides classes and functions used to describe Cretonne instructions. """ # Concrete types. # # Instances (i8, i32, ...) are provided in the cretonne.types module. class Type(object): """A concrete value type.""" def __init__(self, name, membytes, doc): self.name = name self.membytes = membytes self.__doc__ = doc def __str__(self): return self.name class ScalarType(Type): """ A concrete scalar (not vector) type. Also tracks a unique set of :py:class:`VectorType` instances with this type as the lane type. """ def __init__(self, name, membytes, doc): super(ScalarType, self).__init__(name, membytes, doc) self._vectors = dict() def __repr__(self): return 'ScalarType({})'.format(self.name) def by(self, lanes): """ Get a vector type with this type as the lane type. For example, ``i32.by(4)`` returns the :obj:`i32x4` type. """ if lanes in self._vectors: return self._vectors[lanes] else: v = VectorType(self, lanes) self._vectors[lanes] = v return v class VectorType(Type): """ A concrete SIMD vector type. A vector type has a lane type which is an instance of :class:`ScalarType`, and a positive number of lanes. """ def __init__(self, base, lanes): assert isinstance(base, ScalarType), 'SIMD lanes must be scalar types' super(VectorType, self).__init__( name='{}x{}'.format(base.name, lanes), membytes=lanes*base.membytes, doc=""" A SIMD vector with {} lanes containing a {} each. """.format(lanes, base.name)) self.base = base self.lanes = lanes def __repr__(self): return 'VectorType(base={}, lanes={})'.format(self.base.name, self.lanes) class IntType(ScalarType): """A concrete scalar integer type.""" def __init__(self, bits): assert bits > 0, 'IntType must have positive number of bits' super(IntType, self).__init__( name='i{:d}'.format(bits), membytes=bits/8, doc="An integer type with {} bits.".format(bits)) self.bits = bits def __repr__(self): return 'IntType(bits={})'.format(self.bits) class FloatType(ScalarType): """A concrete scalar floating point type.""" def __init__(self, bits, doc): assert bits > 0, 'FloatType must have positive number of bits' super(FloatType, self).__init__( name='f{:d}'.format(bits), membytes=bits/8, doc=doc) self.bits = bits def __repr__(self): return 'FloatType(bits={})'.format(self.bits) # # Parametric polymorphism. # class TypeVar(object): """ A Type Variable. Type variables can be used in place of concrete types when defining instructions. This makes the instructions *polymorphic*. """ def __init__(self, name): self.name = name