lsq_unit.hh (9444:ab47fe7f03f0) lsq_unit.hh (10031:79d034cd6ba3)
1/*
1/*
2 * Copyright (c) 2012 ARM Limited
2 * Copyright (c) 2012-2013 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
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated

--- 345 unchanged lines hidden (view full) ---

356 ~SQEntry()
357 {
358 inst = NULL;
359 }
360
361 /** Constructs a store queue entry for a given instruction. */
362 SQEntry(DynInstPtr &_inst)
363 : inst(_inst), req(NULL), sreqLow(NULL), sreqHigh(NULL), size(0),
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

--- 345 unchanged lines hidden (view full) ---

356 ~SQEntry()
357 {
358 inst = NULL;
359 }
360
361 /** Constructs a store queue entry for a given instruction. */
362 SQEntry(DynInstPtr &_inst)
363 : inst(_inst), req(NULL), sreqLow(NULL), sreqHigh(NULL), size(0),
364 isSplit(0), canWB(0), committed(0), completed(0)
364 isSplit(0), canWB(0), committed(0), completed(0), isAllZeros(0)
365 {
366 std::memset(data, 0, sizeof(data));
367 }
368 /** The store data. */
369 char data[16];
370 /** The store instruction. */
371 DynInstPtr inst;
372 /** The request for the store. */

--- 6 unchanged lines hidden (view full) ---

379 /** Whether or not the store is split into two requests. */
380 bool isSplit;
381 /** Whether or not the store can writeback. */
382 bool canWB;
383 /** Whether or not the store is committed. */
384 bool committed;
385 /** Whether or not the store is completed. */
386 bool completed;
365 {
366 std::memset(data, 0, sizeof(data));
367 }
368 /** The store data. */
369 char data[16];
370 /** The store instruction. */
371 DynInstPtr inst;
372 /** The request for the store. */

--- 6 unchanged lines hidden (view full) ---

379 /** Whether or not the store is split into two requests. */
380 bool isSplit;
381 /** Whether or not the store can writeback. */
382 bool canWB;
383 /** Whether or not the store is committed. */
384 bool committed;
385 /** Whether or not the store is completed. */
386 bool completed;
387 /** Does this request write all zeros and thus doesn't
388 * have any data attached to it. Used for cache block zero
389 * style instructs (ARM DC ZVA; ALPHA WH64)
390 */
391 bool isAllZeros;
387 };
388
389 private:
390 /** The LSQUnit thread id. */
391 ThreadID lsqID;
392
393 /** The store queue. */
394 std::vector<SQEntry> storeQueue;

--- 291 unchanged lines hidden (view full) ---

686 (req->getVaddr() + req->getSize()) >
687 storeQueue[store_idx].inst->effAddr;
688
689 // If the store's data has all of the data needed, we can forward.
690 if ((store_has_lower_limit && store_has_upper_limit)) {
691 // Get shift amount for offset into the store's data.
692 int shift_amt = req->getVaddr() - storeQueue[store_idx].inst->effAddr;
693
392 };
393
394 private:
395 /** The LSQUnit thread id. */
396 ThreadID lsqID;
397
398 /** The store queue. */
399 std::vector<SQEntry> storeQueue;

--- 291 unchanged lines hidden (view full) ---

691 (req->getVaddr() + req->getSize()) >
692 storeQueue[store_idx].inst->effAddr;
693
694 // If the store's data has all of the data needed, we can forward.
695 if ((store_has_lower_limit && store_has_upper_limit)) {
696 // Get shift amount for offset into the store's data.
697 int shift_amt = req->getVaddr() - storeQueue[store_idx].inst->effAddr;
698
694 memcpy(data, storeQueue[store_idx].data + shift_amt,
699 if (storeQueue[store_idx].isAllZeros)
700 memset(data, 0, req->getSize());
701 else
702 memcpy(data, storeQueue[store_idx].data + shift_amt,
695 req->getSize());
696
697 assert(!load_inst->memData);
703 req->getSize());
704
705 assert(!load_inst->memData);
698 load_inst->memData = new uint8_t[64];
699
700 memcpy(load_inst->memData,
706 load_inst->memData = new uint8_t[req->getSize()];
707 if (storeQueue[store_idx].isAllZeros)
708 memset(load_inst->memData, 0, req->getSize());
709 else
710 memcpy(load_inst->memData,
701 storeQueue[store_idx].data + shift_amt, req->getSize());
702
703 DPRINTF(LSQUnit, "Forwarding from store idx %i to load to "
704 "addr %#x, data %#x\n",
705 store_idx, req->getVaddr(), data);
706
707 PacketPtr data_pkt = new Packet(req, MemCmd::ReadReq);
708 data_pkt->dataStatic(load_inst->memData);

--- 63 unchanged lines hidden (view full) ---

772 }
773 }
774
775 // If there's no forwarding case, then go access memory
776 DPRINTF(LSQUnit, "Doing memory access for inst [sn:%lli] PC %s\n",
777 load_inst->seqNum, load_inst->pcState());
778
779 assert(!load_inst->memData);
711 storeQueue[store_idx].data + shift_amt, req->getSize());
712
713 DPRINTF(LSQUnit, "Forwarding from store idx %i to load to "
714 "addr %#x, data %#x\n",
715 store_idx, req->getVaddr(), data);
716
717 PacketPtr data_pkt = new Packet(req, MemCmd::ReadReq);
718 data_pkt->dataStatic(load_inst->memData);

--- 63 unchanged lines hidden (view full) ---

782 }
783 }
784
785 // If there's no forwarding case, then go access memory
786 DPRINTF(LSQUnit, "Doing memory access for inst [sn:%lli] PC %s\n",
787 load_inst->seqNum, load_inst->pcState());
788
789 assert(!load_inst->memData);
780 load_inst->memData = new uint8_t[64];
790 load_inst->memData = new uint8_t[req->getSize()];
781
782 ++usedPorts;
783
784 // if we the cache is not blocked, do cache access
785 bool completedFirst = false;
786 if (!lsq->cacheBlocked()) {
787 MemCmd command =
788 req->isLLSC() ? MemCmd::LoadLockedReq : MemCmd::ReadReq;

--- 122 unchanged lines hidden (view full) ---

911 store_idx, req->getPaddr(), data, storeHead,
912 storeQueue[store_idx].inst->seqNum);
913
914 storeQueue[store_idx].req = req;
915 storeQueue[store_idx].sreqLow = sreqLow;
916 storeQueue[store_idx].sreqHigh = sreqHigh;
917 unsigned size = req->getSize();
918 storeQueue[store_idx].size = size;
791
792 ++usedPorts;
793
794 // if we the cache is not blocked, do cache access
795 bool completedFirst = false;
796 if (!lsq->cacheBlocked()) {
797 MemCmd command =
798 req->isLLSC() ? MemCmd::LoadLockedReq : MemCmd::ReadReq;

--- 122 unchanged lines hidden (view full) ---

921 store_idx, req->getPaddr(), data, storeHead,
922 storeQueue[store_idx].inst->seqNum);
923
924 storeQueue[store_idx].req = req;
925 storeQueue[store_idx].sreqLow = sreqLow;
926 storeQueue[store_idx].sreqHigh = sreqHigh;
927 unsigned size = req->getSize();
928 storeQueue[store_idx].size = size;
919 assert(size <= sizeof(storeQueue[store_idx].data));
929 storeQueue[store_idx].isAllZeros = req->getFlags() & Request::CACHE_BLOCK_ZERO;
930 assert(size <= sizeof(storeQueue[store_idx].data) ||
931 (req->getFlags() & Request::CACHE_BLOCK_ZERO));
920
921 // Split stores can only occur in ISAs with unaligned memory accesses. If
922 // a store request has been split, sreqLow and sreqHigh will be non-null.
923 if (TheISA::HasUnalignedMemAcc && sreqLow) {
924 storeQueue[store_idx].isSplit = true;
925 }
926
932
933 // Split stores can only occur in ISAs with unaligned memory accesses. If
934 // a store request has been split, sreqLow and sreqHigh will be non-null.
935 if (TheISA::HasUnalignedMemAcc && sreqLow) {
936 storeQueue[store_idx].isSplit = true;
937 }
938
927 memcpy(storeQueue[store_idx].data, data, size);
939 if (!(req->getFlags() & Request::CACHE_BLOCK_ZERO))
940 memcpy(storeQueue[store_idx].data, data, size);
928
929 // This function only writes the data to the store queue, so no fault
930 // can happen here.
931 return NoFault;
932}
933
934#endif // __CPU_O3_LSQ_UNIT_HH__
941
942 // This function only writes the data to the store queue, so no fault
943 // can happen here.
944 return NoFault;
945}
946
947#endif // __CPU_O3_LSQ_UNIT_HH__