X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcpu%2Fsimple_thread.hh;h=e862385c57833cefe29dc993dcf0d3709061b490;hb=43335495754abac71377bbd6df0c668b60b22822;hp=8a44eba3712d4eb0fd42904c1aab1afa5114f262;hpb=2871a13ab31aaabea93f1d55595e199ea76e9dcf;p=gem5.git diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index 8a44eba37..e862385c5 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -1,4 +1,17 @@ /* + * Copyright (c) 2011-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 + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2001-2006 The Regents of The University of Michigan * All rights reserved. * @@ -32,44 +45,38 @@ #ifndef __CPU_SIMPLE_THREAD_HH__ #define __CPU_SIMPLE_THREAD_HH__ +#include "arch/decoder.hh" #include "arch/isa.hh" #include "arch/isa_traits.hh" #include "arch/registers.hh" #include "arch/tlb.hh" #include "arch/types.hh" #include "base/types.hh" -#include "config/full_system.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" #include "cpu/thread_state.hh" +#include "debug/CCRegs.hh" +#include "debug/FloatRegs.hh" +#include "debug/IntRegs.hh" +#include "mem/page_table.hh" #include "mem/request.hh" #include "sim/byteswap.hh" #include "sim/eventq.hh" +#include "sim/process.hh" #include "sim/serialize.hh" +#include "sim/system.hh" class BaseCPU; - -#if FULL_SYSTEM - -#include "sim/system.hh" +class CheckerCPU; class FunctionProfile; class ProfileNode; -class FunctionalPort; -class PhysicalPort; namespace TheISA { namespace Kernel { class Statistics; - }; -}; - -#else // !FULL_SYSTEM - -#include "sim/process.hh" -#include "mem/page_table.hh" -class TranslatingPort; - -#endif // FULL_SYSTEM + } +} /** * The SimpleThread object provides a combination of the ThreadState @@ -94,6 +101,7 @@ class SimpleThread : public ThreadState typedef TheISA::MiscReg MiscReg; typedef TheISA::FloatReg FloatReg; typedef TheISA::FloatRegBits FloatRegBits; + typedef TheISA::CCReg CCReg; public: typedef ThreadContext::Status Status; @@ -103,33 +111,21 @@ class SimpleThread : public ThreadState FloatRegBits i[TheISA::NumFloatRegs]; } floatRegs; TheISA::IntReg intRegs[TheISA::NumIntRegs]; - TheISA::ISA isa; // one "instance" of the current ISA. - - /** The current microcode pc for the currently executing macro - * operation. - */ - MicroPC microPC; - - /** The next microcode pc for the currently executing macro - * operation. - */ - MicroPC nextMicroPC; +#ifdef ISA_HAS_CC_REGS + TheISA::CCReg ccRegs[TheISA::NumCCRegs]; +#endif + TheISA::ISA *const isa; // one "instance" of the current ISA. - /** The current pc. - */ - Addr PC; + TheISA::PCState _pcState; - /** The next pc. - */ - Addr nextPC; - - /** The next next pc. - */ - Addr nextNPC; + /** Did this instruction execute or is it predicated false */ + bool predicate; public: - // pointer to CPU associated with this SimpleThread - BaseCPU *cpu; + std::string name() const + { + return csprintf("%s.[tid:%i]", baseCpu->name(), tc->threadId()); + } ProxyThreadContext *tc; @@ -138,17 +134,17 @@ class SimpleThread : public ThreadState TheISA::TLB *itb; TheISA::TLB *dtb; + TheISA::Decoder decoder; + // constructor: initialize SimpleThread from given process structure -#if FULL_SYSTEM + // FS SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system, - TheISA::TLB *_itb, TheISA::TLB *_dtb, + TheISA::TLB *_itb, TheISA::TLB *_dtb, TheISA::ISA *_isa, bool use_kernel_stats = true); -#else - SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process, - TheISA::TLB *_itb, TheISA::TLB *_dtb); -#endif - - SimpleThread(); + // SE + SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system, + Process *_process, TheISA::TLB *_itb, TheISA::TLB *_dtb, + TheISA::ISA *_isa); virtual ~SimpleThread(); @@ -156,12 +152,11 @@ class SimpleThread : public ThreadState void regStats(const std::string &name); - void copyTC(ThreadContext *context); - void copyState(ThreadContext *oldContext); void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); + void startup(); /*************************************************************** * SimpleThread functions to provide CPU with access to various @@ -190,44 +185,34 @@ class SimpleThread : public ThreadState dtb->demapPage(vaddr, asn); } -#if FULL_SYSTEM void dumpFuncProfile(); Fault hwrei(); bool simPalCheck(int palFunc); -#endif - /******************************************* * ThreadContext interface functions. ******************************************/ - BaseCPU *getCpuPtr() { return cpu; } + BaseCPU *getCpuPtr() { return baseCpu; } TheISA::TLB *getITBPtr() { return itb; } TheISA::TLB *getDTBPtr() { return dtb; } - System *getSystemPtr() { return system; } + CheckerCPU *getCheckerCpuPtr() { return NULL; } -#if FULL_SYSTEM - FunctionalPort *getPhysPort() { return physPort; } + TheISA::Decoder *getDecoderPtr() { return &decoder; } - /** Return a virtual port. This port cannot be cached locally in an object. - * After a CPU switch it may point to the wrong memory object which could - * mean stale data. - */ - VirtualPort *getVirtPort() { return virtPort; } -#endif + System *getSystemPtr() { return system; } Status status() const { return _status; } void setStatus(Status newStatus) { _status = newStatus; } - /// Set the status to Active. Optional delay indicates number of - /// cycles to wait before beginning execution. - void activate(int delay = 1); + /// Set the status to Active. + void activate(); /// Set the status to Suspended. void suspend(); @@ -235,24 +220,17 @@ class SimpleThread : public ThreadState /// Set the status to Halted. void halt(); - virtual bool misspeculating(); - - Fault instRead(RequestPtr &req) - { - panic("instRead not implemented"); - // return funcPhysMem->read(req, inst); - return NoFault; - } - void copyArchRegs(ThreadContext *tc); void clearArchRegs() { - microPC = 0; - nextMicroPC = 1; - PC = nextPC = nextNPC = 0; + _pcState = 0; memset(intRegs, 0, sizeof(intRegs)); memset(floatRegs.i, 0, sizeof(floatRegs.i)); +#ifdef ISA_HAS_CC_REGS + memset(ccRegs, 0, sizeof(ccRegs)); +#endif + isa->clear(); } // @@ -260,139 +238,185 @@ class SimpleThread : public ThreadState // uint64_t readIntReg(int reg_idx) { - int flatIndex = isa.flattenIntIndex(reg_idx); + int flatIndex = isa->flattenIntIndex(reg_idx); assert(flatIndex < TheISA::NumIntRegs); - uint64_t regVal = intRegs[flatIndex]; - DPRINTF(IntRegs, "Reading int reg %d as %#x.\n", reg_idx, regVal); + uint64_t regVal(readIntRegFlat(flatIndex)); + DPRINTF(IntRegs, "Reading int reg %d (%d) as %#x.\n", + reg_idx, flatIndex, regVal); return regVal; } FloatReg readFloatReg(int reg_idx) { - int flatIndex = isa.flattenFloatIndex(reg_idx); + int flatIndex = isa->flattenFloatIndex(reg_idx); assert(flatIndex < TheISA::NumFloatRegs); - return floatRegs.f[flatIndex]; + FloatReg regVal(readFloatRegFlat(flatIndex)); + DPRINTF(FloatRegs, "Reading float reg %d (%d) as %f, %#x.\n", + reg_idx, flatIndex, regVal, floatRegs.i[flatIndex]); + return regVal; } FloatRegBits readFloatRegBits(int reg_idx) { - int flatIndex = isa.flattenFloatIndex(reg_idx); + int flatIndex = isa->flattenFloatIndex(reg_idx); assert(flatIndex < TheISA::NumFloatRegs); - return floatRegs.i[flatIndex]; + FloatRegBits regVal(readFloatRegBitsFlat(flatIndex)); + DPRINTF(FloatRegs, "Reading float reg %d (%d) bits as %#x, %f.\n", + reg_idx, flatIndex, regVal, floatRegs.f[flatIndex]); + return regVal; + } + + CCReg readCCReg(int reg_idx) + { +#ifdef ISA_HAS_CC_REGS + int flatIndex = isa->flattenCCIndex(reg_idx); + assert(0 <= flatIndex); + assert(flatIndex < TheISA::NumCCRegs); + uint64_t regVal(readCCRegFlat(flatIndex)); + DPRINTF(CCRegs, "Reading CC reg %d (%d) as %#x.\n", + reg_idx, flatIndex, regVal); + return regVal; +#else + panic("Tried to read a CC register."); + return 0; +#endif } void setIntReg(int reg_idx, uint64_t val) { - int flatIndex = isa.flattenIntIndex(reg_idx); + int flatIndex = isa->flattenIntIndex(reg_idx); assert(flatIndex < TheISA::NumIntRegs); - DPRINTF(IntRegs, "Setting int reg %d to %#x.\n", reg_idx, val); - intRegs[flatIndex] = val; + DPRINTF(IntRegs, "Setting int reg %d (%d) to %#x.\n", + reg_idx, flatIndex, val); + setIntRegFlat(flatIndex, val); } void setFloatReg(int reg_idx, FloatReg val) { - int flatIndex = isa.flattenFloatIndex(reg_idx); + int flatIndex = isa->flattenFloatIndex(reg_idx); assert(flatIndex < TheISA::NumFloatRegs); - floatRegs.f[flatIndex] = val; + setFloatRegFlat(flatIndex, val); + DPRINTF(FloatRegs, "Setting float reg %d (%d) to %f, %#x.\n", + reg_idx, flatIndex, val, floatRegs.i[flatIndex]); } void setFloatRegBits(int reg_idx, FloatRegBits val) { - int flatIndex = isa.flattenFloatIndex(reg_idx); + int flatIndex = isa->flattenFloatIndex(reg_idx); assert(flatIndex < TheISA::NumFloatRegs); - floatRegs.i[flatIndex] = val; - } - - uint64_t readPC() - { - return PC; + // XXX: Fix array out of bounds compiler error for gem5.fast + // when checkercpu enabled + if (flatIndex < TheISA::NumFloatRegs) + setFloatRegBitsFlat(flatIndex, val); + DPRINTF(FloatRegs, "Setting float reg %d (%d) bits to %#x, %#f.\n", + reg_idx, flatIndex, val, floatRegs.f[flatIndex]); } - void setPC(uint64_t val) + void setCCReg(int reg_idx, CCReg val) { - PC = val; +#ifdef ISA_HAS_CC_REGS + int flatIndex = isa->flattenCCIndex(reg_idx); + assert(flatIndex < TheISA::NumCCRegs); + DPRINTF(CCRegs, "Setting CC reg %d (%d) to %#x.\n", + reg_idx, flatIndex, val); + setCCRegFlat(flatIndex, val); +#else + panic("Tried to set a CC register."); +#endif } - uint64_t readMicroPC() + TheISA::PCState + pcState() { - return microPC; + return _pcState; } - void setMicroPC(uint64_t val) + void + pcState(const TheISA::PCState &val) { - microPC = val; + _pcState = val; } - uint64_t readNextPC() + void + pcStateNoRecord(const TheISA::PCState &val) { - return nextPC; + _pcState = val; } - void setNextPC(uint64_t val) + Addr + instAddr() { - nextPC = val; + return _pcState.instAddr(); } - uint64_t readNextMicroPC() + Addr + nextInstAddr() { - return nextMicroPC; + return _pcState.nextInstAddr(); } - void setNextMicroPC(uint64_t val) + MicroPC + microPC() { - nextMicroPC = val; + return _pcState.microPC(); } - uint64_t readNextNPC() + bool readPredicate() { -#if ISA_HAS_DELAY_SLOT - return nextNPC; -#else - return nextPC + sizeof(TheISA::MachInst); -#endif + return predicate; } - void setNextNPC(uint64_t val) + void setPredicate(bool val) { -#if ISA_HAS_DELAY_SLOT - nextNPC = val; -#endif + predicate = val; } MiscReg - readMiscRegNoEffect(int misc_reg, ThreadID tid = 0) + readMiscRegNoEffect(int misc_reg, ThreadID tid = 0) const { - return isa.readMiscRegNoEffect(misc_reg); + return isa->readMiscRegNoEffect(misc_reg); } MiscReg readMiscReg(int misc_reg, ThreadID tid = 0) { - return isa.readMiscReg(misc_reg, tc); + return isa->readMiscReg(misc_reg, tc); } void setMiscRegNoEffect(int misc_reg, const MiscReg &val, ThreadID tid = 0) { - return isa.setMiscRegNoEffect(misc_reg, val); + return isa->setMiscRegNoEffect(misc_reg, val); } void setMiscReg(int misc_reg, const MiscReg &val, ThreadID tid = 0) { - return isa.setMiscReg(misc_reg, val, tc); + return isa->setMiscReg(misc_reg, val, tc); } int flattenIntIndex(int reg) { - return isa.flattenIntIndex(reg); + return isa->flattenIntIndex(reg); } int flattenFloatIndex(int reg) { - return isa.flattenFloatIndex(reg); + return isa->flattenFloatIndex(reg); + } + + int + flattenCCIndex(int reg) + { + return isa->flattenCCIndex(reg); + } + + int + flattenMiscIndex(int reg) + { + return isa->flattenMiscIndex(reg); } unsigned readStCondFailures() { return storeCondFailures; } @@ -400,20 +424,33 @@ class SimpleThread : public ThreadState void setStCondFailures(unsigned sc_failures) { storeCondFailures = sc_failures; } -#if !FULL_SYSTEM void syscall(int64_t callnum) { process->syscall(callnum, tc); } + + uint64_t readIntRegFlat(int idx) { return intRegs[idx]; } + void setIntRegFlat(int idx, uint64_t val) { intRegs[idx] = val; } + + FloatReg readFloatRegFlat(int idx) { return floatRegs.f[idx]; } + void setFloatRegFlat(int idx, FloatReg val) { floatRegs.f[idx] = val; } + + FloatRegBits readFloatRegBitsFlat(int idx) { return floatRegs.i[idx]; } + void setFloatRegBitsFlat(int idx, FloatRegBits val) { + floatRegs.i[idx] = val; + } + +#ifdef ISA_HAS_CC_REGS + CCReg readCCRegFlat(int idx) { return ccRegs[idx]; } + void setCCRegFlat(int idx, CCReg val) { ccRegs[idx] = val; } +#else + CCReg readCCRegFlat(int idx) + { panic("readCCRegFlat w/no CC regs!\n"); } + + void setCCRegFlat(int idx, CCReg val) + { panic("setCCRegFlat w/no CC regs!\n"); } #endif }; -// for non-speculative execution context, spec_mode is always false -inline bool -SimpleThread::misspeculating() -{ - return false; -} - #endif // __CPU_CPU_EXEC_CONTEXT_HH__