From 10fe8b05dbf38acff65d95a696cad95a45bf2e16 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 3 Apr 2007 22:53:26 +0000 Subject: [PATCH] Made the "data" field of store queue entries into a character array. It's sized to match an IntReg which was what it used to be, but we might want to make it something architecture independent. All data is now endian converted before entering the store queue entries which simplifies store to load forwarding in "trans endian" simulations, and makes twin memory ops work. src/cpu/o3/lsq_unit.hh: src/cpu/o3/lsq_unit_impl.hh: fixed twin memory operations. --HG-- extra : convert_revision : 8fb97f98e285cd22413e06e146fa82392ac2a590 --- src/cpu/o3/lsq_unit.hh | 33 ++++++++++++++++----------------- src/cpu/o3/lsq_unit_impl.hh | 15 +-------------- 2 files changed, 17 insertions(+), 31 deletions(-) diff --git a/src/cpu/o3/lsq_unit.hh b/src/cpu/o3/lsq_unit.hh index 1b10843f5..ebfa75059 100644 --- a/src/cpu/o3/lsq_unit.hh +++ b/src/cpu/o3/lsq_unit.hh @@ -297,15 +297,19 @@ class LSQUnit { struct SQEntry { /** Constructs an empty store queue entry. */ SQEntry() - : inst(NULL), req(NULL), size(0), data(0), + : inst(NULL), req(NULL), size(0), canWB(0), committed(0), completed(0) - { } + { + bzero(data, sizeof(data)); + } /** Constructs a store queue entry for a given instruction. */ SQEntry(DynInstPtr &_inst) - : inst(_inst), req(NULL), size(0), data(0), + : inst(_inst), req(NULL), size(0), canWB(0), committed(0), completed(0) - { } + { + bzero(data, sizeof(data)); + } /** The store instruction. */ DynInstPtr inst; @@ -314,7 +318,7 @@ class LSQUnit { /** The size of the store. */ int size; /** The store data. */ - IntReg data; + char data[sizeof(IntReg)]; /** Whether or not the store can writeback. */ bool canWB; /** Whether or not the store is committed. */ @@ -562,22 +566,14 @@ LSQUnit::read(Request *req, T &data, int load_idx) if ((store_has_lower_limit && store_has_upper_limit)) { // Get shift amount for offset into the store's data. int shift_amt = req->getVaddr() & (store_size - 1); - // @todo: Magic number, assumes byte addressing - shift_amt = shift_amt << 3; - - // Cast this to type T? - data = storeQueue[store_idx].data >> shift_amt; - // When the data comes from the store queue entry, it's in host - // order. When it gets sent to the load, it needs to be in guest - // order so when the load converts it again, it ends up back - // in host order like the inst expects. - data = TheISA::htog(data); + memcpy(&data, storeQueue[store_idx].data + shift_amt, sizeof(T)); assert(!load_inst->memData); load_inst->memData = new uint8_t[64]; - memcpy(load_inst->memData, &data, req->getSize()); + memcpy(load_inst->memData, + storeQueue[store_idx].data + shift_amt, req->getSize()); DPRINTF(LSQUnit, "Forwarding from store idx %i to load to " "addr %#x, data %#x\n", @@ -724,7 +720,10 @@ LSQUnit::write(Request *req, T &data, int store_idx) storeQueue[store_idx].req = req; storeQueue[store_idx].size = sizeof(T); - storeQueue[store_idx].data = data; + assert(sizeof(T) <= sizeof(storeQueue[store_idx].data)); + + T gData = htog(data); + memcpy(storeQueue[store_idx].data, &gData, sizeof(T)); // This function only writes the data to the store queue, so no fault // can happen here. diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh index 0a3021046..a47528e32 100644 --- a/src/cpu/o3/lsq_unit_impl.hh +++ b/src/cpu/o3/lsq_unit_impl.hh @@ -641,20 +641,7 @@ LSQUnit::writebackStores() assert(!inst->memData); inst->memData = new uint8_t[64]; - TheISA::IntReg convertedData = - TheISA::htog(storeQueue[storeWBIdx].data); - - //FIXME This is a hack to get SPARC working. It, along with endianness - //in the memory system in general, need to be straightened out more - //formally. The problem is that the data's endianness is swapped when - //it's in the 64 bit data field in the store queue. The data that you - //want won't start at the beginning of the field anymore unless it was - //a 64 bit access. - memcpy(inst->memData, - (uint8_t *)&convertedData + - (TheISA::ByteOrderDiffers ? - (sizeof(TheISA::IntReg) - req->getSize()) : 0), - req->getSize()); + memcpy(inst->memData, storeQueue[storeWBIdx].data, req->getSize()); PacketPtr data_pkt = new Packet(req, MemCmd::WriteReq, Packet::Broadcast); -- 2.30.2