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: --- 62 unchanged lines hidden (view full) --- 71 72output header {{ 73 74 // Base class for combinationally generated macroops 75 class Macroop : public X86ISA::MacroopBase 76 { 77 public: 78 Macroop(const char *mnem, ExtMachInst _machInst, |
79 uint32_t _numMicroops, X86ISA::EmulEnv _env) 80 : MacroopBase(mnem, _machInst, _numMicroops, _env) |
81 {} 82 %(MacroExecPanic)s 83 }; 84}}; 85 86////////////////////////////////////////////////////////////////////////////// 87// 88// X86 specific --- 8 unchanged lines hidden (view full) --- 97 * Static instruction class for "%(mnemonic)s". 98 */ 99 class %(class_name)s : public %(base_class)s 100 { 101 private: 102 %(declareLabels)s 103 public: 104 // Constructor. |
105 %(class_name)s(ExtMachInst machInst, X86ISA::EmulEnv _env); 106 107 std::string 108 generateDisassembly(Addr pc, const SymbolTable *symtab) const; |
109 }; 110 }; 111}}; 112 |
113def template MacroDisassembly {{ 114 std::string 115 X86Macroop::%(class_name)s::generateDisassembly(Addr pc, 116 const SymbolTable *symtab) const 117 { 118 std::stringstream out; 119 out << mnemonic << "\t"; 120 121 int regSize = %(regSize)s; 122 %(disassembly)s 123 // Shut up gcc. 124 regSize = regSize; 125 return out.str(); 126 } 127}}; 128 |
129// Basic instruction class constructor template. 130def template MacroConstructor {{ 131 inline X86Macroop::%(class_name)s::%(class_name)s( |
132 ExtMachInst machInst, EmulEnv _env) 133 : %(base_class)s("%(mnemonic)s", machInst, %(num_microops)s, _env) |
134 { 135 %(adjust_env)s; 136 %(adjust_imm)s; 137 %(adjust_disp)s; 138 %(do_modrm)s; 139 %(constructor)s; |
140 const char *macrocodeBlock = "%(class_name)s"; |
141 //alloc_microops is the code that sets up the microops 142 //array in the parent class. 143 %(alloc_microops)s; 144 } 145}}; 146 147let {{ 148 from micro_asm import Combinational_Macroop, Rom_Macroop --- 24 unchanged lines hidden (view full) --- 173 adjustedImm = adjustedImm; 174 ''' 175 self.adjust_disp = ''' 176 uint64_t adjustedDisp = DISPLACEMENT; 177 //This is to pacify gcc in case the displacement isn't used. 178 adjustedDisp = adjustedDisp; 179 ''' 180 def getAllocator(self, env): |
181 return "new X86Macroop::%s(machInst, %s)" % \ 182 (self.name, env.getAllocator()) 183 def getMnemonic(self): 184 mnemonic = self.name.lower() 185 mnemonic = re.match(r'[^_]*', mnemonic).group(0) 186 return mnemonic |
187 def getDeclaration(self): 188 #FIXME This first parameter should be the mnemonic. I need to 189 #write some code which pulls that out 190 declareLabels = "" 191 for (label, microop) in self.labels.items(): 192 declareLabels += "const static uint64_t label_%s = %d;\n" \ 193 % (label, microop.micropc) |
194 iop = InstObjParams(self.getMnemonic(), self.name, "Macroop", |
195 {"code" : "", 196 "declareLabels" : declareLabels 197 }) 198 return MacroDeclare.subst(iop); |
199 def getDefinition(self, env): |
200 #FIXME This first parameter should be the mnemonic. I need to 201 #write some code which pulls that out 202 numMicroops = len(self.microops) 203 allocMicroops = '' 204 micropc = 0 205 for op in self.microops: 206 isLast = (micropc == numMicroops - 1) 207 allocMicroops += \ 208 "microops[%d] = %s;\n" % \ 209 (micropc, op.getAllocator(True, not isLast, 210 micropc == 0, isLast)) 211 micropc += 1 |
212 if env.useStackSize: 213 useStackSize = "true" 214 else: 215 useStackSize = "false" 216 if env.memoryInst: 217 memoryInst = "true" 218 else: 219 memoryInst = "false" 220 regSize = '''(%s || (env.base == INTREG_RSP && %s) ? 221 env.stackSize : 222 env.dataSize)''' % (useStackSize, memoryInst) 223 iop = InstObjParams(self.getMnemonic(), self.name, "Macroop", |
224 {"code" : "", "num_microops" : numMicroops, 225 "alloc_microops" : allocMicroops, 226 "adjust_env" : self.adjust_env, 227 "adjust_imm" : self.adjust_imm, 228 "adjust_disp" : self.adjust_disp, |
229 "disassembly" : env.disassembly, 230 "regSize" : regSize, |
231 "do_modrm" : self.doModRM}) |
232 return MacroConstructor.subst(iop) + \ 233 MacroDisassembly.subst(iop); |
234}}; 235 236let {{ 237 class EmulEnv(object): 238 def __init__(self): 239 self.reg = "0" 240 self.regUsed = False 241 self.regm = "0" 242 self.regmUsed = False 243 self.seg = "SEGMENT_REG_DS" 244 self.size = None 245 self.addressSize = "ADDRSIZE" 246 self.dataSize = "OPSIZE" 247 self.stackSize = "STACKSIZE" 248 self.doModRM = False |
249 self.disassembly = "" 250 self.firstArgument = True 251 self.useStackSize = False 252 self.memoryInst = False |
253 |
254 def addToDisassembly(self, code): 255 if not self.firstArgument: 256 self.disassembly += "out << \", \";\n" 257 self.firstArgument = False 258 self.disassembly += code 259 |
260 def getAllocator(self): 261 if self.size == 'b': 262 self.dataSize = 1 263 elif self.size == 'd': 264 self.dataSize = 4 265 #This is for "double plus" which is normally a double word unless 266 #the REX W bit is set, in which case it's a quad word. It's used 267 #for some SSE instructions. --- 40 unchanged lines hidden (view full) --- 308 blocks = OutputBlocks() 309 if not macroopDict.has_key(Name): 310 raise Exception, "Unrecognized instruction: %s" % Name 311 macroop = macroopDict[Name] 312 if not macroop.declared: 313 if env.doModRM: 314 macroop.doModRM = doModRMString 315 blocks.header_output = macroop.getDeclaration() |
316 blocks.decoder_output = macroop.getDefinition(env) |
317 macroop.declared = True 318 blocks.decode_block = "return %s;\n" % macroop.getAllocator(env) 319 return blocks 320}}; |