ldstop.isa revision 4601
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 62output header {{ 63 /** 64 * Base class for load and store ops 65 */ 66 class LdStOp : public X86MicroopBase 67 { 68 protected: 69 const uint8_t scale; 70 const RegIndex index; 71 const RegIndex base; 72 const uint64_t disp; 73 const uint8_t segment; 74 const RegIndex data; 75 const uint8_t dataSize; 76 const uint8_t addressSize; 77 78 //Constructor 79 LdStOp(ExtMachInst _machInst, 80 const char * mnem, const char * _instMnem, 81 bool isMicro, bool isDelayed, bool isFirst, bool isLast, 82 uint8_t _scale, RegIndex _index, RegIndex _base, 83 uint64_t _disp, uint8_t _segment, 84 RegIndex _data, 85 uint8_t _dataSize, uint8_t _addressSize, 86 OpClass __opClass) : 87 X86MicroopBase(machInst, mnem, _instMnem, 88 isMicro, isDelayed, isFirst, isLast, __opClass), 89 scale(_scale), index(_index), base(_base), 90 disp(_disp), segment(_segment), 91 data(_data), 92 dataSize(_dataSize), addressSize(_addressSize) 93 {} 94 95 std::string generateDisassembly(Addr pc, 96 const SymbolTable *symtab) const; 97 }; 98}}; 99 100output decoder {{ 101 std::string LdStOp::generateDisassembly(Addr pc, 102 const SymbolTable *symtab) const 103 { 104 std::stringstream response; 105 106 printMnemonic(response, instMnem, mnemonic); 107 printReg(response, data); 108 response << ", "; 109 printSegment(response, segment); 110 ccprintf(response, ":[%d*", scale); 111 printReg(response, index); 112 response << " + "; 113 printReg(response, base); 114 ccprintf(response, " + %#x]", disp); 115 return response.str(); 116 } 117}}; 118 119// LEA template 120 121def template MicroLeaExecute {{ 122 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 123 Trace::InstRecord *traceData) const 124 { 125 Fault fault = NoFault; 126 Addr EA; 127 128 %(op_decl)s; 129 %(op_rd)s; 130 %(ea_code)s; 131 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 132 133 %(code)s; 134 if(fault == NoFault) 135 { 136 %(op_wb)s; 137 } 138 139 return fault; 140 } 141}}; 142 143def template MicroLeaDeclare {{ 144 class %(class_name)s : public %(base_class)s 145 { 146 protected: 147 void buildMe(); 148 149 public: 150 %(class_name)s(ExtMachInst _machInst, 151 const char * instMnem, 152 bool isMicro, bool isDelayed, bool isFirst, bool isLast, 153 uint8_t _scale, RegIndex _index, RegIndex _base, 154 uint64_t _disp, uint8_t _segment, 155 RegIndex _data, 156 uint8_t _dataSize, uint8_t _addressSize); 157 158 %(class_name)s(ExtMachInst _machInst, 159 const char * instMnem, 160 uint8_t _scale, RegIndex _index, RegIndex _base, 161 uint64_t _disp, uint8_t _segment, 162 RegIndex _data, 163 uint8_t _dataSize, uint8_t _addressSize); 164 165 %(BasicExecDeclare)s 166 }; 167}}; 168 169// Load templates 170 171def template MicroLoadExecute {{ 172 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 173 Trace::InstRecord *traceData) const 174 { 175 Fault fault = NoFault; 176 Addr EA; 177 178 %(op_decl)s; 179 %(op_rd)s; 180 %(ea_code)s; 181 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 182 183 fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0); 184 if(fault == NoFault) 185 { 186 %(code)s; 187 } 188 if(fault == NoFault) 189 { 190 %(op_wb)s; 191 } 192 193 return fault; 194 } 195}}; 196 197def template MicroLoadInitiateAcc {{ 198 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 199 Trace::InstRecord * traceData) const 200 { 201 Fault fault = NoFault; 202 Addr EA; 203 204 %(op_decl)s; 205 %(op_rd)s; 206 %(ea_code)s; 207 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 208 209 fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0); 210 211 return fault; 212 } 213}}; 214 215def template MicroLoadCompleteAcc {{ 216 Fault %(class_name)s::completeAcc(PacketPtr pkt, 217 %(CPU_exec_context)s * xc, 218 Trace::InstRecord * traceData) const 219 { 220 Fault fault = NoFault; 221 222 %(op_decl)s; 223 %(op_rd)s; 224 225 Mem = pkt->get<typeof(Mem)>(); 226 %(code)s; 227 228 if(fault == NoFault) 229 { 230 %(op_wb)s; 231 } 232 233 return fault; 234 } 235}}; 236 237// Store templates 238 239def template MicroStoreExecute {{ 240 Fault %(class_name)s::execute(%(CPU_exec_context)s * xc, 241 Trace::InstRecord *traceData) const 242 { 243 Fault fault = NoFault; 244 245 Addr EA; 246 %(op_decl)s; 247 %(op_rd)s; 248 %(ea_code)s; 249 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 250 251 %(code)s; 252 253 if(fault == NoFault) 254 { 255 fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem, 256 EA, 0, 0); 257 } 258 if(fault == NoFault) 259 { 260 %(op_wb)s; 261 } 262 263 return fault; 264 } 265}}; 266 267def template MicroStoreInitiateAcc {{ 268 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 269 Trace::InstRecord * traceData) const 270 { 271 Fault fault = NoFault; 272 273 Addr EA; 274 %(op_decl)s; 275 %(op_rd)s; 276 %(ea_code)s; 277 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 278 279 %(code)s; 280 281 if(fault == NoFault) 282 { 283 fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem, 284 EA, 0, 0); 285 } 286 if(fault == NoFault) 287 { 288 %(op_wb)s; 289 } 290 return fault; 291 } 292}}; 293 294def template MicroStoreCompleteAcc {{ 295 Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc, 296 Trace::InstRecord * traceData) const 297 { 298 return NoFault; 299 } 300}}; 301 302// Common templates 303 304//This delcares the initiateAcc function in memory operations 305def template InitiateAccDeclare {{ 306 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 307}}; 308 309//This declares the completeAcc function in memory operations 310def template CompleteAccDeclare {{ 311 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; 312}}; 313 314def template MicroLdStOpDeclare {{ 315 class %(class_name)s : public %(base_class)s 316 { 317 protected: 318 void buildMe(); 319 320 public: 321 %(class_name)s(ExtMachInst _machInst, 322 const char * instMnem, 323 bool isMicro, bool isDelayed, bool isFirst, bool isLast, 324 uint8_t _scale, RegIndex _index, RegIndex _base, 325 uint64_t _disp, uint8_t _segment, 326 RegIndex _data, 327 uint8_t _dataSize, uint8_t _addressSize); 328 329 %(class_name)s(ExtMachInst _machInst, 330 const char * instMnem, 331 uint8_t _scale, RegIndex _index, RegIndex _base, 332 uint64_t _disp, uint8_t _segment, 333 RegIndex _data, 334 uint8_t _dataSize, uint8_t _addressSize); 335 336 %(BasicExecDeclare)s 337 338 %(InitiateAccDeclare)s 339 340 %(CompleteAccDeclare)s 341 }; 342}}; 343 344def template MicroLdStOpConstructor {{ 345 346 inline void %(class_name)s::buildMe() 347 { 348 %(constructor)s; 349 } 350 351 inline %(class_name)s::%(class_name)s( 352 ExtMachInst machInst, const char * instMnem, 353 uint8_t _scale, RegIndex _index, RegIndex _base, 354 uint64_t _disp, uint8_t _segment, 355 RegIndex _data, 356 uint8_t _dataSize, uint8_t _addressSize) : 357 %(base_class)s(machInst, "%(mnemonic)s", instMnem, 358 false, false, false, false, 359 _scale, _index, _base, 360 _disp, _segment, _data, 361 _dataSize, _addressSize, %(op_class)s) 362 { 363 buildMe(); 364 } 365 366 inline %(class_name)s::%(class_name)s( 367 ExtMachInst machInst, const char * instMnem, 368 bool isMicro, bool isDelayed, bool isFirst, bool isLast, 369 uint8_t _scale, RegIndex _index, RegIndex _base, 370 uint64_t _disp, uint8_t _segment, 371 RegIndex _data, 372 uint8_t _dataSize, uint8_t _addressSize) : 373 %(base_class)s(machInst, "%(mnemonic)s", instMnem, 374 isMicro, isDelayed, isFirst, isLast, 375 _scale, _index, _base, 376 _disp, _segment, _data, 377 _dataSize, _addressSize, %(op_class)s) 378 { 379 buildMe(); 380 } 381}}; 382 383let {{ 384 class LdStOp(X86Microop): 385 def __init__(self, data, segment, addr, disp): 386 self.data = data 387 [self.scale, self.index, self.base] = addr 388 self.disp = disp 389 self.segment = segment 390 self.dataSize = "env.dataSize" 391 self.addressSize = "env.addressSize" 392 393 def getAllocator(self, *microFlags): 394 allocator = '''new %(class_name)s(machInst, mnemonic 395 %(flags)s, %(scale)s, %(index)s, %(base)s, 396 %(disp)s, %(segment)s, %(data)s, 397 %(dataSize)s, %(addressSize)s)''' % { 398 "class_name" : self.className, 399 "flags" : self.microFlagsText(microFlags), 400 "scale" : self.scale, "index" : self.index, 401 "base" : self.base, 402 "disp" : self.disp, 403 "segment" : self.segment, "data" : self.data, 404 "dataSize" : self.dataSize, "addressSize" : self.addressSize} 405 return allocator 406}}; 407 408let {{ 409 410 # Make these empty strings so that concatenating onto 411 # them will always work. 412 header_output = "" 413 decoder_output = "" 414 exec_output = "" 415 416 calculateEA = "EA = scale * Index + Base + disp;" 417 418 def defineMicroLoadOp(mnemonic, code): 419 global header_output 420 global decoder_output 421 global exec_output 422 global microopClasses 423 Name = mnemonic 424 name = mnemonic.lower() 425 426 # Build up the all register version of this micro op 427 iop = InstObjParams(name, Name, 'LdStOp', 428 {"code": code, "ea_code": calculateEA}) 429 header_output += MicroLdStOpDeclare.subst(iop) 430 decoder_output += MicroLdStOpConstructor.subst(iop) 431 exec_output += MicroLoadExecute.subst(iop) 432 exec_output += MicroLoadInitiateAcc.subst(iop) 433 exec_output += MicroLoadCompleteAcc.subst(iop) 434 435 class LoadOp(LdStOp): 436 def __init__(self, data, segment, addr, disp = 0): 437 super(LoadOp, self).__init__(data, segment, addr, disp) 438 self.className = Name 439 self.mnemonic = name 440 441 microopClasses[name] = LoadOp 442 443 defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);') 444 445 def defineMicroStoreOp(mnemonic, code): 446 global header_output 447 global decoder_output 448 global exec_output 449 global microopClasses 450 Name = mnemonic 451 name = mnemonic.lower() 452 453 # Build up the all register version of this micro op 454 iop = InstObjParams(name, Name, 'LdStOp', 455 {"code": code, "ea_code": calculateEA}) 456 header_output += MicroLdStOpDeclare.subst(iop) 457 decoder_output += MicroLdStOpConstructor.subst(iop) 458 exec_output += MicroStoreExecute.subst(iop) 459 exec_output += MicroStoreInitiateAcc.subst(iop) 460 exec_output += MicroStoreCompleteAcc.subst(iop) 461 462 class StoreOp(LdStOp): 463 def __init__(self, data, segment, addr, disp = 0): 464 super(LoadOp, self).__init__(data, segment, addr, disp) 465 self.className = Name 466 self.mnemonic = name 467 468 microopClasses[name] = StoreOp 469 470 defineMicroLoadOp('St', 'Mem = Data;') 471 472 iop = InstObjParams("lea", "Lea", 'LdStOp', 473 {"code": "Data = merge(Data, EA, dataSize);", "ea_code": calculateEA}) 474 header_output += MicroLeaDeclare.subst(iop) 475 decoder_output += MicroLdStOpConstructor.subst(iop) 476 exec_output += MicroLeaExecute.subst(iop) 477 478 class LeaOp(LdStOp): 479 def __init__(self, data, segment, addr, disp = 0): 480 super(LeaOp, self).__init__(data, segment, addr, disp) 481 self.className = "Lea" 482 self.mnemonic = "lea" 483 484 microopClasses["lea"] = LeaOp 485}}; 486 487