From 608641e23c7f2288810c3f23a1a63790b664f2ab Mon Sep 17 00:00:00 2001 From: Nilay Vaish Date: Sun, 26 Jul 2015 10:21:20 -0500 Subject: cpu: implements vector registers This adds a vector register type. The type is defined as a std::array of a fixed number of uint64_ts. The isa_parser.py has been modified to parse vector register operands and generate the required code. Different cpus have vector register files now. --- src/cpu/checker/cpu.hh | 24 ++++++++++++- src/cpu/checker/cpu_impl.hh | 74 +++++++++++++++++++++++++++------------ src/cpu/checker/thread_context.hh | 16 +++++++++ 3 files changed, 91 insertions(+), 23 deletions(-) (limited to 'src/cpu/checker') diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh index a363b6d0f..6d75f7c12 100644 --- a/src/cpu/checker/cpu.hh +++ b/src/cpu/checker/cpu.hh @@ -94,6 +94,7 @@ class CheckerCPU : public BaseCPU, public ExecContext typedef TheISA::FloatReg FloatReg; typedef TheISA::FloatRegBits FloatRegBits; typedef TheISA::MiscReg MiscReg; + typedef TheISA::VectorReg VectorReg; /** id attached to all issued requests */ MasterID masterId; @@ -145,10 +146,19 @@ class CheckerCPU : public BaseCPU, public ExecContext union Result { uint64_t integer; double dbl; + + // I am assuming that vector register type is different from the two + // types used above. Else it seems useless to have a separate typedef + // for vector registers. + VectorReg vector; + void set(uint64_t i) { integer = i; } void set(double d) { dbl = d; } + void set(const VectorReg &v) { vector = v; } + void get(uint64_t& i) { i = integer; } void get(double& d) { d = dbl; } + void get(VectorReg& v) { v = vector; } }; // ISAs like ARM can have multiple destination registers to check, @@ -231,6 +241,11 @@ class CheckerCPU : public BaseCPU, public ExecContext return thread->readCCReg(reg_idx); } + const VectorReg &readVectorRegOperand(const StaticInst *si, int idx) + { + return thread->readVectorReg(si->srcRegIdx(idx)); + } + template void setResult(T t) { @@ -267,6 +282,13 @@ class CheckerCPU : public BaseCPU, public ExecContext setResult(val); } + void setVectorRegOperand(const StaticInst *si, int idx, + const VectorReg &val) + { + thread->setVectorReg(si->destRegIdx(idx), val); + setResult(val); + } + bool readPredicate() { return thread->readPredicate(); } void setPredicate(bool val) { @@ -441,7 +463,7 @@ class Checker : public CheckerCPU void validateExecution(DynInstPtr &inst); void validateState(); - void copyResult(DynInstPtr &inst, uint64_t mismatch_val, int start_idx); + void copyResult(DynInstPtr &inst, Result mismatch_val, int start_idx); void handlePendingInt(); private: diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh index 289861521..d6a467358 100644 --- a/src/cpu/checker/cpu_impl.hh +++ b/src/cpu/checker/cpu_impl.hh @@ -491,7 +491,9 @@ Checker::validateExecution(DynInstPtr &inst) // Unverifiable instructions assume they were executed // properly by the CPU. Grab the result from the // instruction and write it to the register. - copyResult(inst, 0, idx); + Result r; + r.integer = 0; + copyResult(inst, r, idx); } else if (inst->numDestRegs() > 0 && !result.empty()) { DPRINTF(Checker, "Dest regs %d, number of checker dest regs %d\n", inst->numDestRegs(), result.size()); @@ -525,7 +527,9 @@ Checker::validateExecution(DynInstPtr &inst) // The load/store queue in Detailed CPU can also cause problems // if load/store forwarding is allowed. if (inst->isLoad() && warnOnlyOnLoadError) { - copyResult(inst, inst_val, idx); + Result r; + r.integer = inst_val; + copyResult(inst, r, idx); } else { handleError(inst); } @@ -590,7 +594,7 @@ Checker::validateState() template void -Checker::copyResult(DynInstPtr &inst, uint64_t mismatch_val, +Checker::copyResult(DynInstPtr &inst, Result mismatch_val, int start_idx) { // We've already popped one dest off the queue, @@ -599,39 +603,65 @@ Checker::copyResult(DynInstPtr &inst, uint64_t mismatch_val, RegIndex idx = inst->destRegIdx(start_idx); switch (regIdxToClass(idx)) { case IntRegClass: - thread->setIntReg(idx, mismatch_val); + thread->setIntReg(idx, mismatch_val.integer); break; case FloatRegClass: - thread->setFloatRegBits(idx - TheISA::FP_Reg_Base, mismatch_val); + thread->setFloatRegBits(idx - TheISA::FP_Reg_Base, + mismatch_val.integer); break; case CCRegClass: - thread->setCCReg(idx - TheISA::CC_Reg_Base, mismatch_val); + thread->setCCReg(idx - TheISA::CC_Reg_Base, mismatch_val.integer); + break; + case VectorRegClass: + thread->setVectorReg(idx - TheISA::Vector_Reg_Base, + mismatch_val.vector); break; case MiscRegClass: thread->setMiscReg(idx - TheISA::Misc_Reg_Base, - mismatch_val); + mismatch_val.integer); break; } } + start_idx++; - uint64_t res = 0; for (int i = start_idx; i < inst->numDestRegs(); i++) { RegIndex idx = inst->destRegIdx(i); - inst->template popResult(res); switch (regIdxToClass(idx)) { - case IntRegClass: - thread->setIntReg(idx, res); - break; - case FloatRegClass: - thread->setFloatRegBits(idx - TheISA::FP_Reg_Base, res); - break; - case CCRegClass: - thread->setCCReg(idx - TheISA::CC_Reg_Base, res); - break; - case MiscRegClass: - // Try to get the proper misc register index for ARM here... - thread->setMiscReg(idx - TheISA::Misc_Reg_Base, res); - break; + case IntRegClass: { + uint64_t res = 0; + inst->template popResult(res); + thread->setIntReg(idx, res); + } + break; + + case FloatRegClass: { + uint64_t res = 0; + inst->template popResult(res); + thread->setFloatRegBits(idx - TheISA::FP_Reg_Base, res); + } + break; + + case CCRegClass: { + uint64_t res = 0; + inst->template popResult(res); + thread->setCCReg(idx - TheISA::CC_Reg_Base, res); + } + break; + + case VectorRegClass: { + VectorReg res; + inst->template popResult(res); + thread->setVectorReg(idx - TheISA::Vector_Reg_Base, res); + } + break; + + case MiscRegClass: { + // Try to get the proper misc register index for ARM here... + uint64_t res = 0; + inst->template popResult(res); + thread->setMiscReg(idx - TheISA::Misc_Reg_Base, res); + } + break; // else Register is out of range... } } diff --git a/src/cpu/checker/thread_context.hh b/src/cpu/checker/thread_context.hh index 71c231ba0..436c97847 100644 --- a/src/cpu/checker/thread_context.hh +++ b/src/cpu/checker/thread_context.hh @@ -216,6 +216,9 @@ class CheckerThreadContext : public ThreadContext CCReg readCCReg(int reg_idx) { return actualTC->readCCReg(reg_idx); } + const VectorReg &readVectorReg(int reg_idx) + { return actualTC->readVectorReg(reg_idx); } + void setIntReg(int reg_idx, uint64_t val) { actualTC->setIntReg(reg_idx, val); @@ -240,6 +243,12 @@ class CheckerThreadContext : public ThreadContext checkerTC->setCCReg(reg_idx, val); } + void setVectorReg(int reg_idx, const VectorReg &val) + { + actualTC->setVectorReg(reg_idx, val); + checkerTC->setVectorReg(reg_idx, val); + } + /** Reads this thread's PC state. */ TheISA::PCState pcState() { return actualTC->pcState(); } @@ -296,6 +305,7 @@ class CheckerThreadContext : public ThreadContext int flattenIntIndex(int reg) { return actualTC->flattenIntIndex(reg); } int flattenFloatIndex(int reg) { return actualTC->flattenFloatIndex(reg); } int flattenCCIndex(int reg) { return actualTC->flattenCCIndex(reg); } + int flattenVectorIndex(int reg) { return actualTC->flattenVectorIndex(reg); } int flattenMiscIndex(int reg) { return actualTC->flattenMiscIndex(reg); } unsigned readStCondFailures() @@ -331,6 +341,12 @@ class CheckerThreadContext : public ThreadContext void setCCRegFlat(int idx, CCReg val) { actualTC->setCCRegFlat(idx, val); } + + const VectorReg &readVectorRegFlat(int idx) + { return actualTC->readVectorRegFlat(idx); } + + void setVectorRegFlat(int idx, const VectorReg &val) + { actualTC->setVectorRegFlat(idx, val); } }; #endif // __CPU_CHECKER_EXEC_CONTEXT_HH__ -- cgit v1.2.3