diff options
Diffstat (limited to 'src/arch/x86/isa/microasm.isa')
-rw-r--r-- | src/arch/x86/isa/microasm.isa | 185 |
1 files changed, 15 insertions, 170 deletions
diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index 9d21b6bcc..fde430691 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -55,177 +55,22 @@ // // Authors: Gabe Black -//////////////////////////////////////////////////////////////////// -// -// The microcode assembler -// +//Include the definitions of the micro ops. +//These are StaticInst classes which stand on their own and make up an +//internal instruction set, and also python representations which are passed +//into the microcode assembler. +##include "microops/microops.isa" -let {{ - # These are used when setting up microops so that they can specialize their - # base class template properly. - RegOpType = "RegisterOperand" - ImmOpType = "ImmediateOperand" -}}; +//Include code to build macroops in both C++ and python. +##include "macroop.isa" let {{ - class MicroOpStatement(object): - def __init__(self): - self.className = '' - self.label = '' - self.args = [] - - # This converts a list of python bools into - # a comma seperated list of C++ bools. - def microFlagsText(self, vals): - text = "" - for val in vals: - if val: - text += ", true" - else: - text += ", false" - return text - - def getAllocator(self, mnemonic, *microFlags): - args = '' - signature = "<" - emptySig = True - for arg in self.args: - if not emptySig: - signature += ", " - emptySig = False - if arg.has_key("operandImm"): - args += ", %s" % arg["operandImm"] - signature += ImmOpType - elif arg.has_key("operandReg"): - args += ", %s" % arg["operandReg"] - signature += RegOpType - elif arg.has_key("operandLabel"): - raise Exception, "Found a label while creating allocator string." - else: - raise Exception, "Unrecognized operand type." - signature += ">" - return 'new %s%s(machInst, %s%s%s)' % (self.className, signature, mnemonic, self.microFlagsText(microFlags), args) -}}; - -let{{ - def assembleMicro(name, Name, code): - - # This function takes in a block of microcode assembly and returns - # a python list of objects which describe it. - - # Keep this around in case we need it later - orig_code = code - # A list of the statements we've found thus far - statements = [] - - # Regular expressions to pull each piece of the statement out at a - # time. Each expression expects the thing it's looking for to be at - # the beginning of the line, so the previous component is stripped - # before continuing. - labelRe = re.compile(r'^[ \t]*(?P<label>\w\w*)[ \t]:') - lineRe = re.compile(r'^(?P<line>..*)(\n|$)') - classRe = re.compile(r'^[ \t]*(?P<className>[a-zA-Z_]\w*)') - # This recognizes three different flavors of operands: - # 1. Raw decimal numbers composed of digits between 0 and 9 - # 2. Code beginning with "{" and continuing until the first "}" - # ^ This one might need revising - # 3. A label, which starts with a capital or small letter, or - # underscore, which is optionally followed by a sequence of - # capital or small letters, underscores, or digts between 0 and 9 - opRe = re.compile( \ - r'^[ \t]*((\@(?P<operandLabel0>\w\w*))|' + - r'(\@\{(?P<operandLabel1>[^}]*)\})|' + - r'(\%(?P<operandReg0>\w\w*))|' + - r'(\%\{(?P<operandReg1>[^}]*)\})|' + - r'(\$(?P<operandImm0>\w\w*))|' + - r'(\$\{(?P<operandImm1>[^}]*)\}))') - lineMatch = lineRe.search(code) - while lineMatch != None: - statement = MicroOpStatement() - # Get a line and seperate it from the rest of the code - line = lineMatch.group("line") - orig_line = line - #print "Parsing line %s" % line - code = lineRe.sub('', code, 1) - - # Find the label, if any - labelMatch = labelRe.search(line) - if labelMatch != None: - statement.label = labelMatch.group("label") - #print "Found label %s." % statement.label - # Clear the label from the statement - line = labelRe.sub('', line, 1) - - # Find the class name which is roughly equivalent to the op name - classMatch = classRe.search(line) - if classMatch == None: - raise Exception, "Couldn't find class name in statement: %s" \ - % orig_line - else: - statement.className = classMatch.group("className") - #print "Found class name %s." % statement.className - - # Clear the class name from the statement - line = classRe.sub('', line, 1) - - #Find as many arguments as you can - statement.args = [] - opMatch = opRe.search(line) - while opMatch is not None: - statement.args.append({}) - # args is a list of dicts which collect different - # representations of operand values. Different forms might be - # needed in different places, for instance to replace a label - # with an offset. - for opType in ("operandLabel0", "operandReg0", "operandImm0", - "operandLabel1", "operandReg1", "operandImm1"): - if opMatch.group(opType): - statement.args[-1][opType[:-1]] = opMatch.group(opType) - if len(statement.args[-1]) == 0: - print "Problem parsing operand in statement: %s" \ - % orig_line - line = opRe.sub('', line, 1) - #print "Found operand %s." % statement.args[-1] - opMatch = opRe.search(line) - #print "Found operands", statement.args - - # Add this statement to our collection - statements.append(statement) - - # Get the next line - lineMatch = lineRe.search(code) - - # Decode the labels into displacements - - labels = {} - micropc = 0 - for statement in statements: - if statement.label: - labels[statement.label] = count - micropc += 1 - micropc = 0 - for statement in statements: - for arg in statement.args: - if arg.has_key("operandLabel"): - if not labels.has_key(arg["operandLabel"]): - raise Exception, "Unrecognized label: %s." % arg["operandLabel"] - # This is assuming that intra microcode branches go to - # the next micropc + displacement, or - # micropc + 1 + displacement. - arg["operandImm"] = labels[arg["operandLabel"]] - micropc - 1 - micropc += 1 - - if len(statements) == 0: - raise Exception, "Didn't find any microops in microcode: \n%s" % orig_code - - # If we can implement this instruction with exactly one microop, just - # use that directly. - if len(statements) == 1: - decode_block = "return %s;" % \ - statements[0].getAllocator('"' + name + '"') - return ('', '', decode_block, '') - else: - # Build a macroop to contain the sequence of microops we've - # been given. - return genMacroOp(name, Name, statements) + import sys + sys.path[0:0] = ["src/arch/x86/isa/"] + from insts import microcode + print microcode + from micro_asm import MicroAssembler, Rom_Macroop, Rom + mainRom = Rom('main ROM') + assembler = MicroAssembler(X86Macroop, microopClasses, mainRom, Rom_Macroop) + macroopDict = assembler.assemble(microcode) }}; |