summaryrefslogtreecommitdiff
path: root/src/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86')
-rw-r--r--src/arch/x86/faults.cc26
-rw-r--r--src/arch/x86/insts/macroop.hh3
-rw-r--r--src/arch/x86/insts/microop.hh9
-rw-r--r--src/arch/x86/insts/static_inst.hh6
-rw-r--r--src/arch/x86/isa/decoder/two_byte_opcodes.isa2
-rw-r--r--src/arch/x86/isa/formats/unknown.isa4
-rw-r--r--src/arch/x86/isa/microops/regop.isa13
-rw-r--r--src/arch/x86/isa/microops/seqop.isa16
-rw-r--r--src/arch/x86/isa/operands.isa5
-rw-r--r--src/arch/x86/nativetrace.cc2
-rw-r--r--src/arch/x86/predecoder.hh28
-rw-r--r--src/arch/x86/process.cc10
-rw-r--r--src/arch/x86/system.cc3
-rw-r--r--src/arch/x86/tlb.cc2
-rw-r--r--src/arch/x86/types.hh3
-rw-r--r--src/arch/x86/utility.cc9
-rw-r--r--src/arch/x86/utility.hh16
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__