ldstop.isa revision 4587:2c9a2534a489
1// Copyright (c) 2007 The Hewlett-Packard Development Company 2// All rights reserved. 3// 4// Redistribution and use of this software in source and binary forms, 5// with or without modification, are permitted provided that the 6// following conditions are met: 7// 8// The software must be used only for Non-Commercial Use which means any 9// use which is NOT directed to receiving any direct monetary 10// compensation for, or commercial advantage from such use. Illustrative 11// examples of non-commercial use are academic research, personal study, 12// teaching, education and corporate research & development. 13// Illustrative examples of commercial use are distributing products for 14// commercial advantage and providing services using the software for 15// commercial advantage. 16// 17// If you wish to use this software or functionality therein that may be 18// covered by patents for commercial use, please contact: 19// Director of Intellectual Property Licensing 20// Office of Strategy and Technology 21// Hewlett-Packard Company 22// 1501 Page Mill Road 23// Palo Alto, California 94304 24// 25// Redistributions of source code must retain the above copyright notice, 26// this list of conditions and the following disclaimer. Redistributions 27// in binary form must reproduce the above copyright notice, this list of 28// conditions and the following disclaimer in the documentation and/or 29// other materials provided with the distribution. Neither the name of 30// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its 31// contributors may be used to endorse or promote products derived from 32// this software without specific prior written permission. No right of 33// sublicense is granted herewith. Derivatives of the software and 34// output created using the software may be prepared, but only for 35// Non-Commercial Uses. Derivatives of the software may be shared with 36// others provided: (i) the others agree to abide by the list of 37// conditions herein which includes the Non-Commercial Use restrictions; 38// and (ii) such Derivatives of the software include the above copyright 39// notice to acknowledge the contribution from this software where 40// applicable, this list of conditions and the disclaimer below. 41// 42// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 43// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 44// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 45// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 46// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 47// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 48// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 49// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 50// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 51// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 52// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 53// 54// Authors: Gabe Black 55 56////////////////////////////////////////////////////////////////////////// 57// 58// LdStOp Microop templates 59// 60////////////////////////////////////////////////////////////////////////// 61 62 63// Load templates 64 65output header {{ 66 /** 67 * Base class for load and store ops 68 */ 69 class LdStOp : public X86MicroopBase 70 { 71 protected: 72 const uint8_t scale; 73 const RegIndex index; 74 const RegIndex base; 75 const uint64_t disp; 76 const uint8_t segment; 77 const RegIndex data; 78 const uint8_t dataSize; 79 const uint8_t addressSize; 80 81 //Constructor 82 LdStOp(ExtMachInst _machInst, 83 const char * mnem, const char * _instMnem, 84 bool isMicro, bool isDelayed, bool isFirst, bool isLast, 85 uint8_t _scale, RegIndex _index, RegIndex _base, 86 uint64_t _disp, uint8_t _segment, 87 RegIndex _data, 88 uint8_t _dataSize, uint8_t _addressSize, 89 OpClass __opClass) : 90 X86MicroopBase(machInst, mnem, _instMnem, 91 isMicro, isDelayed, isFirst, isLast, __opClass), 92 scale(_scale), index(_index), base(_base), 93 disp(_disp), segment(_segment), 94 data(_data), 95 dataSize(_dataSize), addressSize(_addressSize) 96 {} 97 98 std::string generateDisassembly(Addr pc, 99 const SymbolTable *symtab) const; 100 }; 101}}; 102 103output decoder {{ 104 std::string LdStOp::generateDisassembly(Addr pc, 105 const SymbolTable *symtab) const 106 { 107 std::stringstream response; 108 109 printMnemonic(response, instMnem, mnemonic); 110 printReg(response, data); 111 response << ", "; 112 printSegment(response, segment); 113 ccprintf(response, ":[%d*", scale); 114 printReg(response, index); 115 response << " + "; 116 printReg(response, base); 117 ccprintf(response, " + %#x]", disp); 118 return response.str(); 119 } 120}}; 121 122def template MicroLoadExecute {{ 123 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 124 Trace::InstRecord *traceData) const 125 { 126 Fault fault = NoFault; 127 Addr EA; 128 129 %(op_decl)s; 130 %(op_rd)s; 131 %(ea_code)s; 132 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 133 134 fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0); 135 if(fault == NoFault) 136 { 137 %(code)s; 138 } 139 if(fault == NoFault) 140 { 141 %(op_wb)s; 142 } 143 144 return fault; 145 } 146}}; 147 148def template MicroLoadInitiateAcc {{ 149 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 150 Trace::InstRecord * traceData) const 151 { 152 Fault fault = NoFault; 153 Addr EA; 154 155 %(op_decl)s; 156 %(op_rd)s; 157 %(ea_code)s; 158 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 159 160 fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0); 161 162 return fault; 163 } 164}}; 165 166def template MicroLoadCompleteAcc {{ 167 Fault %(class_name)s::completeAcc(PacketPtr pkt, 168 %(CPU_exec_context)s * xc, 169 Trace::InstRecord * traceData) const 170 { 171 Fault fault = NoFault; 172 173 %(op_decl)s; 174 %(op_rd)s; 175 176 Mem = pkt->get<typeof(Mem)>(); 177 %(code)s; 178 179 if(fault == NoFault) 180 { 181 %(op_wb)s; 182 } 183 184 return fault; 185 } 186}}; 187 188// Store templates 189 190def template MicroStoreExecute {{ 191 Fault %(class_name)s::execute(%(CPU_exec_context)s * xc, 192 Trace::InstRecord *traceData) const 193 { 194 Fault fault = NoFault; 195 196 Addr EA; 197 %(op_decl)s; 198 %(op_rd)s; 199 %(ea_code)s; 200 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 201 202 %(code)s; 203 204 if(fault == NoFault) 205 { 206 fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem, 207 EA, 0, 0); 208 } 209 if(fault == NoFault) 210 { 211 %(op_wb)s; 212 } 213 214 return fault; 215 } 216}}; 217 218def template MicroStoreInitiateAcc {{ 219 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 220 Trace::InstRecord * traceData) const 221 { 222 Fault fault = NoFault; 223 224 Addr EA; 225 %(op_decl)s; 226 %(op_rd)s; 227 %(ea_code)s; 228 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 229 230 %(code)s; 231 232 if(fault == NoFault) 233 { 234 fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem, 235 EA, 0, 0); 236 } 237 if(fault == NoFault) 238 { 239 %(op_wb)s; 240 } 241 return fault; 242 } 243}}; 244 245def template MicroStoreCompleteAcc {{ 246 Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc, 247 Trace::InstRecord * traceData) const 248 { 249 return NoFault; 250 } 251}}; 252 253// Common templates 254 255//This delcares the initiateAcc function in memory operations 256def template InitiateAccDeclare {{ 257 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 258}}; 259 260//This declares the completeAcc function in memory operations 261def template CompleteAccDeclare {{ 262 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; 263}}; 264 265def template MicroLdStOpDeclare {{ 266 class %(class_name)s : public %(base_class)s 267 { 268 protected: 269 void buildMe(); 270 271 public: 272 %(class_name)s(ExtMachInst _machInst, 273 const char * instMnem, 274 bool isMicro, bool isDelayed, bool isFirst, bool isLast, 275 uint8_t _scale, RegIndex _index, RegIndex _base, 276 uint64_t _disp, uint8_t _segment, 277 RegIndex _data, 278 uint8_t _dataSize, uint8_t _addressSize); 279 280 %(class_name)s(ExtMachInst _machInst, 281 const char * instMnem, 282 uint8_t _scale, RegIndex _index, RegIndex _base, 283 uint64_t _disp, uint8_t _segment, 284 RegIndex _data, 285 uint8_t _dataSize, uint8_t _addressSize); 286 287 %(BasicExecDeclare)s 288 289 %(InitiateAccDeclare)s 290 291 %(CompleteAccDeclare)s 292 }; 293}}; 294 295def template MicroLdStOpConstructor {{ 296 297 inline void %(class_name)s::buildMe() 298 { 299 %(constructor)s; 300 } 301 302 inline %(class_name)s::%(class_name)s( 303 ExtMachInst machInst, const char * instMnem, 304 uint8_t _scale, RegIndex _index, RegIndex _base, 305 uint64_t _disp, uint8_t _segment, 306 RegIndex _data, 307 uint8_t _dataSize, uint8_t _addressSize) : 308 %(base_class)s(machInst, "%(mnemonic)s", instMnem, 309 false, false, false, false, 310 _scale, _index, _base, 311 _disp, _segment, _data, 312 _dataSize, _addressSize, %(op_class)s) 313 { 314 buildMe(); 315 } 316 317 inline %(class_name)s::%(class_name)s( 318 ExtMachInst machInst, const char * instMnem, 319 bool isMicro, bool isDelayed, bool isFirst, bool isLast, 320 uint8_t _scale, RegIndex _index, RegIndex _base, 321 uint64_t _disp, uint8_t _segment, 322 RegIndex _data, 323 uint8_t _dataSize, uint8_t _addressSize) : 324 %(base_class)s(machInst, "%(mnemonic)s", instMnem, 325 isMicro, isDelayed, isFirst, isLast, 326 _scale, _index, _base, 327 _disp, _segment, _data, 328 _dataSize, _addressSize, %(op_class)s) 329 { 330 buildMe(); 331 } 332}}; 333 334let {{ 335 class LdStOp(X86Microop): 336 def __init__(self, data, segment, addr, disp): 337 self.data = data 338 [self.scale, self.index, self.base] = addr 339 self.disp = disp 340 self.segment = segment 341 self.dataSize = "env.dataSize" 342 self.addressSize = "env.addressSize" 343 344 def getAllocator(self, *microFlags): 345 allocator = '''new %(class_name)s(machInst, mnemonic 346 %(flags)s, %(scale)s, %(index)s, %(base)s, 347 %(disp)s, %(segment)s, %(data)s, 348 %(dataSize)s, %(addressSize)s)''' % { 349 "class_name" : self.className, 350 "flags" : self.microFlagsText(microFlags), 351 "scale" : self.scale, "index" : self.index, 352 "base" : self.base, 353 "disp" : self.disp, 354 "segment" : self.segment, "data" : self.data, 355 "dataSize" : self.dataSize, "addressSize" : self.addressSize} 356 return allocator 357}}; 358 359let {{ 360 361 # Make these empty strings so that concatenating onto 362 # them will always work. 363 header_output = "" 364 decoder_output = "" 365 exec_output = "" 366 367 calculateEA = "EA = scale * Index + Base + disp;" 368 369 def defineMicroLoadOp(mnemonic, code): 370 global header_output 371 global decoder_output 372 global exec_output 373 global microopClasses 374 Name = mnemonic 375 name = mnemonic.lower() 376 377 # Build up the all register version of this micro op 378 iop = InstObjParams(name, Name, 'LdStOp', 379 {"code": code, "ea_code": calculateEA}) 380 header_output += MicroLdStOpDeclare.subst(iop) 381 decoder_output += MicroLdStOpConstructor.subst(iop) 382 exec_output += MicroLoadExecute.subst(iop) 383 exec_output += MicroLoadInitiateAcc.subst(iop) 384 exec_output += MicroLoadCompleteAcc.subst(iop) 385 386 class LoadOp(LdStOp): 387 def __init__(self, data, segment, addr, disp = 0): 388 super(LoadOp, self).__init__(data, segment, addr, disp) 389 self.className = Name 390 self.mnemonic = name 391 392 microopClasses[name] = LoadOp 393 394 defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);') 395 396 def defineMicroStoreOp(mnemonic, code): 397 global header_output 398 global decoder_output 399 global exec_output 400 global microopClasses 401 Name = mnemonic 402 name = mnemonic.lower() 403 404 # Build up the all register version of this micro op 405 iop = InstObjParams(name, Name, 'LdStOp', 406 {"code": code, "ea_code": calculateEA}) 407 header_output += MicroLdStOpDeclare.subst(iop) 408 decoder_output += MicroLdStOpConstructor.subst(iop) 409 exec_output += MicroStoreExecute.subst(iop) 410 exec_output += MicroStoreInitiateAcc.subst(iop) 411 exec_output += MicroStoreCompleteAcc.subst(iop) 412 413 class StoreOp(LdStOp): 414 def __init__(self, data, addr, segment): 415 super(LoadOp, self).__init__(data, addr, segment) 416 self.className = Name 417 self.mnemonic = name 418 419 microopClasses[name] = StoreOp 420 421 defineMicroLoadOp('St', 'Mem = Data;') 422}}; 423 424