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