ARM: Replace the interworking branch base class with a special operand.
This commit is contained in:
parent
b6e7029dd5
commit
769f3406fe
3 changed files with 43 additions and 40 deletions
|
@ -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;
|
||||||
|
|
|
@ -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,8 +61,8 @@ 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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),
|
||||||
}};
|
}};
|
||||||
|
|
Loading…
Reference in a new issue