summaryrefslogtreecommitdiff
path: root/src/cpu/checker
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/checker')
-rw-r--r--src/cpu/checker/cpu.hh138
-rw-r--r--src/cpu/checker/cpu_impl.hh28
-rw-r--r--src/cpu/checker/thread_context.hh83
3 files changed, 246 insertions, 3 deletions
diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh
index 6571d034a..213106bd2 100644
--- a/src/cpu/checker/cpu.hh
+++ b/src/cpu/checker/cpu.hh
@@ -96,6 +96,7 @@ class CheckerCPU : public BaseCPU, public ExecContext
typedef TheISA::FloatReg FloatReg;
typedef TheISA::FloatRegBits FloatRegBits;
typedef TheISA::MiscReg MiscReg;
+ using VecRegContainer = TheISA::VecRegContainer;
/** id attached to all issued requests */
MasterID masterId;
@@ -225,6 +226,111 @@ class CheckerCPU : public BaseCPU, public ExecContext
return thread->readFloatRegBits(reg.index());
}
+ /**
+ * Read source vector register operand.
+ */
+ const VecRegContainer& readVecRegOperand(const StaticInst *si,
+ int idx) const override
+ {
+ const RegId& reg = si->srcRegIdx(idx);
+ assert(reg.isVecReg());
+ return thread->readVecReg(reg);
+ }
+
+ /**
+ * Read destination vector register operand for modification.
+ */
+ VecRegContainer& getWritableVecRegOperand(const StaticInst *si,
+ int idx) override
+ {
+ const RegId& reg = si->destRegIdx(idx);
+ assert(reg.isVecReg());
+ return thread->getWritableVecReg(reg);
+ }
+
+ /** Vector Register Lane Interfaces. */
+ /** @{ */
+ /** Reads source vector 8bit operand. */
+ virtual ConstVecLane8
+ readVec8BitLaneOperand(const StaticInst *si, int idx) const
+ override
+ {
+ const RegId& reg = si->destRegIdx(idx);
+ assert(reg.isVecReg());
+ return thread->readVec8BitLaneReg(reg);
+ }
+
+ /** Reads source vector 16bit operand. */
+ virtual ConstVecLane16
+ readVec16BitLaneOperand(const StaticInst *si, int idx) const
+ override
+ {
+ const RegId& reg = si->destRegIdx(idx);
+ assert(reg.isVecReg());
+ return thread->readVec16BitLaneReg(reg);
+ }
+
+ /** Reads source vector 32bit operand. */
+ virtual ConstVecLane32
+ readVec32BitLaneOperand(const StaticInst *si, int idx) const
+ override
+ {
+ const RegId& reg = si->destRegIdx(idx);
+ assert(reg.isVecReg());
+ return thread->readVec32BitLaneReg(reg);
+ }
+
+ /** Reads source vector 64bit operand. */
+ virtual ConstVecLane64
+ readVec64BitLaneOperand(const StaticInst *si, int idx) const
+ override
+ {
+ const RegId& reg = si->destRegIdx(idx);
+ assert(reg.isVecReg());
+ return thread->readVec64BitLaneReg(reg);
+ }
+
+ /** Write a lane of the destination vector operand. */
+ template <typename LD>
+ void
+ setVecLaneOperandT(const StaticInst *si, int idx, const LD& val)
+ {
+ const RegId& reg = si->destRegIdx(idx);
+ assert(reg.isVecReg());
+ return thread->setVecLane(reg, val);
+ }
+ virtual void
+ setVecLaneOperand(const StaticInst *si, int idx,
+ const LaneData<LaneSize::Byte>& val) override
+ {
+ setVecLaneOperandT(si, idx, val);
+ }
+ virtual void
+ setVecLaneOperand(const StaticInst *si, int idx,
+ const LaneData<LaneSize::TwoByte>& val) override
+ {
+ setVecLaneOperandT(si, idx, val);
+ }
+ virtual void
+ setVecLaneOperand(const StaticInst *si, int idx,
+ const LaneData<LaneSize::FourByte>& val) override
+ {
+ setVecLaneOperandT(si, idx, val);
+ }
+ virtual void
+ setVecLaneOperand(const StaticInst *si, int idx,
+ const LaneData<LaneSize::EightByte>& val) override
+ {
+ setVecLaneOperandT(si, idx, val);
+ }
+ /** @} */
+
+ VecElem readVecElemOperand(const StaticInst *si, int idx) const override
+ {
+ const RegId& reg = si->srcRegIdx(idx);
+ return thread->readVecElem(reg);
+ }
+
CCReg readCCRegOperand(const StaticInst *si, int idx) override
{
const RegId& reg = si->srcRegIdx(idx);
@@ -239,6 +345,20 @@ class CheckerCPU : public BaseCPU, public ExecContext
InstResult::ResultType::Scalar));
}
+ template<typename T>
+ void setVecResult(T&& t)
+ {
+ result.push(InstResult(std::forward<T>(t),
+ InstResult::ResultType::VecReg));
+ }
+
+ template<typename T>
+ void setVecElemResult(T&& t)
+ {
+ result.push(InstResult(std::forward<T>(t),
+ InstResult::ResultType::VecElem));
+ }
+
void setIntRegOperand(const StaticInst *si, int idx,
IntReg val) override
{
@@ -274,6 +394,24 @@ class CheckerCPU : public BaseCPU, public ExecContext
setScalarResult((uint64_t)val);
}
+ void setVecRegOperand(const StaticInst *si, int idx,
+ const VecRegContainer& val) override
+ {
+ const RegId& reg = si->destRegIdx(idx);
+ assert(reg.isVecReg());
+ thread->setVecReg(reg, val);
+ setVecResult(val);
+ }
+
+ void setVecElemOperand(const StaticInst *si, int idx,
+ const VecElem val) override
+ {
+ const RegId& reg = si->destRegIdx(idx);
+ assert(reg.isVecElem());
+ thread->setVecElem(reg, val);
+ setVecElemResult(val);
+ }
+
bool readPredicate() override { return thread->readPredicate(); }
void setPredicate(bool val) override
{
diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh
index ed86aec84..d81858c14 100644
--- a/src/cpu/checker/cpu_impl.hh
+++ b/src/cpu/checker/cpu_impl.hh
@@ -486,6 +486,7 @@ Checker<Impl>::validateExecution(DynInstPtr &inst)
int idx = -1;
bool result_mismatch = false;
bool scalar_mismatch = false;
+ bool vector_mismatch = false;
if (inst->isUnverifiable()) {
// Unverifiable instructions assume they were executed
@@ -503,8 +504,10 @@ Checker<Impl>::validateExecution(DynInstPtr &inst)
if (checker_val != inst_val) {
result_mismatch = true;
idx = i;
- scalar_mismatch = true;
- break;
+ scalar_mismatch = checker_val.isScalar();
+ vector_mismatch = checker_val.isVector();
+ panic_if(!(scalar_mismatch || vector_mismatch),
+ "Unknown type of result\n");
}
}
} // Checker CPU checks all the saved results in the dyninst passed by
@@ -610,6 +613,15 @@ Checker<Impl>::copyResult(DynInstPtr &inst, const InstResult& mismatch_val,
panic_if(!mismatch_val.isScalar(), "Unexpected type of result");
thread->setFloatRegBits(idx.index(), mismatch_val.asInteger());
break;
+ case VecRegClass:
+ panic_if(!mismatch_val.isVector(), "Unexpected type of result");
+ thread->setVecReg(idx, mismatch_val.asVector());
+ break;
+ case VecElemClass:
+ panic_if(!mismatch_val.isVecElem(),
+ "Unexpected type of result");
+ thread->setVecElem(idx, mismatch_val.asVectorElem());
+ break;
case CCRegClass:
panic_if(!mismatch_val.isScalar(), "Unexpected type of result");
thread->setCCReg(idx.index(), mismatch_val.asInteger());
@@ -618,6 +630,8 @@ Checker<Impl>::copyResult(DynInstPtr &inst, const InstResult& mismatch_val,
panic_if(!mismatch_val.isScalar(), "Unexpected type of result");
thread->setMiscReg(idx.index(), mismatch_val.asInteger());
break;
+ default:
+ panic("Unknown register class: %d", (int)idx.classValue());
}
}
start_idx++;
@@ -634,6 +648,14 @@ Checker<Impl>::copyResult(DynInstPtr &inst, const InstResult& mismatch_val,
panic_if(!res.isScalar(), "Unexpected type of result");
thread->setFloatRegBits(idx.index(), res.asInteger());
break;
+ case VecRegClass:
+ panic_if(!res.isVector(), "Unexpected type of result");
+ thread->setVecReg(idx, res.asVector());
+ break;
+ case VecElemClass:
+ panic_if(!res.isVecElem(), "Unexpected type of result");
+ thread->setVecElem(idx, res.asVectorElem());
+ break;
case CCRegClass:
panic_if(!res.isScalar(), "Unexpected type of result");
thread->setCCReg(idx.index(), res.asInteger());
@@ -644,6 +666,8 @@ Checker<Impl>::copyResult(DynInstPtr &inst, const InstResult& mismatch_val,
thread->setMiscReg(idx.index(), 0);
break;
// else Register is out of range...
+ default:
+ panic("Unknown register class: %d", (int)idx.classValue());
}
}
}
diff --git a/src/cpu/checker/thread_context.hh b/src/cpu/checker/thread_context.hh
index e48f5936b..5208932de 100644
--- a/src/cpu/checker/thread_context.hh
+++ b/src/cpu/checker/thread_context.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2012 ARM Limited
+ * Copyright (c) 2011-2012, 2016 ARM Limited
* Copyright (c) 2013 Advanced Micro Devices, Inc.
* All rights reserved
*
@@ -215,6 +215,55 @@ class CheckerThreadContext : public ThreadContext
FloatRegBits readFloatRegBits(int reg_idx)
{ return actualTC->readFloatRegBits(reg_idx); }
+ const VecRegContainer& readVecReg(const RegId& reg) const
+ { return actualTC->readVecReg(reg); }
+
+ /**
+ * Read vector register for modification, hierarchical indexing.
+ */
+ VecRegContainer& getWritableVecReg(const RegId& reg)
+ { return actualTC->getWritableVecReg(reg); }
+
+ /** Vector Register Lane Interfaces. */
+ /** @{ */
+ /** Reads source vector 8bit operand. */
+ ConstVecLane8
+ readVec8BitLaneReg(const RegId& reg) const
+ { return actualTC->readVec8BitLaneReg(reg); }
+
+ /** Reads source vector 16bit operand. */
+ ConstVecLane16
+ readVec16BitLaneReg(const RegId& reg) const
+ { return actualTC->readVec16BitLaneReg(reg); }
+
+ /** Reads source vector 32bit operand. */
+ ConstVecLane32
+ readVec32BitLaneReg(const RegId& reg) const
+ { return actualTC->readVec32BitLaneReg(reg); }
+
+ /** Reads source vector 64bit operand. */
+ ConstVecLane64
+ readVec64BitLaneReg(const RegId& reg) const
+ { return actualTC->readVec64BitLaneReg(reg); }
+
+ /** Write a lane of the destination vector register. */
+ virtual void setVecLane(const RegId& reg,
+ const LaneData<LaneSize::Byte>& val)
+ { return actualTC->setVecLane(reg, val); }
+ virtual void setVecLane(const RegId& reg,
+ const LaneData<LaneSize::TwoByte>& val)
+ { return actualTC->setVecLane(reg, val); }
+ virtual void setVecLane(const RegId& reg,
+ const LaneData<LaneSize::FourByte>& val)
+ { return actualTC->setVecLane(reg, val); }
+ virtual void setVecLane(const RegId& reg,
+ const LaneData<LaneSize::EightByte>& val)
+ { return actualTC->setVecLane(reg, val); }
+ /** @} */
+
+ const VecElem& readVecElem(const RegId& reg) const
+ { return actualTC->readVecElem(reg); }
+
CCReg readCCReg(int reg_idx)
{ return actualTC->readCCReg(reg_idx); }
@@ -236,6 +285,18 @@ class CheckerThreadContext : public ThreadContext
checkerTC->setFloatRegBits(reg_idx, val);
}
+ void setVecReg(const RegId& reg, const VecRegContainer& val)
+ {
+ actualTC->setVecReg(reg, val);
+ checkerTC->setVecReg(reg, val);
+ }
+
+ void setVecElem(const RegId& reg, const VecElem& val)
+ {
+ actualTC->setVecElem(reg, val);
+ checkerTC->setVecElem(reg, val);
+ }
+
void setCCReg(int reg_idx, CCReg val)
{
actualTC->setCCReg(reg_idx, val);
@@ -333,6 +394,26 @@ class CheckerThreadContext : public ThreadContext
void setFloatRegBitsFlat(int idx, FloatRegBits val)
{ actualTC->setFloatRegBitsFlat(idx, val); }
+ const VecRegContainer& readVecRegFlat(int idx) const
+ { return actualTC->readVecRegFlat(idx); }
+
+ /**
+ * Read vector register for modification, flat indexing.
+ */
+ VecRegContainer& getWritableVecRegFlat(int idx)
+ { return actualTC->getWritableVecRegFlat(idx); }
+
+ void setVecRegFlat(int idx, const VecRegContainer& val)
+ { actualTC->setVecRegFlat(idx, val); }
+
+ const VecElem& readVecElemFlat(const RegIndex& idx,
+ const ElemIndex& elem_idx) const
+ { return actualTC->readVecElemFlat(idx, elem_idx); }
+
+ void setVecElemFlat(const RegIndex& idx,
+ const ElemIndex& elem_idx, const VecElem& val)
+ { actualTC->setVecElemFlat(idx, elem_idx, val); }
+
CCReg readCCRegFlat(int idx)
{ return actualTC->readCCRegFlat(idx); }