summaryrefslogtreecommitdiff
path: root/src/cpu/checker
diff options
context:
space:
mode:
authorAndreas Sandberg <Andreas.Sandberg@ARM.com>2014-09-03 07:42:22 -0400
committerAndreas Sandberg <Andreas.Sandberg@ARM.com>2014-09-03 07:42:22 -0400
commit326662b01b0fbb7fe4e38cec7a96222d2891808b (patch)
tree35bbca1174a6262d3f69dcf729682e1183f8dede /src/cpu/checker
parente1ac9629398027186ef4c2a66772aeff2b4c6792 (diff)
downloadgem5-326662b01b0fbb7fe4e38cec7a96222d2891808b.tar.xz
arch, cpu: Factor out the ExecContext into a proper base class
We currently generate and compile one version of the ISA code per CPU model. This is obviously wasting a lot of resources at compile time. This changeset factors out the interface into a separate ExecContext class, which also serves as documentation for the interface between CPUs and the ISA code. While doing so, this changeset also fixes up interface inconsistencies between the different CPU models. The main argument for using one set of ISA code per CPU model has always been performance as this avoid indirect branches in the generated code. However, this argument does not hold water. Booting Linux on a simulated ARM system running in atomic mode (opt/10.linux-boot/realview-simple-atomic) is actually 2% faster (compiled using clang 3.4) after applying this patch. Additionally, compilation time is decreased by 35%.
Diffstat (limited to 'src/cpu/checker')
-rw-r--r--src/cpu/checker/SConsopts4
-rw-r--r--src/cpu/checker/cpu.hh27
2 files changed, 17 insertions, 14 deletions
diff --git a/src/cpu/checker/SConsopts b/src/cpu/checker/SConsopts
index 94d8e0e9f..5d676ba1b 100644
--- a/src/cpu/checker/SConsopts
+++ b/src/cpu/checker/SConsopts
@@ -30,6 +30,4 @@
Import('*')
-CpuModel('CheckerCPU', 'checker_cpu_exec.cc',
- '#include "cpu/checker/cpu.hh"',
- { 'CPU_exec_context': 'CheckerCPU' })
+CpuModel('CheckerCPU')
diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh
index 9f4c4d58c..bf71dc30e 100644
--- a/src/cpu/checker/cpu.hh
+++ b/src/cpu/checker/cpu.hh
@@ -52,6 +52,7 @@
#include "base/statistics.hh"
#include "cpu/base.hh"
#include "cpu/base_dyn_inst.hh"
+#include "cpu/exec_context.hh"
#include "cpu/pc_event.hh"
#include "cpu/simple_thread.hh"
#include "cpu/static_inst.hh"
@@ -86,7 +87,7 @@ class Request;
* checker to be able to correctly verify instructions, even with
* external accesses to the ThreadContext that change state.
*/
-class CheckerCPU : public BaseCPU
+class CheckerCPU : public BaseCPU, public ExecContext
{
protected:
typedef TheISA::MachInst MachInst;
@@ -194,7 +195,7 @@ class CheckerCPU : public BaseCPU
// These functions are only used in CPU models that split
// effective address computation from the actual memory access.
void setEA(Addr EA) { panic("SimpleCPU::setEA() not implemented\n"); }
- Addr getEA() { panic("SimpleCPU::getEA() not implemented\n"); }
+ Addr getEA() const { panic("SimpleCPU::getEA() not implemented\n"); }
// The register accessor methods provide the index of the
// instruction's operand (e.g., 0 or 1), not the architectural
@@ -207,7 +208,7 @@ class CheckerCPU : public BaseCPU
// storage (which is pretty hard to imagine they would have reason
// to do).
- uint64_t readIntRegOperand(const StaticInst *si, int idx)
+ IntReg readIntRegOperand(const StaticInst *si, int idx)
{
return thread->readIntReg(si->srcRegIdx(idx));
}
@@ -224,7 +225,7 @@ class CheckerCPU : public BaseCPU
return thread->readFloatRegBits(reg_idx);
}
- uint64_t readCCRegOperand(const StaticInst *si, int idx)
+ CCReg readCCRegOperand(const StaticInst *si, int idx)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::CC_Reg_Base;
return thread->readCCReg(reg_idx);
@@ -238,7 +239,7 @@ class CheckerCPU : public BaseCPU
result.push(instRes);
}
- void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
+ void setIntRegOperand(const StaticInst *si, int idx, IntReg val)
{
thread->setIntReg(si->destRegIdx(idx), val);
setResult<uint64_t>(val);
@@ -259,7 +260,7 @@ class CheckerCPU : public BaseCPU
setResult<uint64_t>(val);
}
- void setCCRegOperand(const StaticInst *si, int idx, uint64_t val)
+ void setCCRegOperand(const StaticInst *si, int idx, CCReg val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::CC_Reg_Base;
thread->setCCReg(reg_idx, val);
@@ -272,7 +273,7 @@ class CheckerCPU : public BaseCPU
thread->setPredicate(val);
}
- TheISA::PCState pcState() { return thread->pcState(); }
+ TheISA::PCState pcState() const { return thread->pcState(); }
void pcState(const TheISA::PCState &val)
{
DPRINTF(Checker, "Changing PC to %s, old PC %s.\n",
@@ -322,13 +323,13 @@ class CheckerCPU : public BaseCPU
}
#if THE_ISA == MIPS_ISA
- uint64_t readRegOtherThread(int misc_reg)
+ MiscReg readRegOtherThread(int misc_reg, ThreadID tid)
{
panic("MIPS MT not defined for CheckerCPU.\n");
return 0;
}
- void setRegOtherThread(int misc_reg, const TheISA::MiscReg &val)
+ void setRegOtherThread(int misc_reg, MiscReg val, ThreadID tid)
{
panic("MIPS MT not defined for CheckerCPU.\n");
}
@@ -362,7 +363,11 @@ class CheckerCPU : public BaseCPU
Fault writeMem(uint8_t *data, unsigned size,
Addr addr, unsigned flags, uint64_t *res);
- void setStCondFailures(unsigned sc_failures)
+ unsigned int readStCondFailures() const {
+ return thread->readStCondFailures();
+ }
+
+ void setStCondFailures(unsigned int sc_failures)
{}
/////////////////////////////////////////////////////
@@ -371,7 +376,7 @@ class CheckerCPU : public BaseCPU
void wakeup() { }
// Assume that the normal CPU's call to syscall was successful.
// The checker's state would have already been updated by the syscall.
- void syscall(uint64_t callnum) { }
+ void syscall(int64_t callnum) { }
void handleError()
{