From 6211fe5d2ee00dae9cd72d9cccdc900241a8f9a2 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Tue, 12 May 2009 15:01:15 -0400 Subject: 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 --- src/arch/alpha/floatregfile.hh | 2 + src/cpu/inorder/inorder_dyn_inst.cc | 8 ++-- src/cpu/inorder/inorder_dyn_inst.hh | 6 +-- src/cpu/inorder/resources/cache_unit.cc | 6 +-- src/cpu/inorder/resources/tlb_unit.cc | 13 ++++--- src/cpu/inorder/resources/use_def.cc | 68 ++++++++++++++++++++++++--------- src/cpu/inorder/resources/use_def.hh | 2 +- 7 files changed, 69 insertions(+), 36 deletions(-) (limited to 'src') 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 { -- cgit v1.2.3