diff options
author | Rekai Gonzalez-Alberquilla <Rekai.GonzalezAlberquilla@arm.com> | 2017-04-05 13:20:30 -0500 |
---|---|---|
committer | Andreas Sandberg <andreas.sandberg@arm.com> | 2017-07-05 14:43:49 +0000 |
commit | 2da7656a9a2fbf30cac0caffa4a2d168f736b4a1 (patch) | |
tree | 11d2bd70ca04e751ad4664bb283ecc005462be28 /src/cpu/checker/cpu_impl.hh | |
parent | a473b5a6eb269cc303ecfb5e5643d891a5d255d9 (diff) | |
download | gem5-2da7656a9a2fbf30cac0caffa4a2d168f736b4a1.tar.xz |
cpu: Result refactoring
The Result union used to collect the result of an instruction is now a
class of its own, with its constructor, and explicit casting methods for
cleanliness.
This is also a stepping stone to have vector registers, and instructions
that produce a vector register as output.
Change-Id: I6f40c11cb5e835d8b11f7804a4e967aff18025b9
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/2703
Reviewed-by: Anthony Gutierrez <anthony.gutierrez@amd.com>
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Diffstat (limited to 'src/cpu/checker/cpu_impl.hh')
-rw-r--r-- | src/cpu/checker/cpu_impl.hh | 55 |
1 files changed, 34 insertions, 21 deletions
diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh index 0c90590c7..ed86aec84 100644 --- a/src/cpu/checker/cpu_impl.hh +++ b/src/cpu/checker/cpu_impl.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 ARM Limited + * Copyright (c) 2011, 2016 ARM Limited * Copyright (c) 2013 Advanced Micro Devices, Inc. * All rights reserved * @@ -481,27 +481,29 @@ template <class Impl> void Checker<Impl>::validateExecution(DynInstPtr &inst) { - uint64_t checker_val; - uint64_t inst_val; + InstResult checker_val; + InstResult inst_val; int idx = -1; bool result_mismatch = false; + bool scalar_mismatch = false; if (inst->isUnverifiable()) { // 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); + copyResult(inst, InstResult(0ul, InstResult::ResultType::Scalar), idx); } else if (inst->numDestRegs() > 0 && !result.empty()) { DPRINTF(Checker, "Dest regs %d, number of checker dest regs %d\n", inst->numDestRegs(), result.size()); for (int i = 0; i < inst->numDestRegs() && !result.empty(); i++) { - result.front().get(checker_val); + checker_val = result.front(); result.pop(); - inst_val = 0; - inst->template popResult<uint64_t>(inst_val); + inst_val = inst->popResult( + InstResult(0ul, InstResult::ResultType::Scalar)); if (checker_val != inst_val) { result_mismatch = true; idx = i; + scalar_mismatch = true; break; } } @@ -512,9 +514,12 @@ Checker<Impl>::validateExecution(DynInstPtr &inst) // this is ok and not a bug. May be worthwhile to try and correct this. if (result_mismatch) { - warn("%lli: Instruction results do not match! (Values may not " - "actually be integers) Inst: %#x, checker: %#x", - curTick(), inst_val, checker_val); + if (scalar_mismatch) { + warn("%lli: Instruction results (%i) do not match! (Values may" + " not actually be integers) Inst: %#x, checker: %#x", + curTick(), idx, inst_val.asIntegerNoAssert(), + checker_val.asInteger()); + } // It's useful to verify load values from memory, but in MP // systems the value obtained at execute may be different than @@ -589,7 +594,7 @@ Checker<Impl>::validateState() template <class Impl> void -Checker<Impl>::copyResult(DynInstPtr &inst, uint64_t mismatch_val, +Checker<Impl>::copyResult(DynInstPtr &inst, const InstResult& mismatch_val, int start_idx) { // We've already popped one dest off the queue, @@ -598,37 +603,45 @@ Checker<Impl>::copyResult(DynInstPtr &inst, uint64_t mismatch_val, const RegId& idx = inst->destRegIdx(start_idx); switch (idx.classValue()) { case IntRegClass: - thread->setIntReg(idx.index(), mismatch_val); + panic_if(!mismatch_val.isScalar(), "Unexpected type of result"); + thread->setIntReg(idx.index(), mismatch_val.asInteger()); break; case FloatRegClass: - thread->setFloatRegBits(idx.index(), mismatch_val); + panic_if(!mismatch_val.isScalar(), "Unexpected type of result"); + thread->setFloatRegBits(idx.index(), mismatch_val.asInteger()); break; case CCRegClass: - thread->setCCReg(idx.index(), mismatch_val); + panic_if(!mismatch_val.isScalar(), "Unexpected type of result"); + thread->setCCReg(idx.index(), mismatch_val.asInteger()); break; case MiscRegClass: - thread->setMiscReg(idx.index(), mismatch_val); + panic_if(!mismatch_val.isScalar(), "Unexpected type of result"); + thread->setMiscReg(idx.index(), mismatch_val.asInteger()); break; } } start_idx++; - uint64_t res = 0; + InstResult res; for (int i = start_idx; i < inst->numDestRegs(); i++) { const RegId& idx = inst->destRegIdx(i); - inst->template popResult<uint64_t>(res); + res = inst->popResult(); switch (idx.classValue()) { case IntRegClass: - thread->setIntReg(idx.index(), res); + panic_if(!res.isScalar(), "Unexpected type of result"); + thread->setIntReg(idx.index(), res.asInteger()); break; case FloatRegClass: - thread->setFloatRegBits(idx.index(), res); + panic_if(!res.isScalar(), "Unexpected type of result"); + thread->setFloatRegBits(idx.index(), res.asInteger()); break; case CCRegClass: - thread->setCCReg(idx.index(), res); + panic_if(!res.isScalar(), "Unexpected type of result"); + thread->setCCReg(idx.index(), res.asInteger()); break; case MiscRegClass: + panic_if(res.isValid(), "MiscReg expecting invalid result"); // Try to get the proper misc register index for ARM here... - thread->setMiscReg(idx.index(), res); + thread->setMiscReg(idx.index(), 0); break; // else Register is out of range... } |