summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKorey Sewell <ksewell@umich.edu>2009-05-12 15:01:15 -0400
committerKorey Sewell <ksewell@umich.edu>2009-05-12 15:01:15 -0400
commit6211fe5d2ee00dae9cd72d9cccdc900241a8f9a2 (patch)
treeee0ac43983c31c9c22b7ea28e69725d033287ef4
parent3603dd25efb70ec400e8ea1e76137e8e288e533a (diff)
downloadgem5-6211fe5d2ee00dae9cd72d9cccdc900241a8f9a2.tar.xz
inorder-float: Fix storage of FP results
inorder was incorrectly storing FP values and confusing the integer/fp storage view of floating point operations. A big issue was knowing trying to infer when were doing single or double precision access because this lets you know the size of value to store (32-64 bits). This isnt exactly straightforward since alpha uses all 64-bit regs while mips/sparc uses a dual-reg view. by getting this value from the actual floating point register file, the model can figure out what it needs to store
-rw-r--r--src/arch/alpha/floatregfile.hh2
-rw-r--r--src/cpu/inorder/inorder_dyn_inst.cc8
-rw-r--r--src/cpu/inorder/inorder_dyn_inst.hh6
-rw-r--r--src/cpu/inorder/resources/cache_unit.cc6
-rw-r--r--src/cpu/inorder/resources/tlb_unit.cc13
-rw-r--r--src/cpu/inorder/resources/use_def.cc68
-rw-r--r--src/cpu/inorder/resources/use_def.hh2
7 files changed, 69 insertions, 36 deletions
diff --git a/src/arch/alpha/floatregfile.hh b/src/arch/alpha/floatregfile.hh
index a5a3a7861..f6abb1f86 100644
--- a/src/arch/alpha/floatregfile.hh
+++ b/src/arch/alpha/floatregfile.hh
@@ -52,6 +52,8 @@ const int QuadBytes = QuadWidth / 4;
class FloatRegFile
{
public:
+ static const int regWidth = DoubleWidth;
+
union {
uint64_t q[NumFloatRegs]; // integer qword view
double d[NumFloatRegs]; // double-precision floating point view
diff --git a/src/cpu/inorder/inorder_dyn_inst.cc b/src/cpu/inorder/inorder_dyn_inst.cc
index 280740116..9609db22f 100644
--- a/src/cpu/inorder/inorder_dyn_inst.cc
+++ b/src/cpu/inorder/inorder_dyn_inst.cc
@@ -520,6 +520,7 @@ InOrderDynInst::setFloatRegOperand(const StaticInst *si, int idx, FloatReg val,
}
instResult[idx].tick = curTick;
+ instResult[idx].width = width;
}
/** Sets a FP register as a integer. */
@@ -527,13 +528,10 @@ void
InOrderDynInst::setFloatRegOperandBits(const StaticInst *si, int idx,
FloatRegBits val, int width)
{
- if (width == 32)
- instResult[idx].type = Float;
- else if (width == 64)
- instResult[idx].type = Double;
-
+ instResult[idx].type = Integer;
instResult[idx].val.integer = val;
instResult[idx].tick = curTick;
+ instResult[idx].width = width;
}
/** Sets a misc. register. */
diff --git a/src/cpu/inorder/inorder_dyn_inst.hh b/src/cpu/inorder/inorder_dyn_inst.hh
index 1f9c360df..490992638 100644
--- a/src/cpu/inorder/inorder_dyn_inst.hh
+++ b/src/cpu/inorder/inorder_dyn_inst.hh
@@ -243,9 +243,10 @@ class InOrderDynInst : public FastAlloc, public RefCounted
ResultType type;
InstValue val;
Tick tick;
+ int width;
InstResult()
- : type(None), tick(0)
+ : type(None), tick(0), width(0)
{}
};
@@ -856,8 +857,7 @@ class InOrderDynInst : public FastAlloc, public RefCounted
/** Depending on type, return Float or Double */
double readFloatResult(int idx)
{
- //assert(instResult[idx].type != Integer && instResult[idx].type != None);
- //@todo: TypeCast FLOAT onto DOUBLE instead of separate value
+ //Should this function have a parameter for what width of return?x
return (instResult[idx].type == Float) ?
(float) instResult[idx].val.dbl : instResult[idx].val.dbl;
}
diff --git a/src/cpu/inorder/resources/cache_unit.cc b/src/cpu/inorder/resources/cache_unit.cc
index 3b4dd0420..4ac1fb77e 100644
--- a/src/cpu/inorder/resources/cache_unit.cc
+++ b/src/cpu/inorder/resources/cache_unit.cc
@@ -547,9 +547,9 @@ CacheUnit::processCacheCompletion(PacketPtr pkt)
assert(cache_pkt->isWrite());
DPRINTF(InOrderCachePort,
- "[tid:%u]: [sn:%i]: Data stored was: %08p\n",
- tid, inst->seqNum,
- getMemData(cache_pkt));
+ "[tid:%u]: [sn:%i]: Data stored was: FIX ME\n",
+ tid, inst->seqNum/*,
+ getMemData(cache_pkt)*/);
}
delete cache_pkt;
diff --git a/src/cpu/inorder/resources/tlb_unit.cc b/src/cpu/inorder/resources/tlb_unit.cc
index 8532a30ed..238807ebc 100644
--- a/src/cpu/inorder/resources/tlb_unit.cc
+++ b/src/cpu/inorder/resources/tlb_unit.cc
@@ -160,13 +160,14 @@ TLBUnit::execute(int slot_idx)
DPRINTF(InOrderTLB, "[tid:%i]: %s encountered while translating "
"addr:%08p for [sn:%i] %s.\n", tid, tlb_req->fault->name(),
tlb_req->memReq->getVaddr(), seq_num, inst->instName());
- //insert(inst);
- cpu->pipelineStage[stage_num]->setResStall(tlb_req, tid);
- tlbBlocked[tid] = true;
- scheduleEvent(slot_idx, 1);
- // Let CPU handle the fault
- cpu->trap(tlb_req->fault, tid);
+ cpu->pipelineStage[stage_num]->setResStall(tlb_req, tid);
+ tlbBlocked[tid] = true;
+ scheduleEvent(slot_idx, 1);
+
+ // Let CPU handle the fault
+ cpu->trap(tlb_req->fault, tid);
+
} else {
DPRINTF(InOrderTLB, "[tid:%i]: [sn:%i] virt. addr %08p translated "
"to phys. addr:%08p.\n", tid, seq_num,
diff --git a/src/cpu/inorder/resources/use_def.cc b/src/cpu/inorder/resources/use_def.cc
index 4a6acf7c8..53145640e 100644
--- a/src/cpu/inorder/resources/use_def.cc
+++ b/src/cpu/inorder/resources/use_def.cc
@@ -53,7 +53,10 @@ UseDefUnit::UseDefUnit(string res_name, int res_id, int res_width,
outWriteSeqNum[tid] = maxSeqNum;
regDepMap[tid] = &cpu->archRegDepMap[tid];
+
+ floatRegSize[tid] = cpu->floatRegFile[tid].regWidth;
}
+
}
ResReqPtr
@@ -124,19 +127,23 @@ UseDefUnit::execute(int slot_idx)
// Ask register dependency map if it is OK to read from Arch. Reg. File
if (regDepMap[tid]->canRead(reg_idx, inst)) {
- // Read From Register File
if (inst->seqNum <= outReadSeqNum[tid]) {
- if (reg_idx <= FP_Base_DepTag) {
+ if (reg_idx < FP_Base_DepTag) {
DPRINTF(InOrderUseDef, "[tid:%i]: Reading Int Reg %i from Register File:%i.\n",
tid, reg_idx, cpu->readIntReg(reg_idx,inst->readTid()));
inst->setIntSrc(ud_idx,
cpu->readIntReg(reg_idx,inst->readTid()));
- } else if (reg_idx <= Ctrl_Base_DepTag) {
+ } else if (reg_idx < Ctrl_Base_DepTag) {
reg_idx -= FP_Base_DepTag;
- DPRINTF(InOrderUseDef, "[tid:%i]: Reading Float Reg %i from Register File:%x.\n",
- tid, reg_idx, cpu->readFloatRegBits(reg_idx, inst->readTid()));
- inst->setIntSrc(ud_idx, // Always Read FloatRegBits For Now
- cpu->readFloatRegBits(reg_idx, inst->readTid()));
+ DPRINTF(InOrderUseDef, "[tid:%i]: Reading Float Reg %i from Register File:%x (%08f).\n",
+ tid,
+ reg_idx,
+ cpu->readFloatRegBits(reg_idx, inst->readTid(), floatRegSize[tid]),
+ cpu->readFloatReg(reg_idx, inst->readTid(),floatRegSize[tid]));
+
+ inst->setFloatSrc(ud_idx,
+ cpu->readFloatReg(reg_idx, inst->readTid(), floatRegSize[tid]),
+ floatRegSize[tid]);
} else {
reg_idx -= Ctrl_Base_DepTag;
DPRINTF(InOrderUseDef, "[tid:%i]: Reading Misc Reg %i from Register File:%i.\n",
@@ -156,6 +163,7 @@ UseDefUnit::execute(int slot_idx)
}
} else {
+ // Look for forwarding opportunities
DynInstPtr forward_inst = regDepMap[tid]->canForward(reg_idx, ud_idx, inst);
if (forward_inst) {
@@ -163,18 +171,20 @@ UseDefUnit::execute(int slot_idx)
if (inst->seqNum <= outReadSeqNum[tid]) {
int dest_reg_idx = forward_inst->getDestIdxNum(reg_idx);
- if (reg_idx <= FP_Base_DepTag) {
+ if (reg_idx < FP_Base_DepTag) {
DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest. reg value 0x%x from "
"[sn:%i] to [sn:%i] source #%i.\n",
tid, forward_inst->readIntResult(dest_reg_idx) ,
forward_inst->seqNum, inst->seqNum, ud_idx);
inst->setIntSrc(ud_idx, forward_inst->readIntResult(dest_reg_idx));
- } else if (reg_idx <= Ctrl_Base_DepTag) {
+ } else if (reg_idx < Ctrl_Base_DepTag) {
DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest. reg value 0x%x from "
"[sn:%i] to [sn:%i] source #%i.\n",
tid, forward_inst->readFloatResult(dest_reg_idx) ,
forward_inst->seqNum, inst->seqNum, ud_idx);
- inst->setFloatSrc(ud_idx, forward_inst->readFloatResult(dest_reg_idx));
+ inst->setFloatSrc(ud_idx,
+ forward_inst->readFloatResult(dest_reg_idx),
+ floatRegSize[tid]);
} else {
DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest. reg value 0x%x from "
"[sn:%i] to [sn:%i] source #%i.\n",
@@ -212,7 +222,7 @@ UseDefUnit::execute(int slot_idx)
tid, reg_idx);
if (inst->seqNum <= outReadSeqNum[tid]) {
- if (reg_idx <= FP_Base_DepTag) {
+ if (reg_idx < FP_Base_DepTag) {
DPRINTF(InOrderUseDef, "[tid:%i]: Writing Int. Result 0x%x to register idx %i.\n",
tid, inst->readIntResult(ud_idx), reg_idx);
@@ -222,18 +232,40 @@ UseDefUnit::execute(int slot_idx)
cpu->setIntReg(reg_idx,
inst->readIntResult(ud_idx),
inst->readTid());
- } else if(reg_idx <= Ctrl_Base_DepTag) {
- DPRINTF(InOrderUseDef, "[tid:%i]: Writing FP Result 0x%x (bits:0x%x) to register idx %i.\n",
- tid, inst->readFloatResult(ud_idx), inst->readIntResult(ud_idx), reg_idx);
-
+ } else if(reg_idx < Ctrl_Base_DepTag) {
// Remove Dependencies
regDepMap[tid]->removeFront(reg_idx, inst);
reg_idx -= FP_Base_DepTag;
- cpu->setFloatReg(reg_idx, // Check for FloatRegBits Here
- inst->readFloatResult(ud_idx),
- inst->readTid());
+ if (inst->resultType(ud_idx) == InOrderDynInst::Integer) {
+ DPRINTF(InOrderUseDef, "[tid:%i]: Writing FP-Bits Result 0x%x (bits:0x%x) to register idx %i.\n",
+ tid, inst->readFloatResult(ud_idx), inst->readIntResult(ud_idx), reg_idx);
+
+ cpu->setFloatRegBits(reg_idx, // Check for FloatRegBits Here
+ inst->readIntResult(ud_idx),
+ inst->readTid(),
+ floatRegSize[tid]);
+ } else if (inst->resultType(ud_idx) == InOrderDynInst::Float) {
+ DPRINTF(InOrderUseDef, "[tid:%i]: Writing Float Result 0x%x (bits:0x%x) to register idx %i.\n",
+ tid, inst->readFloatResult(ud_idx), inst->readIntResult(ud_idx), reg_idx);
+
+ cpu->setFloatReg(reg_idx,
+ inst->readFloatResult(ud_idx),
+ inst->readTid(),
+ floatRegSize[tid]);
+ } else if (inst->resultType(ud_idx) == InOrderDynInst::Double) {
+ DPRINTF(InOrderUseDef, "[tid:%i]: Writing Double Result 0x%x (bits:0x%x) to register idx %i.\n",
+ tid, inst->readFloatResult(ud_idx), inst->readIntResult(ud_idx), reg_idx);
+
+ cpu->setFloatReg(reg_idx, // Check for FloatRegBits Here
+ inst->readDoubleResult(ud_idx),
+ inst->readTid(),
+ floatRegSize[tid]);
+ } else {
+ panic("Result Type Not Set For [sn:%i] %s.\n", inst->seqNum, inst->instName());
+ }
+
} else {
DPRINTF(InOrderUseDef, "[tid:%i]: Writing Misc. 0x%x to register idx %i.\n",
tid, inst->readIntResult(ud_idx), reg_idx);
diff --git a/src/cpu/inorder/resources/use_def.hh b/src/cpu/inorder/resources/use_def.hh
index 238591117..51ec2c3f2 100644
--- a/src/cpu/inorder/resources/use_def.hh
+++ b/src/cpu/inorder/resources/use_def.hh
@@ -81,7 +81,7 @@ class UseDefUnit : public Resource {
InstSeqNum *nonSpecSeqNum[ThePipeline::MaxThreads];
- /** @todo: Add Resource Stats Here */
+ InstSeqNum floatRegSize[ThePipeline::MaxThreads];
public:
class UseDefRequest : public ResourceRequest {