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 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 |
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 |
229let{{ |
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 |
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 |
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}}; |