diff options
Diffstat (limited to 'src/arch/arm/insts')
-rw-r--r-- | src/arch/arm/insts/macromem.hh | 12 | ||||
-rw-r--r-- | src/arch/arm/insts/mem.hh | 38 | ||||
-rw-r--r-- | src/arch/arm/insts/pred_inst.hh | 11 | ||||
-rw-r--r-- | src/arch/arm/insts/static_inst.hh | 62 | ||||
-rw-r--r-- | src/arch/arm/insts/vfp.hh | 12 |
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 |