lsq_unit.hh (12748:ae5ce8e42de7) | lsq_unit.hh (12749:223c83ed9979) |
---|---|
1/* 2 * Copyright (c) 2012-2014,2017 ARM Limited 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 --- 496 unchanged lines hidden (view full) --- 505 /** Number of loads that were rescheduled. */ 506 Stats::Scalar lsqRescheduledLoads; 507 508 /** Number of times the LSQ is blocked due to the cache. */ 509 Stats::Scalar lsqCacheBlocked; 510 511 public: 512 /** Executes the load at the given index. */ | 1/* 2 * Copyright (c) 2012-2014,2017 ARM Limited 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 --- 496 unchanged lines hidden (view full) --- 505 /** Number of loads that were rescheduled. */ 506 Stats::Scalar lsqRescheduledLoads; 507 508 /** Number of times the LSQ is blocked due to the cache. */ 509 Stats::Scalar lsqCacheBlocked; 510 511 public: 512 /** Executes the load at the given index. */ |
513 Fault read(RequestPtr req, RequestPtr sreqLow, RequestPtr sreqHigh, | 513 Fault read(const RequestPtr &req, 514 RequestPtr &sreqLow, RequestPtr &sreqHigh, |
514 int load_idx); 515 516 /** Executes the store at the given index. */ | 515 int load_idx); 516 517 /** Executes the store at the given index. */ |
517 Fault write(RequestPtr req, RequestPtr sreqLow, RequestPtr sreqHigh, | 518 Fault write(const RequestPtr &req, 519 const RequestPtr &sreqLow, const RequestPtr &sreqHigh, |
518 uint8_t *data, int store_idx); 519 520 /** Returns the index of the head load instruction. */ 521 int getLoadHead() { return loadHead; } 522 /** Returns the sequence number of the head load instruction. */ 523 InstSeqNum getLoadHeadSeqNum() 524 { 525 if (loadQueue[loadHead]) { --- 18 unchanged lines hidden (view full) --- 544 } 545 546 /** Returns whether or not the LSQ unit is stalled. */ 547 bool isStalled() { return stalled; } 548}; 549 550template <class Impl> 551Fault | 520 uint8_t *data, int store_idx); 521 522 /** Returns the index of the head load instruction. */ 523 int getLoadHead() { return loadHead; } 524 /** Returns the sequence number of the head load instruction. */ 525 InstSeqNum getLoadHeadSeqNum() 526 { 527 if (loadQueue[loadHead]) { --- 18 unchanged lines hidden (view full) --- 546 } 547 548 /** Returns whether or not the LSQ unit is stalled. */ 549 bool isStalled() { return stalled; } 550}; 551 552template <class Impl> 553Fault |
552LSQUnit<Impl>::read(RequestPtr req, RequestPtr sreqLow, RequestPtr sreqHigh, | 554LSQUnit<Impl>::read(const RequestPtr &req, 555 RequestPtr &sreqLow, RequestPtr &sreqHigh, |
553 int load_idx) 554{ 555 DynInstPtr load_inst = loadQueue[load_idx]; 556 557 assert(load_inst); 558 559 assert(!load_inst->isExecuted()); 560 561 // Make sure this isn't a strictly ordered load 562 // A bit of a hackish way to get strictly ordered accesses to work 563 // only if they're at the head of the LSQ and are ready to commit 564 // (at the head of the ROB too). 565 if (req->isStrictlyOrdered() && 566 (load_idx != loadHead || !load_inst->isAtCommit())) { 567 iewStage->rescheduleMemInst(load_inst); 568 ++lsqRescheduledLoads; 569 DPRINTF(LSQUnit, "Strictly ordered load [sn:%lli] PC %s\n", 570 load_inst->seqNum, load_inst->pcState()); 571 | 556 int load_idx) 557{ 558 DynInstPtr load_inst = loadQueue[load_idx]; 559 560 assert(load_inst); 561 562 assert(!load_inst->isExecuted()); 563 564 // Make sure this isn't a strictly ordered load 565 // A bit of a hackish way to get strictly ordered accesses to work 566 // only if they're at the head of the LSQ and are ready to commit 567 // (at the head of the ROB too). 568 if (req->isStrictlyOrdered() && 569 (load_idx != loadHead || !load_inst->isAtCommit())) { 570 iewStage->rescheduleMemInst(load_inst); 571 ++lsqRescheduledLoads; 572 DPRINTF(LSQUnit, "Strictly ordered load [sn:%lli] PC %s\n", 573 load_inst->seqNum, load_inst->pcState()); 574 |
572 // Must delete request now that it wasn't handed off to 573 // memory. This is quite ugly. @todo: Figure out the proper 574 // place to really handle request deletes. 575 delete req; 576 if (TheISA::HasUnalignedMemAcc && sreqLow) { 577 delete sreqLow; 578 delete sreqHigh; 579 } | |
580 return std::make_shared<GenericISA::M5PanicFault>( 581 "Strictly ordered load [sn:%llx] PC %s\n", 582 load_inst->seqNum, load_inst->pcState()); 583 } 584 585 // Check the SQ for any previous stores that might lead to forwarding 586 int store_idx = load_inst->sqIdx; 587 --- 33 unchanged lines hidden (view full) --- 621 fst_data_pkt->dataStatic(load_inst->memData); 622 snd_data_pkt->dataStatic(load_inst->memData + sreqLow->getSize()); 623 624 delay = TheISA::handleIprRead(thread, fst_data_pkt); 625 Cycles delay2 = TheISA::handleIprRead(thread, snd_data_pkt); 626 if (delay2 > delay) 627 delay = delay2; 628 | 575 return std::make_shared<GenericISA::M5PanicFault>( 576 "Strictly ordered load [sn:%llx] PC %s\n", 577 load_inst->seqNum, load_inst->pcState()); 578 } 579 580 // Check the SQ for any previous stores that might lead to forwarding 581 int store_idx = load_inst->sqIdx; 582 --- 33 unchanged lines hidden (view full) --- 616 fst_data_pkt->dataStatic(load_inst->memData); 617 snd_data_pkt->dataStatic(load_inst->memData + sreqLow->getSize()); 618 619 delay = TheISA::handleIprRead(thread, fst_data_pkt); 620 Cycles delay2 = TheISA::handleIprRead(thread, snd_data_pkt); 621 if (delay2 > delay) 622 delay = delay2; 623 |
629 delete sreqLow; 630 delete sreqHigh; | |
631 delete fst_data_pkt; 632 delete snd_data_pkt; 633 } 634 WritebackEvent *wb = new WritebackEvent(load_inst, data_pkt, this); 635 cpu->schedule(wb, cpu->clockEdge(delay)); 636 return NoFault; 637 } 638 --- 60 unchanged lines hidden (view full) --- 699 700 WritebackEvent *wb = new WritebackEvent(load_inst, data_pkt, this); 701 702 // We'll say this has a 1 cycle load-store forwarding latency 703 // for now. 704 // @todo: Need to make this a parameter. 705 cpu->schedule(wb, curTick()); 706 | 624 delete fst_data_pkt; 625 delete snd_data_pkt; 626 } 627 WritebackEvent *wb = new WritebackEvent(load_inst, data_pkt, this); 628 cpu->schedule(wb, cpu->clockEdge(delay)); 629 return NoFault; 630 } 631 --- 60 unchanged lines hidden (view full) --- 692 693 WritebackEvent *wb = new WritebackEvent(load_inst, data_pkt, this); 694 695 // We'll say this has a 1 cycle load-store forwarding latency 696 // for now. 697 // @todo: Need to make this a parameter. 698 cpu->schedule(wb, curTick()); 699 |
707 // Don't need to do anything special for split loads. 708 if (TheISA::HasUnalignedMemAcc && sreqLow) { 709 delete sreqLow; 710 delete sreqHigh; 711 } 712 | |
713 ++lsqForwLoads; 714 return NoFault; 715 } else if ( 716 (!req->isLLSC() && 717 ((store_has_lower_limit && lower_load_has_store_part) || 718 (store_has_upper_limit && upper_load_has_store_part) || 719 (lower_load_has_store_part && upper_load_has_store_part))) || 720 (req->isLLSC() && --- 29 unchanged lines hidden (view full) --- 750 ++lsqRescheduledLoads; 751 752 // Do not generate a writeback event as this instruction is not 753 // complete. 754 DPRINTF(LSQUnit, "Load-store forwarding mis-match. " 755 "Store idx %i to load addr %#x\n", 756 store_idx, req->getVaddr()); 757 | 700 ++lsqForwLoads; 701 return NoFault; 702 } else if ( 703 (!req->isLLSC() && 704 ((store_has_lower_limit && lower_load_has_store_part) || 705 (store_has_upper_limit && upper_load_has_store_part) || 706 (lower_load_has_store_part && upper_load_has_store_part))) || 707 (req->isLLSC() && --- 29 unchanged lines hidden (view full) --- 737 ++lsqRescheduledLoads; 738 739 // Do not generate a writeback event as this instruction is not 740 // complete. 741 DPRINTF(LSQUnit, "Load-store forwarding mis-match. " 742 "Store idx %i to load addr %#x\n", 743 store_idx, req->getVaddr()); 744 |
758 // Must delete request now that it wasn't handed off to 759 // memory. This is quite ugly. @todo: Figure out the 760 // proper place to really handle request deletes. 761 delete req; 762 if (TheISA::HasUnalignedMemAcc && sreqLow) { 763 delete sreqLow; 764 delete sreqHigh; 765 } 766 | |
767 return NoFault; 768 } 769 } 770 771 // If there's no forwarding case, then go access memory 772 DPRINTF(LSQUnit, "Doing memory access for inst [sn:%lli] PC %s\n", 773 load_inst->seqNum, load_inst->pcState()); 774 --- 63 unchanged lines hidden (view full) --- 838 } 839 840 // If the cache was blocked, or has become blocked due to the access, 841 // handle it. 842 if (!successful_load) { 843 if (!sreqLow) { 844 // Packet wasn't split, just delete main packet info 845 delete state; | 745 return NoFault; 746 } 747 } 748 749 // If there's no forwarding case, then go access memory 750 DPRINTF(LSQUnit, "Doing memory access for inst [sn:%lli] PC %s\n", 751 load_inst->seqNum, load_inst->pcState()); 752 --- 63 unchanged lines hidden (view full) --- 816 } 817 818 // If the cache was blocked, or has become blocked due to the access, 819 // handle it. 820 if (!successful_load) { 821 if (!sreqLow) { 822 // Packet wasn't split, just delete main packet info 823 delete state; |
846 delete req; | |
847 delete data_pkt; 848 } 849 850 if (TheISA::HasUnalignedMemAcc && sreqLow) { 851 if (!completedFirst) { 852 // Split packet, but first failed. Delete all state. 853 delete state; | 824 delete data_pkt; 825 } 826 827 if (TheISA::HasUnalignedMemAcc && sreqLow) { 828 if (!completedFirst) { 829 // Split packet, but first failed. Delete all state. 830 delete state; |
854 delete req; | |
855 delete data_pkt; 856 delete fst_data_pkt; 857 delete snd_data_pkt; | 831 delete data_pkt; 832 delete fst_data_pkt; 833 delete snd_data_pkt; |
858 delete sreqLow; 859 delete sreqHigh; 860 sreqLow = NULL; 861 sreqHigh = NULL; | 834 sreqLow.reset(); 835 sreqHigh.reset(); |
862 } else { 863 // Can't delete main packet data or state because first packet 864 // was sent to the memory system 865 delete data_pkt; | 836 } else { 837 // Can't delete main packet data or state because first packet 838 // was sent to the memory system 839 delete data_pkt; |
866 delete req; 867 delete sreqHigh; | |
868 delete snd_data_pkt; | 840 delete snd_data_pkt; |
869 sreqHigh = NULL; | 841 sreqHigh.reset(); |
870 } 871 } 872 873 ++lsqCacheBlocked; 874 875 iewStage->blockMemInst(load_inst); 876 877 // No fault occurred, even though the interface is blocked. 878 return NoFault; 879 } 880 881 return NoFault; 882} 883 884template <class Impl> 885Fault | 842 } 843 } 844 845 ++lsqCacheBlocked; 846 847 iewStage->blockMemInst(load_inst); 848 849 // No fault occurred, even though the interface is blocked. 850 return NoFault; 851 } 852 853 return NoFault; 854} 855 856template <class Impl> 857Fault |
886LSQUnit<Impl>::write(RequestPtr req, RequestPtr sreqLow, RequestPtr sreqHigh, | 858LSQUnit<Impl>::write(const RequestPtr &req, 859 const RequestPtr &sreqLow, const RequestPtr &sreqHigh, |
887 uint8_t *data, int store_idx) 888{ 889 assert(storeQueue[store_idx].inst); 890 891 DPRINTF(LSQUnit, "Doing write to store idx %i, addr %#x" 892 " | storeHead:%i [sn:%i]\n", 893 store_idx, req->getPaddr(), storeHead, 894 storeQueue[store_idx].inst->seqNum); --- 26 unchanged lines hidden --- | 860 uint8_t *data, int store_idx) 861{ 862 assert(storeQueue[store_idx].inst); 863 864 DPRINTF(LSQUnit, "Doing write to store idx %i, addr %#x" 865 " | storeHead:%i [sn:%i]\n", 866 store_idx, req->getPaddr(), storeHead, 867 storeQueue[store_idx].inst->seqNum); --- 26 unchanged lines hidden --- |