dyn_inst_impl.hh revision 5953
19651SAndreas.Sandberg@ARM.com/*
29651SAndreas.Sandberg@ARM.com * Copyright (c) 2004-2006 The Regents of The University of Michigan
39651SAndreas.Sandberg@ARM.com * All rights reserved.
49651SAndreas.Sandberg@ARM.com *
59651SAndreas.Sandberg@ARM.com * Redistribution and use in source and binary forms, with or without
69651SAndreas.Sandberg@ARM.com * modification, are permitted provided that the following conditions are
79651SAndreas.Sandberg@ARM.com * met: redistributions of source code must retain the above copyright
89651SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer;
99651SAndreas.Sandberg@ARM.com * redistributions in binary form must reproduce the above copyright
109651SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer in the
119651SAndreas.Sandberg@ARM.com * documentation and/or other materials provided with the distribution;
129651SAndreas.Sandberg@ARM.com * neither the name of the copyright holders nor the names of its
139651SAndreas.Sandberg@ARM.com * contributors may be used to endorse or promote products derived from
149651SAndreas.Sandberg@ARM.com * this software without specific prior written permission.
159651SAndreas.Sandberg@ARM.com *
169651SAndreas.Sandberg@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
179651SAndreas.Sandberg@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
189651SAndreas.Sandberg@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
199651SAndreas.Sandberg@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
209651SAndreas.Sandberg@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
219651SAndreas.Sandberg@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
229651SAndreas.Sandberg@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
239651SAndreas.Sandberg@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
249651SAndreas.Sandberg@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
259651SAndreas.Sandberg@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
269651SAndreas.Sandberg@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
279651SAndreas.Sandberg@ARM.com *
289651SAndreas.Sandberg@ARM.com * Authors: Kevin Lim
299651SAndreas.Sandberg@ARM.com */
309651SAndreas.Sandberg@ARM.com
319651SAndreas.Sandberg@ARM.com#include "base/cp_annotate.hh"
329651SAndreas.Sandberg@ARM.com#include "cpu/o3/dyn_inst.hh"
339651SAndreas.Sandberg@ARM.com
349651SAndreas.Sandberg@ARM.comtemplate <class Impl>
359651SAndreas.Sandberg@ARM.comBaseO3DynInst<Impl>::BaseO3DynInst(StaticInstPtr staticInst,
369651SAndreas.Sandberg@ARM.com                                   Addr PC, Addr NPC, Addr microPC,
379651SAndreas.Sandberg@ARM.com                                   Addr Pred_PC, Addr Pred_NPC,
389651SAndreas.Sandberg@ARM.com                                   Addr Pred_MicroPC,
399651SAndreas.Sandberg@ARM.com                                   InstSeqNum seq_num, O3CPU *cpu)
409881Sandreas@sandberg.pp.se    : BaseDynInst<Impl>(staticInst, PC, NPC, microPC,
419651SAndreas.Sandberg@ARM.com                        Pred_PC, Pred_NPC, Pred_MicroPC, seq_num, cpu)
429651SAndreas.Sandberg@ARM.com{
4310073Sandreas@sandberg.pp.se    initVars();
4410073Sandreas@sandberg.pp.se}
459651SAndreas.Sandberg@ARM.com
469651SAndreas.Sandberg@ARM.comtemplate <class Impl>
479651SAndreas.Sandberg@ARM.comBaseO3DynInst<Impl>::BaseO3DynInst(ExtMachInst inst,
489651SAndreas.Sandberg@ARM.com                                   Addr PC, Addr NPC, Addr microPC,
499651SAndreas.Sandberg@ARM.com                                   Addr Pred_PC, Addr Pred_NPC,
509651SAndreas.Sandberg@ARM.com                                   Addr Pred_MicroPC,
5110073Sandreas@sandberg.pp.se                                   InstSeqNum seq_num, O3CPU *cpu)
5210073Sandreas@sandberg.pp.se    : BaseDynInst<Impl>(inst, PC, NPC, microPC,
5310073Sandreas@sandberg.pp.se                        Pred_PC, Pred_NPC, Pred_MicroPC, seq_num, cpu)
5410073Sandreas@sandberg.pp.se{
5510073Sandreas@sandberg.pp.se    initVars();
5610073Sandreas@sandberg.pp.se}
5710073Sandreas@sandberg.pp.se
5810073Sandreas@sandberg.pp.setemplate <class Impl>
5910073Sandreas@sandberg.pp.seBaseO3DynInst<Impl>::BaseO3DynInst(StaticInstPtr &_staticInst)
6010073Sandreas@sandberg.pp.se    : BaseDynInst<Impl>(_staticInst)
6110073Sandreas@sandberg.pp.se{
6210073Sandreas@sandberg.pp.se    initVars();
6310073Sandreas@sandberg.pp.se}
6410073Sandreas@sandberg.pp.se
6510073Sandreas@sandberg.pp.setemplate <class Impl>
6610073Sandreas@sandberg.pp.sevoid
679881Sandreas@sandberg.pp.seBaseO3DynInst<Impl>::initVars()
689881Sandreas@sandberg.pp.se{
699881Sandreas@sandberg.pp.se    // Make sure to have the renamed register entries set to the same
709881Sandreas@sandberg.pp.se    // as the normal register entries.  It will allow the IQ to work
719881Sandreas@sandberg.pp.se    // without any modifications.
729881Sandreas@sandberg.pp.se    for (int i = 0; i < this->staticInst->numDestRegs(); i++) {
739881Sandreas@sandberg.pp.se        this->_destRegIdx[i] = this->staticInst->destRegIdx(i);
749881Sandreas@sandberg.pp.se    }
759651SAndreas.Sandberg@ARM.com
769651SAndreas.Sandberg@ARM.com    for (int i = 0; i < this->staticInst->numSrcRegs(); i++) {
779651SAndreas.Sandberg@ARM.com        this->_srcRegIdx[i] = this->staticInst->srcRegIdx(i);
789651SAndreas.Sandberg@ARM.com        this->_readySrcRegIdx[i] = 0;
799651SAndreas.Sandberg@ARM.com    }
809651SAndreas.Sandberg@ARM.com}
819651SAndreas.Sandberg@ARM.com
829651SAndreas.Sandberg@ARM.comtemplate <class Impl>
8310073Sandreas@sandberg.pp.seFault
849651SAndreas.Sandberg@ARM.comBaseO3DynInst<Impl>::execute()
8510073Sandreas@sandberg.pp.se{
869651SAndreas.Sandberg@ARM.com    // @todo: Pretty convoluted way to avoid squashing from happening
879734Sandreas@sandberg.pp.se    // when using the TC during an instruction's execution
889734Sandreas@sandberg.pp.se    // (specifically for instructions that have side-effects that use
899734Sandreas@sandberg.pp.se    // the TC).  Fix this.
909734Sandreas@sandberg.pp.se    bool in_syscall = this->thread->inSyscall;
919734Sandreas@sandberg.pp.se    this->thread->inSyscall = true;
929651SAndreas.Sandberg@ARM.com
939651SAndreas.Sandberg@ARM.com    this->fault = this->staticInst->execute(this, this->traceData);
949651SAndreas.Sandberg@ARM.com
959651SAndreas.Sandberg@ARM.com    this->thread->inSyscall = in_syscall;
969651SAndreas.Sandberg@ARM.com
979651SAndreas.Sandberg@ARM.com    return this->fault;
989651SAndreas.Sandberg@ARM.com}
999651SAndreas.Sandberg@ARM.com
1009651SAndreas.Sandberg@ARM.comtemplate <class Impl>
1019651SAndreas.Sandberg@ARM.comFault
1029651SAndreas.Sandberg@ARM.comBaseO3DynInst<Impl>::initiateAcc()
1039651SAndreas.Sandberg@ARM.com{
1049651SAndreas.Sandberg@ARM.com    // @todo: Pretty convoluted way to avoid squashing from happening
1059651SAndreas.Sandberg@ARM.com    // when using the TC during an instruction's execution
1069651SAndreas.Sandberg@ARM.com    // (specifically for instructions that have side-effects that use
1079651SAndreas.Sandberg@ARM.com    // the TC).  Fix this.
1089651SAndreas.Sandberg@ARM.com    bool in_syscall = this->thread->inSyscall;
1099651SAndreas.Sandberg@ARM.com    this->thread->inSyscall = true;
1109881Sandreas@sandberg.pp.se
1119881Sandreas@sandberg.pp.se    this->fault = this->staticInst->initiateAcc(this, this->traceData);
1129651SAndreas.Sandberg@ARM.com
1139651SAndreas.Sandberg@ARM.com    this->thread->inSyscall = in_syscall;
1149651SAndreas.Sandberg@ARM.com
1159651SAndreas.Sandberg@ARM.com    return this->fault;
1169651SAndreas.Sandberg@ARM.com}
1179651SAndreas.Sandberg@ARM.com
1189651SAndreas.Sandberg@ARM.comtemplate <class Impl>
1199651SAndreas.Sandberg@ARM.comFault
1209651SAndreas.Sandberg@ARM.comBaseO3DynInst<Impl>::completeAcc(PacketPtr pkt)
1219651SAndreas.Sandberg@ARM.com{
1229651SAndreas.Sandberg@ARM.com    this->fault = this->staticInst->completeAcc(pkt, this, this->traceData);
1239651SAndreas.Sandberg@ARM.com
1249651SAndreas.Sandberg@ARM.com    return this->fault;
1259651SAndreas.Sandberg@ARM.com}
1269651SAndreas.Sandberg@ARM.com
1279651SAndreas.Sandberg@ARM.com#if FULL_SYSTEM
1289651SAndreas.Sandberg@ARM.comtemplate <class Impl>
1299651SAndreas.Sandberg@ARM.comFault
1309651SAndreas.Sandberg@ARM.comBaseO3DynInst<Impl>::hwrei()
1319651SAndreas.Sandberg@ARM.com{
1329651SAndreas.Sandberg@ARM.com#if THE_ISA == ALPHA_ISA
1339651SAndreas.Sandberg@ARM.com    // Can only do a hwrei when in pal mode.
1349651SAndreas.Sandberg@ARM.com    if (!(this->readPC() & 0x3))
1359651SAndreas.Sandberg@ARM.com        return new AlphaISA::UnimplementedOpcodeFault;
1369651SAndreas.Sandberg@ARM.com
1379651SAndreas.Sandberg@ARM.com    // Set the next PC based on the value of the EXC_ADDR IPR.
1389651SAndreas.Sandberg@ARM.com    this->setNextPC(this->cpu->readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR,
1399881Sandreas@sandberg.pp.se                                           this->threadNumber));
1409881Sandreas@sandberg.pp.se    if (CPA::available()) {
1419881Sandreas@sandberg.pp.se        ThreadContext *tc = this->cpu->tcBase(this->threadNumber);
1429881Sandreas@sandberg.pp.se        CPA::cpa()->swAutoBegin(tc, this->readNextPC());
1439881Sandreas@sandberg.pp.se    }
1449881Sandreas@sandberg.pp.se
1459881Sandreas@sandberg.pp.se    // Tell CPU to clear any state it needs to if a hwrei is taken.
1469881Sandreas@sandberg.pp.se    this->cpu->hwrei(this->threadNumber);
1479881Sandreas@sandberg.pp.se#else
1489881Sandreas@sandberg.pp.se
1499881Sandreas@sandberg.pp.se#endif
1509881Sandreas@sandberg.pp.se    // FIXME: XXX check for interrupts? XXX
1519881Sandreas@sandberg.pp.se    return NoFault;
1529881Sandreas@sandberg.pp.se}
1539881Sandreas@sandberg.pp.se
1549651SAndreas.Sandberg@ARM.comtemplate <class Impl>
1559881Sandreas@sandberg.pp.sevoid
1569651SAndreas.Sandberg@ARM.comBaseO3DynInst<Impl>::trap(Fault fault)
1579655SAndreas.Sandberg@ARM.com{
1589655SAndreas.Sandberg@ARM.com    this->cpu->trap(fault, this->threadNumber);
1599655SAndreas.Sandberg@ARM.com}
1609655SAndreas.Sandberg@ARM.com
1619655SAndreas.Sandberg@ARM.comtemplate <class Impl>
1629655SAndreas.Sandberg@ARM.combool
1639655SAndreas.Sandberg@ARM.comBaseO3DynInst<Impl>::simPalCheck(int palFunc)
1649655SAndreas.Sandberg@ARM.com{
1659655SAndreas.Sandberg@ARM.com#if THE_ISA != ALPHA_ISA
1669655SAndreas.Sandberg@ARM.com    panic("simPalCheck called, but PAL only exists in Alpha!\n");
1679655SAndreas.Sandberg@ARM.com#endif
1689655SAndreas.Sandberg@ARM.com    return this->cpu->simPalCheck(palFunc, this->threadNumber);
1699655SAndreas.Sandberg@ARM.com}
1709655SAndreas.Sandberg@ARM.com#else
1719655SAndreas.Sandberg@ARM.comtemplate <class Impl>
1729655SAndreas.Sandberg@ARM.comvoid
1739655SAndreas.Sandberg@ARM.comBaseO3DynInst<Impl>::syscall(int64_t callnum)
1749655SAndreas.Sandberg@ARM.com{
1759655SAndreas.Sandberg@ARM.com    // HACK: check CPU's nextPC before and after syscall. If it
1769655SAndreas.Sandberg@ARM.com    // changes, update this instruction's nextPC because the syscall
1779655SAndreas.Sandberg@ARM.com    // must have changed the nextPC.
1789655SAndreas.Sandberg@ARM.com    Addr cpu_next_pc = this->cpu->readNextPC(this->threadNumber);
1799655SAndreas.Sandberg@ARM.com    this->cpu->syscall(callnum, this->threadNumber);
1809655SAndreas.Sandberg@ARM.com    Addr new_next_pc = this->cpu->readNextPC(this->threadNumber);
1819655SAndreas.Sandberg@ARM.com    if (cpu_next_pc != new_next_pc) {
1829655SAndreas.Sandberg@ARM.com        this->setNextPC(new_next_pc);
1839655SAndreas.Sandberg@ARM.com    }
1849655SAndreas.Sandberg@ARM.com}
1859655SAndreas.Sandberg@ARM.com#endif
1869655SAndreas.Sandberg@ARM.com
1879881Sandreas@sandberg.pp.se