microasm.isa revision 4309
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 704309Sgblack@eecs.umich.edu def getAllocator(self, labelDict = {}): 714309Sgblack@eecs.umich.edu args = '' 724309Sgblack@eecs.umich.edu for arg in self.args: 734309Sgblack@eecs.umich.edu if arg.has_key("operandConst"): 744309Sgblack@eecs.umich.edu args += ", %s" % arg["operandConst"] 754309Sgblack@eecs.umich.edu elif arg.has_key("operandCode"): 764309Sgblack@eecs.umich.edu args += ", %s" % arg["operandCode"] 774309Sgblack@eecs.umich.edu elif arg.has_key("operandLabel"): 784309Sgblack@eecs.umich.edu if not labelDict.has_key(arg["operandLabel"]): 794309Sgblack@eecs.umich.edu print "Unrecognized label %s!" % arg["operandLabel"] 804309Sgblack@eecs.umich.edu args += ", %s" % labelDict[arg["operandLabel"]] 814309Sgblack@eecs.umich.edu else: 824309Sgblack@eecs.umich.edu print "Unrecognized operand type!" 834309Sgblack@eecs.umich.edu return 'new %s(machInst %s)' % (self.className, args) 844309Sgblack@eecs.umich.edu 854309Sgblack@eecs.umich.edu 864309Sgblack@eecs.umich.edu def assembleMicro(code): 874309Sgblack@eecs.umich.edu # This function takes in a block of microcode assembly and returns 884309Sgblack@eecs.umich.edu # a python list of objects which describe it. 894309Sgblack@eecs.umich.edu 904309Sgblack@eecs.umich.edu # Keep this around in case we need it later 914309Sgblack@eecs.umich.edu orig_code = code 924309Sgblack@eecs.umich.edu # A list of the statements we've found thus far 934309Sgblack@eecs.umich.edu statements = [] 944309Sgblack@eecs.umich.edu 954309Sgblack@eecs.umich.edu # Regular expressions to pull each piece of the statement out at a 964309Sgblack@eecs.umich.edu # time. Each expression expects the thing it's looking for to be at 974309Sgblack@eecs.umich.edu # the beginning of the line, so the previous component is stripped 984309Sgblack@eecs.umich.edu # before continuing. 994309Sgblack@eecs.umich.edu labelRe = re.compile(r'^[ \t]*(?P<label>[a-zA-Z_]\w*)[ \t]:') 1004309Sgblack@eecs.umich.edu lineRe = re.compile(r'^(?P<line>[^\n][^\n]*)$') 1014309Sgblack@eecs.umich.edu classRe = re.compile(r'^[ \t]*(?P<className>[a-zA-Z_]\w*)') 1024309Sgblack@eecs.umich.edu # This recognizes three different flavors of operands: 1034309Sgblack@eecs.umich.edu # 1. Raw decimal numbers composed of digits between 0 and 9 1044309Sgblack@eecs.umich.edu # 2. Code beginning with "{" and continuing until the first "}" 1054309Sgblack@eecs.umich.edu # ^ This one might need revising 1064309Sgblack@eecs.umich.edu # 3. A label, which starts with a capital or small letter, or 1074309Sgblack@eecs.umich.edu # underscore, which is optionally followed by a sequence of 1084309Sgblack@eecs.umich.edu # capital or small letters, underscores, or digts between 0 and 9 1094309Sgblack@eecs.umich.edu opRe = re.compile( \ 1104309Sgblack@eecs.umich.edu r'^[ \t]*((?P<operandLabel>[a-zA-Z_]\w*)|(?P<operandConst>[0-9][0-9]*)|(\{(?P<operandCode>[^}]*)\}))') 1114309Sgblack@eecs.umich.edu lineMatch = lineRe.search(code) 1124309Sgblack@eecs.umich.edu while lineMatch != None: 1134309Sgblack@eecs.umich.edu statement = MicroOpStatement() 1144309Sgblack@eecs.umich.edu # Get a line and seperate it from the rest of the code 1154309Sgblack@eecs.umich.edu line = lineMatch.group("line") 1164309Sgblack@eecs.umich.edu print "Parsing line %s" % line 1174309Sgblack@eecs.umich.edu code = lineRe.sub('', code, 1) 1184309Sgblack@eecs.umich.edu 1194309Sgblack@eecs.umich.edu # Find the label, if any 1204309Sgblack@eecs.umich.edu labelMatch = labelRe.search(line) 1214309Sgblack@eecs.umich.edu if labelMatch != None: 1224309Sgblack@eecs.umich.edu statement.label = labelMatch.group("label") 1234309Sgblack@eecs.umich.edu print "Found label %s." % statement.label 1244309Sgblack@eecs.umich.edu # Clear the label from the statement 1254309Sgblack@eecs.umich.edu line = labelRe.sub('', line, 1) 1264309Sgblack@eecs.umich.edu 1274309Sgblack@eecs.umich.edu # Find the class name which is roughly equivalent to the op name 1284309Sgblack@eecs.umich.edu classMatch = classRe.search(line) 1294309Sgblack@eecs.umich.edu if classMatch == None: 1304309Sgblack@eecs.umich.edu print "Oh no! I can't find what instruction you want!" 1314309Sgblack@eecs.umich.edu print "I should really bail out here, but I don't know how!" 1324309Sgblack@eecs.umich.edu else: 1334309Sgblack@eecs.umich.edu statement.className = classMatch.group("className") 1344309Sgblack@eecs.umich.edu print "Found class name %s." % statement.className 1354309Sgblack@eecs.umich.edu 1364309Sgblack@eecs.umich.edu # Clear the class name from the statement 1374309Sgblack@eecs.umich.edu line = classRe.sub('', line, 1) 1384309Sgblack@eecs.umich.edu 1394309Sgblack@eecs.umich.edu #Find as many arguments as you can 1404309Sgblack@eecs.umich.edu statement.args = [] 1414309Sgblack@eecs.umich.edu opMatch = opRe.search(line) 1424309Sgblack@eecs.umich.edu while opMatch is not None: 1434309Sgblack@eecs.umich.edu statement.args.append({}) 1444309Sgblack@eecs.umich.edu # args is a list of dicts which collect different 1454309Sgblack@eecs.umich.edu # representations of operand values. Different forms might be 1464309Sgblack@eecs.umich.edu # needed in different places, for instance to replace a label 1474309Sgblack@eecs.umich.edu # with an offset. 1484309Sgblack@eecs.umich.edu for opType in ("operandLabel", "operandConst", "operandCode"): 1494309Sgblack@eecs.umich.edu if opMatch.group(opType): 1504309Sgblack@eecs.umich.edu statement.args[-1][opType] = opMatch.group(opType) 1514309Sgblack@eecs.umich.edu if len(statement.args[-1]) == 0: 1524309Sgblack@eecs.umich.edu print "I had a problem parsing an operand!" 1534309Sgblack@eecs.umich.edu line = opRe.sub('', line, 1) 1544309Sgblack@eecs.umich.edu print "Found operand %s." % statement.args[-1] 1554309Sgblack@eecs.umich.edu opMatch = opRe.search(line) 1564309Sgblack@eecs.umich.edu print "Found operands", statement.args 1574309Sgblack@eecs.umich.edu 1584309Sgblack@eecs.umich.edu # Add this statement to our collection 1594309Sgblack@eecs.umich.edu statements.append(statement) 1604309Sgblack@eecs.umich.edu 1614309Sgblack@eecs.umich.edu # Get the next line 1624309Sgblack@eecs.umich.edu lineMatch = lineRe.search(code) 1634309Sgblack@eecs.umich.edu return statements 1644309Sgblack@eecs.umich.edu 1654309Sgblack@eecs.umich.edu def buildLabelDict(ops): 1664309Sgblack@eecs.umich.edu labels = {} 1674309Sgblack@eecs.umich.edu count = 0 1684309Sgblack@eecs.umich.edu for op in ops: 1694309Sgblack@eecs.umich.edu if op.label: 1704309Sgblack@eecs.umich.edu labels[op.label] = count 1714309Sgblack@eecs.umich.edu count += 1 1724309Sgblack@eecs.umich.edu}}; 173