summaryrefslogtreecommitdiff
path: root/src/cpu/o3
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/o3')
-rw-r--r--src/cpu/o3/lsq_unit.hh33
-rw-r--r--src/cpu/o3/lsq_unit_impl.hh22
-rw-r--r--src/cpu/o3/regfile.hh14
-rw-r--r--src/cpu/o3/rename_impl.hh10
4 files changed, 38 insertions, 41 deletions
diff --git a/src/cpu/o3/lsq_unit.hh b/src/cpu/o3/lsq_unit.hh
index e1b27048d..f24de20d9 100644
--- a/src/cpu/o3/lsq_unit.hh
+++ b/src/cpu/o3/lsq_unit.hh
@@ -289,15 +289,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;
@@ -306,7 +310,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. */
@@ -554,22 +558,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",
@@ -716,7 +712,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 2aa0d6b6a..44e2cea76 100644
--- a/src/cpu/o3/lsq_unit_impl.hh
+++ b/src/cpu/o3/lsq_unit_impl.hh
@@ -645,22 +645,10 @@ 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());
-
- PacketPtr data_pkt = new Packet(req, MemCmd::WriteReq,
+ memcpy(inst->memData, storeQueue[storeWBIdx].data, req->getSize());
+
+ MemCmd command = req->isSwap() ? MemCmd::SwapReq : MemCmd::WriteReq;
+ PacketPtr data_pkt = new Packet(req, command,
Packet::Broadcast);
data_pkt->dataStatic(inst->memData);
@@ -677,7 +665,7 @@ LSQUnit<Impl>::writebackStores()
inst->seqNum);
// @todo: Remove this SC hack once the memory system handles it.
- if (req->isLocked()) {
+ if (inst->isStoreConditional()) {
// Disable recording the result temporarily. Writing to
// misc regs normally updates the result, but this is not
// the desired behavior when handling store conditionals.
diff --git a/src/cpu/o3/regfile.hh b/src/cpu/o3/regfile.hh
index bbc69fc96..b5b1cd021 100644
--- a/src/cpu/o3/regfile.hh
+++ b/src/cpu/o3/regfile.hh
@@ -174,7 +174,7 @@ class PhysRegFile
// Remove the base Float reg dependency.
reg_idx = reg_idx - numPhysicalIntRegs;
- assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
+ assert(reg_idx < numPhysicalFloatRegs);
DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n",
int(reg_idx), (uint64_t)val);
@@ -189,7 +189,7 @@ class PhysRegFile
// Remove the base Float reg dependency.
reg_idx = reg_idx - numPhysicalIntRegs;
- assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
+ assert(reg_idx < numPhysicalFloatRegs);
DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n",
int(reg_idx), (uint64_t)val);
@@ -204,7 +204,7 @@ class PhysRegFile
// Remove the base Float reg dependency.
reg_idx = reg_idx - numPhysicalIntRegs;
- assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
+ assert(reg_idx < numPhysicalFloatRegs);
DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n",
int(reg_idx), (uint64_t)val);
@@ -217,7 +217,7 @@ class PhysRegFile
// Remove the base Float reg dependency.
reg_idx = reg_idx - numPhysicalIntRegs;
- assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
+ assert(reg_idx < numPhysicalFloatRegs);
DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n",
int(reg_idx), (uint64_t)val);
@@ -232,11 +232,11 @@ class PhysRegFile
MiscReg readMiscReg(int misc_reg, unsigned thread_id)
{
- return miscRegs[thread_id].readReg(misc_reg,
- cpu->tcBase(thread_id));
+ return miscRegs[thread_id].readReg(misc_reg, cpu->tcBase(thread_id));
}
- void setMiscRegNoEffect(int misc_reg, const MiscReg &val, unsigned thread_id)
+ void setMiscRegNoEffect(int misc_reg,
+ const MiscReg &val, unsigned thread_id)
{
miscRegs[thread_id].setRegNoEffect(misc_reg, val);
}
diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh
index ec630b31e..431705e19 100644
--- a/src/cpu/o3/rename_impl.hh
+++ b/src/cpu/o3/rename_impl.hh
@@ -996,7 +996,12 @@ DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst,unsigned tid)
if (src_reg < TheISA::FP_Base_DepTag) {
flat_src_reg = TheISA::flattenIntIndex(inst->tcBase(), src_reg);
DPRINTF(Rename, "Flattening index %d to %d.\n", (int)src_reg, (int)flat_src_reg);
+ } else {
+ // Floating point and Miscellaneous registers need their indexes
+ // adjusted to account for the expanded number of flattened int regs.
+ flat_src_reg = src_reg - TheISA::FP_Base_DepTag + TheISA::NumIntRegs;
}
+
inst->flattenSrcReg(src_idx, flat_src_reg);
// Look up the source registers to get the phys. register they've
@@ -1033,8 +1038,13 @@ DefaultRename<Impl>::renameDestRegs(DynInstPtr &inst,unsigned tid)
RegIndex dest_reg = inst->destRegIdx(dest_idx);
RegIndex flat_dest_reg = dest_reg;
if (dest_reg < TheISA::FP_Base_DepTag) {
+ // Integer registers are flattened.
flat_dest_reg = TheISA::flattenIntIndex(inst->tcBase(), dest_reg);
DPRINTF(Rename, "Flattening index %d to %d.\n", (int)dest_reg, (int)flat_dest_reg);
+ } else {
+ // Floating point and Miscellaneous registers need their indexes
+ // adjusted to account for the expanded number of flattened int regs.
+ flat_dest_reg = dest_reg - TheISA::FP_Base_DepTag + TheISA::NumIntRegs;
}
inst->flattenDestReg(dest_idx, flat_dest_reg);