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:

--- 48 unchanged lines hidden (view full) ---

57
58////////////////////////////////////////////////////////////////////
59//
60// Code to "specialize" a microcode sequence to use a particular
61// variety of operands
62//
63
64let {{
65 # This builds either a regular or macro op to implement the sequence of
66 # ops we give it.
67 def genInst(name, Name, ops):
68 # If we can implement this instruction with exactly one microop, just
69 # use that directly.
70 newStmnt = ''
71 if len(ops) == 1:
72 decode_block = "return %s;" % \
73 ops[0].getAllocator()
74 return ('', '', decode_block, '')
75 else:
76 # Build a macroop to contain the sequence of microops we've
77 # been given.
78 return genMacroOp(name, Name, ops)
79}};
80
81let {{
65 # This code builds up a decode block which decodes based on switchval.
66 # vals is a dict which matches case values with what should be decoded to.
67 # builder is called on the exploded contents of "vals" values to generate
68 # whatever code should be used.
69 def doSplitDecode(name, Name, builder, switchVal, vals, default = None):
70 header_output = ''
71 decoder_output = ''
72 decode_block = 'switch(%s) {\n' % switchVal

--- 92 unchanged lines hidden (view full) ---

165 # is equal to 11b
166 code = opRe.sub("%{(uint8_t)MODRM_RM}", code)
167 else:
168 raise Exception, "Unrecognized tag %s." % opType.tag
169 opTypes.pop(-1)
170
171 # At this point, we've built up "code" to have all the necessary extra
172 # instructions needed to implement whatever types of operands were
190 # specified. Now we'll assemble it it into a microOp sequence.
191 ops = assembleMicro(code)
192
193 # Build a macroop to contain the sequence of microops we've
194 # constructed. The decode block will be used to fill in our
195 # inner decode structure, and the rest will be concatenated and
196 # passed back.
197 return genInst(name, Name, ops)
173 # specified. Now we'll assemble it it into a StaticInst.
174 return assembleMicro(name, Name, code)
175}};
176
177////////////////////////////////////////////////////////////////////
178//
179// The microcode assembler
180//
181
182let {{
183 # These are used when setting up microops so that they can specialize their
184 # base class template properly.
185 RegOpType = "RegisterOperand"
186 ImmOpType = "ImmediateOperand"
187}};
188
189let {{
190 class MicroOpStatement(object):
191 def __init__(self):
192 self.className = ''
193 self.label = ''
194 self.args = []
195
196 # This converts a list of python bools into
197 # a comma seperated list of C++ bools.

--- 23 unchanged lines hidden (view full) ---

221 elif arg.has_key("operandLabel"):
222 raise Exception, "Found a label while creating allocator string."
223 else:
224 raise Exception, "Unrecognized operand type."
225 signature += ">"
226 return 'new %s%s(machInst%s%s)' % (self.className, signature, self.microFlagsText(microFlags), args)
227}};
228
245let {{
246 def buildLabelDict(ops):
247 labels = {}
248 micropc = 0
249 for op in ops:
250 if op.label:
251 labels[op.label] = count
252 micropc += 1
253 return labels
254}};
255
229let{{
257 def assembleMicro(code):
230 def assembleMicro(name, Name, code):
231
232 # This function takes in a block of microcode assembly and returns
233 # a python list of objects which describe it.
234
235 # Keep this around in case we need it later
236 orig_code = code
237 # A list of the statements we've found thus far
238 statements = []
239

--- 70 unchanged lines hidden (view full) ---

310
311 # Add this statement to our collection
312 statements.append(statement)
313
314 # Get the next line
315 lineMatch = lineRe.search(code)
316
317 # Decode the labels into displacements
344 labels = buildLabelDict(statements)
318
319 labels = {}
320 micropc = 0
321 for statement in statements:
322 if statement.label:
323 labels[statement.label] = count
324 micropc += 1
325 micropc = 0
326 for statement in statements:
327 for arg in statement.args:
328 if arg.has_key("operandLabel"):
329 if not labels.has_key(arg["operandLabel"]):
330 raise Exception, "Unrecognized label: %s." % arg["operandLabel"]
331 # This is assuming that intra microcode branches go to
332 # the next micropc + displacement, or
333 # micropc + 1 + displacement.
334 arg["operandImm"] = labels[arg["operandLabel"]] - micropc - 1
335 micropc += 1
356 return statements
336
337 # If we can implement this instruction with exactly one microop, just
338 # use that directly.
339 if len(statements) == 1:
340 decode_block = "return %s;" % \
341 statements[0].getAllocator()
342 return ('', '', decode_block, '')
343 else:
344 # Build a macroop to contain the sequence of microops we've
345 # been given.
346 return genMacroOp(name, Name, statements)
347}};