diff options
Diffstat (limited to 'src/arch/mips')
-rw-r--r-- | src/arch/mips/isa/base.isa | 7 | ||||
-rw-r--r-- | src/arch/mips/isa/decoder.isa | 44 | ||||
-rw-r--r-- | src/arch/mips/isa/formats/branch.isa | 90 | ||||
-rw-r--r-- | src/arch/mips/isa/includes.isa | 1 | ||||
-rw-r--r-- | src/arch/mips/isa/operands.isa | 3 | ||||
-rwxr-xr-x | src/arch/mips/mt.hh | 14 | ||||
-rw-r--r-- | src/arch/mips/predecoder.hh | 4 | ||||
-rw-r--r-- | src/arch/mips/process.cc | 5 | ||||
-rw-r--r-- | src/arch/mips/types.hh | 3 | ||||
-rw-r--r-- | src/arch/mips/utility.cc | 7 | ||||
-rw-r--r-- | src/arch/mips/utility.hh | 16 |
11 files changed, 123 insertions, 71 deletions
diff --git a/src/arch/mips/isa/base.isa b/src/arch/mips/isa/base.isa index 4e2b12fc4..cd6faf0f3 100644 --- a/src/arch/mips/isa/base.isa +++ b/src/arch/mips/isa/base.isa @@ -56,6 +56,13 @@ output header {{ void printReg(std::ostream &os, int reg) const; std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + + public: + void + advancePC(MipsISA::PCState &pc) const + { + pc.advance(); + } }; }}; diff --git a/src/arch/mips/isa/decoder.isa b/src/arch/mips/isa/decoder.isa index 9832937b5..3f3bd370a 100644 --- a/src/arch/mips/isa/decoder.isa +++ b/src/arch/mips/isa/decoder.isa @@ -133,25 +133,34 @@ decode OPCODE_HI default Unknown::unknown() { 0x1: jr_hb({{ Config1Reg config1 = Config1; if (config1.ca == 0) { - NNPC = Rs; + pc.nnpc(Rs); } else { panic("MIPS16e not supported\n"); } + PCS = pc; }}, IsReturn, ClearHazards); default: jr({{ Config1Reg config1 = Config1; if (config1.ca == 0) { - NNPC = Rs; + pc.nnpc(Rs); } else { panic("MIPS16e not supported\n"); } + PCS = pc; }}, IsReturn); } 0x1: decode HINT { - 0x1: jalr_hb({{ Rd = NNPC; NNPC = Rs; }}, IsCall - , ClearHazards); - default: jalr({{ Rd = NNPC; NNPC = Rs; }}, IsCall); + 0x1: jalr_hb({{ + Rd = pc.nnpc(); + pc.nnpc(Rs); + PCS = pc; + }}, IsCall, ClearHazards); + default: jalr({{ + Rd = pc.nnpc(); + pc.nnpc(Rs); + PCS = pc; + }}, IsCall); } } @@ -323,9 +332,14 @@ decode OPCODE_HI default Unknown::unknown() { } format Jump { - 0x2: j({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2); }}); - 0x3: jal({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2); }}, - IsCall, Link); + 0x2: j({{ + pc.nnpc((pc.npc() & 0xF0000000) | (JMPTARG << 2)); + PCS = pc; + }}); + 0x3: jal({{ + pc.nnpc((pc.npc() & 0xF0000000) | (JMPTARG << 2)); + PCS = pc; + }}, IsCall, Link); } format Branch { @@ -694,15 +708,16 @@ decode OPCODE_HI default Unknown::unknown() { ConfigReg config = Config; SRSCtlReg srsCtl = SRSCtl; DPRINTF(MipsPRA,"Restoring PC - %x\n",EPC); + MipsISA::PCState pc = PCS; if (status.erl == 1) { status.erl = 0; - NPC = ErrorEPC; + pc.npc(ErrorEPC); // Need to adjust NNPC, otherwise things break - NNPC = ErrorEPC + sizeof(MachInst); + pc.nnpc(ErrorEPC + sizeof(MachInst)); } else { - NPC = EPC; + pc.npc(EPC); // Need to adjust NNPC, otherwise things break - NNPC = EPC + sizeof(MachInst); + pc.nnpc(EPC + sizeof(MachInst)); status.exl = 0; if (config.ar >=1 && srsCtl.hss > 0 && @@ -711,6 +726,7 @@ decode OPCODE_HI default Unknown::unknown() { //xc->setShadowSet(srsCtl.pss); } } + PCS = pc; LLFlag = 0; Status = status; SRSCtl = srsCtl; @@ -718,13 +734,15 @@ decode OPCODE_HI default Unknown::unknown() { 0x1F: deret({{ DebugReg debug = Debug; + MipsISA::PCState pc = PCS; if (debug.dm == 1) { debug.dm = 1; debug.iexi = 0; - NPC = DEPC; + pc.npc(DEPC); } else { // Undefined; } + PCS = pc; Debug = debug; }}, IsReturn, IsSerializing, IsERET); } diff --git a/src/arch/mips/isa/formats/branch.isa b/src/arch/mips/isa/formats/branch.isa index 78f973a70..232a743a7 100644 --- a/src/arch/mips/isa/formats/branch.isa +++ b/src/arch/mips/isa/formats/branch.isa @@ -89,7 +89,7 @@ output header {{ } } - Addr branchTarget(Addr branchPC) const; + MipsISA::PCState branchTarget(const MipsISA::PCState &branchPC) const; std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; @@ -116,7 +116,7 @@ output header {{ { } - Addr branchTarget(ThreadContext *tc) const; + MipsISA::PCState branchTarget(ThreadContext *tc) const; std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; @@ -124,17 +124,25 @@ output header {{ }}; output decoder {{ - Addr - Branch::branchTarget(Addr branchPC) const + MipsISA::PCState + Branch::branchTarget(const MipsISA::PCState &branchPC) const { - return branchPC + 4 + disp; + MipsISA::PCState target = branchPC; + target.advance(); + target.npc(branchPC.pc() + sizeof(MachInst) + disp); + target.nnpc(target.npc() + sizeof(MachInst)); + return target; } - Addr + MipsISA::PCState Jump::branchTarget(ThreadContext *tc) const { - Addr NPC = tc->readNextPC(); - return (NPC & 0xF0000000) | (disp); + MipsISA::PCState target = tc->pcState(); + Addr pc = target.pc(); + target.advance(); + target.npc((pc & 0xF0000000) | disp); + target.nnpc(target.npc() + sizeof(MachInst)); + return target; } const std::string & @@ -217,19 +225,16 @@ output decoder {{ }}; def format Branch(code, *opt_flags) {{ - not_taken_code = ' NNPC = NNPC;\n' - not_taken_code += '} \n' + not_taken_code = '' #Build Instruction Flags #Use Link & Likely Flags to Add Link/Condition Code inst_flags = ('IsDirectControl', ) for x in opt_flags: if x == 'Link': - code += 'R31 = NNPC;\n' + code += 'R31 = pc.nnpc();\n' elif x == 'Likely': - not_taken_code = ' NPC = NNPC;\n' - not_taken_code += ' NNPC = NNPC + 4;\n' - not_taken_code += '} \n' + not_taken_code = 'pc.advance();' inst_flags += ('IsCondDelaySlot', ) else: inst_flags += (x, ) @@ -241,11 +246,17 @@ def format Branch(code, *opt_flags) {{ inst_flags += ('IsCondControl', ) #Condition code - code = 'bool cond;\n' + code - code += 'if (cond) {\n' - code += ' NNPC = NPC + disp;\n' - code += '} else {\n' - code += not_taken_code + code = ''' + bool cond; + MipsISA::PCState pc = PCS; + %(code)s + if (cond) { + pc.nnpc(pc.npc() + disp); + } else { + %(not_taken_code)s + } + PCS = pc; + ''' % { "code" : code, "not_taken_code" : not_taken_code } iop = InstObjParams(name, Name, 'Branch', code, inst_flags) header_output = BasicDeclare.subst(iop) @@ -255,19 +266,16 @@ def format Branch(code, *opt_flags) {{ }}; def format DspBranch(code, *opt_flags) {{ - not_taken_code = ' NNPC = NNPC;\n' - not_taken_code += '} \n' + not_taken_code = '' #Build Instruction Flags #Use Link & Likely Flags to Add Link/Condition Code inst_flags = ('IsDirectControl', ) for x in opt_flags: if x == 'Link': - code += 'R31 = NNPC;\n' + code += 'R32 = pc.nnpc();' elif x == 'Likely': - not_taken_code = ' NPC = NNPC;\n' - not_taken_code += ' NNPC = NNPC + 4;\n' - not_taken_code += '} \n' + not_taken_code = 'pc.advance();' inst_flags += ('IsCondDelaySlot', ) else: inst_flags += (x, ) @@ -278,19 +286,19 @@ def format DspBranch(code, *opt_flags) {{ else: inst_flags += ('IsCondControl', ) - #Declaration code - decl_code = 'bool cond;\n' - decl_code += 'uint32_t dspctl;\n' - - #Fetch code - fetch_code = 'dspctl = DSPControl;\n' - #Condition code - code = decl_code + fetch_code + code - code += 'if (cond) {\n' - code += ' NNPC = NPC + disp;\n' - code += '} else {\n' - code += not_taken_code + code = ''' + MipsISA::PCState pc = PCS; + bool cond; + uint32_t dspctl = DSPControl; + %(code)s + if (cond) { + pc.nnpc(pc.npc() + disp); + } else { + %(not_taken_code)s + } + PCS = pc; + ''' % { "code" : code, "not_taken_code" : not_taken_code } iop = InstObjParams(name, Name, 'Branch', code, inst_flags) header_output = BasicDeclare.subst(iop) @@ -305,12 +313,18 @@ def format Jump(code, *opt_flags) {{ inst_flags = ('IsIndirectControl', 'IsUncondControl') for x in opt_flags: if x == 'Link': - code = 'R31 = NNPC;\n' + code + code = ''' + R31 = pc.nnpc(); + ''' + code elif x == 'ClearHazards': code += '/* Code Needed to Clear Execute & Inst Hazards */\n' else: inst_flags += (x, ) + code = ''' + MipsISA::PCState pc = PCS; + ''' + code + iop = InstObjParams(name, Name, 'Jump', code, inst_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) diff --git a/src/arch/mips/isa/includes.isa b/src/arch/mips/isa/includes.isa index 22eb3bf13..d5e1448ac 100644 --- a/src/arch/mips/isa/includes.isa +++ b/src/arch/mips/isa/includes.isa @@ -39,6 +39,7 @@ output header {{ #include <iomanip> #include "arch/mips/isa_traits.hh" +#include "arch/mips/types.hh" #include "cpu/static_inst.hh" #include "mem/packet.hh" }}; diff --git a/src/arch/mips/isa/operands.isa b/src/arch/mips/isa/operands.isa index 27cb4357a..1bb5ae5b3 100644 --- a/src/arch/mips/isa/operands.isa +++ b/src/arch/mips/isa/operands.isa @@ -151,6 +151,5 @@ def operands {{ 'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4), #Program Counter Operands - 'NPC': ('NPC', 'uw', None, 'IsControl', 4), - 'NNPC':('NNPC', 'uw', None, 'IsControl', 4) + 'PCS': ('PCState', 'uw', None, (None, None, 'IsControl'), 4) }}; diff --git a/src/arch/mips/mt.hh b/src/arch/mips/mt.hh index 7217c335e..3ec6cbe70 100755 --- a/src/arch/mips/mt.hh +++ b/src/arch/mips/mt.hh @@ -77,11 +77,12 @@ haltThread(TC *tc) // Save last known PC in TCRestart // @TODO: Needs to check if this is a branch and if so, // take previous instruction - tc->setMiscReg(MISCREG_TC_RESTART, tc->readNextPC()); + PCState pc = tc->pcState(); + tc->setMiscReg(MISCREG_TC_RESTART, pc.npc()); warn("%i: Halting thread %i in %s @ PC %x, setting restart PC to %x", curTick, tc->threadId(), tc->getCpuPtr()->name(), - tc->readPC(), tc->readNextPC()); + pc.pc(), pc.npc()); } } @@ -91,17 +92,14 @@ restoreThread(TC *tc) { if (tc->status() != TC::Active) { // Restore PC from TCRestart - IntReg pc = tc->readMiscRegNoEffect(MISCREG_TC_RESTART); + Addr restartPC = tc->readMiscRegNoEffect(MISCREG_TC_RESTART); // TODO: SET PC WITH AN EVENT INSTEAD OF INSTANTANEOUSLY - tc->setPC(pc); - tc->setNextPC(pc + 4); - tc->setNextNPC(pc + 8); + tc->pcState(restartPC); tc->activate(0); warn("%i: Restoring thread %i in %s @ PC %x", - curTick, tc->threadId(), tc->getCpuPtr()->name(), - tc->readPC()); + curTick, tc->threadId(), tc->getCpuPtr()->name(), restartPC); } } diff --git a/src/arch/mips/predecoder.hh b/src/arch/mips/predecoder.hh index c20fe1f5f..f059710e5 100644 --- a/src/arch/mips/predecoder.hh +++ b/src/arch/mips/predecoder.hh @@ -75,7 +75,7 @@ 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) { emi = inst; } @@ -94,7 +94,7 @@ class Predecoder //This returns a constant reference to the ExtMachInst to avoid a copy const ExtMachInst & - getExtMachInst() + getExtMachInst(PCState &pc) { return emi; } diff --git a/src/arch/mips/process.cc b/src/arch/mips/process.cc index fa3e3bff9..26a2a0ddb 100644 --- a/src/arch/mips/process.cc +++ b/src/arch/mips/process.cc @@ -176,10 +176,7 @@ MipsLiveProcess::argsInit(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)); - tc->setNextNPC(prog_entry + (2 * sizeof(MachInst))); + tc->pcState(objFile->entryPoint()); } diff --git a/src/arch/mips/types.hh b/src/arch/mips/types.hh index c7ef6afe1..f21db51b1 100644 --- a/src/arch/mips/types.hh +++ b/src/arch/mips/types.hh @@ -31,6 +31,7 @@ #ifndef __ARCH_MIPS_TYPES_HH__ #define __ARCH_MIPS_TYPES_HH__ +#include "arch/generic/types.hh" #include "base/types.hh" namespace MipsISA @@ -39,6 +40,8 @@ namespace MipsISA typedef uint32_t MachInst; typedef uint64_t ExtMachInst; +typedef GenericISA::DelaySlotPCState<MachInst> PCState; + typedef uint64_t LargestRead; //used in FP convert & round function diff --git a/src/arch/mips/utility.cc b/src/arch/mips/utility.cc index faae1e937..0859eb80f 100644 --- a/src/arch/mips/utility.cc +++ b/src/arch/mips/utility.cc @@ -267,10 +267,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)); - tc->setNextPC(tc->readNextPC() + sizeof(TheISA::MachInst)); + TheISA::PCState newPC = tc->pcState(); + newPC.set(tc->readIntReg(ReturnAddressReg)); + tc->pcState(newPC); } diff --git a/src/arch/mips/utility.hh b/src/arch/mips/utility.hh index bc50027c0..2f6726c59 100644 --- a/src/arch/mips/utility.hh +++ b/src/arch/mips/utility.hh @@ -39,12 +39,22 @@ #include "base/misc.hh" #include "base/types.hh" #include "config/full_system.hh" +#include "cpu/static_inst.hh" #include "cpu/thread_context.hh" class ThreadContext; namespace MipsISA { +inline PCState +buildRetPC(const PCState &curPC, const PCState &callPC) +{ + PCState ret = callPC; + ret.advance(); + ret.pc(curPC.npc()); + return ret; +} + uint64_t getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp); //////////////////////////////////////////////////////////////////////// @@ -105,6 +115,12 @@ void copyMiscRegs(ThreadContext *src, ThreadContext *dest); void skipFunction(ThreadContext *tc); +inline void +advancePC(PCState &pc, const StaticInstPtr inst) +{ + pc.advance(); +} + }; |