50c50
< class ArmStaticInst : public StaticInst
---
> class ArmStaticInstBase : public StaticInst
70c70
< ArmStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass)
---
> ArmStaticInstBase(const char *mnem, MachInst _machInst, OpClass __opClass)
148a149,204
>
> class ArmStaticInst : public ArmStaticInstBase
> {
> protected:
> ArmStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass)
> : ArmStaticInstBase(mnem, _machInst, __opClass)
> {
> }
>
> template<class XC>
> static void
> setNextPC(XC *xc, Addr val)
> {
> xc->setNextPC((xc->readNextPC() & PcModeMask) |
> (val & ~PcModeMask));
> }
> };
>
> class ArmInterWorking : public ArmStaticInstBase
> {
> protected:
> ArmInterWorking(const char *mnem, MachInst _machInst, OpClass __opClass)
> : ArmStaticInstBase(mnem, _machInst, __opClass)
> {
> }
>
> template<class XC>
> static void
> setNextPC(XC *xc, Addr val)
> {
> Addr stateBits = xc->readPC() & PcModeMask;
> Addr jBit = (ULL(1) << PcJBitShift);
> Addr tBit = (ULL(1) << PcTBitShift);
> bool thumbEE = (stateBits == (tBit | jBit));
>
> Addr newPc = (val & ~PcModeMask);
> if (thumbEE) {
> if (bits(newPc, 0)) {
> warn("Bad thumbEE interworking branch address %#x.\n", newPc);
> } else {
> newPc = newPc & ~mask(1);
> }
> } 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);
> }
> };