ARM: Replace the interworking branch base class with a special operand.

This commit is contained in:
Gabe Black 2010-06-02 12:58:02 -05:00
parent b6e7029dd5
commit 769f3406fe
3 changed files with 43 additions and 40 deletions

View file

@ -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;

View file

@ -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);
}
}
};
}

View file

@ -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),
}};