1// Copyright (c) 2007-2008 The Hewlett-Packard Development Company |
2// Copyright (c) 2015 Advanced Micro Devices, Inc. |
3// All rights reserved. 4// 5// The license below extends only to copyright in the software and shall 6// not be construed as granting a license to any other intellectual 7// property including but not limited to intellectual property relating 8// to a hardware implementation of the functionality of the software 9// licensed hereunder. You may use the software subject to the license 10// terms below provided that you ensure that this notice is replicated --- 83 unchanged lines hidden (view full) --- 94 Fault fault = NoFault; 95 Addr EA; 96 97 %(op_decl)s; 98 %(op_rd)s; 99 %(ea_code)s; 100 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 101 |
102 fault = readMemAtomic(xc, traceData, EA, Mem, 103 %(memDataSize)s, memFlags); |
104 105 if (fault == NoFault) { 106 %(code)s; 107 } else if (memFlags & Request::PREFETCH) { 108 // For prefetches, ignore any faults/exceptions. 109 return NoFault; 110 } 111 if(fault == NoFault) --- 12 unchanged lines hidden (view full) --- 124 Fault fault = NoFault; 125 Addr EA; 126 127 %(op_decl)s; 128 %(op_rd)s; 129 %(ea_code)s; 130 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 131 |
132 fault = initiateMemRead(xc, traceData, EA, 133 %(memDataSize)s, memFlags); |
134 135 return fault; 136 } 137}}; 138 139def template MicroLoadCompleteAcc {{ 140 Fault %(class_name)s::completeAcc(PacketPtr pkt, 141 CPU_EXEC_CONTEXT * xc, 142 Trace::InstRecord * traceData) const 143 { 144 Fault fault = NoFault; 145 146 %(op_decl)s; 147 %(op_rd)s; 148 |
149 getMem(pkt, Mem, %(memDataSize)s, traceData); |
150 151 %(code)s; 152 153 if(fault == NoFault) 154 { 155 %(op_wb)s; 156 } 157 --- 14 unchanged lines hidden (view full) --- 172 %(op_rd)s; 173 %(ea_code)s; 174 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 175 176 %(code)s; 177 178 if(fault == NoFault) 179 { |
180 fault = writeMemAtomic(xc, traceData, Mem, %(memDataSize)s, EA, |
181 memFlags, NULL); 182 if(fault == NoFault) 183 { 184 %(op_wb)s; 185 } 186 } 187 188 return fault; --- 11 unchanged lines hidden (view full) --- 200 %(op_rd)s; 201 %(ea_code)s; 202 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 203 204 %(code)s; 205 206 if(fault == NoFault) 207 { |
208 fault = writeMemTiming(xc, traceData, Mem, %(memDataSize)s, EA, |
209 memFlags, NULL); 210 } 211 return fault; 212 } 213}}; 214 215def template MicroStoreCompleteAcc {{ 216 Fault %(class_name)s::completeAcc(PacketPtr pkt, --- 34 unchanged lines hidden (view full) --- 251 %(BasicExecDeclare)s 252 253 %(InitiateAccDeclare)s 254 255 %(CompleteAccDeclare)s 256 }; 257}}; 258 |
259// LdStSplitOp is a load or store that uses a pair of regs as the 260// source or destination. Used for cmpxchg{8,16}b. 261def template MicroLdStSplitOpDeclare {{ 262 class %(class_name)s : public %(base_class)s 263 { 264 public: 265 %(class_name)s(ExtMachInst _machInst, 266 const char * instMnem, uint64_t setFlags, 267 uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 268 uint64_t _disp, InstRegIndex _segment, 269 InstRegIndex _dataLow, InstRegIndex _dataHi, 270 uint8_t _dataSize, uint8_t _addressSize, 271 Request::FlagsType _memFlags); 272 273 %(BasicExecDeclare)s 274 275 %(InitiateAccDeclare)s 276 277 %(CompleteAccDeclare)s 278 }; 279}}; 280 |
281def template MicroLdStOpConstructor {{ 282 %(class_name)s::%(class_name)s( 283 ExtMachInst machInst, const char * instMnem, uint64_t setFlags, 284 uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 285 uint64_t _disp, InstRegIndex _segment, 286 InstRegIndex _data, 287 uint8_t _dataSize, uint8_t _addressSize, 288 Request::FlagsType _memFlags) : 289 %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags, 290 _scale, _index, _base, 291 _disp, _segment, _data, 292 _dataSize, _addressSize, _memFlags, %(op_class)s) 293 { 294 %(constructor)s; 295 } 296}}; 297 |
298def template MicroLdStSplitOpConstructor {{ 299 %(class_name)s::%(class_name)s( 300 ExtMachInst machInst, const char * instMnem, uint64_t setFlags, 301 uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 302 uint64_t _disp, InstRegIndex _segment, 303 InstRegIndex _dataLow, InstRegIndex _dataHi, 304 uint8_t _dataSize, uint8_t _addressSize, 305 Request::FlagsType _memFlags) : 306 %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags, 307 _scale, _index, _base, 308 _disp, _segment, _dataLow, _dataHi, 309 _dataSize, _addressSize, _memFlags, %(op_class)s) 310 { 311 %(constructor)s; 312 } 313}}; 314 |
315let {{ 316 class LdStOp(X86Microop): 317 def __init__(self, data, segment, addr, disp, 318 dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec): 319 self.data = data 320 [self.scale, self.index, self.base] = addr 321 self.disp = disp 322 self.segment = segment --- 64 unchanged lines hidden (view full) --- 387 "flags" : self.microFlagsText(microFlags) + self.instFlags, 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 class LdStSplitOp(LdStOp): 397 def __init__(self, data, segment, addr, disp, 398 dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec): 399 super(LdStSplitOp, self).__init__(0, segment, addr, disp, 400 dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec) 401 (self.dataLow, self.dataHi) = data 402 403 def getAllocator(self, microFlags): 404 allocString = '''(StaticInstPtr)(new %(class_name)s(machInst, 405 macrocodeBlock, %(flags)s, %(scale)s, %(index)s, 406 %(base)s, %(disp)s, %(segment)s, 407 %(dataLow)s, %(dataHi)s, 408 %(dataSize)s, %(addressSize)s, %(memFlags)s)) 409 ''' 410 allocator = allocString % { 411 "class_name" : self.className, 412 "flags" : self.microFlagsText(microFlags) + self.instFlags, 413 "scale" : self.scale, "index" : self.index, 414 "base" : self.base, 415 "disp" : self.disp, 416 "segment" : self.segment, 417 "dataLow" : self.dataLow, "dataHi" : self.dataHi, 418 "dataSize" : self.dataSize, "addressSize" : self.addressSize, 419 "memFlags" : self.memFlags} 420 return allocator 421 |
422}}; 423 424let {{ 425 426 # Make these empty strings so that concatenating onto 427 # them will always work. 428 header_output = "" 429 decoder_output = "" 430 exec_output = "" 431 |
432 segmentEAExpr = \ 433 'bits(scale * Index + Base + disp, addressSize * 8 - 1, 0);' |
434 |
435 calculateEA = 'EA = SegBase + ' + segmentEAExpr 436 |
437 def defineMicroLoadOp(mnemonic, code, bigCode='', |
438 mem_flags="0", big=True, nonSpec=False): |
439 global header_output 440 global decoder_output 441 global exec_output 442 global microopClasses 443 Name = mnemonic 444 name = mnemonic.lower() 445 446 # Build up the all register version of this micro op 447 iops = [InstObjParams(name, Name, 'X86ISA::LdStOp', |
448 { "code": code, 449 "ea_code": calculateEA, 450 "memDataSize": "dataSize" })] |
451 if big: 452 iops += [InstObjParams(name, Name + "Big", 'X86ISA::LdStOp', |
453 { "code": bigCode, 454 "ea_code": calculateEA, 455 "memDataSize": "dataSize" })] |
456 for iop in iops: 457 header_output += MicroLdStOpDeclare.subst(iop) 458 decoder_output += MicroLdStOpConstructor.subst(iop) 459 exec_output += MicroLoadExecute.subst(iop) 460 exec_output += MicroLoadInitiateAcc.subst(iop) 461 exec_output += MicroLoadCompleteAcc.subst(iop) 462 463 base = LdStOp 464 if big: 465 base = BigLdStOp 466 class LoadOp(base): 467 def __init__(self, data, segment, addr, disp = 0, 468 dataSize="env.dataSize", 469 addressSize="env.addressSize", |
470 atCPL0=False, prefetch=False, nonSpec=nonSpec): |
471 super(LoadOp, self).__init__(data, segment, addr, 472 disp, dataSize, addressSize, mem_flags, 473 atCPL0, prefetch, nonSpec) 474 self.className = Name 475 self.mnemonic = name 476 477 microopClasses[name] = LoadOp 478 479 defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);', 480 'Data = Mem & mask(dataSize * 8);') 481 defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);', 482 'Data = Mem & mask(dataSize * 8);', 483 '(StoreCheck << FlagShift)') 484 defineMicroLoadOp('Ldstl', 'Data = merge(Data, Mem, dataSize);', 485 'Data = Mem & mask(dataSize * 8);', |
486 '(StoreCheck << FlagShift) | Request::LOCKED_RMW', 487 nonSpec=True) |
488 489 defineMicroLoadOp('Ldfp', code='FpData_uqw = Mem', big = False) 490 491 defineMicroLoadOp('Ldfp87', code=''' 492 switch (dataSize) 493 { 494 case 4: 495 FpData_df = *(float *)&Mem; --- 20 unchanged lines hidden (view full) --- 516 case 8: 517 FpData_df = (int64_t)Mem; 518 break; 519 default: 520 panic("Unhandled data size in LdIFp87.\\n"); 521 } 522 ''', big = False) 523 |
524 def defineMicroLoadSplitOp(mnemonic, code, mem_flags="0", nonSpec=False): 525 global header_output 526 global decoder_output 527 global exec_output 528 global microopClasses 529 Name = mnemonic 530 name = mnemonic.lower() 531 532 iop = InstObjParams(name, Name, 'X86ISA::LdStSplitOp', 533 { "code": code, 534 "ea_code": calculateEA, 535 "memDataSize": "2 * dataSize" }) 536 537 header_output += MicroLdStSplitOpDeclare.subst(iop) 538 decoder_output += MicroLdStSplitOpConstructor.subst(iop) 539 exec_output += MicroLoadExecute.subst(iop) 540 exec_output += MicroLoadInitiateAcc.subst(iop) 541 exec_output += MicroLoadCompleteAcc.subst(iop) 542 543 class LoadOp(LdStSplitOp): 544 def __init__(self, data, segment, addr, disp = 0, 545 dataSize="env.dataSize", 546 addressSize="env.addressSize", 547 atCPL0=False, prefetch=False, nonSpec=nonSpec): 548 super(LoadOp, self).__init__(data, segment, addr, 549 disp, dataSize, addressSize, mem_flags, 550 atCPL0, prefetch, nonSpec) 551 self.className = Name 552 self.mnemonic = name 553 554 microopClasses[name] = LoadOp 555 556 code = ''' 557 switch (dataSize) { 558 case 4: 559 DataLow = bits(Mem_u2qw[0], 31, 0); 560 DataHi = bits(Mem_u2qw[0], 63, 32); 561 break; 562 case 8: 563 DataLow = Mem_u2qw[0]; 564 DataHi = Mem_u2qw[1]; 565 break; 566 default: 567 panic("Unhandled data size %d in LdSplit.\\n", dataSize); 568 }''' 569 570 defineMicroLoadSplitOp('LdSplit', code, 571 '(StoreCheck << FlagShift)') 572 573 defineMicroLoadSplitOp('LdSplitl', code, 574 '(StoreCheck << FlagShift) | Request::LOCKED_RMW', 575 nonSpec=True) 576 |
577 def defineMicroStoreOp(mnemonic, code, completeCode="", mem_flags="0"): 578 global header_output 579 global decoder_output 580 global exec_output 581 global microopClasses 582 Name = mnemonic 583 name = mnemonic.lower() 584 585 # Build up the all register version of this micro op 586 iop = InstObjParams(name, Name, 'X86ISA::LdStOp', |
587 { "code": code, 588 "complete_code": completeCode, 589 "ea_code": calculateEA, 590 "memDataSize": "dataSize" }) |
591 header_output += MicroLdStOpDeclare.subst(iop) 592 decoder_output += MicroLdStOpConstructor.subst(iop) 593 exec_output += MicroStoreExecute.subst(iop) 594 exec_output += MicroStoreInitiateAcc.subst(iop) 595 exec_output += MicroStoreCompleteAcc.subst(iop) 596 597 class StoreOp(LdStOp): 598 def __init__(self, data, segment, addr, disp = 0, --- 26 unchanged lines hidden (view full) --- 625 break; 626 default: 627 panic("Unhandled data size in StFp87.\\n"); 628 } 629 ''') 630 631 defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS") 632 |
633 def defineMicroStoreSplitOp(mnemonic, code, 634 completeCode="", mem_flags="0"): 635 global header_output 636 global decoder_output 637 global exec_output 638 global microopClasses 639 Name = mnemonic 640 name = mnemonic.lower() 641 642 iop = InstObjParams(name, Name, 'X86ISA::LdStSplitOp', 643 { "code": code, 644 "complete_code": completeCode, 645 "ea_code": calculateEA, 646 "memDataSize": "2 * dataSize" }) 647 648 header_output += MicroLdStSplitOpDeclare.subst(iop) 649 decoder_output += MicroLdStSplitOpConstructor.subst(iop) 650 exec_output += MicroStoreExecute.subst(iop) 651 exec_output += MicroStoreInitiateAcc.subst(iop) 652 exec_output += MicroStoreCompleteAcc.subst(iop) 653 654 class StoreOp(LdStSplitOp): 655 def __init__(self, data, segment, addr, disp = 0, 656 dataSize="env.dataSize", 657 addressSize="env.addressSize", 658 atCPL0=False, nonSpec=False): 659 super(StoreOp, self).__init__(data, segment, addr, disp, 660 dataSize, addressSize, mem_flags, atCPL0, False, 661 nonSpec) 662 self.className = Name 663 self.mnemonic = name 664 665 microopClasses[name] = StoreOp 666 667 code = ''' 668 switch (dataSize) { 669 case 4: 670 Mem_u2qw[0] = (DataHi << 32) | DataLow; 671 break; 672 case 8: 673 Mem_u2qw[0] = DataLow; 674 Mem_u2qw[1] = DataHi; 675 break; 676 default: 677 panic("Unhandled data size %d in StSplit.\\n", dataSize); 678 }''' 679 680 defineMicroStoreSplitOp('StSplit', code); 681 682 defineMicroStoreSplitOp('StSplitul', code, 683 mem_flags='Request::LOCKED_RMW') 684 |
685 iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp', |
686 { "code": "Data = merge(Data, EA, dataSize);", 687 "ea_code": "EA = " + segmentEAExpr, 688 "memDataSize": "dataSize" }) |
689 header_output += MicroLeaDeclare.subst(iop) 690 decoder_output += MicroLdStOpConstructor.subst(iop) 691 exec_output += MicroLeaExecute.subst(iop) 692 693 class LeaOp(LdStOp): 694 def __init__(self, data, segment, addr, disp = 0, 695 dataSize="env.dataSize", addressSize="env.addressSize"): 696 super(LeaOp, self).__init__(data, segment, addr, disp, 697 dataSize, addressSize, "0", False, False, False) 698 self.className = "Lea" 699 self.mnemonic = "lea" 700 701 microopClasses["lea"] = LeaOp 702 703 704 iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp', |
705 { "code": "xc->demapPage(EA, 0);", 706 "ea_code": calculateEA, 707 "memDataSize": "dataSize" }) |
708 header_output += MicroLeaDeclare.subst(iop) 709 decoder_output += MicroLdStOpConstructor.subst(iop) 710 exec_output += MicroLeaExecute.subst(iop) 711 712 class TiaOp(LdStOp): 713 def __init__(self, segment, addr, disp = 0, 714 dataSize="env.dataSize", 715 addressSize="env.addressSize"): --- 21 unchanged lines hidden --- |