diff --git a/lib/cretonne/meta/cdsl/ast.py b/lib/cretonne/meta/cdsl/ast.py index 4207253684..0a9b5eece4 100644 --- a/lib/cretonne/meta/cdsl/ast.py +++ b/lib/cretonne/meta/cdsl/ast.py @@ -350,8 +350,8 @@ class Apply(Expr): on this instruction. Immediate operands in a source pattern can be either free variables or - constants like `Enumerator`. We don't currently support constraints on - free variables, but we may in the future. + constants like `ConstantInt` and `Enumerator`. We don't currently + support constraints on free variables, but we may in the future. """ pred = None # type: PredNode iform = self.inst.format @@ -415,6 +415,12 @@ class Apply(Expr): else: if (s[self_a] != other_a): return None + elif isinstance(self_a, ConstantInt): + if not isinstance(other_a, ConstantInt): + return None + assert self_a.kind == other_a.kind + if (self_a.value != other_a.value): + return None else: assert isinstance(self_a, Enumerator) @@ -430,6 +436,32 @@ class Apply(Expr): return s +class ConstantInt(Expr): + """ + A value of an integer immediate operand. + + Immediate operands like `imm64` or `offset32` can be specified in AST + expressions using the call syntax: `imm64(5)` which greates a `ConstantInt` + node. + """ + + def __init__(self, kind, value): + # type: (ImmediateKind, int) -> None + self.kind = kind + self.value = value + + def __str__(self): + # type: () -> str + """ + Get the Rust expression form of this constant. + """ + return str(self.value) + + def __repr__(self): + # type: () -> str + return '{}({})'.format(self.kind, self.value) + + class Enumerator(Expr): """ A value of an enumerated immediate operand. diff --git a/lib/cretonne/meta/cdsl/operands.py b/lib/cretonne/meta/cdsl/operands.py index 44bae5d500..abf409a8c4 100644 --- a/lib/cretonne/meta/cdsl/operands.py +++ b/lib/cretonne/meta/cdsl/operands.py @@ -8,7 +8,7 @@ try: from typing import Union, Dict, TYPE_CHECKING # noqa OperandSpec = Union['OperandKind', ValueType, TypeVar] if TYPE_CHECKING: - from .ast import Enumerator # noqa + from .ast import Enumerator, ConstantInt # noqa except ImportError: pass @@ -107,6 +107,20 @@ class ImmediateKind(OperandKind): n=self.name, a=value)) return Enumerator(self, value) + def __call__(self, value): + # type: (int) -> ConstantInt + """ + Create an AST node representing a constant integer: + + iconst(imm64(0)) + """ + from .ast import ConstantInt # noqa + if self.values: + raise AssertionError( + "{}({}): Can't make a constant numeric value for an enum" + .format(self.name, value)) + return ConstantInt(self, value) + def rust_enumerator(self, value): # type: (str) -> str """