diff options
Diffstat (limited to 'src/arch/alpha')
-rw-r--r-- | src/arch/alpha/ev5.cc | 11 | ||||
-rw-r--r-- | src/arch/alpha/faults.cc | 10 | ||||
-rw-r--r-- | src/arch/alpha/interrupts.hh | 2 | ||||
-rw-r--r-- | src/arch/alpha/isa/branch.isa | 40 | ||||
-rw-r--r-- | src/arch/alpha/isa/decoder.isa | 14 | ||||
-rw-r--r-- | src/arch/alpha/isa/main.isa | 9 | ||||
-rw-r--r-- | src/arch/alpha/predecoder.hh | 6 | ||||
-rw-r--r-- | src/arch/alpha/process.cc | 10 | ||||
-rw-r--r-- | src/arch/alpha/remote_gdb.cc | 20 | ||||
-rw-r--r-- | src/arch/alpha/stacktrace.cc | 4 | ||||
-rw-r--r-- | src/arch/alpha/tlb.cc | 4 | ||||
-rw-r--r-- | src/arch/alpha/types.hh | 3 | ||||
-rw-r--r-- | src/arch/alpha/utility.cc | 9 | ||||
-rw-r--r-- | src/arch/alpha/utility.hh | 16 |
14 files changed, 93 insertions, 65 deletions
diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index 0db75df46..f97244260 100644 --- a/src/arch/alpha/ev5.cc +++ b/src/arch/alpha/ev5.cc @@ -60,8 +60,7 @@ initCPU(ThreadContext *tc, int cpuId) AlphaFault *reset = new ResetFault; - tc->setPC(tc->readMiscRegNoEffect(IPR_PAL_BASE) + reset->vect()); - tc->setNextPC(tc->readPC() + sizeof(MachInst)); + tc->pcState(tc->readMiscRegNoEffect(IPR_PAL_BASE) + reset->vect()); delete reset; } @@ -494,12 +493,14 @@ using namespace AlphaISA; Fault SimpleThread::hwrei() { - if (!(readPC() & 0x3)) + PCState pc = pcState(); + if (!(pc.pc() & 0x3)) return new UnimplementedOpcodeFault; - setNextPC(readMiscRegNoEffect(IPR_EXC_ADDR)); + pc.npc(readMiscRegNoEffect(IPR_EXC_ADDR)); + pcState(pc); - CPA::cpa()->swAutoBegin(tc, readNextPC()); + CPA::cpa()->swAutoBegin(tc, pc.npc()); if (!misspeculating()) { if (kernelStats) diff --git a/src/arch/alpha/faults.cc b/src/arch/alpha/faults.cc index 9d4eeda8a..38386cce1 100644 --- a/src/arch/alpha/faults.cc +++ b/src/arch/alpha/faults.cc @@ -115,9 +115,11 @@ AlphaFault::invoke(ThreadContext *tc, StaticInstPtr inst) FaultBase::invoke(tc); countStat()++; + PCState pc = tc->pcState(); + // exception restart address - if (setRestartAddress() || !(tc->readPC() & 0x3)) - tc->setMiscRegNoEffect(IPR_EXC_ADDR, tc->readPC()); + if (setRestartAddress() || !(pc.pc() & 0x3)) + tc->setMiscRegNoEffect(IPR_EXC_ADDR, pc.pc()); if (skipFaultingInstruction()) { // traps... skip faulting instruction. @@ -125,8 +127,8 @@ AlphaFault::invoke(ThreadContext *tc, StaticInstPtr inst) tc->readMiscRegNoEffect(IPR_EXC_ADDR) + 4); } - tc->setPC(tc->readMiscRegNoEffect(IPR_PAL_BASE) + vect()); - tc->setNextPC(tc->readPC() + sizeof(MachInst)); + pc.set(tc->readMiscRegNoEffect(IPR_PAL_BASE) + vect()); + tc->pcState(pc); } void diff --git a/src/arch/alpha/interrupts.hh b/src/arch/alpha/interrupts.hh index 3200201db..cbaa8e9bf 100644 --- a/src/arch/alpha/interrupts.hh +++ b/src/arch/alpha/interrupts.hh @@ -133,7 +133,7 @@ class Interrupts : public SimObject bool checkInterrupts(ThreadContext *tc) const { - return (intstatus != 0) && !(tc->readPC() & 0x3); + return (intstatus != 0) && !(tc->pcState().pc() & 0x3); } Fault diff --git a/src/arch/alpha/isa/branch.isa b/src/arch/alpha/isa/branch.isa index 974193efd..feb15b158 100644 --- a/src/arch/alpha/isa/branch.isa +++ b/src/arch/alpha/isa/branch.isa @@ -81,7 +81,7 @@ output header {{ { } - Addr branchTarget(Addr branchPC) const; + AlphaISA::PCState branchTarget(const AlphaISA::PCState &branchPC) const; std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; @@ -106,7 +106,7 @@ output header {{ { } - Addr branchTarget(ThreadContext *tc) const; + AlphaISA::PCState branchTarget(ThreadContext *tc) const; std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; @@ -114,18 +114,19 @@ output header {{ }}; output decoder {{ - Addr - Branch::branchTarget(Addr branchPC) const + AlphaISA::PCState + Branch::branchTarget(const AlphaISA::PCState &branchPC) const { - return branchPC + 4 + disp; + return branchPC.pc() + 4 + disp; } - Addr + AlphaISA::PCState Jump::branchTarget(ThreadContext *tc) const { - Addr NPC = tc->readPC() + 4; + PCState pc = tc->pcState(); uint64_t Rb = tc->readIntReg(_srcRegIdx[0]); - return (Rb & ~3) | (NPC & 1); + pc.set((Rb & ~3) | (pc.pc() & 1)); + return pc; } const std::string & @@ -217,7 +218,14 @@ def template JumpOrBranchDecode {{ }}; def format CondBranch(code) {{ - code = 'bool cond;\n' + code + '\nif (cond) NPC = NPC + disp;\n'; + code = ''' + bool cond; + %(code)s; + PCState pc = PCS; + if (cond) + pc.npc(pc.npc() + disp); + PCS = pc; + ''' % { "code" : code } iop = InstObjParams(name, Name, 'Branch', code, ('IsDirectControl', 'IsCondControl')) header_output = BasicDeclare.subst(iop) @@ -229,16 +237,18 @@ def format CondBranch(code) {{ let {{ def UncondCtrlBase(name, Name, base_class, npc_expr, flags): # Declare basic control transfer w/o link (i.e. link reg is R31) - nolink_code = 'NPC = %s;\n' % npc_expr - nolink_iop = InstObjParams(name, Name, base_class, nolink_code, flags) + readpc_code = 'PCState pc = PCS;' + nolink_code = 'pc.npc(%s);\nPCS = pc' % npc_expr + nolink_iop = InstObjParams(name, Name, base_class, + readpc_code + nolink_code, flags) header_output = BasicDeclare.subst(nolink_iop) decoder_output = BasicConstructor.subst(nolink_iop) exec_output = BasicExecute.subst(nolink_iop) # Generate declaration of '*AndLink' version, append to decls - link_code = 'Ra = NPC & ~3;\n' + nolink_code + link_code = 'Ra = pc.npc() & ~3;\n' + nolink_code link_iop = InstObjParams(name, Name + 'AndLink', base_class, - link_code, flags) + readpc_code + link_code, flags) header_output += BasicDeclare.subst(link_iop) decoder_output += BasicConstructor.subst(link_iop) exec_output += BasicExecute.subst(link_iop) @@ -253,13 +263,13 @@ def UncondCtrlBase(name, Name, base_class, npc_expr, flags): def format UncondBranch(*flags) {{ flags += ('IsUncondControl', 'IsDirectControl') (header_output, decoder_output, decode_block, exec_output) = \ - UncondCtrlBase(name, Name, 'Branch', 'NPC + disp', flags) + UncondCtrlBase(name, Name, 'Branch', 'pc.npc() + disp', flags) }}; def format Jump(*flags) {{ flags += ('IsUncondControl', 'IsIndirectControl') (header_output, decoder_output, decode_block, exec_output) = \ - UncondCtrlBase(name, Name, 'Jump', '(Rb & ~3) | (NPC & 1)', flags) + UncondCtrlBase(name, Name, 'Jump', '(Rb & ~3) | (pc.npc() & 1)', flags) }}; diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index fe70e4d16..e2947cf4a 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -856,15 +856,16 @@ decode OPCODE default Unknown::unknown() { // invalid pal function code, or attempt to do privileged // PAL call in non-kernel mode fault = new UnimplementedOpcodeFault; - } - else { + } else { // check to see if simulator wants to do something special // on this PAL call (including maybe suppress it) bool dopal = xc->simPalCheck(palFunc); if (dopal) { - xc->setMiscReg(IPR_EXC_ADDR, NPC); - NPC = xc->readMiscReg(IPR_PAL_BASE) + palOffset; + PCState pc = PCS; + xc->setMiscReg(IPR_EXC_ADDR, pc.npc()); + pc.npc(xc->readMiscReg(IPR_PAL_BASE) + palOffset); + PCS = pc; } } }}, IsNonSpeculative); @@ -1030,13 +1031,14 @@ decode OPCODE default Unknown::unknown() { }}, IsNonSpeculative); #endif 0x54: m5panic({{ - panic("M5 panic instruction called at pc=%#x.", xc->readPC()); + panic("M5 panic instruction called at pc=%#x.", + xc->pcState().pc()); }}, IsNonSpeculative); #define CPANN(lbl) CPA::cpa()->lbl(xc->tcBase()) 0x55: decode RA { 0x00: m5a_old({{ panic("Deprecated M5 annotate instruction executed at pc=%#x\n", - xc->readPC()); + xc->pcState().pc()); }}, IsNonSpeculative); 0x01: m5a_bsm({{ CPANN(swSmBegin); diff --git a/src/arch/alpha/isa/main.isa b/src/arch/alpha/isa/main.isa index 2a0699354..ffc267cd2 100644 --- a/src/arch/alpha/isa/main.isa +++ b/src/arch/alpha/isa/main.isa @@ -46,6 +46,7 @@ output header {{ #include <iomanip> #include "arch/alpha/faults.hh" +#include "arch/alpha/types.hh" #include "config/ss_compatible_fp.hh" #include "cpu/static_inst.hh" #include "mem/request.hh" // some constructors use MemReq flags @@ -185,7 +186,7 @@ def operands {{ 'Fb': ('FloatReg', 'df', 'FB', 'IsFloating', 2), 'Fc': ('FloatReg', 'df', 'FC', 'IsFloating', 3), 'Mem': ('Mem', 'uq', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4), - 'NPC': ('NPC', 'uq', None, ( None, None, 'IsControl' ), 4), + 'PCS': ('PCState', 'uq', None, ( None, None, 'IsControl' ), 4), 'Runiq': ('ControlReg', 'uq', 'MISCREG_UNIQ', None, 1), 'FPCR': ('ControlReg', 'uq', 'MISCREG_FPCR', None, 1), 'IntrFlag': ('ControlReg', 'uq', 'MISCREG_INTR', None, 1), @@ -233,6 +234,12 @@ output header {{ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + + void + advancePC(AlphaISA::PCState &pcState) const + { + pcState.advance(); + } }; }}; diff --git a/src/arch/alpha/predecoder.hh b/src/arch/alpha/predecoder.hh index 913bd8764..f9a716b7f 100644 --- a/src/arch/alpha/predecoder.hh +++ b/src/arch/alpha/predecoder.hh @@ -76,11 +76,11 @@ class Predecoder // Use this to give data to the predecoder. This should be used // when there is control flow. void - moreBytes(Addr pc, Addr fetchPC, MachInst inst) + moreBytes(const PCState &pc, Addr fetchPC, MachInst inst) { ext_inst = inst; #if FULL_SYSTEM - ext_inst |= (static_cast<ExtMachInst>(pc & 0x1) << 32); + ext_inst |= (static_cast<ExtMachInst>(pc.pc() & 0x1) << 32); #endif } @@ -98,7 +98,7 @@ class Predecoder // This returns a constant reference to the ExtMachInst to avoid a copy const ExtMachInst & - getExtMachInst() + getExtMachInst(PCState &pc) { return ext_inst; } diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc index f68a53a6f..3c3fd9b25 100644 --- a/src/arch/alpha/process.cc +++ b/src/arch/alpha/process.cc @@ -162,15 +162,7 @@ AlphaLiveProcess::argsInit(int intSize, int pageSize) setSyscallArg(tc, 1, argv_array_base); tc->setIntReg(StackPointerReg, stack_min); - Addr prog_entry = objFile->entryPoint(); - tc->setPC(prog_entry); - tc->setNextPC(prog_entry + sizeof(MachInst)); - - // MIPS/Sparc need NNPC for delay slot handling, while - // Alpha has no delay slots... However, CPU models - // cycle PCs by PC=NPC, NPC=NNPC, etc. so setting this - // here ensures CPU-Model Compatibility across board - tc->setNextNPC(prog_entry + (2 * sizeof(MachInst))); + tc->pcState(objFile->entryPoint()); } void diff --git a/src/arch/alpha/remote_gdb.cc b/src/arch/alpha/remote_gdb.cc index 5391d2056..9a2a5f23f 100644 --- a/src/arch/alpha/remote_gdb.cc +++ b/src/arch/alpha/remote_gdb.cc @@ -211,7 +211,7 @@ RemoteGDB::getregs() { memset(gdbregs.regs, 0, gdbregs.bytes()); - gdbregs.regs[KGDB_REG_PC] = context->readPC(); + gdbregs.regs[KGDB_REG_PC] = context->pcState().pc(); // @todo: Currently this is very Alpha specific. if (PcPAL(gdbregs.regs[KGDB_REG_PC])) { @@ -254,7 +254,7 @@ RemoteGDB::setregs() context->setFloatRegBits(i, gdbregs.regs[i + KGDB_REG_F0]); } #endif - context->setPC(gdbregs.regs[KGDB_REG_PC]); + context->pcState(gdbregs.regs[KGDB_REG_PC]); } void @@ -273,30 +273,28 @@ RemoteGDB::clearSingleStep() void RemoteGDB::setSingleStep() { - Addr pc = context->readPC(); - Addr npc, bpc; + PCState pc = context->pcState(); + PCState bpc; bool set_bt = false; - npc = pc + sizeof(MachInst); - // User was stopped at pc, e.g. the instruction at pc was not // executed. - MachInst inst = read<MachInst>(pc); - StaticInstPtr si(inst, pc); + MachInst inst = read<MachInst>(pc.pc()); + StaticInstPtr si(inst, pc.pc()); if (si->hasBranchTarget(pc, context, bpc)) { // Don't bother setting a breakpoint on the taken branch if it // is the same as the next pc - if (bpc != npc) + if (bpc.pc() != pc.npc()) set_bt = true; } DPRINTF(GDBMisc, "setSingleStep bt_addr=%#x nt_addr=%#x\n", takenBkpt, notTakenBkpt); - setTempBreakpoint(notTakenBkpt = npc); + setTempBreakpoint(notTakenBkpt = pc.npc()); if (set_bt) - setTempBreakpoint(takenBkpt = bpc); + setTempBreakpoint(takenBkpt = bpc.pc()); } // Write bytes to kernel address space for debugger. diff --git a/src/arch/alpha/stacktrace.cc b/src/arch/alpha/stacktrace.cc index 1b5a9be34..9c6b3cff0 100644 --- a/src/arch/alpha/stacktrace.cc +++ b/src/arch/alpha/stacktrace.cc @@ -145,7 +145,7 @@ StackTrace::trace(ThreadContext *_tc, bool is_call) bool usermode = (tc->readMiscRegNoEffect(IPR_DTB_CM) & 0x18) != 0; - Addr pc = tc->readNextPC(); + Addr pc = tc->pcState().pc(); bool kernel = sys->kernelStart <= pc && pc <= sys->kernelEnd; if (usermode) { @@ -168,7 +168,7 @@ StackTrace::trace(ThreadContext *_tc, bool is_call) panic("could not find address %#x", pc); stack.push_back(addr); - pc = tc->readPC(); + pc = tc->pcState().pc(); } while (ksp > bottom) { diff --git a/src/arch/alpha/tlb.cc b/src/arch/alpha/tlb.cc index b578741d9..614061ddd 100644 --- a/src/arch/alpha/tlb.cc +++ b/src/arch/alpha/tlb.cc @@ -443,8 +443,6 @@ TLB::translateInst(RequestPtr req, ThreadContext *tc) Fault TLB::translateData(RequestPtr req, ThreadContext *tc, bool write) { - Addr pc = tc->readPC(); - mode_type mode = (mode_type)DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM)); @@ -458,7 +456,7 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write) return new DtbAlignmentFault(req->getVaddr(), req->getFlags(), flags); } - if (PcPAL(pc)) { + if (PcPAL(tc->pcState().pc())) { mode = (req->getFlags() & Request::ALTMODE) ? (mode_type)ALT_MODE_AM( tc->readMiscRegNoEffect(IPR_ALT_MODE)) diff --git a/src/arch/alpha/types.hh b/src/arch/alpha/types.hh index 0d285c3b2..06c0168cf 100644 --- a/src/arch/alpha/types.hh +++ b/src/arch/alpha/types.hh @@ -33,12 +33,15 @@ #define __ARCH_ALPHA_TYPES_HH__ #include "base/types.hh" +#include "arch/generic/types.hh" namespace AlphaISA { typedef uint32_t MachInst; typedef uint64_t ExtMachInst; +typedef GenericISA::SimplePCState<MachInst> PCState; + typedef uint64_t LargestRead; enum annotes diff --git a/src/arch/alpha/utility.cc b/src/arch/alpha/utility.cc index 11560259f..2d56ca9b8 100644 --- a/src/arch/alpha/utility.cc +++ b/src/arch/alpha/utility.cc @@ -77,8 +77,7 @@ copyRegs(ThreadContext *src, ThreadContext *dest) copyMiscRegs(src, dest); // Lastly copy PC/NPC - dest->setPC(src->readPC()); - dest->setNextPC(src->readNextPC()); + dest->pcState(src->pcState()); } void @@ -99,9 +98,9 @@ copyMiscRegs(ThreadContext *src, ThreadContext *dest) void skipFunction(ThreadContext *tc) { - Addr newpc = tc->readIntReg(ReturnAddressReg); - tc->setPC(newpc); - tc->setNextPC(tc->readPC() + sizeof(TheISA::MachInst)); + TheISA::PCState newPC = tc->pcState(); + newPC.set(tc->readIntReg(ReturnAddressReg)); + tc->pcState(newPC); } diff --git a/src/arch/alpha/utility.hh b/src/arch/alpha/utility.hh index 6d5b8baf6..fdac8b8d1 100644 --- a/src/arch/alpha/utility.hh +++ b/src/arch/alpha/utility.hh @@ -37,10 +37,19 @@ #include "arch/alpha/registers.hh" #include "base/misc.hh" #include "config/full_system.hh" +#include "cpu/static_inst.hh" #include "cpu/thread_context.hh" namespace AlphaISA { +inline PCState +buildRetPC(const PCState &curPC, const PCState &callPC) +{ + PCState retPC = callPC; + retPC.advance(); + return retPC; +} + uint64_t getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp); inline bool @@ -95,6 +104,13 @@ void copyRegs(ThreadContext *src, ThreadContext *dest); void copyMiscRegs(ThreadContext *src, ThreadContext *dest); void skipFunction(ThreadContext *tc); + +inline void +advancePC(PCState &pc, const StaticInstPtr inst) +{ + pc.advance(); +} + } // namespace AlphaISA #endif // __ARCH_ALPHA_UTILITY_HH__ |