microasm.isa (4343:3f11bcf873b3) | microasm.isa (4344:174e31456abe) |
---|---|
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 {{ | 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 {{ | |
82 # This code builds up a decode block which decodes based on switchval. 83 # vals is a dict which matches case values with what should be decoded to. 84 # builder is called on the exploded contents of "vals" values to generate 85 # whatever code should be used. 86 def doSplitDecode(name, Name, builder, switchVal, vals, default = None): 87 header_output = '' 88 decoder_output = '' 89 decode_block = 'switch(%s) {\n' % switchVal --- 92 unchanged lines hidden (view full) --- 182 # is equal to 11b 183 code = opRe.sub("%{(uint8_t)MODRM_RM}", code) 184 else: 185 raise Exception, "Unrecognized tag %s." % opType.tag 186 opTypes.pop(-1) 187 188 # At this point, we've built up "code" to have all the necessary extra 189 # instructions needed to implement whatever types of operands were | 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) |
198}}; 199 200//////////////////////////////////////////////////////////////////// 201// 202// The microcode assembler 203// 204 205let {{ | 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 {{ |
|
206 class MicroOpStatement(object): 207 def __init__(self): 208 self.className = '' 209 self.label = '' 210 self.args = [] 211 212 # This converts a list of python bools into 213 # a comma seperated list of C++ bools. --- 23 unchanged lines hidden (view full) --- 237 elif arg.has_key("operandLabel"): 238 raise Exception, "Found a label while creating allocator string." 239 else: 240 raise Exception, "Unrecognized operand type." 241 signature += ">" 242 return 'new %s%s(machInst%s%s)' % (self.className, signature, self.microFlagsText(microFlags), args) 243}}; 244 | 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 | |
256let{{ | 229let{{ |
257 def assembleMicro(code): | 230 def assembleMicro(name, Name, code): 231 |
258 # This function takes in a block of microcode assembly and returns 259 # a python list of objects which describe it. 260 261 # Keep this around in case we need it later 262 orig_code = code 263 # A list of the statements we've found thus far 264 statements = [] 265 --- 70 unchanged lines hidden (view full) --- 336 337 # Add this statement to our collection 338 statements.append(statement) 339 340 # Get the next line 341 lineMatch = lineRe.search(code) 342 343 # Decode the labels into displacements | 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 = {} |
345 micropc = 0 346 for statement in statements: | 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: |
|
347 for arg in statement.args: 348 if arg.has_key("operandLabel"): 349 if not labels.has_key(arg["operandLabel"]): 350 raise Exception, "Unrecognized label: %s." % arg["operandLabel"] 351 # This is assuming that intra microcode branches go to 352 # the next micropc + displacement, or 353 # micropc + 1 + displacement. 354 arg["operandImm"] = labels[arg["operandLabel"]] - micropc - 1 355 micropc += 1 | 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) |
357}}; | 347}}; |