O3: Generaize the O3 dynamic instruction class so it isn't split out by ISA.
--HG-- rename : src/cpu/o3/dyn_inst.hh => src/cpu/o3/dyn_inst_decl.hh rename : src/cpu/o3/alpha/dyn_inst_impl.hh => src/cpu/o3/dyn_inst_impl.hh
This commit is contained in:
parent
e09c403d32
commit
f57c286d2c
17 changed files with 361 additions and 1182 deletions
|
@ -49,11 +49,10 @@ template <class XC>
|
|||
inline void
|
||||
handleLockedRead(XC *xc, Request *req)
|
||||
{
|
||||
unsigned tid = req->getThreadNum();
|
||||
xc->setMiscRegNoEffect(LLAddr, req->getPaddr() & ~0xf, tid);
|
||||
xc->setMiscRegNoEffect(LLFlag, true, tid);
|
||||
xc->setMiscRegNoEffect(LLAddr, req->getPaddr() & ~0xf);
|
||||
xc->setMiscRegNoEffect(LLFlag, true);
|
||||
DPRINTF(LLSC, "[tid:%i]: Load-Link Flag Set & Load-Link Address set to %x.\n",
|
||||
tid, req->getPaddr() & ~0xf);
|
||||
req->getThreadNum(), req->getPaddr() & ~0xf);
|
||||
}
|
||||
|
||||
|
||||
|
@ -61,22 +60,20 @@ template <class XC>
|
|||
inline bool
|
||||
handleLockedWrite(XC *xc, Request *req)
|
||||
{
|
||||
unsigned tid = req->getThreadNum();
|
||||
|
||||
if (req->isUncacheable()) {
|
||||
// Funky Turbolaser mailbox access...don't update
|
||||
// result register (see stq_c in decoder.isa)
|
||||
req->setExtraData(2);
|
||||
} else {
|
||||
// standard store conditional
|
||||
bool lock_flag = xc->readMiscRegNoEffect(LLFlag, tid);
|
||||
Addr lock_addr = xc->readMiscRegNoEffect(LLAddr, tid);
|
||||
bool lock_flag = xc->readMiscRegNoEffect(LLFlag);
|
||||
Addr lock_addr = xc->readMiscRegNoEffect(LLAddr);
|
||||
|
||||
if (!lock_flag || (req->getPaddr() & ~0xf) != lock_addr) {
|
||||
// Lock flag not set or addr mismatch in CPU;
|
||||
// don't even bother sending to memory system
|
||||
req->setExtraData(0);
|
||||
xc->setMiscRegNoEffect(LLFlag, false, tid);
|
||||
xc->setMiscRegNoEffect(LLFlag, false);
|
||||
|
||||
// the rest of this code is not architectural;
|
||||
// it's just a debugging aid to help detect
|
||||
|
@ -97,10 +94,10 @@ handleLockedWrite(XC *xc, Request *req)
|
|||
|
||||
if (!lock_flag){
|
||||
DPRINTF(LLSC, "[tid:%i]: Lock Flag Set, Store Conditional Failed.\n",
|
||||
tid);
|
||||
req->getThreadNum());
|
||||
} else if ((req->getPaddr() & ~0xf) != lock_addr) {
|
||||
DPRINTF(LLSC, "[tid:%i]: Load-Link Address Mismatch, Store Conditional Failed.\n",
|
||||
tid);
|
||||
req->getThreadNum());
|
||||
}
|
||||
// store conditional failed already, so don't issue it to mem
|
||||
return false;
|
||||
|
|
|
@ -28,9 +28,9 @@
|
|||
* Authors: Kevin Lim
|
||||
*/
|
||||
|
||||
#include "cpu/o3/alpha/dyn_inst_impl.hh"
|
||||
#include "cpu/o3/alpha/impl.hh"
|
||||
#include "cpu/o3/dyn_inst_impl.hh"
|
||||
|
||||
// Force instantiation of AlphaDynInst for all the implementations that
|
||||
// are needed.
|
||||
template class AlphaDynInst<AlphaSimpleImpl>;
|
||||
template class BaseO3DynInst<AlphaSimpleImpl>;
|
||||
|
|
|
@ -1,277 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2006 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Kevin Lim
|
||||
*/
|
||||
|
||||
#ifndef __CPU_O3_ALPHA_DYN_INST_HH__
|
||||
#define __CPU_O3_ALPHA_DYN_INST_HH__
|
||||
|
||||
#include "arch/isa_traits.hh"
|
||||
#include "cpu/base_dyn_inst.hh"
|
||||
#include "cpu/inst_seq.hh"
|
||||
#include "cpu/o3/alpha/impl.hh"
|
||||
#include "cpu/o3/cpu.hh"
|
||||
|
||||
class Packet;
|
||||
|
||||
/**
|
||||
* Mostly implementation & ISA specific AlphaDynInst. As with most
|
||||
* other classes in the new CPU model, it is templated on the Impl to
|
||||
* allow for passing in of all types, such as the CPU type and the ISA
|
||||
* type. The AlphaDynInst serves as the primary interface to the CPU
|
||||
* for instructions that are executing.
|
||||
*/
|
||||
template <class Impl>
|
||||
class AlphaDynInst : public BaseDynInst<Impl>
|
||||
{
|
||||
public:
|
||||
/** Typedef for the CPU. */
|
||||
typedef typename Impl::O3CPU O3CPU;
|
||||
|
||||
/** Binary machine instruction type. */
|
||||
typedef TheISA::MachInst MachInst;
|
||||
/** Extended machine instruction type. */
|
||||
typedef TheISA::ExtMachInst ExtMachInst;
|
||||
/** Logical register index type. */
|
||||
typedef TheISA::RegIndex RegIndex;
|
||||
/** Integer register index type. */
|
||||
typedef TheISA::IntReg IntReg;
|
||||
typedef TheISA::FloatReg FloatReg;
|
||||
typedef TheISA::FloatRegBits FloatRegBits;
|
||||
/** Misc register index type. */
|
||||
typedef TheISA::MiscReg MiscReg;
|
||||
|
||||
enum {
|
||||
MaxInstSrcRegs = TheISA::MaxInstSrcRegs, //< Max source regs
|
||||
MaxInstDestRegs = TheISA::MaxInstDestRegs, //< Max dest regs
|
||||
};
|
||||
|
||||
public:
|
||||
/** BaseDynInst constructor given a binary instruction. */
|
||||
AlphaDynInst(StaticInstPtr staticInst, Addr PC, Addr NPC, Addr microPC,
|
||||
Addr Pred_PC, Addr Pred_NPC, Addr Pred_MicroPC,
|
||||
InstSeqNum seq_num, O3CPU *cpu);
|
||||
|
||||
/** BaseDynInst constructor given a binary instruction. */
|
||||
AlphaDynInst(ExtMachInst inst, Addr PC, Addr NPC, Addr microPC,
|
||||
Addr Pred_PC, Addr Pred_NPC, Addr Pred_MicroPC,
|
||||
InstSeqNum seq_num, O3CPU *cpu);
|
||||
|
||||
/** BaseDynInst constructor given a static inst pointer. */
|
||||
AlphaDynInst(StaticInstPtr &_staticInst);
|
||||
|
||||
/** Executes the instruction.*/
|
||||
Fault execute();
|
||||
|
||||
/** Initiates the access. Only valid for memory operations. */
|
||||
Fault initiateAcc();
|
||||
|
||||
/** Completes the access. Only valid for memory operations. */
|
||||
Fault completeAcc(PacketPtr pkt);
|
||||
|
||||
private:
|
||||
/** Initializes variables. */
|
||||
void initVars();
|
||||
|
||||
public:
|
||||
/** Reads a miscellaneous register. */
|
||||
MiscReg readMiscRegNoEffect(int misc_reg)
|
||||
{
|
||||
return this->cpu->readMiscRegNoEffect(misc_reg, this->threadNumber);
|
||||
}
|
||||
|
||||
/** Reads a misc. register, including any side-effects the read
|
||||
* might have as defined by the architecture.
|
||||
*/
|
||||
MiscReg readMiscReg(int misc_reg)
|
||||
{
|
||||
return this->cpu->readMiscReg(misc_reg, this->threadNumber);
|
||||
}
|
||||
|
||||
/** Sets a misc. register. */
|
||||
void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
this->instResult.integer = val;
|
||||
return this->cpu->setMiscRegNoEffect(misc_reg, val, this->threadNumber);
|
||||
}
|
||||
|
||||
/** Sets a misc. register, including any side-effects the write
|
||||
* might have as defined by the architecture.
|
||||
*/
|
||||
void setMiscReg(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
return this->cpu->setMiscReg(misc_reg, val,
|
||||
this->threadNumber);
|
||||
}
|
||||
|
||||
/** Reads a miscellaneous register. */
|
||||
TheISA::MiscReg readMiscRegOperandNoEffect(const StaticInst *si, int idx)
|
||||
{
|
||||
return this->cpu->readMiscRegNoEffect(
|
||||
si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
|
||||
this->threadNumber);
|
||||
}
|
||||
|
||||
/** Reads a misc. register, including any side-effects the read
|
||||
* might have as defined by the architecture.
|
||||
*/
|
||||
TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx)
|
||||
{
|
||||
return this->cpu->readMiscReg(
|
||||
si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
|
||||
this->threadNumber);
|
||||
}
|
||||
|
||||
/** Sets a misc. register. */
|
||||
void setMiscRegOperandNoEffect(const StaticInst * si, int idx, const MiscReg &val)
|
||||
{
|
||||
this->instResult.integer = val;
|
||||
return this->cpu->setMiscRegNoEffect(
|
||||
si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
|
||||
val, this->threadNumber);
|
||||
}
|
||||
|
||||
/** Sets a misc. register, including any side-effects the write
|
||||
* might have as defined by the architecture.
|
||||
*/
|
||||
void setMiscRegOperand(const StaticInst *si, int idx,
|
||||
const MiscReg &val)
|
||||
{
|
||||
return this->cpu->setMiscReg(
|
||||
si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
|
||||
val, this->threadNumber);
|
||||
}
|
||||
|
||||
#if FULL_SYSTEM
|
||||
/** Calls hardware return from error interrupt. */
|
||||
Fault hwrei();
|
||||
/** Traps to handle specified fault. */
|
||||
void trap(Fault fault);
|
||||
bool simPalCheck(int palFunc);
|
||||
#else
|
||||
/** Calls a syscall. */
|
||||
void syscall(int64_t callnum);
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
// 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 readIntRegOperand(const StaticInst *si, int idx)
|
||||
{
|
||||
return this->cpu->readIntReg(this->_srcRegIdx[idx]);
|
||||
}
|
||||
|
||||
FloatReg readFloatRegOperand(const StaticInst *si, int idx, int width)
|
||||
{
|
||||
return this->cpu->readFloatReg(this->_srcRegIdx[idx], width);
|
||||
}
|
||||
|
||||
FloatReg readFloatRegOperand(const StaticInst *si, int idx)
|
||||
{
|
||||
return this->cpu->readFloatReg(this->_srcRegIdx[idx]);
|
||||
}
|
||||
|
||||
FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx,
|
||||
int width)
|
||||
{
|
||||
return this->cpu->readFloatRegBits(this->_srcRegIdx[idx], width);
|
||||
}
|
||||
|
||||
FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx)
|
||||
{
|
||||
return this->cpu->readFloatRegBits(this->_srcRegIdx[idx]);
|
||||
}
|
||||
|
||||
/** @todo: Make results into arrays so they can handle multiple dest
|
||||
* registers.
|
||||
*/
|
||||
void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
|
||||
{
|
||||
this->cpu->setIntReg(this->_destRegIdx[idx], val);
|
||||
BaseDynInst<Impl>::setIntRegOperand(si, idx, val);
|
||||
}
|
||||
|
||||
void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val,
|
||||
int width)
|
||||
{
|
||||
this->cpu->setFloatReg(this->_destRegIdx[idx], val, width);
|
||||
BaseDynInst<Impl>::setFloatRegOperand(si, idx, val, width);
|
||||
}
|
||||
|
||||
void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
|
||||
{
|
||||
this->cpu->setFloatReg(this->_destRegIdx[idx], val);
|
||||
BaseDynInst<Impl>::setFloatRegOperand(si, idx, val);
|
||||
}
|
||||
|
||||
void setFloatRegOperandBits(const StaticInst *si, int idx,
|
||||
FloatRegBits val, int width)
|
||||
{
|
||||
this->cpu->setFloatRegBits(this->_destRegIdx[idx], val, width);
|
||||
BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val);
|
||||
}
|
||||
|
||||
void setFloatRegOperandBits(const StaticInst *si, int idx,
|
||||
FloatRegBits val)
|
||||
{
|
||||
this->cpu->setFloatRegBits(this->_destRegIdx[idx], val);
|
||||
BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val);
|
||||
}
|
||||
|
||||
public:
|
||||
/** Calculates EA part of a memory instruction. Currently unused,
|
||||
* though it may be useful in the future if we want to split
|
||||
* memory operations into EA calculation and memory access parts.
|
||||
*/
|
||||
Fault calcEA()
|
||||
{
|
||||
return this->staticInst->eaCompInst()->execute(this, this->traceData);
|
||||
}
|
||||
|
||||
/** Does the memory access part of a memory instruction. Currently unused,
|
||||
* though it may be useful in the future if we want to split
|
||||
* memory operations into EA calculation and memory access parts.
|
||||
*/
|
||||
Fault memAccess()
|
||||
{
|
||||
return this->staticInst->memAccInst()->execute(this, this->traceData);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __CPU_O3_ALPHA_DYN_INST_HH__
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
// Forward declarations.
|
||||
template <class Impl>
|
||||
class AlphaDynInst;
|
||||
class BaseO3DynInst;
|
||||
|
||||
template <class Impl>
|
||||
class FullO3CPU;
|
||||
|
@ -60,7 +60,7 @@ struct AlphaSimpleImpl
|
|||
typedef SimpleCPUPolicy<AlphaSimpleImpl> CPUPol;
|
||||
|
||||
/** The DynInst type to be used. */
|
||||
typedef AlphaDynInst<AlphaSimpleImpl> DynInst;
|
||||
typedef BaseO3DynInst<AlphaSimpleImpl> DynInst;
|
||||
|
||||
/** The refcounted DynInst pointer to be used. In most cases this is
|
||||
* what should be used, and not DynInst *.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2006 The Regents of The University of Michigan
|
||||
* Copyright (c) 2004-2006 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -25,36 +25,266 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Korey Sewell
|
||||
* Authors: Kevin Lim
|
||||
*/
|
||||
|
||||
#ifndef __CPU_O3_DYN_INST_HH__
|
||||
#define __CPU_O3_DYN_INST_HH__
|
||||
|
||||
#include "arch/isa_specific.hh"
|
||||
#include "arch/isa_traits.hh"
|
||||
#include "cpu/base_dyn_inst.hh"
|
||||
#include "cpu/inst_seq.hh"
|
||||
#include "cpu/o3/cpu.hh"
|
||||
#include "cpu/o3/isa_specific.hh"
|
||||
|
||||
#if THE_ISA == ALPHA_ISA
|
||||
template <class Impl> class AlphaDynInst;
|
||||
struct AlphaSimpleImpl;
|
||||
typedef AlphaDynInst<AlphaSimpleImpl> O3DynInst;
|
||||
#elif THE_ISA == MIPS_ISA
|
||||
template <class Impl> class MipsDynInst;
|
||||
struct MipsSimpleImpl;
|
||||
typedef MipsDynInst<MipsSimpleImpl> O3DynInst;
|
||||
#elif THE_ISA == SPARC_ISA
|
||||
template <class Impl> class SparcDynInst;
|
||||
struct SparcSimpleImpl;
|
||||
typedef SparcDynInst<SparcSimpleImpl> O3DynInst;
|
||||
#elif THE_ISA == X86_ISA
|
||||
template <class Impl> class X86DynInst;
|
||||
struct X86SimpleImpl;
|
||||
typedef X86DynInst<X86SimpleImpl> O3DynInst;
|
||||
#elif THE_ISA == ARM_ISA
|
||||
template <class Impl> class ArmDynInst;
|
||||
struct ArmSimpleImpl;
|
||||
typedef ArmDynInst<ArmSimpleImpl> O3DynInst;
|
||||
class Packet;
|
||||
|
||||
/**
|
||||
* Mostly implementation & ISA specific AlphaDynInst. As with most
|
||||
* other classes in the new CPU model, it is templated on the Impl to
|
||||
* allow for passing in of all types, such as the CPU type and the ISA
|
||||
* type. The AlphaDynInst serves as the primary interface to the CPU
|
||||
* for instructions that are executing.
|
||||
*/
|
||||
template <class Impl>
|
||||
class BaseO3DynInst : public BaseDynInst<Impl>
|
||||
{
|
||||
public:
|
||||
/** Typedef for the CPU. */
|
||||
typedef typename Impl::O3CPU O3CPU;
|
||||
|
||||
/** Binary machine instruction type. */
|
||||
typedef TheISA::MachInst MachInst;
|
||||
/** Extended machine instruction type. */
|
||||
typedef TheISA::ExtMachInst ExtMachInst;
|
||||
/** Logical register index type. */
|
||||
typedef TheISA::RegIndex RegIndex;
|
||||
/** Integer register index type. */
|
||||
typedef TheISA::IntReg IntReg;
|
||||
typedef TheISA::FloatReg FloatReg;
|
||||
typedef TheISA::FloatRegBits FloatRegBits;
|
||||
/** Misc register index type. */
|
||||
typedef TheISA::MiscReg MiscReg;
|
||||
|
||||
enum {
|
||||
MaxInstSrcRegs = TheISA::MaxInstSrcRegs, //< Max source regs
|
||||
MaxInstDestRegs = TheISA::MaxInstDestRegs, //< Max dest regs
|
||||
};
|
||||
|
||||
public:
|
||||
/** BaseDynInst constructor given a binary instruction. */
|
||||
BaseO3DynInst(StaticInstPtr staticInst, Addr PC, Addr NPC, Addr microPC,
|
||||
Addr Pred_PC, Addr Pred_NPC, Addr Pred_MicroPC,
|
||||
InstSeqNum seq_num, O3CPU *cpu);
|
||||
|
||||
/** BaseDynInst constructor given a binary instruction. */
|
||||
BaseO3DynInst(ExtMachInst inst, Addr PC, Addr NPC, Addr microPC,
|
||||
Addr Pred_PC, Addr Pred_NPC, Addr Pred_MicroPC,
|
||||
InstSeqNum seq_num, O3CPU *cpu);
|
||||
|
||||
/** BaseDynInst constructor given a static inst pointer. */
|
||||
BaseO3DynInst(StaticInstPtr &_staticInst);
|
||||
|
||||
/** Executes the instruction.*/
|
||||
Fault execute();
|
||||
|
||||
/** Initiates the access. Only valid for memory operations. */
|
||||
Fault initiateAcc();
|
||||
|
||||
/** Completes the access. Only valid for memory operations. */
|
||||
Fault completeAcc(PacketPtr pkt);
|
||||
|
||||
private:
|
||||
/** Initializes variables. */
|
||||
void initVars();
|
||||
|
||||
public:
|
||||
/** Reads a miscellaneous register. */
|
||||
MiscReg readMiscRegNoEffect(int misc_reg)
|
||||
{
|
||||
return this->cpu->readMiscRegNoEffect(misc_reg, this->threadNumber);
|
||||
}
|
||||
|
||||
/** Reads a misc. register, including any side-effects the read
|
||||
* might have as defined by the architecture.
|
||||
*/
|
||||
MiscReg readMiscReg(int misc_reg)
|
||||
{
|
||||
return this->cpu->readMiscReg(misc_reg, this->threadNumber);
|
||||
}
|
||||
|
||||
/** Sets a misc. register. */
|
||||
void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
this->instResult.integer = val;
|
||||
return this->cpu->setMiscRegNoEffect(misc_reg, val, this->threadNumber);
|
||||
}
|
||||
|
||||
/** Sets a misc. register, including any side-effects the write
|
||||
* might have as defined by the architecture.
|
||||
*/
|
||||
void setMiscReg(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
return this->cpu->setMiscReg(misc_reg, val,
|
||||
this->threadNumber);
|
||||
}
|
||||
|
||||
/** Reads a miscellaneous register. */
|
||||
TheISA::MiscReg readMiscRegOperandNoEffect(const StaticInst *si, int idx)
|
||||
{
|
||||
return this->cpu->readMiscRegNoEffect(
|
||||
si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
|
||||
this->threadNumber);
|
||||
}
|
||||
|
||||
/** Reads a misc. register, including any side-effects the read
|
||||
* might have as defined by the architecture.
|
||||
*/
|
||||
TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx)
|
||||
{
|
||||
return this->cpu->readMiscReg(
|
||||
si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
|
||||
this->threadNumber);
|
||||
}
|
||||
|
||||
/** Sets a misc. register. */
|
||||
void setMiscRegOperandNoEffect(const StaticInst * si, int idx, const MiscReg &val)
|
||||
{
|
||||
this->instResult.integer = val;
|
||||
return this->cpu->setMiscRegNoEffect(
|
||||
si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
|
||||
val, this->threadNumber);
|
||||
}
|
||||
|
||||
/** Sets a misc. register, including any side-effects the write
|
||||
* might have as defined by the architecture.
|
||||
*/
|
||||
void setMiscRegOperand(const StaticInst *si, int idx,
|
||||
const MiscReg &val)
|
||||
{
|
||||
return this->cpu->setMiscReg(
|
||||
si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
|
||||
val, this->threadNumber);
|
||||
}
|
||||
|
||||
#if FULL_SYSTEM
|
||||
/** Calls hardware return from error interrupt. */
|
||||
Fault hwrei();
|
||||
/** Traps to handle specified fault. */
|
||||
void trap(Fault fault);
|
||||
bool simPalCheck(int palFunc);
|
||||
#else
|
||||
#error "O3DynInst not defined for this ISA"
|
||||
/** Calls a syscall. */
|
||||
void syscall(int64_t callnum);
|
||||
#endif
|
||||
|
||||
#endif // __CPU_O3_DYN_INST_HH__
|
||||
public:
|
||||
|
||||
// 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 readIntRegOperand(const StaticInst *si, int idx)
|
||||
{
|
||||
return this->cpu->readIntReg(this->_srcRegIdx[idx]);
|
||||
}
|
||||
|
||||
FloatReg readFloatRegOperand(const StaticInst *si, int idx, int width)
|
||||
{
|
||||
return this->cpu->readFloatReg(this->_srcRegIdx[idx], width);
|
||||
}
|
||||
|
||||
FloatReg readFloatRegOperand(const StaticInst *si, int idx)
|
||||
{
|
||||
return this->cpu->readFloatReg(this->_srcRegIdx[idx]);
|
||||
}
|
||||
|
||||
FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx,
|
||||
int width)
|
||||
{
|
||||
return this->cpu->readFloatRegBits(this->_srcRegIdx[idx], width);
|
||||
}
|
||||
|
||||
FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx)
|
||||
{
|
||||
return this->cpu->readFloatRegBits(this->_srcRegIdx[idx]);
|
||||
}
|
||||
|
||||
/** @todo: Make results into arrays so they can handle multiple dest
|
||||
* registers.
|
||||
*/
|
||||
void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
|
||||
{
|
||||
this->cpu->setIntReg(this->_destRegIdx[idx], val);
|
||||
BaseDynInst<Impl>::setIntRegOperand(si, idx, val);
|
||||
}
|
||||
|
||||
void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val,
|
||||
int width)
|
||||
{
|
||||
this->cpu->setFloatReg(this->_destRegIdx[idx], val, width);
|
||||
BaseDynInst<Impl>::setFloatRegOperand(si, idx, val, width);
|
||||
}
|
||||
|
||||
void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
|
||||
{
|
||||
this->cpu->setFloatReg(this->_destRegIdx[idx], val);
|
||||
BaseDynInst<Impl>::setFloatRegOperand(si, idx, val);
|
||||
}
|
||||
|
||||
void setFloatRegOperandBits(const StaticInst *si, int idx,
|
||||
FloatRegBits val, int width)
|
||||
{
|
||||
this->cpu->setFloatRegBits(this->_destRegIdx[idx], val, width);
|
||||
BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val);
|
||||
}
|
||||
|
||||
void setFloatRegOperandBits(const StaticInst *si, int idx,
|
||||
FloatRegBits val)
|
||||
{
|
||||
this->cpu->setFloatRegBits(this->_destRegIdx[idx], val);
|
||||
BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val);
|
||||
}
|
||||
|
||||
#if THE_ISA == MIPS_ISA
|
||||
uint64_t readRegOtherThread(int misc_reg)
|
||||
{
|
||||
panic("MIPS MT not defined for O3 CPU.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void setRegOtherThread(int misc_reg, const TheISA::MiscReg &val)
|
||||
{
|
||||
panic("MIPS MT not defined for O3 CPU.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
public:
|
||||
/** Calculates EA part of a memory instruction. Currently unused,
|
||||
* though it may be useful in the future if we want to split
|
||||
* memory operations into EA calculation and memory access parts.
|
||||
*/
|
||||
Fault calcEA()
|
||||
{
|
||||
return this->staticInst->eaCompInst()->execute(this, this->traceData);
|
||||
}
|
||||
|
||||
/** Does the memory access part of a memory instruction. Currently unused,
|
||||
* though it may be useful in the future if we want to split
|
||||
* memory operations into EA calculation and memory access parts.
|
||||
*/
|
||||
Fault memAccess()
|
||||
{
|
||||
return this->staticInst->memAccInst()->execute(this, this->traceData);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __CPU_O3_ALPHA_DYN_INST_HH__
|
||||
|
||||
|
|
56
src/cpu/o3/dyn_inst_decl.hh
Normal file
56
src/cpu/o3/dyn_inst_decl.hh
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2006 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Korey Sewell
|
||||
*/
|
||||
|
||||
#ifndef __CPU_O3_DYN_INST_DECL_HH__
|
||||
#define __CPU_O3_DYN_INST_DECL_HH__
|
||||
|
||||
#include "arch/isa_specific.hh"
|
||||
|
||||
template <class Impl> class BaseO3DynInst;
|
||||
#if THE_ISA == ALPHA_ISA
|
||||
struct AlphaSimpleImpl;
|
||||
typedef BaseO3DynInst<AlphaSimpleImpl> O3DynInst;
|
||||
#elif THE_ISA == MIPS_ISA
|
||||
struct MipsSimpleImpl;
|
||||
typedef BaseO3DynInst<MipsSimpleImpl> O3DynInst;
|
||||
#elif THE_ISA == SPARC_ISA
|
||||
struct SparcSimpleImpl;
|
||||
typedef BaseO3DynInst<SparcSimpleImpl> O3DynInst;
|
||||
#elif THE_ISA == X86_ISA
|
||||
struct X86SimpleImpl;
|
||||
typedef BaseO3DynInst<X86SimpleImpl> O3DynInst;
|
||||
#elif THE_ISA == ARM_ISA
|
||||
struct ArmSimpleImpl;
|
||||
typedef BaseO3DynInst<ArmSimpleImpl> O3DynInst;
|
||||
#else
|
||||
#error "O3DynInst not defined for this ISA"
|
||||
#endif
|
||||
|
||||
#endif // __CPU_O3_DYN_INST_DECL_HH__
|
|
@ -28,34 +28,34 @@
|
|||
* Authors: Kevin Lim
|
||||
*/
|
||||
|
||||
#include "cpu/o3/alpha/dyn_inst.hh"
|
||||
#include "cpu/o3/dyn_inst.hh"
|
||||
|
||||
template <class Impl>
|
||||
AlphaDynInst<Impl>::AlphaDynInst(StaticInstPtr staticInst,
|
||||
Addr PC, Addr NPC, Addr microPC,
|
||||
Addr Pred_PC, Addr Pred_NPC,
|
||||
Addr Pred_MicroPC,
|
||||
InstSeqNum seq_num, O3CPU *cpu)
|
||||
BaseO3DynInst<Impl>::BaseO3DynInst(StaticInstPtr staticInst,
|
||||
Addr PC, Addr NPC, Addr microPC,
|
||||
Addr Pred_PC, Addr Pred_NPC,
|
||||
Addr Pred_MicroPC,
|
||||
InstSeqNum seq_num, O3CPU *cpu)
|
||||
: BaseDynInst<Impl>(staticInst, PC, NPC, microPC,
|
||||
Pred_PC, Pred_NPC, Pred_MicroPC, seq_num, cpu)
|
||||
Pred_PC, Pred_NPC, Pred_MicroPC, seq_num, cpu)
|
||||
{
|
||||
initVars();
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
AlphaDynInst<Impl>::AlphaDynInst(ExtMachInst inst,
|
||||
Addr PC, Addr NPC, Addr microPC,
|
||||
Addr Pred_PC, Addr Pred_NPC,
|
||||
Addr Pred_MicroPC,
|
||||
InstSeqNum seq_num, O3CPU *cpu)
|
||||
BaseO3DynInst<Impl>::BaseO3DynInst(ExtMachInst inst,
|
||||
Addr PC, Addr NPC, Addr microPC,
|
||||
Addr Pred_PC, Addr Pred_NPC,
|
||||
Addr Pred_MicroPC,
|
||||
InstSeqNum seq_num, O3CPU *cpu)
|
||||
: BaseDynInst<Impl>(inst, PC, NPC, microPC,
|
||||
Pred_PC, Pred_NPC, Pred_MicroPC, seq_num, cpu)
|
||||
Pred_PC, Pred_NPC, Pred_MicroPC, seq_num, cpu)
|
||||
{
|
||||
initVars();
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
AlphaDynInst<Impl>::AlphaDynInst(StaticInstPtr &_staticInst)
|
||||
BaseO3DynInst<Impl>::BaseO3DynInst(StaticInstPtr &_staticInst)
|
||||
: BaseDynInst<Impl>(_staticInst)
|
||||
{
|
||||
initVars();
|
||||
|
@ -63,7 +63,7 @@ AlphaDynInst<Impl>::AlphaDynInst(StaticInstPtr &_staticInst)
|
|||
|
||||
template <class Impl>
|
||||
void
|
||||
AlphaDynInst<Impl>::initVars()
|
||||
BaseO3DynInst<Impl>::initVars()
|
||||
{
|
||||
// Make sure to have the renamed register entries set to the same
|
||||
// as the normal register entries. It will allow the IQ to work
|
||||
|
@ -80,7 +80,7 @@ AlphaDynInst<Impl>::initVars()
|
|||
|
||||
template <class Impl>
|
||||
Fault
|
||||
AlphaDynInst<Impl>::execute()
|
||||
BaseO3DynInst<Impl>::execute()
|
||||
{
|
||||
// @todo: Pretty convoluted way to avoid squashing from happening
|
||||
// when using the TC during an instruction's execution
|
||||
|
@ -98,7 +98,7 @@ AlphaDynInst<Impl>::execute()
|
|||
|
||||
template <class Impl>
|
||||
Fault
|
||||
AlphaDynInst<Impl>::initiateAcc()
|
||||
BaseO3DynInst<Impl>::initiateAcc()
|
||||
{
|
||||
// @todo: Pretty convoluted way to avoid squashing from happening
|
||||
// when using the TC during an instruction's execution
|
||||
|
@ -116,7 +116,7 @@ AlphaDynInst<Impl>::initiateAcc()
|
|||
|
||||
template <class Impl>
|
||||
Fault
|
||||
AlphaDynInst<Impl>::completeAcc(PacketPtr pkt)
|
||||
BaseO3DynInst<Impl>::completeAcc(PacketPtr pkt)
|
||||
{
|
||||
this->fault = this->staticInst->completeAcc(pkt, this, this->traceData);
|
||||
|
||||
|
@ -126,8 +126,9 @@ AlphaDynInst<Impl>::completeAcc(PacketPtr pkt)
|
|||
#if FULL_SYSTEM
|
||||
template <class Impl>
|
||||
Fault
|
||||
AlphaDynInst<Impl>::hwrei()
|
||||
BaseO3DynInst<Impl>::hwrei()
|
||||
{
|
||||
#if THE_ISA == ALPHA_ISA
|
||||
// Can only do a hwrei when in pal mode.
|
||||
if (!(this->readPC() & 0x3))
|
||||
return new AlphaISA::UnimplementedOpcodeFault;
|
||||
|
@ -138,28 +139,33 @@ AlphaDynInst<Impl>::hwrei()
|
|||
|
||||
// Tell CPU to clear any state it needs to if a hwrei is taken.
|
||||
this->cpu->hwrei(this->threadNumber);
|
||||
#else
|
||||
|
||||
#endif
|
||||
// FIXME: XXX check for interrupts? XXX
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
AlphaDynInst<Impl>::trap(Fault fault)
|
||||
BaseO3DynInst<Impl>::trap(Fault fault)
|
||||
{
|
||||
this->cpu->trap(fault, this->threadNumber);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
bool
|
||||
AlphaDynInst<Impl>::simPalCheck(int palFunc)
|
||||
BaseO3DynInst<Impl>::simPalCheck(int palFunc)
|
||||
{
|
||||
#if THE_ISA != ALPHA_ISA
|
||||
panic("simPalCheck called, but PAL only exists in Alpha!\n");
|
||||
#endif
|
||||
return this->cpu->simPalCheck(palFunc, this->threadNumber);
|
||||
}
|
||||
#else
|
||||
template <class Impl>
|
||||
void
|
||||
AlphaDynInst<Impl>::syscall(int64_t callnum)
|
||||
BaseO3DynInst<Impl>::syscall(int64_t callnum)
|
||||
{
|
||||
// HACK: check CPU's nextPC before and after syscall. If it
|
||||
// changes, update this instruction's nextPC because the syscall
|
|
@ -32,13 +32,11 @@
|
|||
|
||||
#if THE_ISA == ALPHA_ISA
|
||||
#include "cpu/o3/alpha/impl.hh"
|
||||
#include "cpu/o3/alpha/dyn_inst.hh"
|
||||
#elif THE_ISA == MIPS_ISA
|
||||
#include "cpu/o3/mips/impl.hh"
|
||||
#include "cpu/o3/mips/dyn_inst.hh"
|
||||
#elif THE_ISA == SPARC_ISA
|
||||
#include "cpu/o3/sparc/impl.hh"
|
||||
#include "cpu/o3/sparc/dyn_inst.hh"
|
||||
#else
|
||||
#error "ISA-specific header files O3CPU not defined ISA"
|
||||
#endif
|
||||
#include "cpu/o3/dyn_inst.hh"
|
||||
|
|
|
@ -29,9 +29,9 @@
|
|||
* Korey Sewell
|
||||
*/
|
||||
|
||||
#include "cpu/o3/mips/dyn_inst_impl.hh"
|
||||
#include "cpu/o3/dyn_inst_impl.hh"
|
||||
#include "cpu/o3/mips/impl.hh"
|
||||
|
||||
// Force instantiation of MipsDynInst for all the implementations that
|
||||
// are needed.
|
||||
template class MipsDynInst<MipsSimpleImpl>;
|
||||
template class BaseO3DynInst<MipsSimpleImpl>;
|
||||
|
|
|
@ -1,281 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2006 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Kevin Lim
|
||||
* Korey Sewell
|
||||
*/
|
||||
|
||||
#ifndef __CPU_O3_MIPS_DYN_INST_HH__
|
||||
#define __CPU_O3_MIPS_DYN_INST_HH__
|
||||
|
||||
#include "arch/isa_traits.hh"
|
||||
#include "cpu/base_dyn_inst.hh"
|
||||
#include "cpu/inst_seq.hh"
|
||||
#include "cpu/o3/cpu.hh"
|
||||
#include "cpu/o3/mips/impl.hh"
|
||||
|
||||
class Packet;
|
||||
|
||||
/**
|
||||
* Mostly implementation & ISA specific MipsDynInst. As with most
|
||||
* other classes in the new CPU model, it is templated on the Impl to
|
||||
* allow for passing in of all types, such as the CPU type and the ISA
|
||||
* type. The MipsDynInst serves as the primary interface to the CPU
|
||||
* for instructions that are executing.
|
||||
*/
|
||||
template <class Impl>
|
||||
class MipsDynInst : public BaseDynInst<Impl>
|
||||
{
|
||||
public:
|
||||
/** Typedef for the CPU. */
|
||||
typedef typename Impl::O3CPU O3CPU;
|
||||
|
||||
/** Logical register index type. */
|
||||
typedef TheISA::RegIndex RegIndex;
|
||||
/** Integer register index type. */
|
||||
typedef TheISA::IntReg IntReg;
|
||||
typedef TheISA::FloatReg FloatReg;
|
||||
typedef TheISA::FloatRegBits FloatRegBits;
|
||||
/** Misc register index type. */
|
||||
typedef TheISA::MiscReg MiscReg;
|
||||
|
||||
enum {
|
||||
MaxInstSrcRegs = TheISA::MaxInstSrcRegs, //< Max source regs
|
||||
MaxInstDestRegs = TheISA::MaxInstDestRegs, //< Max dest regs
|
||||
};
|
||||
|
||||
public:
|
||||
/** BaseDynInst constructor given a binary instruction. */
|
||||
MipsDynInst(StaticInstPtr staticInst,
|
||||
Addr PC, Addr NPC, Addr microPC,
|
||||
Addr Pred_PC, Addr Pred_NPC, Addr Pred_MicroPC,
|
||||
InstSeqNum seq_num, O3CPU *cpu);
|
||||
|
||||
/** BaseDynInst constructor given a binary instruction. */
|
||||
MipsDynInst(ExtMachInst inst,
|
||||
Addr PC, Addr NPC, Addr microPC,
|
||||
Addr Pred_PC, Addr Pred_NPC, Addr Pred_MicroPC,
|
||||
InstSeqNum seq_num, O3CPU *cpu);
|
||||
|
||||
/** BaseDynInst constructor given a static inst pointer. */
|
||||
MipsDynInst(StaticInstPtr &_staticInst);
|
||||
|
||||
/** Executes the instruction.*/
|
||||
Fault execute();
|
||||
|
||||
/** Initiates the access. Only valid for memory operations. */
|
||||
Fault initiateAcc();
|
||||
|
||||
/** Completes the access. Only valid for memory operations. */
|
||||
Fault completeAcc(PacketPtr pkt);
|
||||
|
||||
private:
|
||||
/** Initializes variables. */
|
||||
void initVars();
|
||||
|
||||
public:
|
||||
/** Reads a miscellaneous register. */
|
||||
/** TODO: Use thread number from argument if given, will probably not work for MIPS MT as is */
|
||||
MiscReg readMiscRegNoEffect(int misc_reg, unsigned tid = 0)
|
||||
{
|
||||
return this->cpu->readMiscRegNoEffect(misc_reg, this->threadNumber);
|
||||
}
|
||||
|
||||
/** Reads a misc. register, including any side-effects the read
|
||||
* might have as defined by the architecture.
|
||||
*/
|
||||
MiscReg readMiscReg(int misc_reg, unsigned tid = 0)
|
||||
{
|
||||
return this->cpu->readMiscReg(misc_reg, this->threadNumber);
|
||||
}
|
||||
|
||||
/** Sets a misc. register. */
|
||||
void setMiscRegNoEffect(int misc_reg, const MiscReg &val, unsigned tid = 0)
|
||||
{
|
||||
this->instResult.integer = val;
|
||||
this->cpu->setMiscRegNoEffect(misc_reg, val, this->threadNumber);
|
||||
}
|
||||
|
||||
/** Sets a misc. register, including any side-effects the write
|
||||
* might have as defined by the architecture.
|
||||
*/
|
||||
void setMiscReg(int misc_reg, const MiscReg &val, unsigned tid = 0)
|
||||
{
|
||||
return this->cpu->setMiscReg(misc_reg, val,
|
||||
this->threadNumber);
|
||||
}
|
||||
|
||||
|
||||
/** Calls a syscall. */
|
||||
void syscall(int64_t callnum);
|
||||
|
||||
public:
|
||||
|
||||
// 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 readIntRegOperand(const StaticInst *si, int idx)
|
||||
{
|
||||
return this->cpu->readIntReg(this->_srcRegIdx[idx]);
|
||||
}
|
||||
|
||||
FloatReg readFloatRegOperand(const StaticInst *si, int idx, int width)
|
||||
{
|
||||
return this->cpu->readFloatReg(this->_srcRegIdx[idx], width);
|
||||
}
|
||||
|
||||
FloatReg readFloatRegOperand(const StaticInst *si, int idx)
|
||||
{
|
||||
return this->cpu->readFloatReg(this->_srcRegIdx[idx]);
|
||||
}
|
||||
|
||||
FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx,
|
||||
int width)
|
||||
{
|
||||
return this->cpu->readFloatRegBits(this->_srcRegIdx[idx], width);
|
||||
}
|
||||
|
||||
FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx)
|
||||
{
|
||||
return this->cpu->readFloatRegBits(this->_srcRegIdx[idx]);
|
||||
}
|
||||
|
||||
/** @todo: Make results into arrays so they can handle multiple dest
|
||||
* registers.
|
||||
*/
|
||||
void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
|
||||
{
|
||||
this->cpu->setIntReg(this->_destRegIdx[idx], val);
|
||||
BaseDynInst<Impl>::setIntRegOperand(si, idx, val);
|
||||
}
|
||||
|
||||
void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val,
|
||||
int width)
|
||||
{
|
||||
this->cpu->setFloatReg(this->_destRegIdx[idx], val, width);
|
||||
BaseDynInst<Impl>::setFloatRegOperand(si, idx, val, width);
|
||||
}
|
||||
|
||||
void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
|
||||
{
|
||||
this->cpu->setFloatReg(this->_destRegIdx[idx], val);
|
||||
BaseDynInst<Impl>::setFloatRegOperand(si, idx, val);
|
||||
}
|
||||
|
||||
void setFloatRegOperandBits(const StaticInst *si, int idx,
|
||||
FloatRegBits val, int width)
|
||||
{
|
||||
this->cpu->setFloatRegBits(this->_destRegIdx[idx], val, width);
|
||||
BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val);
|
||||
}
|
||||
|
||||
void setFloatRegOperandBits(const StaticInst *si, int idx,
|
||||
FloatRegBits val)
|
||||
{
|
||||
this->cpu->setFloatRegBits(this->_destRegIdx[idx], val);
|
||||
BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val);
|
||||
}
|
||||
|
||||
/** Reads a miscellaneous register. */
|
||||
TheISA::MiscReg readMiscRegOperandNoEffect(const StaticInst *si, int idx)
|
||||
{
|
||||
return this->cpu->readMiscRegNoEffect(
|
||||
si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
|
||||
this->threadNumber);
|
||||
}
|
||||
|
||||
/** Reads a misc. register, including any side-effects the read
|
||||
* might have as defined by the architecture.
|
||||
*/
|
||||
TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx)
|
||||
{
|
||||
return this->cpu->readMiscReg(
|
||||
si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
|
||||
this->threadNumber);
|
||||
}
|
||||
|
||||
/** Sets a misc. register. */
|
||||
void setMiscRegOperandNoEffect(const StaticInst * si, int idx, const MiscReg &val)
|
||||
{
|
||||
this->instResult.integer = val;
|
||||
return this->cpu->setMiscRegNoEffect(
|
||||
si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
|
||||
val, this->threadNumber);
|
||||
}
|
||||
|
||||
/** Sets a misc. register, including any side-effects the write
|
||||
* might have as defined by the architecture.
|
||||
*/
|
||||
void setMiscRegOperand(const StaticInst *si, int idx,
|
||||
const MiscReg &val)
|
||||
{
|
||||
return this->cpu->setMiscReg(
|
||||
si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
|
||||
val, this->threadNumber);
|
||||
}
|
||||
|
||||
uint64_t readRegOtherThread(int misc_reg)
|
||||
{
|
||||
panic("MIPS MT not defined for O3 CPU.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void setRegOtherThread(int misc_reg, const TheISA::MiscReg &val)
|
||||
{
|
||||
panic("MIPS MT not defined for O3 CPU.\n");
|
||||
}
|
||||
|
||||
public:
|
||||
/** Calculates EA part of a memory instruction. Currently unused,
|
||||
* though it may be useful in the future if we want to split
|
||||
* memory operations into EA calculation and memory access parts.
|
||||
*/
|
||||
Fault calcEA()
|
||||
{
|
||||
return this->staticInst->eaCompInst()->execute(this, this->traceData);
|
||||
}
|
||||
|
||||
/** Does the memory access part of a memory instruction. Currently unused,
|
||||
* though it may be useful in the future if we want to split
|
||||
* memory operations into EA calculation and memory access parts.
|
||||
*/
|
||||
Fault memAccess()
|
||||
{
|
||||
return this->staticInst->memAccInst()->execute(this, this->traceData);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __CPU_O3_MIPS_DYN_INST_HH__
|
||||
|
|
@ -1,130 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2006 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Kevin Lim
|
||||
*/
|
||||
|
||||
#include "cpu/o3/mips/dyn_inst.hh"
|
||||
|
||||
template <class Impl>
|
||||
MipsDynInst<Impl>::MipsDynInst(StaticInstPtr staticInst,
|
||||
Addr PC, Addr NPC, Addr microPC,
|
||||
Addr Pred_PC, Addr Pred_NPC, Addr Pred_MicroPC,
|
||||
InstSeqNum seq_num, O3CPU *cpu)
|
||||
: BaseDynInst<Impl>(staticInst, PC, NPC, microPC,
|
||||
Pred_PC, Pred_NPC, Pred_MicroPC, seq_num, cpu)
|
||||
{
|
||||
initVars();
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
MipsDynInst<Impl>::MipsDynInst(ExtMachInst inst,
|
||||
Addr PC, Addr NPC, Addr microPC,
|
||||
Addr Pred_PC, Addr Pred_NPC, Addr Pred_MicroPC,
|
||||
InstSeqNum seq_num, O3CPU *cpu)
|
||||
: BaseDynInst<Impl>(inst, PC, NPC, microPC,
|
||||
Pred_PC, Pred_NPC, Pred_MicroPC, seq_num, cpu)
|
||||
{
|
||||
initVars();
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
MipsDynInst<Impl>::MipsDynInst(StaticInstPtr &_staticInst)
|
||||
: BaseDynInst<Impl>(_staticInst)
|
||||
{
|
||||
initVars();
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
MipsDynInst<Impl>::initVars()
|
||||
{
|
||||
// Make sure to have the renamed register entries set to the same
|
||||
// as the normal register entries. It will allow the IQ to work
|
||||
// without any modifications.
|
||||
for (int i = 0; i < this->staticInst->numDestRegs(); i++) {
|
||||
this->_destRegIdx[i] = this->staticInst->destRegIdx(i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < this->staticInst->numSrcRegs(); i++) {
|
||||
this->_srcRegIdx[i] = this->staticInst->srcRegIdx(i);
|
||||
this->_readySrcRegIdx[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
Fault
|
||||
MipsDynInst<Impl>::execute()
|
||||
{
|
||||
// @todo: Pretty convoluted way to avoid squashing from happening
|
||||
// when using the TC during an instruction's execution
|
||||
// (specifically for instructions that have side-effects that use
|
||||
// the TC). Fix this.
|
||||
bool in_syscall = this->thread->inSyscall;
|
||||
this->thread->inSyscall = true;
|
||||
|
||||
this->fault = this->staticInst->execute(this, this->traceData);
|
||||
|
||||
this->thread->inSyscall = in_syscall;
|
||||
|
||||
return this->fault;
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
Fault
|
||||
MipsDynInst<Impl>::initiateAcc()
|
||||
{
|
||||
// @todo: Pretty convoluted way to avoid squashing from happening
|
||||
// when using the TC during an instruction's execution
|
||||
// (specifically for instructions that have side-effects that use
|
||||
// the TC). Fix this.
|
||||
bool in_syscall = this->thread->inSyscall;
|
||||
this->thread->inSyscall = true;
|
||||
|
||||
this->fault = this->staticInst->initiateAcc(this, this->traceData);
|
||||
|
||||
this->thread->inSyscall = in_syscall;
|
||||
|
||||
return this->fault;
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
Fault
|
||||
MipsDynInst<Impl>::completeAcc(PacketPtr pkt)
|
||||
{
|
||||
this->fault = this->staticInst->completeAcc(pkt, this, this->traceData);
|
||||
|
||||
return this->fault;
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
MipsDynInst<Impl>::syscall(int64_t callnum)
|
||||
{
|
||||
this->cpu->syscall(callnum, this->threadNumber);
|
||||
}
|
||||
|
|
@ -36,10 +36,9 @@
|
|||
|
||||
#include "cpu/o3/cpu_policy.hh"
|
||||
|
||||
|
||||
// Forward declarations.
|
||||
template <class Impl>
|
||||
class MipsDynInst;
|
||||
class BaseO3DynInst;
|
||||
|
||||
template <class Impl>
|
||||
class FullO3CPU;
|
||||
|
@ -61,7 +60,7 @@ struct MipsSimpleImpl
|
|||
typedef SimpleCPUPolicy<MipsSimpleImpl> CPUPol;
|
||||
|
||||
/** The DynInst type to be used. */
|
||||
typedef MipsDynInst<MipsSimpleImpl> DynInst;
|
||||
typedef BaseO3DynInst<MipsSimpleImpl> DynInst;
|
||||
|
||||
/** The refcounted DynInst pointer to be used. In most cases this is
|
||||
* what should be used, and not DynInst *.
|
||||
|
|
|
@ -28,9 +28,9 @@
|
|||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#include "cpu/o3/sparc/dyn_inst_impl.hh"
|
||||
#include "cpu/o3/dyn_inst_impl.hh"
|
||||
#include "cpu/o3/sparc/impl.hh"
|
||||
|
||||
// Force instantiation of SparcDynInst for all the implementations that
|
||||
// are needed.
|
||||
template class SparcDynInst<SparcSimpleImpl>;
|
||||
template class BaseO3DynInst<SparcSimpleImpl>;
|
||||
|
|
|
@ -1,265 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2006 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#ifndef __CPU_O3_SPARC_DYN_INST_HH__
|
||||
#define __CPU_O3_SPARC_DYN_INST_HH__
|
||||
|
||||
#include "arch/sparc/isa_traits.hh"
|
||||
#include "arch/sparc/types.hh"
|
||||
#include "cpu/base_dyn_inst.hh"
|
||||
#include "cpu/inst_seq.hh"
|
||||
#include "cpu/o3/cpu.hh"
|
||||
#include "cpu/o3/sparc/impl.hh"
|
||||
|
||||
class Packet;
|
||||
|
||||
/**
|
||||
* Mostly implementation & ISA specific SparcDynInst. As with most
|
||||
* other classes in the new CPU model, it is templated on the Impl to
|
||||
* allow for passing in of all types, such as the CPU type and the ISA
|
||||
* type. The SparcDynInst serves as the primary interface to the CPU
|
||||
* for instructions that are executing.
|
||||
*/
|
||||
template <class Impl>
|
||||
class SparcDynInst : public BaseDynInst<Impl>
|
||||
{
|
||||
public:
|
||||
/** Typedef for the CPU. */
|
||||
typedef typename Impl::O3CPU O3CPU;
|
||||
|
||||
public:
|
||||
/** BaseDynInst constructor given a binary instruction. */
|
||||
SparcDynInst(StaticInstPtr staticInst, Addr PC, Addr NPC, Addr microPC,
|
||||
Addr Pred_PC, Addr Pred_NPC, Addr Pred_MicroPC,
|
||||
InstSeqNum seq_num, O3CPU *cpu);
|
||||
|
||||
/** BaseDynInst constructor given a binary instruction. */
|
||||
SparcDynInst(TheISA::ExtMachInst inst, Addr PC, Addr NPC, Addr microPC,
|
||||
Addr Pred_PC, Addr Pred_NPC, Addr Pred_MicroPC,
|
||||
InstSeqNum seq_num, O3CPU *cpu);
|
||||
|
||||
/** BaseDynInst constructor given a static inst pointer. */
|
||||
SparcDynInst(StaticInstPtr &_staticInst);
|
||||
|
||||
/** Executes the instruction.*/
|
||||
Fault execute();
|
||||
|
||||
/** Initiates the access. Only valid for memory operations. */
|
||||
Fault initiateAcc();
|
||||
|
||||
/** Completes the access. Only valid for memory operations. */
|
||||
Fault completeAcc(PacketPtr pkt);
|
||||
|
||||
private:
|
||||
/** Initializes variables. */
|
||||
void initVars();
|
||||
|
||||
public:
|
||||
/** Reads a miscellaneous register. */
|
||||
TheISA::MiscReg readMiscRegNoEffect(int misc_reg)
|
||||
{
|
||||
return this->cpu->readMiscRegNoEffect(misc_reg, this->threadNumber);
|
||||
}
|
||||
|
||||
/** Reads a misc. register, including any side-effects the read
|
||||
* might have as defined by the architecture.
|
||||
*/
|
||||
TheISA::MiscReg readMiscReg(int misc_reg)
|
||||
{
|
||||
return this->cpu->readMiscReg(misc_reg, this->threadNumber);
|
||||
}
|
||||
|
||||
/** Sets a misc. register. */
|
||||
void setMiscRegNoEffect(int misc_reg, const TheISA::MiscReg &val)
|
||||
{
|
||||
this->instResult.integer = val;
|
||||
return this->cpu->setMiscRegNoEffect(misc_reg, val, this->threadNumber);
|
||||
}
|
||||
|
||||
/** Sets a misc. register, including any side-effects the write
|
||||
* might have as defined by the architecture.
|
||||
*/
|
||||
void setMiscReg(int misc_reg, const TheISA::MiscReg &val)
|
||||
{
|
||||
return this->cpu->setMiscReg(misc_reg, val,
|
||||
this->threadNumber);
|
||||
}
|
||||
|
||||
/** Reads a miscellaneous register. */
|
||||
TheISA::MiscReg readMiscRegOperandNoEffect(const StaticInst *si, int idx)
|
||||
{
|
||||
return this->cpu->readMiscRegNoEffect(
|
||||
si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
|
||||
this->threadNumber);
|
||||
}
|
||||
|
||||
/** Reads a misc. register, including any side-effects the read
|
||||
* might have as defined by the architecture.
|
||||
*/
|
||||
TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx)
|
||||
{
|
||||
return this->cpu->readMiscReg(
|
||||
si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
|
||||
this->threadNumber);
|
||||
}
|
||||
|
||||
/** Sets a misc. register. */
|
||||
void setMiscRegOperandNoEffect(const StaticInst * si,
|
||||
int idx, const TheISA::MiscReg &val)
|
||||
{
|
||||
this->instResult.integer = val;
|
||||
return this->cpu->setMiscRegNoEffect(
|
||||
si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
|
||||
val, this->threadNumber);
|
||||
}
|
||||
|
||||
/** Sets a misc. register, including any side-effects the write
|
||||
* might have as defined by the architecture.
|
||||
*/
|
||||
void setMiscRegOperand(
|
||||
const StaticInst *si, int idx, const TheISA::MiscReg &val)
|
||||
{
|
||||
return this->cpu->setMiscReg(
|
||||
si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
|
||||
val, this->threadNumber);
|
||||
}
|
||||
|
||||
#if FULL_SYSTEM
|
||||
/** Calls hardware return from error interrupt. */
|
||||
Fault hwrei();
|
||||
/** Traps to handle specified fault. */
|
||||
void trap(Fault fault);
|
||||
bool simPalCheck(int palFunc);
|
||||
#else
|
||||
/** Calls a syscall. */
|
||||
void syscall(int64_t callnum);
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
// 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 readIntRegOperand(const StaticInst *si, int idx)
|
||||
{
|
||||
uint64_t val = this->cpu->readIntReg(this->_srcRegIdx[idx]);
|
||||
DPRINTF(Sparc, "Reading int reg %d (%d, %d) as %x\n", (int)this->_flatSrcRegIdx[idx], (int)this->_srcRegIdx[idx], idx, val);
|
||||
return val;
|
||||
}
|
||||
|
||||
TheISA::FloatReg readFloatRegOperand(const StaticInst *si,
|
||||
int idx, int width)
|
||||
{
|
||||
return this->cpu->readFloatReg(this->_srcRegIdx[idx], width);
|
||||
}
|
||||
|
||||
TheISA::FloatReg readFloatRegOperand(const StaticInst *si, int idx)
|
||||
{
|
||||
return this->cpu->readFloatReg(this->_srcRegIdx[idx]);
|
||||
}
|
||||
|
||||
TheISA::FloatRegBits readFloatRegOperandBits(const StaticInst *si,
|
||||
int idx, int width)
|
||||
{
|
||||
return this->cpu->readFloatRegBits(this->_srcRegIdx[idx], width);
|
||||
}
|
||||
|
||||
TheISA::FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx)
|
||||
{
|
||||
return this->cpu->readFloatRegBits(this->_srcRegIdx[idx]);
|
||||
}
|
||||
|
||||
/** @todo: Make results into arrays so they can handle multiple dest
|
||||
* registers.
|
||||
*/
|
||||
void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
|
||||
{
|
||||
DPRINTF(Sparc, "Setting int reg %d (%d, %d) to %x\n", (int)this->_flatDestRegIdx[idx], (int)this->_destRegIdx[idx], idx, val);
|
||||
this->cpu->setIntReg(this->_destRegIdx[idx], val);
|
||||
BaseDynInst<Impl>::setIntRegOperand(si, idx, val);
|
||||
}
|
||||
|
||||
void setFloatRegOperand(const StaticInst *si, int idx,
|
||||
TheISA::FloatReg val, int width)
|
||||
{
|
||||
this->cpu->setFloatReg(this->_destRegIdx[idx], val, width);
|
||||
BaseDynInst<Impl>::setFloatRegOperand(si, idx, val, width);
|
||||
}
|
||||
|
||||
void setFloatRegOperand(const StaticInst *si, int idx, TheISA::FloatReg val)
|
||||
{
|
||||
this->cpu->setFloatReg(this->_destRegIdx[idx], val);
|
||||
BaseDynInst<Impl>::setFloatRegOperand(si, idx, val);
|
||||
}
|
||||
|
||||
void setFloatRegOperandBits(const StaticInst *si, int idx,
|
||||
TheISA::FloatRegBits val, int width)
|
||||
{
|
||||
this->cpu->setFloatRegBits(this->_destRegIdx[idx], val, width);
|
||||
BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val);
|
||||
}
|
||||
|
||||
void setFloatRegOperandBits(const StaticInst *si,
|
||||
int idx, TheISA::FloatRegBits val)
|
||||
{
|
||||
this->cpu->setFloatRegBits(this->_destRegIdx[idx], val);
|
||||
BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val);
|
||||
}
|
||||
|
||||
public:
|
||||
/** Calculates EA part of a memory instruction. Currently unused,
|
||||
* though it may be useful in the future if we want to split
|
||||
* memory operations into EA calculation and memory access parts.
|
||||
*/
|
||||
Fault calcEA()
|
||||
{
|
||||
return this->staticInst->eaCompInst()->execute(this, this->traceData);
|
||||
}
|
||||
|
||||
/** Does the memory access part of a memory instruction. Currently unused,
|
||||
* though it may be useful in the future if we want to split
|
||||
* memory operations into EA calculation and memory access parts.
|
||||
*/
|
||||
Fault memAccess()
|
||||
{
|
||||
return this->staticInst->memAccInst()->execute(this, this->traceData);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __CPU_O3_SPARC_DYN_INST_HH__
|
||||
|
|
@ -1,154 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2006 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#include "cpu/o3/sparc/dyn_inst.hh"
|
||||
|
||||
template <class Impl>
|
||||
SparcDynInst<Impl>::SparcDynInst(StaticInstPtr staticInst,
|
||||
Addr PC, Addr NPC, Addr microPC,
|
||||
Addr Pred_PC, Addr Pred_NPC, Addr Pred_MicroPC,
|
||||
InstSeqNum seq_num, O3CPU *cpu)
|
||||
: BaseDynInst<Impl>(staticInst, PC, NPC, microPC,
|
||||
Pred_PC, Pred_NPC, Pred_MicroPC, seq_num, cpu)
|
||||
{
|
||||
initVars();
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
SparcDynInst<Impl>::SparcDynInst(TheISA::ExtMachInst inst,
|
||||
Addr PC, Addr NPC, Addr microPC,
|
||||
Addr Pred_PC, Addr Pred_NPC, Addr Pred_MicroPC,
|
||||
InstSeqNum seq_num, O3CPU *cpu)
|
||||
: BaseDynInst<Impl>(inst, PC, NPC, microPC,
|
||||
Pred_PC, Pred_NPC, Pred_MicroPC, seq_num, cpu)
|
||||
{
|
||||
initVars();
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
SparcDynInst<Impl>::SparcDynInst(StaticInstPtr &_staticInst)
|
||||
: BaseDynInst<Impl>(_staticInst)
|
||||
{
|
||||
initVars();
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
SparcDynInst<Impl>::initVars()
|
||||
{
|
||||
// Make sure to have the renamed register entries set to the same
|
||||
// as the normal register entries. It will allow the IQ to work
|
||||
// without any modifications.
|
||||
for (int i = 0; i < this->staticInst->numDestRegs(); i++) {
|
||||
this->_destRegIdx[i] = this->staticInst->destRegIdx(i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < this->staticInst->numSrcRegs(); i++) {
|
||||
this->_srcRegIdx[i] = this->staticInst->srcRegIdx(i);
|
||||
this->_readySrcRegIdx[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
Fault
|
||||
SparcDynInst<Impl>::execute()
|
||||
{
|
||||
// @todo: Pretty convoluted way to avoid squashing from happening
|
||||
// when using the TC during an instruction's execution
|
||||
// (specifically for instructions that have side-effects that use
|
||||
// the TC). Fix this.
|
||||
bool in_syscall = this->thread->inSyscall;
|
||||
this->thread->inSyscall = true;
|
||||
|
||||
this->fault = this->staticInst->execute(this, this->traceData);
|
||||
|
||||
this->thread->inSyscall = in_syscall;
|
||||
|
||||
return this->fault;
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
Fault
|
||||
SparcDynInst<Impl>::initiateAcc()
|
||||
{
|
||||
// @todo: Pretty convoluted way to avoid squashing from happening
|
||||
// when using the TC during an instruction's execution
|
||||
// (specifically for instructions that have side-effects that use
|
||||
// the TC). Fix this.
|
||||
bool in_syscall = this->thread->inSyscall;
|
||||
this->thread->inSyscall = true;
|
||||
|
||||
this->fault = this->staticInst->initiateAcc(this, this->traceData);
|
||||
|
||||
this->thread->inSyscall = in_syscall;
|
||||
|
||||
return this->fault;
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
Fault
|
||||
SparcDynInst<Impl>::completeAcc(PacketPtr pkt)
|
||||
{
|
||||
this->fault = this->staticInst->completeAcc(pkt, this, this->traceData);
|
||||
|
||||
return this->fault;
|
||||
}
|
||||
|
||||
#if FULL_SYSTEM
|
||||
template <class Impl>
|
||||
Fault
|
||||
SparcDynInst<Impl>::hwrei()
|
||||
{
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
SparcDynInst<Impl>::trap(Fault fault)
|
||||
{
|
||||
this->cpu->trap(fault, this->threadNumber);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
bool
|
||||
SparcDynInst<Impl>::simPalCheck(int palFunc)
|
||||
{
|
||||
panic("simPalCheck called, but there's no PAL in SPARC!\n");
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
template <class Impl>
|
||||
void
|
||||
SparcDynInst<Impl>::syscall(int64_t callnum)
|
||||
{
|
||||
this->cpu->syscall(callnum, this->threadNumber);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
// Forward declarations.
|
||||
template <class Impl>
|
||||
class SparcDynInst;
|
||||
class BaseO3DynInst;
|
||||
|
||||
template <class Impl>
|
||||
class FullO3CPU;
|
||||
|
@ -60,7 +60,7 @@ struct SparcSimpleImpl
|
|||
typedef SimpleCPUPolicy<SparcSimpleImpl> CPUPol;
|
||||
|
||||
/** The DynInst type to be used. */
|
||||
typedef SparcDynInst<SparcSimpleImpl> DynInst;
|
||||
typedef BaseO3DynInst<SparcSimpleImpl> DynInst;
|
||||
|
||||
/** The refcounted DynInst pointer to be used. In most cases this is
|
||||
* what should be used, and not DynInst *.
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
#include "base/misc.hh"
|
||||
#include "base/refcnt.hh"
|
||||
#include "cpu/op_class.hh"
|
||||
#include "cpu/o3/dyn_inst.hh"
|
||||
#include "cpu/o3/dyn_inst_decl.hh"
|
||||
#include "sim/faults.hh"
|
||||
#include "sim/host.hh"
|
||||
|
||||
|
|
Loading…
Reference in a new issue