microasm.isa revision 4323
14309Sgblack@eecs.umich.edu// -*- mode:c++ -*- 24309Sgblack@eecs.umich.edu 34309Sgblack@eecs.umich.edu// Copyright (c) 2007 The Hewlett-Packard Development Company 44309Sgblack@eecs.umich.edu// All rights reserved. 54309Sgblack@eecs.umich.edu// 64309Sgblack@eecs.umich.edu// Redistribution and use of this software in source and binary forms, 74309Sgblack@eecs.umich.edu// with or without modification, are permitted provided that the 84309Sgblack@eecs.umich.edu// following conditions are met: 94309Sgblack@eecs.umich.edu// 104309Sgblack@eecs.umich.edu// The software must be used only for Non-Commercial Use which means any 114309Sgblack@eecs.umich.edu// use which is NOT directed to receiving any direct monetary 124309Sgblack@eecs.umich.edu// compensation for, or commercial advantage from such use. Illustrative 134309Sgblack@eecs.umich.edu// examples of non-commercial use are academic research, personal study, 144309Sgblack@eecs.umich.edu// teaching, education and corporate research & development. 154309Sgblack@eecs.umich.edu// Illustrative examples of commercial use are distributing products for 164309Sgblack@eecs.umich.edu// commercial advantage and providing services using the software for 174309Sgblack@eecs.umich.edu// commercial advantage. 184309Sgblack@eecs.umich.edu// 194309Sgblack@eecs.umich.edu// If you wish to use this software or functionality therein that may be 204309Sgblack@eecs.umich.edu// covered by patents for commercial use, please contact: 214309Sgblack@eecs.umich.edu// Director of Intellectual Property Licensing 224309Sgblack@eecs.umich.edu// Office of Strategy and Technology 234309Sgblack@eecs.umich.edu// Hewlett-Packard Company 244309Sgblack@eecs.umich.edu// 1501 Page Mill Road 254309Sgblack@eecs.umich.edu// Palo Alto, California 94304 264309Sgblack@eecs.umich.edu// 274309Sgblack@eecs.umich.edu// Redistributions of source code must retain the above copyright notice, 284309Sgblack@eecs.umich.edu// this list of conditions and the following disclaimer. Redistributions 294309Sgblack@eecs.umich.edu// in binary form must reproduce the above copyright notice, this list of 304309Sgblack@eecs.umich.edu// conditions and the following disclaimer in the documentation and/or 314309Sgblack@eecs.umich.edu// other materials provided with the distribution. Neither the name of 324309Sgblack@eecs.umich.edu// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its 334309Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from 344309Sgblack@eecs.umich.edu// this software without specific prior written permission. No right of 354309Sgblack@eecs.umich.edu// sublicense is granted herewith. Derivatives of the software and 364309Sgblack@eecs.umich.edu// output created using the software may be prepared, but only for 374309Sgblack@eecs.umich.edu// Non-Commercial Uses. Derivatives of the software may be shared with 384309Sgblack@eecs.umich.edu// others provided: (i) the others agree to abide by the list of 394309Sgblack@eecs.umich.edu// conditions herein which includes the Non-Commercial Use restrictions; 404309Sgblack@eecs.umich.edu// and (ii) such Derivatives of the software include the above copyright 414309Sgblack@eecs.umich.edu// notice to acknowledge the contribution from this software where 424309Sgblack@eecs.umich.edu// applicable, this list of conditions and the disclaimer below. 434309Sgblack@eecs.umich.edu// 444309Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 454309Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 464309Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 474309Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 484309Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 494309Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 504309Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 514309Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 524309Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 534309Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 544309Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 554309Sgblack@eecs.umich.edu// 564309Sgblack@eecs.umich.edu// Authors: Gabe Black 574309Sgblack@eecs.umich.edu 584309Sgblack@eecs.umich.edu//////////////////////////////////////////////////////////////////// 594309Sgblack@eecs.umich.edu// 604309Sgblack@eecs.umich.edu// Code to "assemble" microcode sequences 614309Sgblack@eecs.umich.edu// 624309Sgblack@eecs.umich.edu 634309Sgblack@eecs.umich.edulet {{ 644309Sgblack@eecs.umich.edu class MicroOpStatement: 654309Sgblack@eecs.umich.edu def __init__(self): 664309Sgblack@eecs.umich.edu self.className = '' 674309Sgblack@eecs.umich.edu self.label = '' 684309Sgblack@eecs.umich.edu self.args = [] 694309Sgblack@eecs.umich.edu 704323Sgblack@eecs.umich.edu # This converts a list of python bools into 714323Sgblack@eecs.umich.edu # a comma seperated list of C++ bools. 724323Sgblack@eecs.umich.edu def microFlagsText(self, vals): 734323Sgblack@eecs.umich.edu text = "" 744323Sgblack@eecs.umich.edu for val in vals: 754323Sgblack@eecs.umich.edu if val: 764323Sgblack@eecs.umich.edu text += ", true" 774323Sgblack@eecs.umich.edu else: 784323Sgblack@eecs.umich.edu text += ", false" 794323Sgblack@eecs.umich.edu return text 804323Sgblack@eecs.umich.edu 814323Sgblack@eecs.umich.edu def getAllocator(self, *microFlags): 824309Sgblack@eecs.umich.edu args = '' 834309Sgblack@eecs.umich.edu for arg in self.args: 844309Sgblack@eecs.umich.edu if arg.has_key("operandConst"): 854309Sgblack@eecs.umich.edu args += ", %s" % arg["operandConst"] 864309Sgblack@eecs.umich.edu elif arg.has_key("operandCode"): 874309Sgblack@eecs.umich.edu args += ", %s" % arg["operandCode"] 884309Sgblack@eecs.umich.edu elif arg.has_key("operandLabel"): 894323Sgblack@eecs.umich.edu raise Exception, "Found a label while creating allocator string." 904309Sgblack@eecs.umich.edu else: 914323Sgblack@eecs.umich.edu raise Exception, "Unrecognized operand type." 924323Sgblack@eecs.umich.edu return 'new %s(machInst%s%s)' % (self.className, self.microFlagsText(microFlags), args) 934323Sgblack@eecs.umich.edu}}; 944309Sgblack@eecs.umich.edu 954323Sgblack@eecs.umich.edulet {{ 964323Sgblack@eecs.umich.edu def buildLabelDict(ops): 974323Sgblack@eecs.umich.edu labels = {} 984323Sgblack@eecs.umich.edu micropc = 0 994323Sgblack@eecs.umich.edu for op in ops: 1004323Sgblack@eecs.umich.edu if op.label: 1014323Sgblack@eecs.umich.edu labels[op.label] = count 1024323Sgblack@eecs.umich.edu micropc += 1 1034323Sgblack@eecs.umich.edu return labels 1044309Sgblack@eecs.umich.edu 1054309Sgblack@eecs.umich.edu def assembleMicro(code): 1064309Sgblack@eecs.umich.edu # This function takes in a block of microcode assembly and returns 1074309Sgblack@eecs.umich.edu # a python list of objects which describe it. 1084309Sgblack@eecs.umich.edu 1094309Sgblack@eecs.umich.edu # Keep this around in case we need it later 1104309Sgblack@eecs.umich.edu orig_code = code 1114309Sgblack@eecs.umich.edu # A list of the statements we've found thus far 1124309Sgblack@eecs.umich.edu statements = [] 1134309Sgblack@eecs.umich.edu 1144309Sgblack@eecs.umich.edu # Regular expressions to pull each piece of the statement out at a 1154309Sgblack@eecs.umich.edu # time. Each expression expects the thing it's looking for to be at 1164309Sgblack@eecs.umich.edu # the beginning of the line, so the previous component is stripped 1174309Sgblack@eecs.umich.edu # before continuing. 1184309Sgblack@eecs.umich.edu labelRe = re.compile(r'^[ \t]*(?P<label>[a-zA-Z_]\w*)[ \t]:') 1194309Sgblack@eecs.umich.edu lineRe = re.compile(r'^(?P<line>[^\n][^\n]*)$') 1204309Sgblack@eecs.umich.edu classRe = re.compile(r'^[ \t]*(?P<className>[a-zA-Z_]\w*)') 1214309Sgblack@eecs.umich.edu # This recognizes three different flavors of operands: 1224309Sgblack@eecs.umich.edu # 1. Raw decimal numbers composed of digits between 0 and 9 1234309Sgblack@eecs.umich.edu # 2. Code beginning with "{" and continuing until the first "}" 1244309Sgblack@eecs.umich.edu # ^ This one might need revising 1254309Sgblack@eecs.umich.edu # 3. A label, which starts with a capital or small letter, or 1264309Sgblack@eecs.umich.edu # underscore, which is optionally followed by a sequence of 1274309Sgblack@eecs.umich.edu # capital or small letters, underscores, or digts between 0 and 9 1284309Sgblack@eecs.umich.edu opRe = re.compile( \ 1294309Sgblack@eecs.umich.edu r'^[ \t]*((?P<operandLabel>[a-zA-Z_]\w*)|(?P<operandConst>[0-9][0-9]*)|(\{(?P<operandCode>[^}]*)\}))') 1304309Sgblack@eecs.umich.edu lineMatch = lineRe.search(code) 1314309Sgblack@eecs.umich.edu while lineMatch != None: 1324309Sgblack@eecs.umich.edu statement = MicroOpStatement() 1334309Sgblack@eecs.umich.edu # Get a line and seperate it from the rest of the code 1344309Sgblack@eecs.umich.edu line = lineMatch.group("line") 1354323Sgblack@eecs.umich.edu orig_line = line 1364323Sgblack@eecs.umich.edu # print "Parsing line %s" % line 1374309Sgblack@eecs.umich.edu code = lineRe.sub('', code, 1) 1384309Sgblack@eecs.umich.edu 1394309Sgblack@eecs.umich.edu # Find the label, if any 1404309Sgblack@eecs.umich.edu labelMatch = labelRe.search(line) 1414309Sgblack@eecs.umich.edu if labelMatch != None: 1424309Sgblack@eecs.umich.edu statement.label = labelMatch.group("label") 1434323Sgblack@eecs.umich.edu # print "Found label %s." % statement.label 1444309Sgblack@eecs.umich.edu # Clear the label from the statement 1454309Sgblack@eecs.umich.edu line = labelRe.sub('', line, 1) 1464309Sgblack@eecs.umich.edu 1474309Sgblack@eecs.umich.edu # Find the class name which is roughly equivalent to the op name 1484309Sgblack@eecs.umich.edu classMatch = classRe.search(line) 1494309Sgblack@eecs.umich.edu if classMatch == None: 1504323Sgblack@eecs.umich.edu raise Exception, "Couldn't find class name in statement: %s" \ 1514323Sgblack@eecs.umich.edu % orig_line 1524309Sgblack@eecs.umich.edu else: 1534309Sgblack@eecs.umich.edu statement.className = classMatch.group("className") 1544323Sgblack@eecs.umich.edu # print "Found class name %s." % statement.className 1554309Sgblack@eecs.umich.edu 1564309Sgblack@eecs.umich.edu # Clear the class name from the statement 1574309Sgblack@eecs.umich.edu line = classRe.sub('', line, 1) 1584309Sgblack@eecs.umich.edu 1594309Sgblack@eecs.umich.edu #Find as many arguments as you can 1604309Sgblack@eecs.umich.edu statement.args = [] 1614309Sgblack@eecs.umich.edu opMatch = opRe.search(line) 1624309Sgblack@eecs.umich.edu while opMatch is not None: 1634309Sgblack@eecs.umich.edu statement.args.append({}) 1644309Sgblack@eecs.umich.edu # args is a list of dicts which collect different 1654309Sgblack@eecs.umich.edu # representations of operand values. Different forms might be 1664309Sgblack@eecs.umich.edu # needed in different places, for instance to replace a label 1674309Sgblack@eecs.umich.edu # with an offset. 1684309Sgblack@eecs.umich.edu for opType in ("operandLabel", "operandConst", "operandCode"): 1694309Sgblack@eecs.umich.edu if opMatch.group(opType): 1704309Sgblack@eecs.umich.edu statement.args[-1][opType] = opMatch.group(opType) 1714309Sgblack@eecs.umich.edu if len(statement.args[-1]) == 0: 1724323Sgblack@eecs.umich.edu print "Problem parsing operand in statement: %s" \ 1734323Sgblack@eecs.umich.edu % orig_line 1744309Sgblack@eecs.umich.edu line = opRe.sub('', line, 1) 1754323Sgblack@eecs.umich.edu # print "Found operand %s." % statement.args[-1] 1764309Sgblack@eecs.umich.edu opMatch = opRe.search(line) 1774323Sgblack@eecs.umich.edu # print "Found operands", statement.args 1784309Sgblack@eecs.umich.edu 1794309Sgblack@eecs.umich.edu # Add this statement to our collection 1804309Sgblack@eecs.umich.edu statements.append(statement) 1814309Sgblack@eecs.umich.edu 1824309Sgblack@eecs.umich.edu # Get the next line 1834309Sgblack@eecs.umich.edu lineMatch = lineRe.search(code) 1844323Sgblack@eecs.umich.edu 1854323Sgblack@eecs.umich.edu # Decode the labels into displacements 1864323Sgblack@eecs.umich.edu labels = buildLabelDict(statements) 1874323Sgblack@eecs.umich.edu micropc = 0 1884323Sgblack@eecs.umich.edu for statement in statements: 1894323Sgblack@eecs.umich.edu for arg in statement.args: 1904323Sgblack@eecs.umich.edu if arg.has_key("operandLabel"): 1914323Sgblack@eecs.umich.edu if not labels.has_key(arg["operandLabel"]): 1924323Sgblack@eecs.umich.edu raise Exception, "Unrecognized label: %s." % arg["operandLabel"] 1934323Sgblack@eecs.umich.edu # This is assuming that intra microcode branches go to 1944323Sgblack@eecs.umich.edu # the next micropc + displacement, or 1954323Sgblack@eecs.umich.edu # micropc + 1 + displacement. 1964323Sgblack@eecs.umich.edu arg["operandConst"] = labels[arg["operandLabel"]] - micropc - 1 1974323Sgblack@eecs.umich.edu micropc += 1 1984309Sgblack@eecs.umich.edu return statements 1994309Sgblack@eecs.umich.edu}}; 200