Allow for instructions with operands in encodings.

When defining an instruction encoding, allow part of the instruction
predicate to be provided as operands on the instruction opcode:

    icmp.i32(intcc.ult, x, y)

This generates an instruction predicate that checks

    IntCompare.cond == IntCC::UnsignedLessThan
This commit is contained in:
Jakob Stoklund Olesen
2017-03-31 11:58:59 -07:00
parent 3c3d068379
commit ebc418d25e

View File

@@ -2,18 +2,23 @@
from __future__ import absolute_import from __future__ import absolute_import
from .predicates import And from .predicates import And
from .registers import RegClass, Register from .registers import RegClass, Register
from .ast import Apply
# The typing module is only required by mypy, and we don't use these imports # The typing module is only required by mypy, and we don't use these imports
# outside type comments. # outside type comments.
try: try:
from typing import Tuple, Union, Any, Iterable, Sequence, List, Set, TYPE_CHECKING # noqa from typing import Tuple, Union, Any, Iterable, Sequence, List, Set, TYPE_CHECKING # noqa
from .instructions import MaybeBoundInst, InstructionGroup, InstructionFormat # noqa if TYPE_CHECKING:
from .predicates import PredNode # noqa from .instructions import MaybeBoundInst, InstructionGroup, InstructionFormat # noqa
from .settings import SettingGroup # noqa from .predicates import PredNode # noqa
from .types import ValueType # noqa from .settings import SettingGroup # noqa
from .registers import RegBank # noqa from .types import ValueType # noqa
OperandConstraint = Union[RegClass, Register, int] from .registers import RegBank # noqa
ConstraintSeq = Union[OperandConstraint, Tuple[OperandConstraint, ...]] OperandConstraint = Union[RegClass, Register, int]
ConstraintSeq = Union[OperandConstraint, Tuple[OperandConstraint, ...]]
# Instruction specification for encodings. Allows for predicated
# instructions.
InstSpec = Union[MaybeBoundInst, Apply]
except ImportError: except ImportError:
pass pass
@@ -210,6 +215,14 @@ class Encoding(object):
An `Encoding` object ties an instruction opcode with concrete type An `Encoding` object ties an instruction opcode with concrete type
variables together with and encoding recipe and encoding bits. variables together with and encoding recipe and encoding bits.
The concrete instruction can be in three different forms:
1. A naked opcode: `trap` for non-polymorphic instructions.
2. With bound type variables: `iadd.i32` for polymorphic instructions.
3. With operands providing constraints: `icmp.i32(intcc.eq, x, y)`.
If the instruction is polymorphic, all type variables must be provided.
:param cpumode: The CPU mode where the encoding is active. :param cpumode: The CPU mode where the encoding is active.
:param inst: The :py:class:`Instruction` or :py:class:`BoundInstruction` :param inst: The :py:class:`Instruction` or :py:class:`BoundInstruction`
being encoded. being encoded.
@@ -220,10 +233,18 @@ class Encoding(object):
""" """
def __init__(self, cpumode, inst, recipe, encbits, instp=None, isap=None): def __init__(self, cpumode, inst, recipe, encbits, instp=None, isap=None):
# type: (CPUMode, MaybeBoundInst, EncRecipe, int, PredNode, PredNode) -> None # noqa # type: (CPUMode, InstSpec, EncRecipe, int, PredNode, PredNode) -> None # noqa
assert isinstance(cpumode, CPUMode) assert isinstance(cpumode, CPUMode)
assert isinstance(recipe, EncRecipe) assert isinstance(recipe, EncRecipe)
self.inst, self.typevars = inst.fully_bound()
# Check for possible instruction predicates in `inst`.
if isinstance(inst, Apply):
instp = And.combine(instp, inst.inst_predicate())
self.inst = inst.inst
self.typevars = inst.typevars
else:
self.inst, self.typevars = inst.fully_bound()
self.cpumode = cpumode self.cpumode = cpumode
assert self.inst.format == recipe.format, ( assert self.inst.format == recipe.format, (
"Format {} must match recipe: {}".format( "Format {} must match recipe: {}".format(