summaryrefslogtreecommitdiff
path: root/src/arch/arm/insts
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/arm/insts')
-rw-r--r--src/arch/arm/insts/macromem.hh12
-rw-r--r--src/arch/arm/insts/mem.hh38
-rw-r--r--src/arch/arm/insts/pred_inst.hh11
-rw-r--r--src/arch/arm/insts/static_inst.hh62
-rw-r--r--src/arch/arm/insts/vfp.hh12
5 files changed, 79 insertions, 56 deletions
diff --git a/src/arch/arm/insts/macromem.hh b/src/arch/arm/insts/macromem.hh
index c1c8383da..018cb1de5 100644
--- a/src/arch/arm/insts/macromem.hh
+++ b/src/arch/arm/insts/macromem.hh
@@ -77,6 +77,18 @@ class MicroOp : public PredOp
{
flags[IsDelayedCommit] = true;
}
+
+ void
+ advancePC(PCState &pcState) const
+ {
+ if (flags[IsLastMicroop]) {
+ pcState.uEnd();
+ } else if (flags[IsMicroop]) {
+ pcState.uAdvance();
+ } else {
+ pcState.advance();
+ }
+ }
};
/**
diff --git a/src/arch/arm/insts/mem.hh b/src/arch/arm/insts/mem.hh
index 1baba5112..2aa4de1d7 100644
--- a/src/arch/arm/insts/mem.hh
+++ b/src/arch/arm/insts/mem.hh
@@ -63,8 +63,28 @@ class Swap : public PredOp
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
+class MightBeMicro : public PredOp
+{
+ protected:
+ MightBeMicro(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
+ : PredOp(mnem, _machInst, __opClass)
+ {}
+
+ void
+ advancePC(PCState &pcState) const
+ {
+ if (flags[IsLastMicroop]) {
+ pcState.uEnd();
+ } else if (flags[IsMicroop]) {
+ pcState.uAdvance();
+ } else {
+ pcState.advance();
+ }
+ }
+};
+
// The address is a base register plus an immediate.
-class RfeOp : public PredOp
+class RfeOp : public MightBeMicro
{
public:
enum AddrMode {
@@ -83,7 +103,7 @@ class RfeOp : public PredOp
RfeOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _base, AddrMode _mode, bool _wb)
- : PredOp(mnem, _machInst, __opClass),
+ : MightBeMicro(mnem, _machInst, __opClass),
base(_base), mode(_mode), wb(_wb), uops(NULL)
{}
@@ -94,7 +114,7 @@ class RfeOp : public PredOp
}
StaticInstPtr
- fetchMicroop(MicroPC microPC)
+ fetchMicroop(MicroPC microPC) const
{
assert(uops != NULL && microPC < numMicroops);
return uops[microPC];
@@ -104,7 +124,7 @@ class RfeOp : public PredOp
};
// The address is a base register plus an immediate.
-class SrsOp : public PredOp
+class SrsOp : public MightBeMicro
{
public:
enum AddrMode {
@@ -123,7 +143,7 @@ class SrsOp : public PredOp
SrsOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
uint32_t _regMode, AddrMode _mode, bool _wb)
- : PredOp(mnem, _machInst, __opClass),
+ : MightBeMicro(mnem, _machInst, __opClass),
regMode(_regMode), mode(_mode), wb(_wb), uops(NULL)
{}
@@ -134,7 +154,7 @@ class SrsOp : public PredOp
}
StaticInstPtr
- fetchMicroop(MicroPC microPC)
+ fetchMicroop(MicroPC microPC) const
{
assert(uops != NULL && microPC < numMicroops);
return uops[microPC];
@@ -143,7 +163,7 @@ class SrsOp : public PredOp
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
-class Memory : public PredOp
+class Memory : public MightBeMicro
{
public:
enum AddrMode {
@@ -163,7 +183,7 @@ class Memory : public PredOp
Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _dest, IntRegIndex _base, bool _add)
- : PredOp(mnem, _machInst, __opClass),
+ : MightBeMicro(mnem, _machInst, __opClass),
dest(_dest), base(_base), add(_add), uops(NULL)
{}
@@ -174,7 +194,7 @@ class Memory : public PredOp
}
StaticInstPtr
- fetchMicroop(MicroPC microPC)
+ fetchMicroop(MicroPC microPC) const
{
assert(uops != NULL && microPC < numMicroops);
return uops[microPC];
diff --git a/src/arch/arm/insts/pred_inst.hh b/src/arch/arm/insts/pred_inst.hh
index b7d4c4709..f779b46f5 100644
--- a/src/arch/arm/insts/pred_inst.hh
+++ b/src/arch/arm/insts/pred_inst.hh
@@ -312,7 +312,7 @@ class PredMacroOp : public PredOp
}
StaticInstPtr
- fetchMicroop(MicroPC microPC)
+ fetchMicroop(MicroPC microPC) const
{
assert(microPC < numMicroops);
return microOps[microPC];
@@ -332,6 +332,15 @@ class PredMicroop : public PredOp
{
flags[IsMicroop] = true;
}
+
+ void
+ advancePC(PCState &pcState) const
+ {
+ if (flags[IsLastMicroop])
+ pcState.uEnd();
+ else
+ pcState.uAdvance();
+ }
};
}
diff --git a/src/arch/arm/insts/static_inst.hh b/src/arch/arm/insts/static_inst.hh
index ad89a1a79..fa850190f 100644
--- a/src/arch/arm/insts/static_inst.hh
+++ b/src/arch/arm/insts/static_inst.hh
@@ -155,6 +155,12 @@ class ArmStaticInst : public StaticInst
IntRegIndex rs, uint32_t shiftAmt, ArmShiftType type,
uint32_t imm) const;
+ void
+ advancePC(PCState &pcState) const
+ {
+ pcState.advance();
+ }
+
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
static inline uint32_t
@@ -219,26 +225,16 @@ class ArmStaticInst : public StaticInst
static inline Addr
readPC(XC *xc)
{
- Addr pc = xc->readPC();
- if (isThumb(pc))
- return pc + 4;
- else
- return pc + 8;
+ return xc->pcState().instPC();
}
- // Perform an regular branch.
template<class XC>
static inline void
setNextPC(XC *xc, Addr val)
{
- Addr npc = xc->readNextPC();
- if (isThumb(npc)) {
- val &= ~mask(1);
- } else {
- val &= ~mask(2);
- }
- xc->setNextPC((npc & PcModeMask) |
- (val & ~PcModeMask));
+ PCState pc = xc->pcState();
+ pc.instNPC(val);
+ xc->pcState(pc);
}
template<class T>
@@ -279,30 +275,9 @@ class ArmStaticInst : public StaticInst
static inline void
setIWNextPC(XC *xc, Addr val)
{
- Addr stateBits = xc->readPC() & PcModeMask;
- Addr jBit = PcJBit;
- Addr tBit = PcTBit;
- bool thumbEE = (stateBits == (tBit | jBit));
-
- Addr newPc = (val & ~PcModeMask);
- if (thumbEE) {
- if (bits(newPc, 0)) {
- newPc = newPc & ~mask(1);
- } else {
- panic("Bad thumbEE interworking branch address %#x.\n", newPc);
- }
- } else {
- if (bits(newPc, 0)) {
- stateBits = tBit;
- newPc = newPc & ~mask(1);
- } else if (!bits(newPc, 1)) {
- stateBits = 0;
- } else {
- warn("Bad interworking branch address %#x.\n", newPc);
- }
- }
- newPc = newPc | stateBits;
- xc->setNextPC(newPc);
+ PCState pc = xc->pcState();
+ pc.instIWNPC(val);
+ xc->pcState(pc);
}
// Perform an interworking branch in ARM mode, a regular branch
@@ -311,14 +286,9 @@ class ArmStaticInst : public StaticInst
static inline void
setAIWNextPC(XC *xc, Addr val)
{
- Addr stateBits = xc->readPC() & PcModeMask;
- Addr jBit = PcJBit;
- Addr tBit = PcTBit;
- if (!jBit && !tBit) {
- setIWNextPC(xc, val);
- } else {
- setNextPC(xc, val);
- }
+ PCState pc = xc->pcState();
+ pc.instAIWNPC(val);
+ xc->pcState(pc);
}
inline Fault
diff --git a/src/arch/arm/insts/vfp.hh b/src/arch/arm/insts/vfp.hh
index 964b62673..e962704e0 100644
--- a/src/arch/arm/insts/vfp.hh
+++ b/src/arch/arm/insts/vfp.hh
@@ -459,6 +459,18 @@ class FpOp : public PredOp
unaryOp(FPSCR &fpscr, fpType op1,
fpType (*func)(fpType),
bool flush, uint32_t rMode) const;
+
+ void
+ advancePC(PCState &pcState) const
+ {
+ if (flags[IsLastMicroop]) {
+ pcState.uEnd();
+ } else if (flags[IsMicroop]) {
+ pcState.uAdvance();
+ } else {
+ pcState.advance();
+ }
+ }
};
class FpRegRegOp : public FpOp