/*
* Copyright (c) 2012 ARM Limited
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
* All rights reserved
*
* The license below extends only to copyright in the software and shall
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
#include "cpu/quiesce_event.hh"
+#include "cpu/reg_class.hh"
#include "cpu/simple_thread.hh"
#include "cpu/thread_context.hh"
#include "debug/Activity.hh"
InOrderCPU::CachePort::CachePort(CacheUnit *_cacheUnit,
const std::string& name) :
- CpuPort(_cacheUnit->name() + name, _cacheUnit->cpu),
+ MasterPort(_cacheUnit->name() + name, _cacheUnit->cpu),
cacheUnit(_cacheUnit)
{ }
resReqCount(0),
#endif // DEBUG
drainCount(0),
- deferRegistration(false/*params->deferRegistration*/),
stageTracing(params->stageTracing),
lastRunningCycle(0),
instsPerSwitch(0)
memset(intRegs[tid], 0, sizeof(intRegs[tid]));
memset(floatRegs.i[tid], 0, sizeof(floatRegs.i[tid]));
+#ifdef ISA_HAS_CC_REGS
+ memset(ccRegs[tid], 0, sizeof(ccRegs[tid]));
+#endif
isa[tid]->clear();
// Define dummy instructions and resource requests to be used.
}
// InOrderCPU always requires an interrupt controller.
- if (!params->defer_registration && !interrupts) {
+ if (!params->switched_out && !interrupts) {
fatal("InOrderCPU %s has no interrupt controller.\n"
"Ensure createInterruptController() is called.\n", name());
}
{
BaseCPU::init();
- if (!params()->defer_registration &&
- system->getMemoryMode() != Enums::timing) {
- fatal("The in-order CPU requires the memory system to be in "
- "'timing' mode.\n");
- }
-
for (ThreadID tid = 0; tid < numThreads; ++tid) {
// Set noSquashFromTC so that the CPU doesn't squash when initially
// setting up registers.
thread[tid]->initMemProxies(thread[tid]->getTC());
}
- if (FullSystem && !params()->defer_registration) {
+ if (FullSystem && !params()->switched_out) {
for (ThreadID tid = 0; tid < numThreads; tid++) {
ThreadContext *src_tc = threadContexts[tid];
TheISA::initCPU(src_tc, src_tc->contextId());
resPool->init();
}
+void
+InOrderCPU::verifyMemoryMode() const
+{
+ if (!system->isTimingMode()) {
+ fatal("The in-order CPU requires the memory system to be in "
+ "'timing' mode.\n");
+ }
+}
+
Fault
InOrderCPU::hwrei(ThreadID tid)
{
RegIndex
-InOrderCPU::flattenRegIdx(RegIndex reg_idx, RegType ®_type, ThreadID tid)
-{
- if (reg_idx < FP_Base_DepTag) {
- reg_type = IntType;
- return isa[tid]->flattenIntIndex(reg_idx);
- } else if (reg_idx < Ctrl_Base_DepTag) {
- reg_type = FloatType;
- reg_idx -= FP_Base_DepTag;
- return isa[tid]->flattenFloatIndex(reg_idx);
- } else {
- reg_type = MiscType;
- return reg_idx - TheISA::Ctrl_Base_DepTag;
+InOrderCPU::flattenRegIdx(RegIndex reg_idx, RegClass ®_type, ThreadID tid)
+{
+ RegIndex rel_idx;
+
+ reg_type = regIdxToClass(reg_idx, &rel_idx);
+
+ switch (reg_type) {
+ case IntRegClass:
+ return isa[tid]->flattenIntIndex(rel_idx);
+
+ case FloatRegClass:
+ return isa[tid]->flattenFloatIndex(rel_idx);
+
+ case MiscRegClass:
+ return rel_idx;
+
+ default:
+ panic("register %d out of range\n", reg_idx);
}
}
return floatRegs.i[tid][reg_idx];
}
+CCReg
+InOrderCPU::readCCReg(RegIndex reg_idx, ThreadID tid)
+{
+#ifdef ISA_HAS_CC_REGS
+ DPRINTF(CCRegs, "[tid:%i]: Reading CC. Reg %i as %x\n",
+ tid, reg_idx, ccRegs[tid][reg_idx]);
+
+ return ccRegs[tid][reg_idx];
+#else
+ panic("readCCReg: ISA does not have CC regs\n");
+#endif
+}
+
void
InOrderCPU::setIntReg(RegIndex reg_idx, uint64_t val, ThreadID tid)
{
floatRegs.f[tid][reg_idx]);
}
+void
+InOrderCPU::setCCReg(RegIndex reg_idx, CCReg val, ThreadID tid)
+{
+#ifdef ISA_HAS_CC_REGS
+ DPRINTF(CCRegs, "[tid:%i]: Setting CC. Reg %i to %x\n",
+ tid, reg_idx, val);
+ ccRegs[tid][reg_idx] = val;
+#else
+ panic("readCCReg: ISA does not have CC regs\n");
+#endif
+}
+
uint64_t
InOrderCPU::readRegOtherThread(unsigned reg_idx, ThreadID tid)
{
tid = TheISA::getTargetThread(tcBase(tid));
}
- if (reg_idx < FP_Base_DepTag) {
+ RegIndex rel_idx;
+
+ switch (regIdxToClass(reg_idx, &rel_idx)) {
+ case IntRegClass:
// Integer Register File
- return readIntReg(reg_idx, tid);
- } else if (reg_idx < Ctrl_Base_DepTag) {
+ return readIntReg(rel_idx, tid);
+
+ case FloatRegClass:
// Float Register File
- reg_idx -= FP_Base_DepTag;
- return readFloatRegBits(reg_idx, tid);
- } else {
- reg_idx -= Ctrl_Base_DepTag;
- return readMiscReg(reg_idx, tid); // Misc. Register File
+ return readFloatRegBits(rel_idx, tid);
+
+ case MiscRegClass:
+ return readMiscReg(rel_idx, tid); // Misc. Register File
+
+ default:
+ panic("register %d out of range\n", reg_idx);
}
}
+
void
InOrderCPU::setRegOtherThread(unsigned reg_idx, const MiscReg &val,
ThreadID tid)
tid = TheISA::getTargetThread(tcBase(tid));
}
- if (reg_idx < FP_Base_DepTag) { // Integer Register File
- setIntReg(reg_idx, val, tid);
- } else if (reg_idx < Ctrl_Base_DepTag) { // Float Register File
- reg_idx -= FP_Base_DepTag;
- setFloatRegBits(reg_idx, val, tid);
- } else {
- reg_idx -= Ctrl_Base_DepTag;
- setMiscReg(reg_idx, val, tid); // Misc. Register File
+ RegIndex rel_idx;
+
+ switch (regIdxToClass(reg_idx, &rel_idx)) {
+ case IntRegClass:
+ setIntReg(rel_idx, val, tid);
+ break;
+
+ case FloatRegClass:
+ setFloatRegBits(rel_idx, val, tid);
+ break;
+
+ case CCRegClass:
+ setCCReg(rel_idx, val, tid);
+ break;
+
+ case MiscRegClass:
+ setMiscReg(rel_idx, val, tid); // Misc. Register File
+ break;
}
}
numCycles += extra_cycles;
- schedule(&tickEvent, nextCycle());
+ schedule(&tickEvent, clockEdge());
}
// Lots of copied full system code...place into BaseCPU class?