diff --git a/cranelift/docs/conf.py b/cranelift/docs/conf.py index 120d32011a..0b7f7667d8 100644 --- a/cranelift/docs/conf.py +++ b/cranelift/docs/conf.py @@ -21,6 +21,10 @@ import shlex # documentation root, use os.path.abspath to make it absolute, like shown here. sys.path.insert(0, os.path.abspath('.')) +# Also add the meta directory to sys.path so autodoc can find the Cretonne meta +# language definitions. +sys.path.insert(0, os.path.abspath('../meta')) + # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. diff --git a/cranelift/docs/index.rst b/cranelift/docs/index.rst index 668b055c97..88d9257213 100644 --- a/cranelift/docs/index.rst +++ b/cranelift/docs/index.rst @@ -7,6 +7,7 @@ Contents: :maxdepth: 2 langref + metaref Indices and tables ================== diff --git a/cranelift/docs/metaref.rst b/cranelift/docs/metaref.rst new file mode 100644 index 0000000000..42a471cc93 --- /dev/null +++ b/cranelift/docs/metaref.rst @@ -0,0 +1,33 @@ +******************************** +Cretonne Meta Language Reference +******************************** + +.. default-domain:: py +.. highlight:: python + +The Cretonne meta language is used to define instructions for Cretonne. It is a +domain specific language embedded in Python. + +An instruction set is described by a Python module under the :file:`meta` +directory that has a global variable called ``instructions``. The basic +Cretonne instruction set described in :doc:`langref` is defined by the Python +module :mod:`cretonne.instrs`. + +Types +===== + +Concrete value types are represented as instances of :class:`cretonne.Type`. There are +subclasses to represent scalar and vector types. + +.. autoclass:: cretonne.Type +.. autoclass:: cretonne.ScalarType + :members: +.. autoclass:: cretonne.VectorType + :members: +.. autoclass:: cretonne.IntType + :members: +.. autoclass:: cretonne.FloatType + :members: +.. automodule:: cretonne.types + :members: + diff --git a/meta/cretonne/__init__.py b/meta/cretonne/__init__.py new file mode 100644 index 0000000000..9133f8e062 --- /dev/null +++ b/meta/cretonne/__init__.py @@ -0,0 +1,83 @@ +""" +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 __str__(self): + return self.name + +class ScalarType(Type): + """ + A concrete scalar (not vector) type. + + Also tracks a unique set of :class:`VectorType` instances with this type as + the lane type. + """ + + def __init__(self, name): + self.name = name + 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' + self.base = base + self.lanes = lanes + self.name = '{}x{}'.format(base.name, 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__('i{:d}'.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): + assert bits > 0, 'FloatType must have positive number of bits' + super(FloatType, self).__init__('f{:d}'.format(bits)) + self.bits = bits + + def __repr__(self): + return 'FloatType(bits={})'.format(self.bits) diff --git a/meta/cretonne/types.py b/meta/cretonne/types.py new file mode 100644 index 0000000000..382fe0def2 --- /dev/null +++ b/meta/cretonne/types.py @@ -0,0 +1,20 @@ +"""Predefined types.""" + +from . import ScalarType, IntType, FloatType + +#: A boolean value. +bool = ScalarType('bool') + +i8 = IntType(8) #: 8-bit int. +i16 = IntType(16) #: 16-bit int. +i32 = IntType(32) #: 32-bit int. +i64 = IntType(64) #: 64-bit int. + +f32 = FloatType(32) #: IEEE 32-bit float. +f64 = FloatType(64) #: IEEE 64-bit float + +i8x16 = i8.by(16) #: Vector of 16 i8 lanes. + +f32x4 = f32.by(4) #: Vector of 4 f32 lanes. +f64x2 = f64.by(2) #: Vector of 2 f64 lanes. +