diff options
Diffstat (limited to 'src/arch/x86')
-rw-r--r-- | src/arch/x86/faults.cc | 26 | ||||
-rw-r--r-- | src/arch/x86/insts/macroop.hh | 3 | ||||
-rw-r--r-- | src/arch/x86/insts/microop.hh | 9 | ||||
-rw-r--r-- | src/arch/x86/insts/static_inst.hh | 6 | ||||
-rw-r--r-- | src/arch/x86/isa/decoder/two_byte_opcodes.isa | 2 | ||||
-rw-r--r-- | src/arch/x86/isa/formats/unknown.isa | 4 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/regop.isa | 13 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/seqop.isa | 16 | ||||
-rw-r--r-- | src/arch/x86/isa/operands.isa | 5 | ||||
-rw-r--r-- | src/arch/x86/nativetrace.cc | 2 | ||||
-rw-r--r-- | src/arch/x86/predecoder.hh | 28 | ||||
-rw-r--r-- | src/arch/x86/process.cc | 10 | ||||
-rw-r--r-- | src/arch/x86/system.cc | 3 | ||||
-rw-r--r-- | src/arch/x86/tlb.cc | 2 | ||||
-rw-r--r-- | src/arch/x86/types.hh | 3 | ||||
-rw-r--r-- | src/arch/x86/utility.cc | 9 | ||||
-rw-r--r-- | src/arch/x86/utility.hh | 16 |
17 files changed, 105 insertions, 52 deletions
diff --git a/src/arch/x86/faults.cc b/src/arch/x86/faults.cc index 4f2d97f90..7fb677c69 100644 --- a/src/arch/x86/faults.cc +++ b/src/arch/x86/faults.cc @@ -58,7 +58,8 @@ namespace X86ISA #if FULL_SYSTEM void X86FaultBase::invoke(ThreadContext * tc, StaticInstPtr inst) { - Addr pc = tc->readPC(); + PCState pcState = tc->pcState(); + Addr pc = pcState.pc(); DPRINTF(Faults, "RIP %#x: vector %d: %s\n", pc, vector, describe()); using namespace X86ISAInst::RomLabels; HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG); @@ -86,8 +87,9 @@ namespace X86ISA assert(!isSoft()); tc->setIntReg(INTREG_MICRO(15), errorCode); } - tc->setMicroPC(romMicroPC(entry)); - tc->setNextMicroPC(romMicroPC(entry) + 1); + pcState.upc(romMicroPC(entry)); + pcState.nupc(romMicroPC(entry) + 1); + tc->pcState(pcState); } std::string @@ -106,9 +108,8 @@ namespace X86ISA { X86FaultBase::invoke(tc); // This is the same as a fault, but it happens -after- the instruction. - tc->setPC(tc->readNextPC()); - tc->setNextPC(tc->readNextNPC()); - tc->setNextNPC(tc->readNextNPC() + sizeof(MachInst)); + PCState pc = tc->pcState(); + pc.uEnd(); } void X86Abort::invoke(ThreadContext * tc, StaticInstPtr inst) @@ -207,9 +208,8 @@ namespace X86ISA tc->setMiscReg(MISCREG_CS_LIMIT, 0xffffffff); tc->setMiscReg(MISCREG_CS_ATTR, codeAttr); - tc->setPC(0x000000000000fff0ULL + - tc->readMiscReg(MISCREG_CS_BASE)); - tc->setNextPC(tc->readPC() + sizeof(MachInst)); + PCState pc(0x000000000000fff0ULL + tc->readMiscReg(MISCREG_CS_BASE)); + tc->pcState(pc); tc->setMiscReg(MISCREG_TSG_BASE, 0); tc->setMiscReg(MISCREG_TSG_LIMIT, 0xffff); @@ -243,8 +243,9 @@ namespace X86ISA // Update the handy M5 Reg. tc->setMiscReg(MISCREG_M5_REG, 0); MicroPC entry = X86ISAInst::RomLabels::extern_label_initIntHalt; - tc->setMicroPC(romMicroPC(entry)); - tc->setNextMicroPC(romMicroPC(entry) + 1); + pc.upc(romMicroPC(entry)); + pc.nupc(romMicroPC(entry) + 1); + tc->pcState(pc); } void @@ -263,8 +264,7 @@ namespace X86ISA // This has the base value pre-added. tc->setMiscReg(MISCREG_CS_LIMIT, 0xffff); - tc->setPC(tc->readMiscReg(MISCREG_CS_BASE)); - tc->setNextPC(tc->readPC() + sizeof(MachInst)); + tc->pcState(tc->readMiscReg(MISCREG_CS_BASE)); } #else diff --git a/src/arch/x86/insts/macroop.hh b/src/arch/x86/insts/macroop.hh index 7ead7bdc2..fcf051a37 100644 --- a/src/arch/x86/insts/macroop.hh +++ b/src/arch/x86/insts/macroop.hh @@ -73,7 +73,8 @@ class MacroopBase : public X86StaticInst StaticInstPtr * microops; - StaticInstPtr fetchMicroop(MicroPC microPC) + StaticInstPtr + fetchMicroop(MicroPC microPC) const { assert(microPC < numMicroops); return microops[microPC]; diff --git a/src/arch/x86/insts/microop.hh b/src/arch/x86/insts/microop.hh index 9b0497efc..6fc215452 100644 --- a/src/arch/x86/insts/microop.hh +++ b/src/arch/x86/insts/microop.hh @@ -114,6 +114,15 @@ namespace X86ISA } bool checkCondition(uint64_t flags, int condition) const; + + void + advancePC(PCState &pcState) const + { + if (flags[IsLastMicroop]) + pcState.uEnd(); + else + pcState.uAdvance(); + } }; } diff --git a/src/arch/x86/insts/static_inst.hh b/src/arch/x86/insts/static_inst.hh index 2df5df092..8813f216c 100644 --- a/src/arch/x86/insts/static_inst.hh +++ b/src/arch/x86/insts/static_inst.hh @@ -158,6 +158,12 @@ namespace X86ISA panic("Tried to pick with unrecognized size %d.\n", size); } } + + void + advancePC(PCState &pcState) const + { + pcState.advance(); + } }; } diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index de167d1c1..def9b7f9d 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -199,7 +199,7 @@ #endif 0x54: m5panic({{ panic("M5 panic instruction called at pc=%#x.\n", - xc->readPC()); + xc->pcState().pc()); }}, IsNonSpeculative); 0x55: m5reserved1({{ warn("M5 reserved opcode 1 ignored.\n"); diff --git a/src/arch/x86/isa/formats/unknown.isa b/src/arch/x86/isa/formats/unknown.isa index 11751e861..1108fd4a4 100644 --- a/src/arch/x86/isa/formats/unknown.isa +++ b/src/arch/x86/isa/formats/unknown.isa @@ -47,13 +47,13 @@ output header {{ /** * Class for Unknown/Illegal instructions */ - class Unknown : public StaticInst + class Unknown : public X86ISA::X86StaticInst { public: // Constructor Unknown(ExtMachInst _machInst) : - StaticInst("unknown", _machInst, No_OpClass) + X86ISA::X86StaticInst("unknown", _machInst, No_OpClass) { } diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 9ccea82dd..86ebac174 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -944,8 +944,12 @@ let {{ code = 'DoubleBits = psrc1 ^ op2;' class Wrip(WrRegOp, CondRegOp): - code = 'RIP = psrc1 + sop2 + CSBase' - else_code="RIP = RIP;" + code = ''' + X86ISA::PCState pc = PCS; + pc.npc(psrc1 + sop2 + CSBase); + PCS = pc; + ''' + else_code = "PCS = PCS;" class Wruflags(WrRegOp): code = 'ccFlagBits = psrc1 ^ op2' @@ -961,7 +965,10 @@ let {{ ''' class Rdip(RdRegOp): - code = 'DestReg = RIP - CSBase' + code = ''' + X86ISA::PCState pc = PCS; + DestReg = pc.npc() - CSBase; + ''' class Ruflags(RdRegOp): code = 'DestReg = ccFlagBits' diff --git a/src/arch/x86/isa/microops/seqop.isa b/src/arch/x86/isa/microops/seqop.isa index 57c44d48c..a3e22b0aa 100644 --- a/src/arch/x86/isa/microops/seqop.isa +++ b/src/arch/x86/isa/microops/seqop.isa @@ -169,15 +169,23 @@ let {{ return super(Eret, self).getAllocator(microFlags) iop = InstObjParams("br", "MicroBranchFlags", "SeqOpBase", - {"code": "nuIP = target", - "else_code": "nuIP = nuIP", + {"code": ''' + X86ISA::PCState pc = PCS; + pc.nupc(target); + PCS = pc; + ''', + "else_code": "PCS = PCS", "cond_test": "checkCondition(ccFlagBits, cc)"}) exec_output += SeqOpExecute.subst(iop) header_output += SeqOpDeclare.subst(iop) decoder_output += SeqOpConstructor.subst(iop) iop = InstObjParams("br", "MicroBranch", "SeqOpBase", - {"code": "nuIP = target", - "else_code": "nuIP = nuIP", + {"code": ''' + X86ISA::PCState pc = PCS; + pc.nupc(target); + PCS = pc; + ''', + "else_code": "PCS = PCS", "cond_test": "true"}) exec_output += SeqOpExecute.subst(iop) header_output += SeqOpDeclare.subst(iop) diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa index d4140e414..25b73a8f2 100644 --- a/src/arch/x86/isa/operands.isa +++ b/src/arch/x86/isa/operands.isa @@ -97,9 +97,8 @@ def operands {{ 'FpSrcReg2': floatReg('src2', 21), 'FpDestReg': floatReg('dest', 22), 'FpData': floatReg('data', 23), - 'RIP': ('NPC', 'uqw', None, (None, None, 'IsControl'), 50), - 'uIP': ('UPC', 'uqw', None, (None, None, 'IsControl'), 51), - 'nuIP': ('NUPC', 'uqw', None, (None, None, 'IsControl'), 52), + 'PCS': ('PCState', 'udw', None, + (None, None, 'IsControl'), 50), # This holds the condition code portion of the flag register. The # nccFlagBits version holds the rest. 'ccFlagBits': intReg('INTREG_PSEUDO(0)', 60), diff --git a/src/arch/x86/nativetrace.cc b/src/arch/x86/nativetrace.cc index c5c891be9..6f92cfacf 100644 --- a/src/arch/x86/nativetrace.cc +++ b/src/arch/x86/nativetrace.cc @@ -85,7 +85,7 @@ X86NativeTrace::ThreadState::update(ThreadContext *tc) r13 = tc->readIntReg(X86ISA::INTREG_R13); r14 = tc->readIntReg(X86ISA::INTREG_R14); r15 = tc->readIntReg(X86ISA::INTREG_R15); - rip = tc->readNextPC(); + rip = tc->pcState().pc(); //This should be expanded if x87 registers are considered for (int i = 0; i < 8; i++) mmx[i] = tc->readFloatRegBits(X86ISA::FLOATREG_MMX(i)); diff --git a/src/arch/x86/predecoder.hh b/src/arch/x86/predecoder.hh index 5b38402e0..c06ec18bc 100644 --- a/src/arch/x86/predecoder.hh +++ b/src/arch/x86/predecoder.hh @@ -188,11 +188,11 @@ namespace X86ISA //Use this to give data to the predecoder. This should be used //when there is control flow. - void moreBytes(Addr pc, Addr fetchPC, MachInst data) + void moreBytes(const PCState &pc, Addr fetchPC, MachInst data) { DPRINTF(Predecoder, "Getting more bytes.\n"); basePC = fetchPC; - offset = (fetchPC >= pc) ? 0 : pc - fetchPC; + offset = (fetchPC >= pc.instAddr()) ? 0 : pc.instAddr() - fetchPC; fetchChunk = data; outOfBytes = false; process(); @@ -208,22 +208,26 @@ namespace X86ISA return emiIsReady; } + int + getInstSize() + { + int size = basePC + offset - origPC; + DPRINTF(Predecoder, + "Calculating the instruction size: " + "basePC: %#x offset: %#x origPC: %#x size: %d\n", + basePC, offset, origPC, size); + return size; + } + //This returns a constant reference to the ExtMachInst to avoid a copy - const ExtMachInst & getExtMachInst() + const ExtMachInst & + getExtMachInst(X86ISA::PCState &nextPC) { assert(emiIsReady); emiIsReady = false; + nextPC.npc(nextPC.pc() + getInstSize()); return emi; } - - int getInstSize() - { - DPRINTF(Predecoder, - "Calculating the instruction size: " - "basePC: %#x offset: %#x origPC: %#x\n", - basePC, offset, origPC); - return basePC + offset - origPC; - } }; }; diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index 946a7cbe1..bb875686e 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -116,10 +116,12 @@ X86_64LiveProcess::X86_64LiveProcess(LiveProcessParams *params, void I386LiveProcess::syscall(int64_t callnum, ThreadContext *tc) { - Addr eip = tc->readPC(); + TheISA::PCState pc = tc->pcState(); + Addr eip = pc.pc(); if (eip >= vsyscallPage.base && eip < vsyscallPage.base + vsyscallPage.size) { - tc->setNextPC(vsyscallPage.base + vsyscallPage.vsysexitOffset); + pc.npc(vsyscallPage.base + vsyscallPage.vsysexitOffset); + tc->pcState(pc); } X86LiveProcess::syscall(callnum, tc); } @@ -645,11 +647,9 @@ X86LiveProcess::argsInit(int pageSize, //Set the stack pointer register tc->setIntReg(StackPointerReg, stack_min); - Addr prog_entry = objFile->entryPoint(); // There doesn't need to be any segment base added in since we're dealing // with the flat segmentation model. - tc->setPC(prog_entry); - tc->setNextPC(prog_entry + sizeof(MachInst)); + tc->pcState(objFile->entryPoint()); //Align the "stack_min" to a page boundary. stack_min = roundDown(stack_min, pageSize); diff --git a/src/arch/x86/system.cc b/src/arch/x86/system.cc index ae47b14fd..3fc16e729 100644 --- a/src/arch/x86/system.cc +++ b/src/arch/x86/system.cc @@ -320,8 +320,7 @@ X86System::initState() cr0.pg = 1; tc->setMiscReg(MISCREG_CR0, cr0); - tc->setPC(tc->getSystemPtr()->kernelEntry); - tc->setNextPC(tc->readPC()); + tc->pcState(tc->getSystemPtr()->kernelEntry); // We should now be in long mode. Yay! diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 71e0b3adb..dbba52af0 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -609,7 +609,7 @@ TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation, #else DPRINTF(TLB, "Handling a TLB miss for " "address %#x at pc %#x.\n", - vaddr, tc->readPC()); + vaddr, tc->instAddr()); Process *p = tc->getProcessPtr(); TlbEntry newEntry; diff --git a/src/arch/x86/types.hh b/src/arch/x86/types.hh index 2a0da7d65..5a208446a 100644 --- a/src/arch/x86/types.hh +++ b/src/arch/x86/types.hh @@ -42,6 +42,7 @@ #include <iostream> +#include "arch/generic/types.hh" #include "base/bitunion.hh" #include "base/cprintf.hh" #include "base/hashmap.hh" @@ -221,6 +222,8 @@ namespace X86ISA return true; } + typedef GenericISA::UPCState<MachInst> PCState; + struct CoreSpecific { int core_type; }; diff --git a/src/arch/x86/utility.cc b/src/arch/x86/utility.cc index 624e8132f..88d5bfe58 100644 --- a/src/arch/x86/utility.cc +++ b/src/arch/x86/utility.cc @@ -72,8 +72,10 @@ void initCPU(ThreadContext *tc, int cpuId) InitInterrupt init(0); init.invoke(tc); - tc->setMicroPC(0); - tc->setNextMicroPC(1); + PCState pc = tc->pcState(); + pc.upc(0); + pc.nupc(1); + tc->pcState(pc); // These next two loops zero internal microcode and implicit registers. // They aren't specified by the ISA but are used internally by M5's @@ -231,8 +233,7 @@ copyRegs(ThreadContext *src, ThreadContext *dest) //copy float regs copyMiscRegs(src, dest); - dest->setPC(src->readPC()); - dest->setNextPC(src->readNextPC()); + dest->pcState(src->pcState()); } void diff --git a/src/arch/x86/utility.hh b/src/arch/x86/utility.hh index 05ce53347..143fde00c 100644 --- a/src/arch/x86/utility.hh +++ b/src/arch/x86/utility.hh @@ -46,12 +46,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 X86ISA { + + inline PCState + buildRetPC(const PCState &curPC, const PCState &callPC) + { + PCState retPC = callPC; + retPC.uEnd(); + return retPC; + } + uint64_t getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp); @@ -86,6 +96,12 @@ namespace X86ISA void copyMiscRegs(ThreadContext *src, ThreadContext *dest); void skipFunction(ThreadContext *tc); + + inline void + advancePC(PCState &pc, const StaticInstPtr inst) + { + inst->advancePC(pc); + } }; #endif // __ARCH_X86_UTILITY_HH__ |