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 ---