summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/arm/insts/static_inst.cc20
-rw-r--r--src/arch/arm/insts/static_inst.hh52
-rw-r--r--src/arch/arm/isa/operands.isa11
3 files changed, 43 insertions, 40 deletions
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<class XC>
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<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, ExtMachInst _machInst, OpClass __opClass)
- : ArmStaticInstBase(mnem, _machInst, __opClass)
- {
- }
-
- template<class XC>
- 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<class XC>
+ 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),
}};