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.
This commit is contained in:
@@ -15,15 +15,15 @@ module :mod:`cretonne.base`.
|
|||||||
|
|
||||||
.. module:: cretonne
|
.. 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.
|
subclasses to represent scalar and vector types.
|
||||||
|
|
||||||
.. inheritance-diagram:: Type ScalarType VectorType IntType FloatType
|
.. inheritance-diagram:: ValueType ScalarType VectorType IntType FloatType
|
||||||
:parts: 1
|
:parts: 1
|
||||||
.. autoclass:: Type
|
.. autoclass:: ValueType
|
||||||
.. autoclass:: ScalarType
|
.. autoclass:: ScalarType
|
||||||
:members:
|
:members:
|
||||||
.. autoclass:: VectorType
|
.. autoclass:: VectorType
|
||||||
@@ -48,33 +48,35 @@ types for their operands. This makes the instructions polymorphic.
|
|||||||
|
|
||||||
.. autoclass:: TypeVar
|
.. 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
|
Instructions
|
||||||
============
|
============
|
||||||
|
|
||||||
New instructions are defined as instances of the :class:`cretonne.Instruction`
|
New instructions are defined as instances of the :class:`cretonne.Instruction`
|
||||||
class.
|
class.
|
||||||
|
|
||||||
.. autoclass:: Operand
|
|
||||||
.. autoclass:: Instruction
|
.. autoclass:: Instruction
|
||||||
|
.. autoclass:: Operand
|
||||||
|
.. autoclass:: OperandKind
|
||||||
.. autoclass:: InstructionGroup
|
.. autoclass:: InstructionGroup
|
||||||
:members:
|
: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
|
Targets
|
||||||
=======
|
=======
|
||||||
|
|
||||||
|
|||||||
@@ -16,13 +16,75 @@ def camel_case(s):
|
|||||||
return camel_re.sub(lambda m: m.group(2).upper(), 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):
|
#: An SSA value operand. This is a value defined by another instruction.
|
||||||
"""A concrete value type."""
|
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):
|
def __init__(self, name, membytes, doc):
|
||||||
self.name = name
|
self.name = name
|
||||||
@@ -32,8 +94,15 @@ class Type(object):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
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.
|
A concrete scalar (not vector) type.
|
||||||
|
|
||||||
@@ -62,7 +131,7 @@ class ScalarType(Type):
|
|||||||
return v
|
return v
|
||||||
|
|
||||||
|
|
||||||
class VectorType(Type):
|
class VectorType(ValueType):
|
||||||
"""
|
"""
|
||||||
A concrete SIMD vector type.
|
A concrete SIMD vector type.
|
||||||
|
|
||||||
@@ -144,27 +213,12 @@ class TypeVar(object):
|
|||||||
self.name = name
|
self.name = name
|
||||||
self.__doc__ = doc
|
self.__doc__ = doc
|
||||||
|
|
||||||
|
def operand_kind(self):
|
||||||
# Immediate operands.
|
|
||||||
#
|
|
||||||
# Instances of immediate operand types are provided in the cretonne.immediates
|
|
||||||
# module.
|
|
||||||
|
|
||||||
|
|
||||||
class ImmediateType(object):
|
|
||||||
"""
|
"""
|
||||||
The type of an immediate instruction operand.
|
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
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
# Defining instructions.
|
# Defining instructions.
|
||||||
@@ -225,14 +279,14 @@ class Operand(object):
|
|||||||
An instruction operand can be either an *immediate* or an *SSA value*. The
|
An instruction operand can be either an *immediate* or an *SSA value*. The
|
||||||
type of the operand is one of:
|
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.
|
concrete type.
|
||||||
|
|
||||||
2. A :py:class:`TypeVar` instance indicates an SSA value operand, and the
|
2. A :py:class:`TypeVar` instance indicates an SSA value operand, and the
|
||||||
instruction is polymorphic over the possible concrete types that the
|
instruction is polymorphic over the possible concrete types that the
|
||||||
type variable can assume.
|
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
|
whose value is encoded in the instruction itself rather than being
|
||||||
passed as an SSA value.
|
passed as an SSA value.
|
||||||
|
|
||||||
@@ -241,6 +295,7 @@ class Operand(object):
|
|||||||
self.name = name
|
self.name = name
|
||||||
self.typ = typ
|
self.typ = typ
|
||||||
self.__doc__ = doc
|
self.__doc__ = doc
|
||||||
|
self.kind = typ.operand_kind()
|
||||||
|
|
||||||
def get_doc(self):
|
def get_doc(self):
|
||||||
if self.__doc__:
|
if self.__doc__:
|
||||||
@@ -251,7 +306,7 @@ class Operand(object):
|
|||||||
|
|
||||||
class Instruction(object):
|
class Instruction(object):
|
||||||
"""
|
"""
|
||||||
An instruction.
|
An instruction description.
|
||||||
|
|
||||||
The operands to the instruction are specified as two tuples: ``ins`` and
|
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
|
``outs``. Since the Python singleton tuple syntax is a bit awkward, it is
|
||||||
|
|||||||
@@ -281,6 +281,7 @@ ishl = Instruction(
|
|||||||
a &:= x \cdot 2^s \pmod{2^B}.
|
a &:= x \cdot 2^s \pmod{2^B}.
|
||||||
|
|
||||||
.. todo:: Add ``ishl_imm`` variant with an immediate ``y``.
|
.. todo:: Add ``ishl_imm`` variant with an immediate ``y``.
|
||||||
|
|
||||||
""",
|
""",
|
||||||
ins=(x, y), outs=a)
|
ins=(x, y), outs=a)
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
types.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from . import ImmediateType
|
from . import ImmediateKind
|
||||||
|
|
||||||
#: A 64-bit immediate integer operand.
|
#: A 64-bit immediate integer operand.
|
||||||
#:
|
#:
|
||||||
#: This type of immediate integer can interact with SSA values with any
|
#: This type of immediate integer can interact with SSA values with any
|
||||||
#: :py:class:`cretonne.IntType` type.
|
#: :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.
|
#: A 32-bit immediate floating point operand.
|
||||||
#:
|
#:
|
||||||
#: IEEE 754-2008 binary32 interchange format.
|
#: 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.
|
#: A 64-bit immediate floating point operand.
|
||||||
#:
|
#:
|
||||||
#: IEEE 754-2008 binary64 interchange format.
|
#: 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.
|
#: A large SIMD vector constant.
|
||||||
immvector = ImmediateType('immvector', 'An immediate SIMD vector.')
|
immvector = ImmediateKind('immvector', 'An immediate SIMD vector.')
|
||||||
|
|||||||
Reference in New Issue
Block a user