summaryrefslogtreecommitdiff
path: root/src/arch/alpha
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/alpha')
-rw-r--r--src/arch/alpha/ev5.cc11
-rw-r--r--src/arch/alpha/faults.cc10
-rw-r--r--src/arch/alpha/interrupts.hh2
-rw-r--r--src/arch/alpha/isa/branch.isa40
-rw-r--r--src/arch/alpha/isa/decoder.isa14
-rw-r--r--src/arch/alpha/isa/main.isa9
-rw-r--r--src/arch/alpha/predecoder.hh6
-rw-r--r--src/arch/alpha/process.cc10
-rw-r--r--src/arch/alpha/remote_gdb.cc20
-rw-r--r--src/arch/alpha/stacktrace.cc4
-rw-r--r--src/arch/alpha/tlb.cc4
-rw-r--r--src/arch/alpha/types.hh3
-rw-r--r--src/arch/alpha/utility.cc9
-rw-r--r--src/arch/alpha/utility.hh16
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__