microasm.isa (4323:13ca4002d2ac) | microasm.isa (4336:bd6ab22f8e11) |
---|---|
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: --- 43 unchanged lines hidden (view full) --- 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// | 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: --- 43 unchanged lines hidden (view full) --- 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 | 60// Code to "specialize" a microcode sequence to use a particular 61// variety of operands |
61// 62 63let {{ | 62// 63 64let {{ |
64 class MicroOpStatement: | 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 (X86StaticInst *)(%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 90 exec_output = '' 91 for (val, todo) in vals.items(): 92 (new_header_output, 93 new_decoder_output, 94 new_decode_block, 95 new_exec_output) = builder(name, Name, *todo) 96 header_output += new_header_output 97 decoder_output += new_decoder_output 98 decode_block += '\tcase %s: %s\n' % (val, new_decode_block) 99 exec_output += new_exec_output 100 if default: 101 (new_header_output, 102 new_decoder_output, 103 new_decode_block, 104 new_exec_output) = builder(name, Name, *default) 105 header_output += new_header_output 106 decoder_output += new_decoder_output 107 decode_block += '\tdefault: %s\n' % new_decode_block 108 exec_output += new_exec_output 109 decode_block += '}\n' 110 return (header_output, decoder_output, decode_block, exec_output) 111}}; 112 113let {{ 114 class OpType(object): 115 parser = re.compile(r"(?P<tag>[A-Z][A-Z]*)(?P<size>[a-z][a-z]*)|(r(?P<reg>[A-Za-z0-9][A-Za-z0-9]*))") 116 def __init__(self, opTypeString): 117 match = OpType.parser.search(opTypeString) 118 if match == None: 119 raise Exception, "Problem parsing operand type %s" % opTypeString 120 self.reg = match.group("reg") 121 self.tag = match.group("tag") 122 self.size = match.group("size") 123}}; 124 125let {{ 126 127 # This function specializes the given piece of code to use a particular 128 # set of argument types described by "opTypes". These are "implemented" 129 # in reverse order. 130 def specializeInst(name, Name, code, opTypes): 131 opNum = len(opTypes) - 1 132 while len(opTypes): 133 # print "Building a composite op with tags", opTypes 134 # print "And code", code 135 opNum = len(opTypes) - 1 136 # A regular expression to find the operand placeholders we're 137 # interested in. 138 opRe = re.compile("%%(?P<operandNum>%d)(?=[^0-9]|$)" % opNum) 139 140 # Parse the operand type strign we're working with 141 print "About to parse tag %s" % opTypes[opNum] 142 opType = OpType(opTypes[opNum]) 143 144 if opType.reg: 145 #Figure out what to do with fixed register operands 146 if opType.reg in ("Ax", "Bx", "Cx", "Dx"): 147 code = opRe.sub("{INTREG_R%s}" % opType.reg.upper(), code) 148 elif opType.reg == "Al": 149 # We need a way to specify register width 150 code = opRe.sub("{INTREG_RAX}", code) 151 else: 152 print "Didn't know how to encode fixed register %s!" % opType.reg 153 elif opType.tag == None or opType.size == None: 154 raise Exception, "Problem parsing operand tag: %s" % opType.tag 155 elif opType.tag in ("C", "D", "G", "P", "S", "T", "V"): 156 # Use the "reg" field of the ModRM byte to select the register 157 code = opRe.sub("{(uint8_t)MODRM_REG}", code) 158 elif opType.tag in ("E", "Q", "W"): 159 # This might refer to memory or to a register. We need to 160 # divide it up farther. 161 regCode = opRe.sub("{(uint8_t)MODRM_RM}", code) 162 regTypes = copy.copy(opTypes) 163 regTypes.pop(-1) 164 # This needs to refer to memory, but we'll fill in the details 165 # later. It needs to take into account unaligned memory 166 # addresses. 167 memCode = opRe.sub("0", code) 168 memTypes = copy.copy(opTypes) 169 memTypes.pop(-1) 170 return doSplitDecode(name, Name, specializeInst, "MODRM_MOD", 171 {"3" : (regCode, regTypes)}, (memCode, memTypes)) 172 elif opType.tag in ("I", "J"): 173 # Immediates are already in the instruction, so don't leave in 174 # those parameters 175 code = opRe.sub("", code) 176 elif opType.tag == "M": 177 # This needs to refer to memory, but we'll fill in the details 178 # later. It needs to take into account unaligned memory 179 # addresses. 180 code = opRe.sub("0", code) 181 elif opType.tag in ("PR", "R", "VR"): 182 # There should probably be a check here to verify that mod 183 # is equal to 11b 184 code = opRe.sub("{(uint8_t)MODRM_RM}", code) 185 else: 186 raise Exception, "Unrecognized tag %s." % opType.tag 187 opTypes.pop(-1) 188 189 # At this point, we've built up "code" to have all the necessary extra 190 # instructions needed to implement whatever types of operands were 191 # specified. Now we'll assemble it it into a microOp sequence. 192 ops = assembleMicro(code) 193 194 # Build a macroop to contain the sequence of microops we've 195 # constructed. The decode block will be used to fill in our 196 # inner decode structure, and the rest will be concatenated and 197 # passed back. 198 return genInst(name, Name, ops) 199}}; 200 201//////////////////////////////////////////////////////////////////// 202// 203// The microcode assembler 204// 205 206let {{ 207 class MicroOpStatement(object): |
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): --- 23 unchanged lines hidden (view full) --- 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 | 208 def __init__(self): 209 self.className = '' 210 self.label = '' 211 self.args = [] 212 213 # This converts a list of python bools into 214 # a comma seperated list of C++ bools. 215 def microFlagsText(self, vals): --- 23 unchanged lines hidden (view full) --- 239 def buildLabelDict(ops): 240 labels = {} 241 micropc = 0 242 for op in ops: 243 if op.label: 244 labels[op.label] = count 245 micropc += 1 246 return labels |
247}}; |
|
104 | 248 |
249let{{ |
|
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 = [] --- 87 unchanged lines hidden --- | 250 def assembleMicro(code): 251 # This function takes in a block of microcode assembly and returns 252 # a python list of objects which describe it. 253 254 # Keep this around in case we need it later 255 orig_code = code 256 # A list of the statements we've found thus far 257 statements = [] --- 87 unchanged lines hidden --- |