From af7eddaad1f07f10f5c078fd3dccb1260816d6e9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 28 Sep 2020 01:12:14 -0700 Subject: [PATCH] arch: Build the operand REs in the isa_parser on demand. These regular expressions search code snippets to find places where operands are used. Rather than build them explicitly at the end of processing the operands{{}} construct, wait until they're first going to be used. That way, we'll be able to define operands in as many places as we want, as long as we've done all we're going to do before the first instructions are defined. This will pave the way to defining operands in regular python in let blocks, and then possibly outside of the parser altogether, perhaps into scons where having lots of output files for individual instructions will be easier to manage. For now, this just lets you define multiple operands blocks which is not all that exciting on its own :) Change-Id: I1179092316c1c0ac2613810bfd236a32235502fb Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/35237 Reviewed-by: Jason Lowe-Power Reviewed-by: Richard Cooper Reviewed-by: Steve Reinhardt Maintainer: Gabe Black Tested-by: kokoro --- src/arch/isa_parser.py | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index 86f50892f..955d4e276 100755 --- a/src/arch/isa_parser.py +++ b/src/arch/isa_parser.py @@ -1133,7 +1133,7 @@ class OperandList(object): # search for operands next_pos = 0 while 1: - match = parser.operandsRE.search(code, next_pos) + match = parser.operandsRE().search(code, next_pos) if not match: # no more matches: we're done break @@ -1303,7 +1303,7 @@ class SubOperandList(OperandList): # search for operands next_pos = 0 while 1: - match = parser.operandsRE.search(code, next_pos) + match = parser.operandsRE().search(code, next_pos) if not match: # no more matches: we're done break @@ -1558,6 +1558,13 @@ class ISAParser(Grammar): # variable to hold templates self.templateMap = {} + # variable to hold operands + self.operandNameMap = {} + + # Regular expressions for working with operands + self._operandsRE = None + self._operandsWithExtRE = None + # This dictionary maps format name strings to Format objects. self.formatMap = {} @@ -1590,6 +1597,16 @@ class ISAParser(Grammar): self.maxInstDestRegs = 0 self.maxMiscDestRegs = 0 + def operandsRE(self): + if not self._operandsRE: + self.buildOperandREs() + return self._operandsRE + + def operandsWithExtRE(self): + if not self._operandsWithExtRE: + self.buildOperandREs() + return self._operandsWithExtRE + def __getitem__(self, i): # Allow object (self) to be return getattr(self, i) # passed to %-substitutions @@ -2581,18 +2598,19 @@ StaticInstPtr # in tmp_dict, just as if we evaluated a class declaration. operand_name[op_name] = type(cls_name, (base_cls,), tmp_dict) - self.operandNameMap = operand_name + self.operandNameMap.update(operand_name) + def buildOperandREs(self): # Define operand variables. - operands = list(user_dict.keys()) + operands = list(self.operandNameMap.keys()) # Add the elems defined in the vector operands and # build a map elem -> vector (used in OperandList) elem_to_vec = {} - for op in user_dict.keys(): - if hasattr(self.operandNameMap[op], 'elems'): - for elem in self.operandNameMap[op].elems.keys(): + for op_name, op in self.operandNameMap.items(): + if hasattr(op, 'elems'): + for elem in op.elems.keys(): operands.append(elem) - elem_to_vec[elem] = op + elem_to_vec[elem] = op_name self.elemToVector = elem_to_vec extensions = self.operandTypeMap.keys() @@ -2602,7 +2620,8 @@ StaticInstPtr (?!\w) # neg. lookahead assertion: prevent partial matches ''' % ('|'.join(operands), '|'.join(extensions)) - self.operandsRE = re.compile(operandsREString, re.MULTILINE|re.VERBOSE) + self._operandsRE = re.compile(operandsREString, + re.MULTILINE | re.VERBOSE) # Same as operandsREString, but extension is mandatory, and only two # groups are returned (base and ext, not full name as above). @@ -2610,14 +2629,14 @@ StaticInstPtr operandsWithExtREString = r'(?