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 // Shift Rm by an immediate value
int32_t 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 uint32_t type, uint32_t cfval) const
{ {
assert(shamt < 32); assert(shamt < 32);
@ -86,7 +86,7 @@ ArmStaticInstBase::shift_rm_imm(uint32_t base, uint32_t shamt,
// Shift Rm by Rs // Shift Rm by Rs
int32_t 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 uint32_t type, uint32_t cfval) const
{ {
enum ArmShiftType shiftType; enum ArmShiftType shiftType;
@ -126,7 +126,7 @@ ArmStaticInstBase::shift_rm_rs(uint32_t base, uint32_t shamt,
// Generate C for a shift by immediate // Generate C for a shift by immediate
bool 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 uint32_t type, uint32_t cfval) const
{ {
enum ArmShiftType shiftType; enum ArmShiftType shiftType;
@ -166,7 +166,7 @@ ArmStaticInstBase::shift_carry_imm(uint32_t base, uint32_t shamt,
// Generate C for a shift by Rs // Generate C for a shift by Rs
bool 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 uint32_t type, uint32_t cfval) const
{ {
enum ArmShiftType shiftType; enum ArmShiftType shiftType;
@ -206,7 +206,7 @@ ArmStaticInstBase::shift_carry_rs(uint32_t base, uint32_t shamt,
void void
ArmStaticInstBase::printReg(std::ostream &os, int reg) const ArmStaticInst::printReg(std::ostream &os, int reg) const
{ {
if (reg < FP_Base_DepTag) { if (reg < FP_Base_DepTag) {
switch (reg) { switch (reg) {
@ -236,7 +236,7 @@ ArmStaticInstBase::printReg(std::ostream &os, int reg) const
} }
void void
ArmStaticInstBase::printMnemonic(std::ostream &os, ArmStaticInst::printMnemonic(std::ostream &os,
const std::string &suffix, const std::string &suffix,
bool withPred) const bool withPred) const
{ {
@ -303,7 +303,7 @@ ArmStaticInstBase::printMnemonic(std::ostream &os,
} }
void void
ArmStaticInstBase::printMemSymbol(std::ostream &os, ArmStaticInst::printMemSymbol(std::ostream &os,
const SymbolTable *symtab, const SymbolTable *symtab,
const std::string &prefix, const std::string &prefix,
const Addr addr, const Addr addr,
@ -320,7 +320,7 @@ ArmStaticInstBase::printMemSymbol(std::ostream &os,
} }
void void
ArmStaticInstBase::printShiftOperand(std::ostream &os, ArmStaticInst::printShiftOperand(std::ostream &os,
IntRegIndex rm, IntRegIndex rm,
bool immShift, bool immShift,
uint32_t shiftAmt, uint32_t shiftAmt,
@ -384,7 +384,7 @@ ArmStaticInstBase::printShiftOperand(std::ostream &os,
} }
void void
ArmStaticInstBase::printDataInst(std::ostream &os, bool withImm, ArmStaticInst::printDataInst(std::ostream &os, bool withImm,
bool immShift, bool s, IntRegIndex rd, IntRegIndex rn, bool immShift, bool s, IntRegIndex rd, IntRegIndex rn,
IntRegIndex rm, IntRegIndex rs, uint32_t shiftAmt, IntRegIndex rm, IntRegIndex rs, uint32_t shiftAmt,
ArmShiftType type, uint32_t imm) const ArmShiftType type, uint32_t imm) const
@ -416,7 +416,7 @@ ArmStaticInstBase::printDataInst(std::ostream &os, bool withImm,
} }
std::string std::string
ArmStaticInstBase::generateDisassembly(Addr pc, ArmStaticInst::generateDisassembly(Addr pc,
const SymbolTable *symtab) const const SymbolTable *symtab) const
{ {
std::stringstream ss; std::stringstream ss;

View file

@ -47,7 +47,7 @@
namespace ArmISA namespace ArmISA
{ {
class ArmStaticInstBase : public StaticInst class ArmStaticInst : public StaticInst
{ {
protected: protected:
int32_t shift_rm_imm(uint32_t base, uint32_t shamt, int32_t shift_rm_imm(uint32_t base, uint32_t shamt,
@ -61,7 +61,7 @@ class ArmStaticInstBase : public StaticInst
uint32_t type, uint32_t cfval) const; uint32_t type, uint32_t cfval) const;
// Constructor // Constructor
ArmStaticInstBase(const char *mnem, ExtMachInst _machInst, ArmStaticInst(const char *mnem, ExtMachInst _machInst,
OpClass __opClass) OpClass __opClass)
: StaticInst(mnem, _machInst, __opClass) : StaticInst(mnem, _machInst, __opClass)
{ {
@ -151,6 +151,7 @@ class ArmStaticInstBase : public StaticInst
return pc + 8; return pc + 8;
} }
// Perform an regular branch.
template<class XC> template<class XC>
static void static void
setNextPC(XC *xc, Addr val) setNextPC(XC *xc, Addr val)
@ -158,36 +159,11 @@ class ArmStaticInstBase : public StaticInst
xc->setNextPC((xc->readNextPC() & PcModeMask) | xc->setNextPC((xc->readNextPC() & PcModeMask) |
(val & ~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> template<class XC>
static void static void
setNextPC(XC *xc, Addr val) setIWNextPC(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)
{ {
Addr stateBits = xc->readPC() & PcModeMask; Addr stateBits = xc->readPC() & PcModeMask;
Addr jBit = (ULL(1) << PcJBitShift); Addr jBit = (ULL(1) << PcJBitShift);
@ -214,6 +190,22 @@ class ArmInterWorking : public ArmStaticInstBase
newPc = newPc | stateBits; newPc = newPc | stateBits;
xc->setNextPC(newPc); 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) : ((%(reg_idx)s == PCReg) ? setNextPC(xc, %(final_val)s) :
xc->%(func)s(this, %(op_idx)s, %(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' readNPC = 'xc->readNextPC() & ~PcModeMask'
writeNPC = 'setNextPC(xc, %(final_val)s)' writeNPC = 'setNextPC(xc, %(final_val)s)'
writeIWNPC = 'setIWNextPC(xc, %(final_val)s)'
}}; }};
def operands {{ def operands {{
#Abstracted integer reg operands #Abstracted integer reg operands
'Dest': ('IntReg', 'uw', 'dest', 'IsInteger', 0, 'Dest': ('IntReg', 'uw', 'dest', 'IsInteger', 0,
maybePCRead, maybePCWrite), maybePCRead, maybePCWrite),
'IWDest': ('IntReg', 'uw', 'dest', 'IsInteger', 0,
maybePCRead, maybeIWPCWrite),
'AIWDest': ('IntReg', 'uw', 'dest', 'IsInteger', 0,
maybePCRead, maybeIWPCWrite),
'Base': ('IntReg', 'uw', 'base', 'IsInteger', 1, 'Base': ('IntReg', 'uw', 'base', 'IsInteger', 1,
maybePCRead, maybePCWrite), maybePCRead, maybePCWrite),
'Index': ('IntReg', 'uw', 'index', 'IsInteger', 2, 'Index': ('IntReg', 'uw', 'index', 'IsInteger', 2,
@ -116,4 +125,6 @@ def operands {{
'Fpexc': ('ControlReg', 'uw', 'MISCREG_FPEXC', None, 45), 'Fpexc': ('ControlReg', 'uw', 'MISCREG_FPEXC', None, 45),
'NPC': ('NPC', 'ud', None, (None, None, 'IsControl'), 51, 'NPC': ('NPC', 'ud', None, (None, None, 'IsControl'), 51,
readNPC, writeNPC), readNPC, writeNPC),
'IWNPC': ('NPC', 'ud', None, (None, None, 'IsControl'), 51,
readNPC, writeIWNPC),
}}; }};