summaryrefslogtreecommitdiff
path: root/src/cpu/o3/alpha_dyn_inst_impl.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/o3/alpha_dyn_inst_impl.hh')
-rw-r--r--src/cpu/o3/alpha_dyn_inst_impl.hh110
1 files changed, 85 insertions, 25 deletions
diff --git a/src/cpu/o3/alpha_dyn_inst_impl.hh b/src/cpu/o3/alpha_dyn_inst_impl.hh
index 96b7d3430..a73cf4a7d 100644
--- a/src/cpu/o3/alpha_dyn_inst_impl.hh
+++ b/src/cpu/o3/alpha_dyn_inst_impl.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2005 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
@@ -24,47 +24,95 @@
* 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/alpha_dyn_inst.hh"
template <class Impl>
-AlphaDynInst<Impl>::AlphaDynInst(MachInst inst, Addr PC, Addr Pred_PC,
+AlphaDynInst<Impl>::AlphaDynInst(ExtMachInst inst, Addr PC, Addr Pred_PC,
InstSeqNum seq_num, FullCPU *cpu)
: BaseDynInst<Impl>(inst, PC, Pred_PC, seq_num, cpu)
{
+ initVars();
+}
+
+template <class Impl>
+AlphaDynInst<Impl>::AlphaDynInst(StaticInstPtr &_staticInst)
+ : BaseDynInst<Impl>(_staticInst)
+{
+ initVars();
+}
+
+template <class Impl>
+void
+AlphaDynInst<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++)
- {
+ for (int i = 0; i < this->staticInst->numDestRegs(); i++) {
_destRegIdx[i] = this->staticInst->destRegIdx(i);
}
- for (int i = 0; i < this->staticInst->numSrcRegs(); i++)
- {
+ for (int i = 0; i < this->staticInst->numSrcRegs(); i++) {
_srcRegIdx[i] = this->staticInst->srcRegIdx(i);
this->_readySrcRegIdx[i] = 0;
}
+}
+
+template <class Impl>
+Fault
+AlphaDynInst<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>
-AlphaDynInst<Impl>::AlphaDynInst(StaticInstPtr &_staticInst)
- : BaseDynInst<Impl>(_staticInst)
+Fault
+AlphaDynInst<Impl>::initiateAcc()
{
- // 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 < _staticInst->numDestRegs(); i++)
- {
- _destRegIdx[i] = _staticInst->destRegIdx(i);
- }
+ // @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;
- for (int i = 0; i < _staticInst->numSrcRegs(); i++)
- {
- _srcRegIdx[i] = _staticInst->srcRegIdx(i);
+ return this->fault;
+}
+
+template <class Impl>
+Fault
+AlphaDynInst<Impl>::completeAcc(Packet *pkt)
+{
+ if (this->isLoad()) {
+ this->fault = this->staticInst->completeAcc(pkt, this,
+ this->traceData);
+ } else if (this->isStore()) {
+ this->fault = this->staticInst->completeAcc(pkt, this,
+ this->traceData);
+ } else {
+ panic("Unknown type!");
}
+
+ return this->fault;
}
#if FULL_SYSTEM
@@ -72,14 +120,26 @@ template <class Impl>
Fault
AlphaDynInst<Impl>::hwrei()
{
- return this->cpu->hwrei();
+ // Can only do a hwrei when in pal mode.
+ if (!this->cpu->inPalMode(this->readPC()))
+ return new AlphaISA::UnimplementedOpcodeFault;
+
+ // Set the next PC based on the value of the EXC_ADDR IPR.
+ this->setNextPC(this->cpu->readMiscReg(AlphaISA::IPR_EXC_ADDR,
+ this->threadNumber));
+
+ // Tell CPU to clear any state it needs to if a hwrei is taken.
+ this->cpu->hwrei(this->threadNumber);
+
+ // FIXME: XXX check for interrupts? XXX
+ return NoFault;
}
template <class Impl>
int
AlphaDynInst<Impl>::readIntrFlag()
{
-return this->cpu->readIntrFlag();
+ return this->cpu->readIntrFlag();
}
template <class Impl>
@@ -93,28 +153,28 @@ template <class Impl>
bool
AlphaDynInst<Impl>::inPalMode()
{
- return this->cpu->inPalMode();
+ return this->cpu->inPalMode(this->PC);
}
template <class Impl>
void
AlphaDynInst<Impl>::trap(Fault fault)
{
- this->cpu->trap(fault);
+ this->cpu->trap(fault, this->threadNumber);
}
template <class Impl>
bool
AlphaDynInst<Impl>::simPalCheck(int palFunc)
{
- return this->cpu->simPalCheck(palFunc);
+ return this->cpu->simPalCheck(palFunc, this->threadNumber);
}
#else
template <class Impl>
void
-AlphaDynInst<Impl>::syscall()
+AlphaDynInst<Impl>::syscall(int64_t callnum)
{
- this->cpu->syscall(this->threadNumber);
+ this->cpu->syscall(callnum, this->threadNumber);
}
#endif