microasm.isa revision 4309:47807357f0d7
1// -*- mode:c++ -*- 2 3// Copyright (c) 2007 The Hewlett-Packard Development Company 4// All rights reserved. 5// 6// Redistribution and use of this software in source and binary forms, 7// with or without modification, are permitted provided that the 8// following conditions are met: 9// 10// The software must be used only for Non-Commercial Use which means any 11// use which is NOT directed to receiving any direct monetary 12// compensation for, or commercial advantage from such use. Illustrative 13// examples of non-commercial use are academic research, personal study, 14// teaching, education and corporate research & development. 15// Illustrative examples of commercial use are distributing products for 16// commercial advantage and providing services using the software for 17// commercial advantage. 18// 19// If you wish to use this software or functionality therein that may be 20// covered by patents for commercial use, please contact: 21// Director of Intellectual Property Licensing 22// Office of Strategy and Technology 23// Hewlett-Packard Company 24// 1501 Page Mill Road 25// Palo Alto, California 94304 26// 27// Redistributions of source code must retain the above copyright notice, 28// this list of conditions and the following disclaimer. Redistributions 29// in binary form must reproduce the above copyright notice, this list of 30// conditions and the following disclaimer in the documentation and/or 31// other materials provided with the distribution. Neither the name of 32// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its 33// contributors may be used to endorse or promote products derived from 34// this software without specific prior written permission. No right of 35// sublicense is granted herewith. Derivatives of the software and 36// output created using the software may be prepared, but only for 37// Non-Commercial Uses. Derivatives of the software may be shared with 38// others provided: (i) the others agree to abide by the list of 39// conditions herein which includes the Non-Commercial Use restrictions; 40// and (ii) such Derivatives of the software include the above copyright 41// notice to acknowledge the contribution from this software where 42// applicable, this list of conditions and the disclaimer below. 43// 44// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 45// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 46// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 47// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 48// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 49// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 50// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 51// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 52// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 53// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 54// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 55// 56// Authors: Gabe Black 57 58//////////////////////////////////////////////////////////////////// 59// 60// Code to "assemble" microcode sequences 61// 62 63let {{ 64 class MicroOpStatement: 65 def __init__(self): 66 self.className = '' 67 self.label = '' 68 self.args = [] 69 70 def getAllocator(self, labelDict = {}): 71 args = '' 72 for arg in self.args: 73 if arg.has_key("operandConst"): 74 args += ", %s" % arg["operandConst"] 75 elif arg.has_key("operandCode"): 76 args += ", %s" % arg["operandCode"] 77 elif arg.has_key("operandLabel"): 78 if not labelDict.has_key(arg["operandLabel"]): 79 print "Unrecognized label %s!" % arg["operandLabel"] 80 args += ", %s" % labelDict[arg["operandLabel"]] 81 else: 82 print "Unrecognized operand type!" 83 return 'new %s(machInst %s)' % (self.className, args) 84 85 86 def assembleMicro(code): 87 # This function takes in a block of microcode assembly and returns 88 # a python list of objects which describe it. 89 90 # Keep this around in case we need it later 91 orig_code = code 92 # A list of the statements we've found thus far 93 statements = [] 94 95 # Regular expressions to pull each piece of the statement out at a 96 # time. Each expression expects the thing it's looking for to be at 97 # the beginning of the line, so the previous component is stripped 98 # before continuing. 99 labelRe = re.compile(r'^[ \t]*(?P<label>[a-zA-Z_]\w*)[ \t]:') 100 lineRe = re.compile(r'^(?P<line>[^\n][^\n]*)$') 101 classRe = re.compile(r'^[ \t]*(?P<className>[a-zA-Z_]\w*)') 102 # This recognizes three different flavors of operands: 103 # 1. Raw decimal numbers composed of digits between 0 and 9 104 # 2. Code beginning with "{" and continuing until the first "}" 105 # ^ This one might need revising 106 # 3. A label, which starts with a capital or small letter, or 107 # underscore, which is optionally followed by a sequence of 108 # capital or small letters, underscores, or digts between 0 and 9 109 opRe = re.compile( \ 110 r'^[ \t]*((?P<operandLabel>[a-zA-Z_]\w*)|(?P<operandConst>[0-9][0-9]*)|(\{(?P<operandCode>[^}]*)\}))') 111 lineMatch = lineRe.search(code) 112 while lineMatch != None: 113 statement = MicroOpStatement() 114 # Get a line and seperate it from the rest of the code 115 line = lineMatch.group("line") 116 print "Parsing line %s" % line 117 code = lineRe.sub('', code, 1) 118 119 # Find the label, if any 120 labelMatch = labelRe.search(line) 121 if labelMatch != None: 122 statement.label = labelMatch.group("label") 123 print "Found label %s." % statement.label 124 # Clear the label from the statement 125 line = labelRe.sub('', line, 1) 126 127 # Find the class name which is roughly equivalent to the op name 128 classMatch = classRe.search(line) 129 if classMatch == None: 130 print "Oh no! I can't find what instruction you want!" 131 print "I should really bail out here, but I don't know how!" 132 else: 133 statement.className = classMatch.group("className") 134 print "Found class name %s." % statement.className 135 136 # Clear the class name from the statement 137 line = classRe.sub('', line, 1) 138 139 #Find as many arguments as you can 140 statement.args = [] 141 opMatch = opRe.search(line) 142 while opMatch is not None: 143 statement.args.append({}) 144 # args is a list of dicts which collect different 145 # representations of operand values. Different forms might be 146 # needed in different places, for instance to replace a label 147 # with an offset. 148 for opType in ("operandLabel", "operandConst", "operandCode"): 149 if opMatch.group(opType): 150 statement.args[-1][opType] = opMatch.group(opType) 151 if len(statement.args[-1]) == 0: 152 print "I had a problem parsing an operand!" 153 line = opRe.sub('', line, 1) 154 print "Found operand %s." % statement.args[-1] 155 opMatch = opRe.search(line) 156 print "Found operands", statement.args 157 158 # Add this statement to our collection 159 statements.append(statement) 160 161 # Get the next line 162 lineMatch = lineRe.search(code) 163 return statements 164 165 def buildLabelDict(ops): 166 labels = {} 167 count = 0 168 for op in ops: 169 if op.label: 170 labels[op.label] = count 171 count += 1 172}}; 173