diff --git a/cranelift/docs/metaref.rst b/cranelift/docs/metaref.rst index c8f8b0e265..fe46e8af4a 100644 --- a/cranelift/docs/metaref.rst +++ b/cranelift/docs/metaref.rst @@ -15,15 +15,15 @@ module :mod:`cretonne.base`. .. module:: cretonne -Types -===== +Value Types +=========== -Concrete value types are represented as instances of :class:`cretonne.Type`. There are +Concrete value types are represented as instances of :class:`cretonne.ValueType`. There are subclasses to represent scalar and vector types. -.. inheritance-diagram:: Type ScalarType VectorType IntType FloatType +.. inheritance-diagram:: ValueType ScalarType VectorType IntType FloatType :parts: 1 -.. autoclass:: Type +.. autoclass:: ValueType .. autoclass:: ScalarType :members: .. autoclass:: VectorType @@ -48,33 +48,35 @@ types for their operands. This makes the instructions polymorphic. .. autoclass:: TypeVar -Immediates ----------- - -Immediate instruction operands don't correspond to SSA values, but have values -that are encoded directly in the instruction. Immediate operands don't -have types from the :class:`cretonne.Type` type system; they often have -enumerated values of a specific type. The type of an immediate operand is -indicated with an instance of :class:`ImmediateType`. - -.. autoclass:: ImmediateType - -.. automodule:: cretonne.immediates - :members: - -.. currentmodule:: cretonne - Instructions ============ New instructions are defined as instances of the :class:`cretonne.Instruction` class. -.. autoclass:: Operand .. autoclass:: Instruction +.. autoclass:: Operand +.. autoclass:: OperandKind .. autoclass:: InstructionGroup :members: + +Immediates +---------- + +Immediate instruction operands don't correspond to SSA values, but have values +that are encoded directly in the instruction. Immediate operands don't +have types from the :class:`cretonne.ValueType` type system; they often have +enumerated values of a specific type. The type of an immediate operand is +indicated with an instance of :class:`ImmediateKind`. + +.. autoclass:: ImmediateKind + +.. automodule:: cretonne.immediates + :members: + +.. currentmodule:: cretonne + Targets ======= diff --git a/meta/cretonne/__init__.py b/meta/cretonne/__init__.py index a4ef2830c0..26a3664c64 100644 --- a/meta/cretonne/__init__.py +++ b/meta/cretonne/__init__.py @@ -16,13 +16,75 @@ def camel_case(s): return camel_re.sub(lambda m: m.group(2).upper(), s) -# Concrete types. +# Kinds of operands. # -# Instances (i8, i32, ...) are provided in the cretonne.types module. +# Each instruction has an opcode and a number of operands. The opcode +# determines the instruction format, and the format determines the number of +# operands and the kind of each operand. +class OperandKind(object): + """ + The kind of an operand. + + An instance of the `OperandKind` class corresponds to a kind of operand. + Each operand kind has a corresponding type in the Rust representation of an + instruction. + """ + + def __init__(self, name, doc): + self.name = name + self.__doc__ = doc + # The camel-cased name of an operand kind is also the Rust type used to + # represent it. + self.camel_name = camel_case(name) + + def __str__(self): + return self.name + + def __repr__(self): + return 'OperandKind({})'.format(self.name) -class Type(object): - """A concrete value type.""" +#: An SSA value operand. This is a value defined by another instruction. +value = OperandKind( + 'value', """ + An SSA value defined by another instruction. + + This kind of operand can represent any SSA value type, but the + instruction format may restrict the valid value types for a given + operand. + """) + + +# Instances of immediate operand types are provided in the cretonne.immediates +# module. +class ImmediateKind(OperandKind): + """ + The type of an immediate instruction operand. + """ + + def __init__(self, name, doc): + self.name = name + self.__doc__ = doc + + def __repr__(self): + return 'ImmediateKind({})'.format(self.name) + + def operand_kind(self): + """ + An `ImmediateKind` instance can be used directly as the type of an + `Operand` when defining an instruction. + """ + return self + + +# ValueType instances (i8, i32, ...) are provided in the cretonne.types module. +class ValueType(object): + """ + A concrete SSA value type. + + All SSA values have a type that is described by an instance of `ValueType` + or one of its subclasses. + """ def __init__(self, name, membytes, doc): self.name = name @@ -32,8 +94,15 @@ class Type(object): def __str__(self): return self.name + def operand_kind(self): + """ + When a `ValueType` object is used to describe the type of an `Operand` + in an instruction definition, the kind of that operand is an SSA value. + """ + return value -class ScalarType(Type): + +class ScalarType(ValueType): """ A concrete scalar (not vector) type. @@ -62,7 +131,7 @@ class ScalarType(Type): return v -class VectorType(Type): +class VectorType(ValueType): """ A concrete SIMD vector type. @@ -144,27 +213,12 @@ class TypeVar(object): self.name = name self.__doc__ = doc - -# Immediate operands. -# -# Instances of immediate operand types are provided in the cretonne.immediates -# module. - - -class ImmediateType(object): - """ - The type of an immediate instruction operand. - """ - - def __init__(self, name, doc): - self.name = name - self.__doc__ = doc - - def __str__(self): - return self.name - - def __repr__(self): - return 'ImmediateType({})'.format(self.name) + def operand_kind(self): + """ + When a `TypeVar` object is used to describe the type of an `Operand` + in an instruction definition, the kind of that operand is an SSA value. + """ + return value # Defining instructions. @@ -225,14 +279,14 @@ class Operand(object): An instruction operand can be either an *immediate* or an *SSA value*. The type of the operand is one of: - 1. A :py:class:`Type` instance indicates an SSA value operand with a + 1. A :py:class:`ValueType` instance indicates an SSA value operand with a concrete type. 2. A :py:class:`TypeVar` instance indicates an SSA value operand, and the instruction is polymorphic over the possible concrete types that the type variable can assume. - 3. An :py:class:`ImmediateType` instance indicates an immediate operand + 3. An :py:class:`ImmediateKind` instance indicates an immediate operand whose value is encoded in the instruction itself rather than being passed as an SSA value. @@ -241,6 +295,7 @@ class Operand(object): self.name = name self.typ = typ self.__doc__ = doc + self.kind = typ.operand_kind() def get_doc(self): if self.__doc__: @@ -251,7 +306,7 @@ class Operand(object): class Instruction(object): """ - An instruction. + An instruction description. The operands to the instruction are specified as two tuples: ``ins`` and ``outs``. Since the Python singleton tuple syntax is a bit awkward, it is diff --git a/meta/cretonne/base.py b/meta/cretonne/base.py index 033be2c148..412e7f3abd 100644 --- a/meta/cretonne/base.py +++ b/meta/cretonne/base.py @@ -277,10 +277,11 @@ ishl = Instruction( When shifting a B-bits integer type, this instruction computes: .. math:: - s &:= y \pmod B, \\ - a &:= x \cdot 2^s \pmod{2^B}. + s &:= y \pmod B, \\ + a &:= x \cdot 2^s \pmod{2^B}. .. todo:: Add ``ishl_imm`` variant with an immediate ``y``. + """, ins=(x, y), outs=a) @@ -295,8 +296,8 @@ ushr = Instruction( When shifting a B-bits integer type, this instruction computes: .. math:: - s &:= y \pmod B, \\ - a &:= \lfloor x \cdot 2^{-s} \rfloor. + s &:= y \pmod B, \\ + a &:= \lfloor x \cdot 2^{-s} \rfloor. .. todo:: Add ``ushr_imm`` variant with an immediate ``y``. """, diff --git a/meta/cretonne/immediates.py b/meta/cretonne/immediates.py index 2735cd6be1..af7bd72feb 100644 --- a/meta/cretonne/immediates.py +++ b/meta/cretonne/immediates.py @@ -1,25 +1,25 @@ """ -The cretonne.immdiates module predefines all the Cretonne immediate operand +The cretonne.immediates module predefines all the Cretonne immediate operand types. """ -from . import ImmediateType +from . import ImmediateKind #: A 64-bit immediate integer operand. #: #: This type of immediate integer can interact with SSA values with any #: :py:class:`cretonne.IntType` type. -imm64 = ImmediateType('imm64', 'A 64-bit immediate integer.') +imm64 = ImmediateKind('imm64', 'A 64-bit immediate integer.') #: A 32-bit immediate floating point operand. #: #: IEEE 754-2008 binary32 interchange format. -ieee32 = ImmediateType('ieee32', 'A 32-bit immediate floating point number.') +ieee32 = ImmediateKind('ieee32', 'A 32-bit immediate floating point number.') #: A 64-bit immediate floating point operand. #: #: IEEE 754-2008 binary64 interchange format. -ieee64 = ImmediateType('ieee64', 'A 64-bit immediate floating point number.') +ieee64 = ImmediateKind('ieee64', 'A 64-bit immediate floating point number.') #: A large SIMD vector constant. -immvector = ImmediateType('immvector', 'An immediate SIMD vector.') +immvector = ImmediateKind('immvector', 'An immediate SIMD vector.')