diff options
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/x86/predecoder.hh | 6 | ||||
-rw-r--r-- | src/arch/x86/types.hh | 50 |
2 files changed, 54 insertions, 2 deletions
diff --git a/src/arch/x86/predecoder.hh b/src/arch/x86/predecoder.hh index c06ec18bc..5c67e28e1 100644 --- a/src/arch/x86/predecoder.hh +++ b/src/arch/x86/predecoder.hh @@ -225,7 +225,11 @@ namespace X86ISA { assert(emiIsReady); emiIsReady = false; - nextPC.npc(nextPC.pc() + getInstSize()); + if (!nextPC.size()) { + Addr size = getInstSize(); + nextPC.size(size); + nextPC.npc(nextPC.pc() + size); + } return emi; } }; diff --git a/src/arch/x86/types.hh b/src/arch/x86/types.hh index 5a208446a..d78af1b81 100644 --- a/src/arch/x86/types.hh +++ b/src/arch/x86/types.hh @@ -222,7 +222,55 @@ namespace X86ISA return true; } - typedef GenericISA::UPCState<MachInst> PCState; + class PCState : public GenericISA::UPCState<MachInst> + { + protected: + typedef GenericISA::UPCState<MachInst> Base; + + uint8_t _size; + + public: + void + set(Addr val) + { + Base::set(val); + _size = 0; + } + + PCState() {} + PCState(Addr val) { set(val); } + + uint8_t size() const { return _size; } + void size(uint8_t newSize) { _size = newSize; } + + void + advance() + { + Base::advance(); + _size = 0; + } + + void + uEnd() + { + Base::uEnd(); + _size = 0; + } + + void + serialize(std::ostream &os) + { + Base::serialize(os); + SERIALIZE_SCALAR(_size); + } + + void + unserialize(Checkpoint *cp, const std::string §ion) + { + Base::unserialize(cp, section); + UNSERIALIZE_SCALAR(_size); + } + }; struct CoreSpecific { int core_type; |