Deleted Added
sdiff udiff text old ( 4323:13ca4002d2ac ) new ( 4336:bd6ab22f8e11 )
full compact
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 # This converts a list of python bools into
71 # a comma seperated list of C++ bools.
72 def microFlagsText(self, vals):
73 text = ""
74 for val in vals:
75 if val:
76 text += ", true"
77 else:
78 text += ", false"
79 return text
80
81 def getAllocator(self, *microFlags):
82 args = ''
83 for arg in self.args:
84 if arg.has_key("operandConst"):
85 args += ", %s" % arg["operandConst"]
86 elif arg.has_key("operandCode"):
87 args += ", %s" % arg["operandCode"]
88 elif arg.has_key("operandLabel"):
89 raise Exception, "Found a label while creating allocator string."
90 else:
91 raise Exception, "Unrecognized operand type."
92 return 'new %s(machInst%s%s)' % (self.className, self.microFlagsText(microFlags), args)
93}};
94
95let {{
96 def buildLabelDict(ops):
97 labels = {}
98 micropc = 0
99 for op in ops:
100 if op.label:
101 labels[op.label] = count
102 micropc += 1
103 return labels
104
105 def assembleMicro(code):
106 # This function takes in a block of microcode assembly and returns
107 # a python list of objects which describe it.
108
109 # Keep this around in case we need it later
110 orig_code = code
111 # A list of the statements we've found thus far
112 statements = []
113
114 # Regular expressions to pull each piece of the statement out at a
115 # time. Each expression expects the thing it's looking for to be at
116 # the beginning of the line, so the previous component is stripped
117 # before continuing.
118 labelRe = re.compile(r'^[ \t]*(?P<label>[a-zA-Z_]\w*)[ \t]:')
119 lineRe = re.compile(r'^(?P<line>[^\n][^\n]*)$')
120 classRe = re.compile(r'^[ \t]*(?P<className>[a-zA-Z_]\w*)')
121 # This recognizes three different flavors of operands:
122 # 1. Raw decimal numbers composed of digits between 0 and 9
123 # 2. Code beginning with "{" and continuing until the first "}"
124 # ^ This one might need revising
125 # 3. A label, which starts with a capital or small letter, or
126 # underscore, which is optionally followed by a sequence of
127 # capital or small letters, underscores, or digts between 0 and 9
128 opRe = re.compile( \
129 r'^[ \t]*((?P<operandLabel>[a-zA-Z_]\w*)|(?P<operandConst>[0-9][0-9]*)|(\{(?P<operandCode>[^}]*)\}))')
130 lineMatch = lineRe.search(code)
131 while lineMatch != None:
132 statement = MicroOpStatement()
133 # Get a line and seperate it from the rest of the code
134 line = lineMatch.group("line")
135 orig_line = line
136 # print "Parsing line %s" % line
137 code = lineRe.sub('', code, 1)
138
139 # Find the label, if any
140 labelMatch = labelRe.search(line)
141 if labelMatch != None:
142 statement.label = labelMatch.group("label")
143 # print "Found label %s." % statement.label
144 # Clear the label from the statement
145 line = labelRe.sub('', line, 1)
146
147 # Find the class name which is roughly equivalent to the op name
148 classMatch = classRe.search(line)
149 if classMatch == None:
150 raise Exception, "Couldn't find class name in statement: %s" \
151 % orig_line
152 else:
153 statement.className = classMatch.group("className")
154 # print "Found class name %s." % statement.className
155
156 # Clear the class name from the statement
157 line = classRe.sub('', line, 1)
158
159 #Find as many arguments as you can
160 statement.args = []
161 opMatch = opRe.search(line)
162 while opMatch is not None:
163 statement.args.append({})
164 # args is a list of dicts which collect different
165 # representations of operand values. Different forms might be
166 # needed in different places, for instance to replace a label
167 # with an offset.
168 for opType in ("operandLabel", "operandConst", "operandCode"):
169 if opMatch.group(opType):
170 statement.args[-1][opType] = opMatch.group(opType)
171 if len(statement.args[-1]) == 0:
172 print "Problem parsing operand in statement: %s" \
173 % orig_line
174 line = opRe.sub('', line, 1)
175 # print "Found operand %s." % statement.args[-1]
176 opMatch = opRe.search(line)
177 # print "Found operands", statement.args
178
179 # Add this statement to our collection
180 statements.append(statement)
181
182 # Get the next line
183 lineMatch = lineRe.search(code)
184
185 # Decode the labels into displacements
186 labels = buildLabelDict(statements)
187 micropc = 0
188 for statement in statements:
189 for arg in statement.args:
190 if arg.has_key("operandLabel"):
191 if not labels.has_key(arg["operandLabel"]):
192 raise Exception, "Unrecognized label: %s." % arg["operandLabel"]
193 # This is assuming that intra microcode branches go to
194 # the next micropc + displacement, or
195 # micropc + 1 + displacement.
196 arg["operandConst"] = labels[arg["operandLabel"]] - micropc - 1
197 micropc += 1
198 return statements
199}};