macroop.isa revision 5046:da031ef02439
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: 9// 10// The software must be used only for Non-Commercial Use which means any 11// use which is NOT directed to receiving any direct monetary 12// compensation for, or commercial advantage from such use. Illustrative 13// examples of non-commercial use are academic research, personal study, 14// teaching, education and corporate research & development. 15// Illustrative examples of commercial use are distributing products for 16// commercial advantage and providing services using the software for 17// commercial advantage. 18// 19// If you wish to use this software or functionality therein that may be 20// covered by patents for commercial use, please contact: 21// Director of Intellectual Property Licensing 22// Office of Strategy and Technology 23// Hewlett-Packard Company 24// 1501 Page Mill Road 25// Palo Alto, California 94304 26// 27// Redistributions of source code must retain the above copyright notice, 28// this list of conditions and the following disclaimer. Redistributions 29// in binary form must reproduce the above copyright notice, this list of 30// conditions and the following disclaimer in the documentation and/or 31// other materials provided with the distribution. Neither the name of 32// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its 33// contributors may be used to endorse or promote products derived from 34// this software without specific prior written permission. No right of 35// sublicense is granted herewith. Derivatives of the software and 36// output created using the software may be prepared, but only for 37// Non-Commercial Uses. Derivatives of the software may be shared with 38// others provided: (i) the others agree to abide by the list of 39// conditions herein which includes the Non-Commercial Use restrictions; 40// and (ii) such Derivatives of the software include the above copyright 41// notice to acknowledge the contribution from this software where 42// applicable, this list of conditions and the disclaimer below. 43// 44// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 45// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 46// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 47// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 48// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 49// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 50// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 51// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 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// Architecture independent 61// 62 63// Execute method for macroops. 64def template MacroExecPanic {{ 65 Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const 66 { 67 panic("Tried to execute macroop directly!"); 68 return NoFault; 69 } 70}}; 71 72output header {{ 73 74 // Base class for combinationally generated macroops 75 class Macroop : public StaticInst 76 { 77 protected: 78 const uint32_t numMicroops; 79 80 //Constructor. 81 Macroop(const char *mnem, ExtMachInst _machInst, 82 uint32_t _numMicroops) 83 : StaticInst(mnem, _machInst, No_OpClass), 84 numMicroops(_numMicroops) 85 { 86 assert(numMicroops); 87 microops = new StaticInstPtr[numMicroops]; 88 flags[IsMacroop] = true; 89 } 90 91 ~Macroop() 92 { 93 delete [] microops; 94 } 95 96 StaticInstPtr * microops; 97 98 StaticInstPtr fetchMicroop(MicroPC microPC) 99 { 100 assert(microPC < numMicroops); 101 return microops[microPC]; 102 } 103 104 std::string generateDisassembly(Addr pc, 105 const SymbolTable *symtab) const 106 { 107 return mnemonic; 108 } 109 110 %(MacroExecPanic)s 111 }; 112}}; 113 114////////////////////////////////////////////////////////////////////////////// 115// 116// X86 specific 117// 118////////////////////////////////////////////////////////////////////////////// 119 120// Basic instruction class declaration template. 121def template MacroDeclare {{ 122 namespace X86Macroop 123 { 124 /** 125 * Static instruction class for "%(mnemonic)s". 126 */ 127 class %(class_name)s : public %(base_class)s 128 { 129 private: 130 %(declareLabels)s 131 public: 132 // Constructor. 133 %(class_name)s(ExtMachInst machInst, X86ISA::EmulEnv env); 134 }; 135 }; 136}}; 137 138// Basic instruction class constructor template. 139def template MacroConstructor {{ 140 inline X86Macroop::%(class_name)s::%(class_name)s( 141 ExtMachInst machInst, EmulEnv env) 142 : %(base_class)s("%(mnemonic)s", machInst, %(num_microops)s) 143 { 144 %(adjust_env)s; 145 %(do_modrm)s; 146 %(constructor)s; 147 //alloc_microops is the code that sets up the microops 148 //array in the parent class. 149 %(alloc_microops)s; 150 } 151}}; 152 153let {{ 154 from micro_asm import Combinational_Macroop, Rom_Macroop 155 class X86Macroop(Combinational_Macroop): 156 def add_microop(self, mnemonic, microop): 157 microop.mnemonic = mnemonic 158 microop.micropc = len(self.microops) 159 self.microops.append(microop) 160 def setAdjustEnv(self, val): 161 self.adjust_env = val 162 def __init__(self, name): 163 super(X86Macroop, self).__init__(name) 164 self.directives = { 165 "adjust_env" : self.setAdjustEnv 166 } 167 self.declared = False 168 self.adjust_env = "" 169 self.doModRM = "" 170 def getAllocator(self, env): 171 return "new X86Macroop::%s(machInst, %s)" % (self.name, env.getAllocator()) 172 def getDeclaration(self): 173 #FIXME This first parameter should be the mnemonic. I need to 174 #write some code which pulls that out 175 declareLabels = "" 176 for (label, microop) in self.labels.items(): 177 declareLabels += "const static uint64_t label_%s = %d;\n" \ 178 % (label, microop.micropc) 179 iop = InstObjParams(self.name, self.name, "Macroop", 180 {"code" : "", 181 "declareLabels" : declareLabels 182 }) 183 return MacroDeclare.subst(iop); 184 def getDefinition(self): 185 #FIXME This first parameter should be the mnemonic. I need to 186 #write some code which pulls that out 187 numMicroops = len(self.microops) 188 allocMicroops = '' 189 micropc = 0 190 for op in self.microops: 191 allocMicroops += \ 192 "microops[%d] = %s;\n" % \ 193 (micropc, op.getAllocator(True, False, 194 micropc == 0, 195 micropc == numMicroops - 1)) 196 micropc += 1 197 iop = InstObjParams(self.name, self.name, "Macroop", 198 {"code" : "", "num_microops" : numMicroops, 199 "alloc_microops" : allocMicroops, 200 "adjust_env" : self.adjust_env, 201 "do_modrm" : self.doModRM}) 202 return MacroConstructor.subst(iop); 203}}; 204 205let {{ 206 class EmulEnv(object): 207 def __init__(self): 208 self.reg = "0" 209 self.regUsed = False 210 self.regm = "0" 211 self.regmUsed = False 212 self.seg = "SEGMENT_REG_DS" 213 self.size = None 214 self.addressSize = "ADDRSIZE" 215 self.dataSize = "OPSIZE" 216 self.stackSize = "STACKSIZE" 217 self.doModRM = False 218 219 def getAllocator(self): 220 if self.size == 'b': 221 self.dataSize = 1 222 elif self.size == 'd': 223 self.dataSize = 4 224 #This is for "double plus" which is normally a double word unless 225 #the REX W bit is set, in which case it's a quad word. It's used 226 #for some SSE instructions. 227 elif self.size == 'dp': 228 self.dataSize = "(REX_W ? 8 : 4)" 229 elif self.size == 'q': 230 self.dataSize = 8 231 elif self.size == 'v': 232 self.dataSize = "OPSIZE" 233 elif self.size == 'w': 234 self.dataSize = 2 235 elif self.size == 'z': 236 self.dataSize = "((OPSIZE == 8) ? 4 : OPSIZE)" 237 elif self.size: 238 raise Exception, "Unrecognized size type %s!" % self.size 239 return '''EmulEnv(%(reg)s, 240 %(regm)s, 241 %(dataSize)s, 242 %(addressSize)s, 243 %(stackSize)s)''' % \ 244 self.__dict__ 245 246 def addReg(self, reg): 247 if not self.regUsed: 248 self.reg = reg 249 self.regUsed = True 250 elif not self.regmUsed: 251 self.regm = reg 252 self.regmUsed = True 253 else: 254 raise Exception, "EmulEnv is out of register specialization spots." 255 def setSize(self, size): 256 if not self.size: 257 self.size = size 258 else: 259 if self.size != size: 260 raise Exception, "Conflicting register sizes %s and %s!" %\ 261 (self.size, size) 262}}; 263 264let {{ 265 doModRMString = "env.doModRM(machInst);\n" 266 def genMacroop(Name, env): 267 blocks = OutputBlocks() 268 if not macroopDict.has_key(Name): 269 raise Exception, "Unrecognized instruction: %s" % Name 270 macroop = macroopDict[Name] 271 if not macroop.declared: 272 if env.doModRM: 273 macroop.doModRM = doModRMString 274 blocks.header_output = macroop.getDeclaration() 275 blocks.decoder_output = macroop.getDefinition() 276 macroop.declared = True 277 blocks.decode_block = "return %s;\n" % macroop.getAllocator(env) 278 return blocks 279}}; 280