diff options
Diffstat (limited to 'cpu')
-rw-r--r-- | cpu/exec_context.cc | 15 | ||||
-rw-r--r-- | cpu/exec_context.hh | 24 | ||||
-rw-r--r-- | cpu/simple_cpu/simple_cpu.cc | 10 | ||||
-rw-r--r-- | cpu/simple_cpu/simple_cpu.hh | 73 | ||||
-rw-r--r-- | cpu/static_inst.hh | 11 |
5 files changed, 111 insertions, 22 deletions
diff --git a/cpu/exec_context.cc b/cpu/exec_context.cc index 7f7719bf0..0d3a80fe7 100644 --- a/cpu/exec_context.cc +++ b/cpu/exec_context.cc @@ -106,6 +106,7 @@ ExecContext::serialize(ostream &os) regs.serialize(os); // thread_num and cpu_id are deterministic from the config SERIALIZE_SCALAR(func_exe_inst); + SERIALIZE_SCALAR(inst); #ifdef FULL_SYSTEM bool ctx = false; @@ -143,6 +144,7 @@ ExecContext::unserialize(Checkpoint *cp, const std::string §ion) regs.unserialize(cp, section); // thread_num and cpu_id are deterministic from the config UNSERIALIZE_SCALAR(func_exe_inst); + UNSERIALIZE_SCALAR(inst); #ifdef FULL_SYSTEM bool ctx; @@ -233,3 +235,16 @@ ExecContext::regStats(const string &name) kernelStats.regStats(name + ".kern"); #endif } + +void +ExecContext::trap(Fault fault) +{ + //TheISA::trap(fault); //One possible way to do it... + + /** @todo: Going to hack it for now. Do a true fixup later. */ +#ifdef FULL_SYSTEM + ev5_trap(fault); +#else + fatal("fault (%d) detected @ PC 0x%08p", fault, readPC()); +#endif +} diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 7be83539a..a62225f1b 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -31,6 +31,7 @@ #include "sim/host.hh" #include "mem/mem_req.hh" +#include "mem/functional_mem/functional_memory.hh" #include "sim/serialize.hh" // forward declaration: see functional_memory.hh @@ -114,6 +115,9 @@ class ExecContext // pointer to CPU associated with this context BaseCPU *cpu; + // Current instruction + MachInst inst; + // Index of hardware thread context on the CPU that this represents. int thread_num; @@ -311,6 +315,18 @@ class ExecContext virtual bool misspeculating(); + MachInst getInst() { return inst; } + + void setInst(MachInst new_inst) + { + inst = new_inst; + } + + Fault instRead(MemReqPtr &req) + { + return mem->read(req, inst); + } + // // New accessors for new decoder. // @@ -395,6 +411,14 @@ class ExecContext bool simPalCheck(int palFunc); #endif + /** Meant to be more generic trap function to be + * called when an instruction faults. + * @param fault The fault generated by executing the instruction. + * @todo How to do this properly so it's dependent upon ISA only? + */ + + void trap(Fault fault); + #ifndef FULL_SYSTEM IntReg getSyscallArg(int i) { diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc index 765507345..e1a861ad8 100644 --- a/cpu/simple_cpu/simple_cpu.cc +++ b/cpu/simple_cpu/simple_cpu.cc @@ -42,6 +42,7 @@ #include "base/pollevent.hh" #include "base/range.hh" #include "base/trace.hh" +#include "base/stats/events.hh" #include "cpu/base_cpu.hh" #include "cpu/exec_context.hh" #include "cpu/exetrace.hh" @@ -402,6 +403,9 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags) } } + if (!dcacheInterface && (memReq->flags & UNCACHEABLE)) + Stats::recordEvent("Uncached Read"); + return fault; } @@ -487,6 +491,9 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) if (res && (fault == No_Fault)) *res = memReq->result; + if (!dcacheInterface && (memReq->flags & UNCACHEABLE)) + Stats::recordEvent("Uncached Write"); + return fault; } @@ -707,8 +714,7 @@ SimpleCPU::tick() xc->regs.pc); #ifdef FULL_SYSTEM - xc->regs.opcode = (inst >> 26) & 0x3f; - xc->regs.ra = (inst >> 21) & 0x1f; + xc->setInst(inst); #endif // FULL_SYSTEM xc->func_exe_inst++; diff --git a/cpu/simple_cpu/simple_cpu.hh b/cpu/simple_cpu/simple_cpu.hh index a9091da7e..1c6b18d03 100644 --- a/cpu/simple_cpu/simple_cpu.hh +++ b/cpu/simple_cpu/simple_cpu.hh @@ -35,6 +35,7 @@ #include "cpu/pc_event.hh" #include "base/statistics.hh" #include "cpu/exec_context.hh" +#include "cpu/static_inst.hh" // forward declarations #ifdef FULL_SYSTEM @@ -261,37 +262,71 @@ class SimpleCPU : public BaseCPU Fault copy(Addr dest); - uint64_t readIntReg(int reg_idx) { return xc->readIntReg(reg_idx); } + // The register accessor methods provide the index of the + // instruction's operand (e.g., 0 or 1), not the architectural + // register index, to simplify the implementation of register + // renaming. We find the architectural register index by indexing + // into the instruction's own operand index table. Note that a + // raw pointer to the StaticInst is provided instead of a + // ref-counted StaticInstPtr to redice overhead. This is fine as + // long as these methods don't copy the pointer into any long-term + // storage (which is pretty hard to imagine they would have reason + // to do). + + uint64_t readIntReg(StaticInst<TheISA> *si, int idx) + { + return xc->readIntReg(si->srcRegIdx(idx)); + } - float readFloatRegSingle(int reg_idx) - { return xc->readFloatRegSingle(reg_idx); } + float readFloatRegSingle(StaticInst<TheISA> *si, int idx) + { + int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; + return xc->readFloatRegSingle(reg_idx); + } - double readFloatRegDouble(int reg_idx) - { return xc->readFloatRegDouble(reg_idx); } + double readFloatRegDouble(StaticInst<TheISA> *si, int idx) + { + int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; + return xc->readFloatRegDouble(reg_idx); + } - uint64_t readFloatRegInt(int reg_idx) - { return xc->readFloatRegInt(reg_idx); } + uint64_t readFloatRegInt(StaticInst<TheISA> *si, int idx) + { + int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; + return xc->readFloatRegInt(reg_idx); + } - void setIntReg(int reg_idx, uint64_t val) - { return xc->setIntReg(reg_idx, val); } + void setIntReg(StaticInst<TheISA> *si, int idx, uint64_t val) + { + xc->setIntReg(si->destRegIdx(idx), val); + } - void setFloatRegSingle(int reg_idx, float val) - { return xc->setFloatRegSingle(reg_idx, val); } + void setFloatRegSingle(StaticInst<TheISA> *si, int idx, float val) + { + int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; + xc->setFloatRegSingle(reg_idx, val); + } - void setFloatRegDouble(int reg_idx, double val) - { return xc->setFloatRegDouble(reg_idx, val); } + void setFloatRegDouble(StaticInst<TheISA> *si, int idx, double val) + { + int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; + xc->setFloatRegDouble(reg_idx, val); + } - void setFloatRegInt(int reg_idx, uint64_t val) - { return xc->setFloatRegInt(reg_idx, val); } + void setFloatRegInt(StaticInst<TheISA> *si, int idx, uint64_t val) + { + int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; + xc->setFloatRegInt(reg_idx, val); + } uint64_t readPC() { return xc->readPC(); } - void setNextPC(uint64_t val) { return xc->setNextPC(val); } + void setNextPC(uint64_t val) { xc->setNextPC(val); } uint64_t readUniq() { return xc->readUniq(); } - void setUniq(uint64_t val) { return xc->setUniq(val); } + void setUniq(uint64_t val) { xc->setUniq(val); } uint64_t readFpcr() { return xc->readFpcr(); } - void setFpcr(uint64_t val) { return xc->setFpcr(val); } + void setFpcr(uint64_t val) { xc->setFpcr(val); } #ifdef FULL_SYSTEM uint64_t readIpr(int idx, Fault &fault) { return xc->readIpr(idx, fault); } @@ -300,7 +335,7 @@ class SimpleCPU : public BaseCPU int readIntrFlag() { return xc->readIntrFlag(); } void setIntrFlag(int val) { xc->setIntrFlag(val); } bool inPalMode() { return xc->inPalMode(); } - void ev5_trap(Fault fault) { return xc->ev5_trap(fault); } + void ev5_trap(Fault fault) { xc->ev5_trap(fault); } bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); } #else void syscall() { xc->syscall(); } diff --git a/cpu/static_inst.hh b/cpu/static_inst.hh index 1065fa3d4..3eeefb675 100644 --- a/cpu/static_inst.hh +++ b/cpu/static_inst.hh @@ -42,6 +42,7 @@ // forward declarations class ExecContext; class DynInst; +class FastCPU; class SimpleCPU; class SymbolTable; @@ -106,11 +107,13 @@ class StaticInstBase : public RefCounted IsThreadSync, ///< Thread synchronization operation. - IsSerializing, ///< Serializes pipeline: won't until all + IsSerializing, ///< Serializes pipeline: won't execute until all /// older instructions have committed. IsMemBarrier, ///< Is a memory barrier IsWriteBarrier, ///< Is a write barrier + IsNonSpeculative, ///< Should not be executed speculatively + NumFlags }; @@ -192,6 +195,7 @@ class StaticInstBase : public RefCounted bool isSerializing() const { return flags[IsSerializing]; } bool isMemBarrier() const { return flags[IsMemBarrier]; } bool isWriteBarrier() const { return flags[IsWriteBarrier]; } + bool isNonSpeculative() const { return flags[IsNonSpeculative]; } //@} /// Operation class. Used to select appropriate function unit in issue. @@ -310,6 +314,11 @@ class StaticInst : public StaticInstBase virtual Fault execute(SimpleCPU *xc, Trace::InstRecord *traceData) = 0; /** + * Execute this instruction under FastCPU model. + */ + virtual Fault execute(FastCPU *xc, Trace::InstRecord *traceData) = 0; + + /** * Execute this instruction under detailed FullCPU model. */ virtual Fault execute(DynInst *xc, Trace::InstRecord *traceData) = 0; |