Create format fields for immediate operands.

Each InstructionFormat instance gets data members corresponding to its immediate
operands, so the can be referred to as BinaryImm.imm, for example.

This will be used to construct instruction predicates.
This commit is contained in:
Jakob Stoklund Olesen
2016-08-23 13:29:29 -07:00
parent 7ead1e3f6f
commit fe7ad84129
2 changed files with 50 additions and 4 deletions

View File

@@ -622,9 +622,9 @@ class InstructionFormat(object):
def __init__(self, *kinds, **kwargs): def __init__(self, *kinds, **kwargs):
self.name = kwargs.get('name', None) self.name = kwargs.get('name', None)
self.kinds = kinds
self.multiple_results = kwargs.get('multiple_results', False) self.multiple_results = kwargs.get('multiple_results', False)
self.boxed_storage = kwargs.get('boxed_storage', False) self.boxed_storage = kwargs.get('boxed_storage', False)
self.kinds = tuple(self._process_member_names(kinds))
# Which of self.kinds are `value`? # Which of self.kinds are `value`?
self.value_operands = tuple( self.value_operands = tuple(
@@ -640,7 +640,7 @@ class InstructionFormat(object):
self.typevar_operand = self.value_operands[0] self.typevar_operand = self.value_operands[0]
# Compute a signature for the global registry. # Compute a signature for the global registry.
sig = (self.multiple_results,) + kinds sig = (self.multiple_results,) + self.kinds
if sig in InstructionFormat._registry: if sig in InstructionFormat._registry:
raise RuntimeError( raise RuntimeError(
"Format '{}' has the same signature as existing format '{}'" "Format '{}' has the same signature as existing format '{}'"
@@ -648,6 +648,31 @@ class InstructionFormat(object):
InstructionFormat._registry[sig] = self InstructionFormat._registry[sig] = self
InstructionFormat.all_formats.append(self) InstructionFormat.all_formats.append(self)
def _process_member_names(self, kinds):
"""
Extract names of all the immediate operands in the kinds tuple.
Each entry is either an `OperandKind` instance, or a `(member, kind)`
pair. The member names correspond to members in the Rust
`InstructionData` data structure.
Yields the operand kinds.
"""
for i, k in enumerate(kinds):
if isinstance(k, tuple):
member, k = k
else:
member = None
yield k
# Create `FormatField` instances for the immediates.
if isinstance(k, ImmediateKind):
if not member:
member = k.default_member
assert not hasattr(self, member), "Duplicate member name"
field = FormatField(self, i, member)
setattr(self, member, field)
@staticmethod @staticmethod
def lookup(ins, outs): def lookup(ins, outs):
""" """
@@ -680,6 +705,27 @@ class InstructionFormat(object):
obj.name = name obj.name = name
class FormatField(object):
"""
A field in an instruction format.
This corresponds to a single member of a variant of the `InstructionData`
data type.
:param format: Parent `InstructionFormat`.
:param operand: Operand number in parent.
:param name: Member name in `InstructionData` variant.
"""
def __init__(self, format, operand, name):
self.format = format
self.operand = operand
self.name = name
def __str__(self):
return '{}.{}'.format(self.format.name, self.name)
class Instruction(object): class Instruction(object):
""" """
The operands to the instruction are specified as two tuples: ``ins`` and The operands to the instruction are specified as two tuples: ``ins`` and

View File

@@ -30,8 +30,8 @@ BinaryOverflow = InstructionFormat(value, value, multiple_results=True)
# The fma instruction has the same constraint on all inputs. # The fma instruction has the same constraint on all inputs.
Ternary = InstructionFormat(value, value, value, typevar_operand=1) Ternary = InstructionFormat(value, value, value, typevar_operand=1)
InsertLane = InstructionFormat(value, uimm8, value) InsertLane = InstructionFormat(value, ('lane', uimm8), value)
ExtractLane = InstructionFormat(value, uimm8) ExtractLane = InstructionFormat(value, ('lane', uimm8))
IntCompare = InstructionFormat(intcc, value, value) IntCompare = InstructionFormat(intcc, value, value)
FloatCompare = InstructionFormat(floatcc, value, value) FloatCompare = InstructionFormat(floatcc, value, value)