Allow dot syntax notation for enumerated immediate operands.
The meta language patterns sometimes need to refer to specific values of enumerated immediate operands. The dot syntax provides a namespaced, typed way of doing that: icmp(intcc.ult, a, x). Add an ast.Enumerator class for representing this kind of AST leaf node. Add value definitions for the intcc and floatcc immediate operand kinds.
This commit is contained in:
@@ -34,7 +34,19 @@ ieee64 = ImmediateKind('ieee64', 'A 64-bit immediate floating point number.')
|
|||||||
intcc = ImmediateKind(
|
intcc = ImmediateKind(
|
||||||
'intcc',
|
'intcc',
|
||||||
'An integer comparison condition code.',
|
'An integer comparison condition code.',
|
||||||
default_member='cond', rust_type='IntCC')
|
default_member='cond', rust_type='IntCC',
|
||||||
|
values={
|
||||||
|
'eq': 'Equal',
|
||||||
|
'ne': 'NotEqual',
|
||||||
|
'sge': 'SignedGreaterThanOrEqual',
|
||||||
|
'sgt': 'SignedGreaterThan',
|
||||||
|
'sle': 'SignedLessThanOrEqual',
|
||||||
|
'slt': 'SignedLessThan',
|
||||||
|
'uge': 'UnsignedGreaterThanOrEqual',
|
||||||
|
'ugt': 'UnsignedGreaterThan',
|
||||||
|
'ule': 'UnsignedLessThanOrEqual',
|
||||||
|
'ult': 'UnsignedLessThan',
|
||||||
|
})
|
||||||
|
|
||||||
#: A condition code for comparing floating point values.
|
#: A condition code for comparing floating point values.
|
||||||
#:
|
#:
|
||||||
@@ -43,4 +55,20 @@ intcc = ImmediateKind(
|
|||||||
floatcc = ImmediateKind(
|
floatcc = ImmediateKind(
|
||||||
'floatcc',
|
'floatcc',
|
||||||
'A floating point comparison condition code.',
|
'A floating point comparison condition code.',
|
||||||
default_member='cond', rust_type='FloatCC')
|
default_member='cond', rust_type='FloatCC',
|
||||||
|
values={
|
||||||
|
'ord': 'Ordered',
|
||||||
|
'uno': 'Unordered',
|
||||||
|
'eq': 'Equal',
|
||||||
|
'ne': 'NotEqual',
|
||||||
|
'one': 'OrderedNotEqual',
|
||||||
|
'ueq': 'UnorderedOrEqual',
|
||||||
|
'lt': 'LessThan',
|
||||||
|
'le': 'LessThanOrEqual',
|
||||||
|
'gt': 'GreaterThan',
|
||||||
|
'ge': 'GreaterThanOrEqual',
|
||||||
|
'ult': 'UnorderedOrLessThan',
|
||||||
|
'ule': 'UnorderedOrLessThanOrEqual',
|
||||||
|
'ugt': 'UnorderedOrGreaterThan',
|
||||||
|
'uge': 'UnorderedOrGreaterThanOrEqual',
|
||||||
|
})
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ patterns that describe how base instructions can be transformed to other base
|
|||||||
instructions that are legal.
|
instructions that are legal.
|
||||||
"""
|
"""
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
from .immediates import intcc
|
||||||
from .instructions import iadd, iadd_cout, iadd_cin, iadd_carry, iadd_imm
|
from .instructions import iadd, iadd_cout, iadd_cin, iadd_carry, iadd_imm
|
||||||
from .instructions import isub, isub_bin, isub_bout, isub_borrow
|
from .instructions import isub, isub_bin, isub_bout, isub_borrow
|
||||||
from .instructions import band, bor, bxor, isplit, iconcat
|
from .instructions import band, bor, bxor, isplit, iconcat
|
||||||
@@ -90,14 +91,14 @@ expand.legalize(
|
|||||||
(a, c) << iadd_cout(x, y),
|
(a, c) << iadd_cout(x, y),
|
||||||
Rtl(
|
Rtl(
|
||||||
a << iadd(x, y),
|
a << iadd(x, y),
|
||||||
c << icmp('IntCC::UnsignedLessThan', a, x)
|
c << icmp(intcc.ult, a, x)
|
||||||
))
|
))
|
||||||
|
|
||||||
expand.legalize(
|
expand.legalize(
|
||||||
(a, b) << isub_bout(x, y),
|
(a, b) << isub_bout(x, y),
|
||||||
Rtl(
|
Rtl(
|
||||||
a << isub(x, y),
|
a << isub(x, y),
|
||||||
b << icmp('IntCC::UnsignedGreaterThan', a, x)
|
b << icmp(intcc.ugt, a, x)
|
||||||
))
|
))
|
||||||
|
|
||||||
expand.legalize(
|
expand.legalize(
|
||||||
|
|||||||
@@ -9,7 +9,9 @@ from . import instructions
|
|||||||
from .typevar import TypeVar
|
from .typevar import TypeVar
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from typing import Union, Tuple, Sequence # noqa
|
from typing import Union, Tuple, Sequence, TYPE_CHECKING # noqa
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .operands import ImmediateKind # noqa
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -404,3 +406,35 @@ class Apply(Expr):
|
|||||||
args = defs[0].rust_type() + ', ' + args
|
args = defs[0].rust_type() + ', ' + args
|
||||||
method = self.inst.snake_name()
|
method = self.inst.snake_name()
|
||||||
return '{}({})'.format(method, args)
|
return '{}({})'.format(method, args)
|
||||||
|
|
||||||
|
|
||||||
|
class Enumerator(Expr):
|
||||||
|
"""
|
||||||
|
A value of an enumerated immediate operand.
|
||||||
|
|
||||||
|
Some immediate operand kinds like `intcc` and `floatcc` have an enumerated
|
||||||
|
range of values corresponding to a Rust enum type. An `Enumerator` object
|
||||||
|
is an AST leaf node representing one of the values.
|
||||||
|
|
||||||
|
:param kind: The enumerated `ImmediateKind` containing the value.
|
||||||
|
:param value: The textual IL representation of the value.
|
||||||
|
|
||||||
|
`Enumerator` nodes are not usually created directly. They are created by
|
||||||
|
using the dot syntax on immediate kinds: `intcc.ult`.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, kind, value):
|
||||||
|
# type: (ImmediateKind, str) -> None
|
||||||
|
self.kind = kind
|
||||||
|
self.value = value
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
# type: () -> str
|
||||||
|
"""
|
||||||
|
Get the Rust expression form of this enumerator.
|
||||||
|
"""
|
||||||
|
return self.kind.rust_enumerator(self.value)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
# type: () -> str
|
||||||
|
return '{}.{}'.format(self.kind, self.value)
|
||||||
|
|||||||
@@ -5,8 +5,10 @@ from .types import ValueType
|
|||||||
from .typevar import TypeVar
|
from .typevar import TypeVar
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from typing import Union
|
from typing import Union, Dict, TYPE_CHECKING # noqa
|
||||||
OperandSpec = Union['OperandKind', ValueType, TypeVar]
|
OperandSpec = Union['OperandKind', ValueType, TypeVar]
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .ast import Enumerator # noqa
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -74,15 +76,44 @@ class ImmediateKind(OperandKind):
|
|||||||
`InstructionData` data structure.
|
`InstructionData` data structure.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, name, doc, default_member='imm', rust_type=None):
|
def __init__(
|
||||||
# type: (str, str, str, str) -> None
|
self, name, doc,
|
||||||
|
default_member='imm',
|
||||||
|
rust_type=None,
|
||||||
|
values=None):
|
||||||
|
# type: (str, str, str, str, Dict[str, str]) -> None
|
||||||
super(ImmediateKind, self).__init__(
|
super(ImmediateKind, self).__init__(
|
||||||
name, doc, default_member, rust_type)
|
name, doc, default_member, rust_type)
|
||||||
|
self.values = values
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
# type: () -> str
|
# type: () -> str
|
||||||
return 'ImmediateKind({})'.format(self.name)
|
return 'ImmediateKind({})'.format(self.name)
|
||||||
|
|
||||||
|
def __getattr__(self, value):
|
||||||
|
# type: (str) -> Enumerator
|
||||||
|
"""
|
||||||
|
Enumerated immediate kinds allow the use of dot syntax to produce
|
||||||
|
`Enumerator` AST nodes: `icmp.i32(intcc.ult, a, b)`.
|
||||||
|
"""
|
||||||
|
from .ast import Enumerator # noqa
|
||||||
|
if not self.values:
|
||||||
|
raise AssertionError(
|
||||||
|
'{n} is not an enumerated operand kind: {n}.{a}'.format(
|
||||||
|
n=self.name, a=value))
|
||||||
|
if value not in self.values:
|
||||||
|
raise AssertionError(
|
||||||
|
'No such {n} enumerator: {n}.{a}'.format(
|
||||||
|
n=self.name, a=value))
|
||||||
|
return Enumerator(self, value)
|
||||||
|
|
||||||
|
def rust_enumerator(self, value):
|
||||||
|
# type: (str) -> str
|
||||||
|
"""
|
||||||
|
Get the qualified Rust name of the enumerator value `value`.
|
||||||
|
"""
|
||||||
|
return '{}::{}'.format(self.rust_type, self.values[value])
|
||||||
|
|
||||||
|
|
||||||
# Instances of entity reference operand types are provided in the
|
# Instances of entity reference operand types are provided in the
|
||||||
# `cretonne.entities` module.
|
# `cretonne.entities` module.
|
||||||
|
|||||||
Reference in New Issue
Block a user