ldstop.isa revision 5969
1// Copyright (c) 2008 The Regents of The University of Michigan 2// All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions are 6// met: redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer; 8// redistributions in binary form must reproduce the above copyright 9// notice, this list of conditions and the following disclaimer in the 10// documentation and/or other materials provided with the distribution; 11// neither the name of the copyright holders nor the names of its 12// contributors may be used to endorse or promote products derived from 13// this software without specific prior written permission. 14// 15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26// 27// Authors: Gabe Black 28 29// Copyright (c) 2007-2008 The Hewlett-Packard Development Company 30// All rights reserved. 31// 32// Redistribution and use of this software in source and binary forms, 33// with or without modification, are permitted provided that the 34// following conditions are met: 35// 36// The software must be used only for Non-Commercial Use which means any 37// use which is NOT directed to receiving any direct monetary 38// compensation for, or commercial advantage from such use. Illustrative 39// examples of non-commercial use are academic research, personal study, 40// teaching, education and corporate research & development. 41// Illustrative examples of commercial use are distributing products for 42// commercial advantage and providing services using the software for 43// commercial advantage. 44// 45// If you wish to use this software or functionality therein that may be 46// covered by patents for commercial use, please contact: 47// Director of Intellectual Property Licensing 48// Office of Strategy and Technology 49// Hewlett-Packard Company 50// 1501 Page Mill Road 51// Palo Alto, California 94304 52// 53// Redistributions of source code must retain the above copyright notice, 54// this list of conditions and the following disclaimer. Redistributions 55// in binary form must reproduce the above copyright notice, this list of 56// conditions and the following disclaimer in the documentation and/or 57// other materials provided with the distribution. Neither the name of 58// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its 59// contributors may be used to endorse or promote products derived from 60// this software without specific prior written permission. No right of 61// sublicense is granted herewith. Derivatives of the software and 62// output created using the software may be prepared, but only for 63// Non-Commercial Uses. Derivatives of the software may be shared with 64// others provided: (i) the others agree to abide by the list of 65// conditions herein which includes the Non-Commercial Use restrictions; 66// and (ii) such Derivatives of the software include the above copyright 67// notice to acknowledge the contribution from this software where 68// applicable, this list of conditions and the disclaimer below. 69// 70// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 71// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 72// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 73// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 74// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 75// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 76// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 77// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 78// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 79// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 80// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 81// 82// Authors: Gabe Black 83 84////////////////////////////////////////////////////////////////////////// 85// 86// LdStOp Microop templates 87// 88////////////////////////////////////////////////////////////////////////// 89 90// LEA template 91 92def template MicroLeaExecute {{ 93 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 94 Trace::InstRecord *traceData) const 95 { 96 Fault fault = NoFault; 97 Addr EA; 98 99 %(op_decl)s; 100 %(op_rd)s; 101 %(ea_code)s; 102 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 103 104 %(code)s; 105 if(fault == NoFault) 106 { 107 %(op_wb)s; 108 } 109 110 return fault; 111 } 112}}; 113 114def template MicroLeaDeclare {{ 115 class %(class_name)s : public %(base_class)s 116 { 117 protected: 118 void buildMe(); 119 120 public: 121 %(class_name)s(ExtMachInst _machInst, 122 const char * instMnem, 123 bool isMicro, bool isDelayed, bool isFirst, bool isLast, 124 uint8_t _scale, RegIndex _index, RegIndex _base, 125 uint64_t _disp, uint8_t _segment, 126 RegIndex _data, 127 uint8_t _dataSize, uint8_t _addressSize, 128 Request::FlagsType _memFlags); 129 130 %(class_name)s(ExtMachInst _machInst, 131 const char * instMnem, 132 uint8_t _scale, RegIndex _index, RegIndex _base, 133 uint64_t _disp, uint8_t _segment, 134 RegIndex _data, 135 uint8_t _dataSize, uint8_t _addressSize, 136 Request::FlagsType _memFlags); 137 138 %(BasicExecDeclare)s 139 }; 140}}; 141 142// Load templates 143 144def template MicroLoadExecute {{ 145 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 146 Trace::InstRecord *traceData) const 147 { 148 Fault fault = NoFault; 149 Addr EA; 150 151 %(op_decl)s; 152 %(op_rd)s; 153 %(ea_code)s; 154 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 155 156 fault = read(xc, EA, Mem, memFlags); 157 158 if (fault == NoFault) { 159 %(code)s; 160 } else if (memFlags & Request::PF_EXCLUSIVE) { 161 // For prefetches, ignore any faults/exceptions. 162 return NoFault; 163 } 164 if(fault == NoFault) 165 { 166 %(op_wb)s; 167 } 168 169 return fault; 170 } 171}}; 172 173def template MicroLoadInitiateAcc {{ 174 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 175 Trace::InstRecord * traceData) const 176 { 177 Fault fault = NoFault; 178 Addr EA; 179 180 %(op_decl)s; 181 %(op_rd)s; 182 %(ea_code)s; 183 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 184 185 fault = read(xc, EA, Mem, memFlags); 186 187 return fault; 188 } 189}}; 190 191def template MicroLoadCompleteAcc {{ 192 Fault %(class_name)s::completeAcc(PacketPtr pkt, 193 %(CPU_exec_context)s * xc, 194 Trace::InstRecord * traceData) const 195 { 196 Fault fault = NoFault; 197 198 %(op_decl)s; 199 %(op_rd)s; 200 201 Mem = get(pkt); 202 203 %(code)s; 204 205 if(fault == NoFault) 206 { 207 %(op_wb)s; 208 } 209 210 return fault; 211 } 212}}; 213 214// Store templates 215 216def template MicroStoreExecute {{ 217 Fault %(class_name)s::execute(%(CPU_exec_context)s * xc, 218 Trace::InstRecord *traceData) const 219 { 220 Fault fault = NoFault; 221 222 Addr EA; 223 %(op_decl)s; 224 %(op_rd)s; 225 %(ea_code)s; 226 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 227 228 %(code)s; 229 230 if(fault == NoFault) 231 { 232 fault = write(xc, Mem, EA, memFlags); 233 if(fault == NoFault) 234 { 235 %(post_code)s; 236 %(op_wb)s; 237 } 238 } 239 240 return fault; 241 } 242}}; 243 244def template MicroStoreInitiateAcc {{ 245 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 246 Trace::InstRecord * traceData) const 247 { 248 Fault fault = NoFault; 249 250 Addr EA; 251 %(op_decl)s; 252 %(op_rd)s; 253 %(ea_code)s; 254 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 255 256 %(code)s; 257 258 if(fault == NoFault) 259 { 260 write(xc, Mem, EA, memFlags); 261 } 262 return fault; 263 } 264}}; 265 266def template MicroStoreCompleteAcc {{ 267 Fault %(class_name)s::completeAcc(PacketPtr pkt, 268 %(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const 269 { 270 %(op_decl)s; 271 %(op_rd)s; 272 %(complete_code)s; 273 %(op_wb)s; 274 return NoFault; 275 } 276}}; 277 278// Common templates 279 280//This delcares the initiateAcc function in memory operations 281def template InitiateAccDeclare {{ 282 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 283}}; 284 285//This declares the completeAcc function in memory operations 286def template CompleteAccDeclare {{ 287 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; 288}}; 289 290def template MicroLdStOpDeclare {{ 291 class %(class_name)s : public %(base_class)s 292 { 293 protected: 294 void buildMe(); 295 296 public: 297 %(class_name)s(ExtMachInst _machInst, 298 const char * instMnem, 299 bool isMicro, bool isDelayed, bool isFirst, bool isLast, 300 uint8_t _scale, RegIndex _index, RegIndex _base, 301 uint64_t _disp, uint8_t _segment, 302 RegIndex _data, 303 uint8_t _dataSize, uint8_t _addressSize, 304 Request::FlagsType _memFlags); 305 306 %(class_name)s(ExtMachInst _machInst, 307 const char * instMnem, 308 uint8_t _scale, RegIndex _index, RegIndex _base, 309 uint64_t _disp, uint8_t _segment, 310 RegIndex _data, 311 uint8_t _dataSize, uint8_t _addressSize, 312 Request::FlagsType _memFlags); 313 314 %(BasicExecDeclare)s 315 316 %(InitiateAccDeclare)s 317 318 %(CompleteAccDeclare)s 319 }; 320}}; 321 322def template MicroLdStOpConstructor {{ 323 324 inline void %(class_name)s::buildMe() 325 { 326 %(constructor)s; 327 } 328 329 inline %(class_name)s::%(class_name)s( 330 ExtMachInst machInst, 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 Request::FlagsType _memFlags) : 336 %(base_class)s(machInst, "%(mnemonic)s", instMnem, 337 false, false, false, false, 338 _scale, _index, _base, 339 _disp, _segment, _data, 340 _dataSize, _addressSize, _memFlags, %(op_class)s) 341 { 342 buildMe(); 343 } 344 345 inline %(class_name)s::%(class_name)s( 346 ExtMachInst machInst, const char * instMnem, 347 bool isMicro, bool isDelayed, bool isFirst, bool isLast, 348 uint8_t _scale, RegIndex _index, RegIndex _base, 349 uint64_t _disp, uint8_t _segment, 350 RegIndex _data, 351 uint8_t _dataSize, uint8_t _addressSize, 352 Request::FlagsType _memFlags) : 353 %(base_class)s(machInst, "%(mnemonic)s", instMnem, 354 isMicro, isDelayed, isFirst, isLast, 355 _scale, _index, _base, 356 _disp, _segment, _data, 357 _dataSize, _addressSize, _memFlags, %(op_class)s) 358 { 359 buildMe(); 360 } 361}}; 362 363let {{ 364 class LdStOp(X86Microop): 365 def __init__(self, data, segment, addr, disp, 366 dataSize, addressSize, baseFlags, atCPL0, prefetch): 367 self.data = data 368 [self.scale, self.index, self.base] = addr 369 self.disp = disp 370 self.segment = segment 371 self.dataSize = dataSize 372 self.addressSize = addressSize 373 self.memFlags = baseFlags 374 if atCPL0: 375 self.memFlags += " | (CPL0FlagBit << FlagShift)" 376 if prefetch: 377 self.memFlags += " | Request::PF_EXCLUSIVE" 378 self.memFlags += " | (machInst.legacy.addr ? " + \ 379 "(AddrSizeFlagBit << FlagShift) : 0)" 380 381 def getAllocator(self, *microFlags): 382 allocator = '''new %(class_name)s(machInst, macrocodeBlock 383 %(flags)s, %(scale)s, %(index)s, %(base)s, 384 %(disp)s, %(segment)s, %(data)s, 385 %(dataSize)s, %(addressSize)s, %(memFlags)s)''' % { 386 "class_name" : self.className, 387 "flags" : self.microFlagsText(microFlags), 388 "scale" : self.scale, "index" : self.index, 389 "base" : self.base, 390 "disp" : self.disp, 391 "segment" : self.segment, "data" : self.data, 392 "dataSize" : self.dataSize, "addressSize" : self.addressSize, 393 "memFlags" : self.memFlags} 394 return allocator 395}}; 396 397let {{ 398 399 # Make these empty strings so that concatenating onto 400 # them will always work. 401 header_output = "" 402 decoder_output = "" 403 exec_output = "" 404 405 calculateEA = ''' 406 EA = bits(SegBase + scale * Index + Base + disp, addressSize * 8 - 1, 0); 407 ''' 408 409 def defineMicroLoadOp(mnemonic, code, mem_flags="0"): 410 global header_output 411 global decoder_output 412 global exec_output 413 global microopClasses 414 Name = mnemonic 415 name = mnemonic.lower() 416 417 # Build up the all register version of this micro op 418 iop = InstObjParams(name, Name, 'X86ISA::LdStOp', 419 {"code": code, 420 "ea_code": calculateEA}) 421 header_output += MicroLdStOpDeclare.subst(iop) 422 decoder_output += MicroLdStOpConstructor.subst(iop) 423 exec_output += MicroLoadExecute.subst(iop) 424 exec_output += MicroLoadInitiateAcc.subst(iop) 425 exec_output += MicroLoadCompleteAcc.subst(iop) 426 427 class LoadOp(LdStOp): 428 def __init__(self, data, segment, addr, disp = 0, 429 dataSize="env.dataSize", 430 addressSize="env.addressSize", 431 atCPL0=False, prefetch=False): 432 super(LoadOp, self).__init__(data, segment, addr, 433 disp, dataSize, addressSize, mem_flags, 434 atCPL0, prefetch) 435 self.className = Name 436 self.mnemonic = name 437 438 microopClasses[name] = LoadOp 439 440 defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);') 441 defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);', 442 'X86ISA::StoreCheck') 443 defineMicroLoadOp('Ldfp', 'FpData.uqw = Mem;') 444 445 def defineMicroStoreOp(mnemonic, code, \ 446 postCode="", completeCode="", mem_flags="0"): 447 global header_output 448 global decoder_output 449 global exec_output 450 global microopClasses 451 Name = mnemonic 452 name = mnemonic.lower() 453 454 # Build up the all register version of this micro op 455 iop = InstObjParams(name, Name, 'X86ISA::LdStOp', 456 {"code": code, 457 "post_code": postCode, 458 "complete_code": completeCode, 459 "ea_code": calculateEA}) 460 header_output += MicroLdStOpDeclare.subst(iop) 461 decoder_output += MicroLdStOpConstructor.subst(iop) 462 exec_output += MicroStoreExecute.subst(iop) 463 exec_output += MicroStoreInitiateAcc.subst(iop) 464 exec_output += MicroStoreCompleteAcc.subst(iop) 465 466 class StoreOp(LdStOp): 467 def __init__(self, data, segment, addr, disp = 0, 468 dataSize="env.dataSize", 469 addressSize="env.addressSize", 470 atCPL0=False): 471 super(StoreOp, self).__init__(data, segment, addr, 472 disp, dataSize, addressSize, mem_flags, atCPL0, False) 473 self.className = Name 474 self.mnemonic = name 475 476 microopClasses[name] = StoreOp 477 478 defineMicroStoreOp('St', 'Mem = pick(Data, 2, dataSize);') 479 defineMicroStoreOp('Stfp', 'Mem = FpData.uqw;') 480 defineMicroStoreOp('Stupd', 'Mem = pick(Data, 2, dataSize);', 481 'Base = merge(Base, EA - SegBase, addressSize);', 482 'Base = merge(Base, pkt->req->getVaddr() - SegBase, addressSize);'); 483 defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS") 484 485 iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp', 486 {"code": "Data = merge(Data, EA, dataSize);", 487 "ea_code": calculateEA}) 488 header_output += MicroLeaDeclare.subst(iop) 489 decoder_output += MicroLdStOpConstructor.subst(iop) 490 exec_output += MicroLeaExecute.subst(iop) 491 492 class LeaOp(LdStOp): 493 def __init__(self, data, segment, addr, disp = 0, 494 dataSize="env.dataSize", addressSize="env.addressSize"): 495 super(LeaOp, self).__init__(data, segment, 496 addr, disp, dataSize, addressSize, "0", False, False) 497 self.className = "Lea" 498 self.mnemonic = "lea" 499 500 microopClasses["lea"] = LeaOp 501 502 503 iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp', 504 {"code": "xc->demapPage(EA, 0);", 505 "ea_code": calculateEA}) 506 header_output += MicroLeaDeclare.subst(iop) 507 decoder_output += MicroLdStOpConstructor.subst(iop) 508 exec_output += MicroLeaExecute.subst(iop) 509 510 class TiaOp(LdStOp): 511 def __init__(self, segment, addr, disp = 0, 512 dataSize="env.dataSize", 513 addressSize="env.addressSize"): 514 super(TiaOp, self).__init__("NUM_INTREGS", segment, 515 addr, disp, dataSize, addressSize, "0", False, False) 516 self.className = "Tia" 517 self.mnemonic = "tia" 518 519 microopClasses["tia"] = TiaOp 520 521 class CdaOp(LdStOp): 522 def __init__(self, segment, addr, disp = 0, 523 dataSize="env.dataSize", 524 addressSize="env.addressSize", atCPL0=False): 525 super(CdaOp, self).__init__("NUM_INTREGS", segment, 526 addr, disp, dataSize, addressSize, "0", atCPL0, False) 527 self.className = "Cda" 528 self.mnemonic = "cda" 529 530 microopClasses["cda"] = CdaOp 531}}; 532 533