summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cpu/o3/lsq_unit.hh33
-rw-r--r--src/cpu/o3/lsq_unit_impl.hh15
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<Impl>::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<Impl>::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<Impl>::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);