Browse Source

Add OperandKind to the meta language.

We have a two-level type system: OperandKinds and ValueTypes. The value types
only apply to value operands, but there are many more kinds of operands:
immediate numbers, condition codes, basic block references, etc.
pull/1019/head
Jakob Stoklund Olesen 9 years ago
parent
commit
477fa01bfc
  1. 40
      cranelift/docs/metaref.rst
  2. 115
      meta/cretonne/__init__.py
  3. 9
      meta/cretonne/base.py
  4. 12
      meta/cretonne/immediates.py

40
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
Instructions
============
New instructions are defined as instances of the :class:`cretonne.Instruction`
class.
.. 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.Type` type system; they often have
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:`ImmediateType`.
indicated with an instance of :class:`ImmediateKind`.
.. autoclass:: ImmediateType
.. autoclass:: ImmediateKind
.. automodule:: cretonne.immediates
:members:
.. currentmodule:: cretonne
Instructions
============
New instructions are defined as instances of the :class:`cretonne.Instruction`
class.
.. autoclass:: Operand
.. autoclass:: Instruction
.. autoclass:: InstructionGroup
:members:
Targets
=======

115
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)
#: 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.
class Type(object):
"""A concrete 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

9
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``.
""",

12
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.')

Loading…
Cancel
Save