diff --git a/src/arch/arm/insts/static_inst.cc b/src/arch/arm/insts/static_inst.cc index 61a1ebde6..41bfeac59 100644 --- a/src/arch/arm/insts/static_inst.cc +++ b/src/arch/arm/insts/static_inst.cc @@ -50,7 +50,7 @@ namespace ArmISA { // Shift Rm by an immediate value int32_t -ArmStaticInstBase::shift_rm_imm(uint32_t base, uint32_t shamt, +ArmStaticInst::shift_rm_imm(uint32_t base, uint32_t shamt, uint32_t type, uint32_t cfval) const { assert(shamt < 32); @@ -86,7 +86,7 @@ ArmStaticInstBase::shift_rm_imm(uint32_t base, uint32_t shamt, // Shift Rm by Rs int32_t -ArmStaticInstBase::shift_rm_rs(uint32_t base, uint32_t shamt, +ArmStaticInst::shift_rm_rs(uint32_t base, uint32_t shamt, uint32_t type, uint32_t cfval) const { enum ArmShiftType shiftType; @@ -126,7 +126,7 @@ ArmStaticInstBase::shift_rm_rs(uint32_t base, uint32_t shamt, // Generate C for a shift by immediate bool -ArmStaticInstBase::shift_carry_imm(uint32_t base, uint32_t shamt, +ArmStaticInst::shift_carry_imm(uint32_t base, uint32_t shamt, uint32_t type, uint32_t cfval) const { enum ArmShiftType shiftType; @@ -166,7 +166,7 @@ ArmStaticInstBase::shift_carry_imm(uint32_t base, uint32_t shamt, // Generate C for a shift by Rs bool -ArmStaticInstBase::shift_carry_rs(uint32_t base, uint32_t shamt, +ArmStaticInst::shift_carry_rs(uint32_t base, uint32_t shamt, uint32_t type, uint32_t cfval) const { enum ArmShiftType shiftType; @@ -206,7 +206,7 @@ ArmStaticInstBase::shift_carry_rs(uint32_t base, uint32_t shamt, void -ArmStaticInstBase::printReg(std::ostream &os, int reg) const +ArmStaticInst::printReg(std::ostream &os, int reg) const { if (reg < FP_Base_DepTag) { switch (reg) { @@ -236,7 +236,7 @@ ArmStaticInstBase::printReg(std::ostream &os, int reg) const } void -ArmStaticInstBase::printMnemonic(std::ostream &os, +ArmStaticInst::printMnemonic(std::ostream &os, const std::string &suffix, bool withPred) const { @@ -303,7 +303,7 @@ ArmStaticInstBase::printMnemonic(std::ostream &os, } void -ArmStaticInstBase::printMemSymbol(std::ostream &os, +ArmStaticInst::printMemSymbol(std::ostream &os, const SymbolTable *symtab, const std::string &prefix, const Addr addr, @@ -320,7 +320,7 @@ ArmStaticInstBase::printMemSymbol(std::ostream &os, } void -ArmStaticInstBase::printShiftOperand(std::ostream &os, +ArmStaticInst::printShiftOperand(std::ostream &os, IntRegIndex rm, bool immShift, uint32_t shiftAmt, @@ -384,7 +384,7 @@ ArmStaticInstBase::printShiftOperand(std::ostream &os, } void -ArmStaticInstBase::printDataInst(std::ostream &os, bool withImm, +ArmStaticInst::printDataInst(std::ostream &os, bool withImm, bool immShift, bool s, IntRegIndex rd, IntRegIndex rn, IntRegIndex rm, IntRegIndex rs, uint32_t shiftAmt, ArmShiftType type, uint32_t imm) const @@ -416,7 +416,7 @@ ArmStaticInstBase::printDataInst(std::ostream &os, bool withImm, } std::string -ArmStaticInstBase::generateDisassembly(Addr pc, +ArmStaticInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const { std::stringstream ss; diff --git a/src/arch/arm/insts/static_inst.hh b/src/arch/arm/insts/static_inst.hh index 59d7fe705..485d6997e 100644 --- a/src/arch/arm/insts/static_inst.hh +++ b/src/arch/arm/insts/static_inst.hh @@ -47,7 +47,7 @@ namespace ArmISA { -class ArmStaticInstBase : public StaticInst +class ArmStaticInst : public StaticInst { protected: int32_t shift_rm_imm(uint32_t base, uint32_t shamt, @@ -61,8 +61,8 @@ class ArmStaticInstBase : public StaticInst uint32_t type, uint32_t cfval) const; // Constructor - ArmStaticInstBase(const char *mnem, ExtMachInst _machInst, - OpClass __opClass) + ArmStaticInst(const char *mnem, ExtMachInst _machInst, + OpClass __opClass) : StaticInst(mnem, _machInst, __opClass) { } @@ -151,6 +151,7 @@ class ArmStaticInstBase : public StaticInst return pc + 8; } + // Perform an regular branch. template static void setNextPC(XC *xc, Addr val) @@ -158,36 +159,11 @@ class ArmStaticInstBase : public StaticInst xc->setNextPC((xc->readNextPC() & PcModeMask) | (val & ~PcModeMask)); } -}; - -class ArmStaticInst : public ArmStaticInstBase -{ - protected: - ArmStaticInst(const char *mnem, ExtMachInst _machInst, OpClass __opClass) - : ArmStaticInstBase(mnem, _machInst, __opClass) - { - } + // Perform an interworking branch. template static void - setNextPC(XC *xc, Addr val) - { - xc->setNextPC((xc->readNextPC() & PcModeMask) | - (val & ~PcModeMask)); - } -}; - -class ArmInterWorking : public ArmStaticInstBase -{ - protected: - ArmInterWorking(const char *mnem, ExtMachInst _machInst, OpClass __opClass) - : ArmStaticInstBase(mnem, _machInst, __opClass) - { - } - - template - static void - setNextPC(XC *xc, Addr val) + setIWNextPC(XC *xc, Addr val) { Addr stateBits = xc->readPC() & PcModeMask; Addr jBit = (ULL(1) << PcJBitShift); @@ -214,6 +190,22 @@ class ArmInterWorking : public ArmStaticInstBase newPc = newPc | stateBits; xc->setNextPC(newPc); } + + // Perform an interworking branch in ARM mode, a regular branch + // otherwise. + template + static void + setAIWNextPC(XC *xc, Addr val) + { + Addr stateBits = xc->readPC() & PcModeMask; + Addr jBit = (ULL(1) << PcJBitShift); + Addr tBit = (ULL(1) << PcTBitShift); + if (!jBit && !tBit) { + setIWNextPC(xc, val); + } else { + setNextPC(xc, val); + } + } }; } diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa index 911f0425e..3f331832c 100644 --- a/src/arch/arm/isa/operands.isa +++ b/src/arch/arm/isa/operands.isa @@ -60,15 +60,24 @@ let {{ ((%(reg_idx)s == PCReg) ? setNextPC(xc, %(final_val)s) : xc->%(func)s(this, %(op_idx)s, %(final_val)s)) ''' + maybeIWPCWrite = ''' + ((%(reg_idx)s == PCReg) ? setIWNextPC(xc, %(final_val)s) : + xc->%(func)s(this, %(op_idx)s, %(final_val)s)) + ''' readNPC = 'xc->readNextPC() & ~PcModeMask' writeNPC = 'setNextPC(xc, %(final_val)s)' + writeIWNPC = 'setIWNextPC(xc, %(final_val)s)' }}; def operands {{ #Abstracted integer reg operands 'Dest': ('IntReg', 'uw', 'dest', 'IsInteger', 0, maybePCRead, maybePCWrite), + 'IWDest': ('IntReg', 'uw', 'dest', 'IsInteger', 0, + maybePCRead, maybeIWPCWrite), + 'AIWDest': ('IntReg', 'uw', 'dest', 'IsInteger', 0, + maybePCRead, maybeIWPCWrite), 'Base': ('IntReg', 'uw', 'base', 'IsInteger', 1, maybePCRead, maybePCWrite), 'Index': ('IntReg', 'uw', 'index', 'IsInteger', 2, @@ -116,4 +125,6 @@ def operands {{ 'Fpexc': ('ControlReg', 'uw', 'MISCREG_FPEXC', None, 45), 'NPC': ('NPC', 'ud', None, (None, None, 'IsControl'), 51, readNPC, writeNPC), + 'IWNPC': ('NPC', 'ud', None, (None, None, 'IsControl'), 51, + readNPC, writeIWNPC), }};