From fe7ad84129d8a179fa10a482698764e4de25d28f Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Tue, 23 Aug 2016 13:29:29 -0700 Subject: [PATCH] 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. --- meta/cretonne/__init__.py | 50 +++++++++++++++++++++++++++++++++++++-- meta/cretonne/formats.py | 4 ++-- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/meta/cretonne/__init__.py b/meta/cretonne/__init__.py index c79e0f7bdc..c6693a7c4a 100644 --- a/meta/cretonne/__init__.py +++ b/meta/cretonne/__init__.py @@ -622,9 +622,9 @@ class InstructionFormat(object): def __init__(self, *kinds, **kwargs): self.name = kwargs.get('name', None) - self.kinds = kinds self.multiple_results = kwargs.get('multiple_results', False) self.boxed_storage = kwargs.get('boxed_storage', False) + self.kinds = tuple(self._process_member_names(kinds)) # Which of self.kinds are `value`? self.value_operands = tuple( @@ -640,7 +640,7 @@ class InstructionFormat(object): self.typevar_operand = self.value_operands[0] # Compute a signature for the global registry. - sig = (self.multiple_results,) + kinds + sig = (self.multiple_results,) + self.kinds if sig in InstructionFormat._registry: raise RuntimeError( "Format '{}' has the same signature as existing format '{}'" @@ -648,6 +648,31 @@ class InstructionFormat(object): InstructionFormat._registry[sig] = 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 def lookup(ins, outs): """ @@ -680,6 +705,27 @@ class InstructionFormat(object): 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): """ The operands to the instruction are specified as two tuples: ``ins`` and diff --git a/meta/cretonne/formats.py b/meta/cretonne/formats.py index efd535b693..06f4593086 100644 --- a/meta/cretonne/formats.py +++ b/meta/cretonne/formats.py @@ -30,8 +30,8 @@ BinaryOverflow = InstructionFormat(value, value, multiple_results=True) # The fma instruction has the same constraint on all inputs. Ternary = InstructionFormat(value, value, value, typevar_operand=1) -InsertLane = InstructionFormat(value, uimm8, value) -ExtractLane = InstructionFormat(value, uimm8) +InsertLane = InstructionFormat(value, ('lane', uimm8), value) +ExtractLane = InstructionFormat(value, ('lane', uimm8)) IntCompare = InstructionFormat(intcc, value, value) FloatCompare = InstructionFormat(floatcc, value, value)