summaryrefslogtreecommitdiff
path: root/src/arch/x86/isa/microasm.isa
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86/isa/microasm.isa')
-rw-r--r--src/arch/x86/isa/microasm.isa185
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)
}};