ARM: Explicitly keep track of the second destination for double loads/stores.
This commit is contained in:
parent
28023f6f3d
commit
9d4a1bf2ba
8 changed files with 222 additions and 36 deletions
|
@ -66,7 +66,7 @@ void
|
|||
Memory::printInst(std::ostream &os, AddrMode addrMode) const
|
||||
{
|
||||
printMnemonic(os);
|
||||
printReg(os, dest);
|
||||
printDest(os);
|
||||
os << ", [";
|
||||
printReg(os, base);
|
||||
if (addrMode != AddrMd_PostIndex) {
|
||||
|
|
|
@ -88,6 +88,12 @@ class Memory : public PredOp
|
|||
printOffset(std::ostream &os) const
|
||||
{}
|
||||
|
||||
virtual void
|
||||
printDest(std::ostream &os) const
|
||||
{
|
||||
printReg(os, dest);
|
||||
}
|
||||
|
||||
void printInst(std::ostream &os, AddrMode addrMode) const;
|
||||
};
|
||||
|
||||
|
@ -112,6 +118,28 @@ class MemoryImm : public Memory
|
|||
}
|
||||
};
|
||||
|
||||
// The address is a base register plus an immediate.
|
||||
class MemoryDImm : public MemoryImm
|
||||
{
|
||||
protected:
|
||||
IntRegIndex dest2;
|
||||
|
||||
MemoryDImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
|
||||
IntRegIndex _dest, IntRegIndex _dest2,
|
||||
IntRegIndex _base, bool _add, int32_t _imm)
|
||||
: MemoryImm(mnem, _machInst, __opClass, _dest, _base, _add, _imm),
|
||||
dest2(_dest2)
|
||||
{}
|
||||
|
||||
void
|
||||
printDest(std::ostream &os) const
|
||||
{
|
||||
MemoryImm::printDest(os);
|
||||
os << ", ";
|
||||
printReg(os, dest2);
|
||||
}
|
||||
};
|
||||
|
||||
// The address is a shifted register plus an immediate
|
||||
class MemoryReg : public Memory
|
||||
{
|
||||
|
@ -165,6 +193,30 @@ class MemoryReg : public Memory
|
|||
}
|
||||
};
|
||||
|
||||
class MemoryDReg : public MemoryReg
|
||||
{
|
||||
protected:
|
||||
IntRegIndex dest2;
|
||||
|
||||
MemoryDReg(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
|
||||
IntRegIndex _dest, IntRegIndex _dest2,
|
||||
IntRegIndex _base, bool _add,
|
||||
int32_t _shiftAmt, ArmShiftType _shiftType,
|
||||
IntRegIndex _index)
|
||||
: MemoryReg(mnem, _machInst, __opClass, _dest, _base, _add,
|
||||
_shiftAmt, _shiftType, _index),
|
||||
dest2(_dest2)
|
||||
{}
|
||||
|
||||
void
|
||||
printDest(std::ostream &os) const
|
||||
{
|
||||
MemoryReg::printDest(os);
|
||||
os << ", ";
|
||||
printReg(os, dest2);
|
||||
}
|
||||
};
|
||||
|
||||
template<class Base>
|
||||
class MemoryOffset : public Base
|
||||
{
|
||||
|
@ -183,6 +235,21 @@ class MemoryOffset : public Base
|
|||
_shiftAmt, _shiftType, _index)
|
||||
{}
|
||||
|
||||
MemoryOffset(const char *mnem, ExtMachInst _machInst,
|
||||
OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
|
||||
IntRegIndex _base, bool _add, int32_t _imm)
|
||||
: Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add, _imm)
|
||||
{}
|
||||
|
||||
MemoryOffset(const char *mnem, ExtMachInst _machInst,
|
||||
OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
|
||||
IntRegIndex _base, bool _add,
|
||||
int32_t _shiftAmt, ArmShiftType _shiftType,
|
||||
IntRegIndex _index)
|
||||
: Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add,
|
||||
_shiftAmt, _shiftType, _index)
|
||||
{}
|
||||
|
||||
std::string
|
||||
generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
|
@ -210,6 +277,21 @@ class MemoryPreIndex : public Base
|
|||
_shiftAmt, _shiftType, _index)
|
||||
{}
|
||||
|
||||
MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
|
||||
OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
|
||||
IntRegIndex _base, bool _add, int32_t _imm)
|
||||
: Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add, _imm)
|
||||
{}
|
||||
|
||||
MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
|
||||
OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
|
||||
IntRegIndex _base, bool _add,
|
||||
int32_t _shiftAmt, ArmShiftType _shiftType,
|
||||
IntRegIndex _index)
|
||||
: Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add,
|
||||
_shiftAmt, _shiftType, _index)
|
||||
{}
|
||||
|
||||
std::string
|
||||
generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
|
@ -237,6 +319,21 @@ class MemoryPostIndex : public Base
|
|||
_shiftAmt, _shiftType, _index)
|
||||
{}
|
||||
|
||||
MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
|
||||
OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
|
||||
IntRegIndex _base, bool _add, int32_t _imm)
|
||||
: Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add, _imm)
|
||||
{}
|
||||
|
||||
MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
|
||||
OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
|
||||
IntRegIndex _base, bool _add,
|
||||
int32_t _shiftAmt, ArmShiftType _shiftType,
|
||||
IntRegIndex _index)
|
||||
: Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add,
|
||||
_shiftAmt, _shiftType, _index)
|
||||
{}
|
||||
|
||||
std::string
|
||||
generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
|
|
|
@ -150,6 +150,10 @@ def format AddrMode3() {{
|
|||
addStr = "true"
|
||||
else:
|
||||
addStr = "false"
|
||||
if d:
|
||||
dests = "RT & ~1, RT | 1"
|
||||
else:
|
||||
dests = "RT"
|
||||
if i:
|
||||
if load:
|
||||
if d:
|
||||
|
@ -165,8 +169,8 @@ def format AddrMode3() {{
|
|||
className = storeImmClassName(post, add, writeback, \
|
||||
size=size, sign=sign, \
|
||||
user=user)
|
||||
decode += ("%s(machInst, RT, RN, %s, imm);\n" % \
|
||||
(className, addStr))
|
||||
decode += ("%s(machInst, %s, RN, %s, imm);\n" % \
|
||||
(className, dests, addStr))
|
||||
else:
|
||||
if load:
|
||||
if d:
|
||||
|
@ -182,8 +186,8 @@ def format AddrMode3() {{
|
|||
className = storeRegClassName(post, add, writeback, \
|
||||
size=size, sign=sign, \
|
||||
user=user)
|
||||
decode += ("%s(machInst, RT, RN, %s, 0, LSL, RM);\n" % \
|
||||
(className, addStr))
|
||||
decode += ("%s(machInst, %s, RN, %s, 0, LSL, RM);\n" % \
|
||||
(className, dests, addStr))
|
||||
return decode
|
||||
|
||||
def decodePuiw(load, d, size=4, sign=False):
|
||||
|
|
|
@ -59,14 +59,15 @@ let {{
|
|||
def loadDoubleRegClassName(post, add, writeback):
|
||||
return memClassName("LOAD_REGD", post, add, writeback, 4, False, False)
|
||||
|
||||
def emitLoad(name, Name, imm, eaCode, accCode, memFlags, instFlags, base):
|
||||
def emitLoad(name, Name, imm, eaCode, accCode, \
|
||||
memFlags, instFlags, base, double=False):
|
||||
global header_output, decoder_output, exec_output
|
||||
|
||||
(newHeader,
|
||||
newDecoder,
|
||||
newExec) = loadStoreBase(name, Name, imm,
|
||||
eaCode, accCode,
|
||||
memFlags, instFlags,
|
||||
memFlags, instFlags, double,
|
||||
base, execTemplateBase = 'Load')
|
||||
|
||||
header_output += newHeader
|
||||
|
@ -143,7 +144,8 @@ let {{
|
|||
accCode += "Base = Base %s;\n" % offset
|
||||
base = buildMemBase("MemoryReg", post, writeback)
|
||||
|
||||
emitLoad(name, Name, False, eaCode, accCode, memFlags, [], base)
|
||||
emitLoad(name, Name, False, eaCode, accCode, \
|
||||
memFlags, [], base)
|
||||
|
||||
def buildDoubleImmLoad(mnem, post, add, writeback, ldrex=False):
|
||||
name = mnem
|
||||
|
@ -161,8 +163,8 @@ let {{
|
|||
eaCode += ";"
|
||||
|
||||
accCode = '''
|
||||
Rdo = bits(Mem.ud, 31, 0);
|
||||
Rde = bits(Mem.ud, 63, 32);
|
||||
Dest = bits(Mem.ud, 31, 0);
|
||||
Dest2 = bits(Mem.ud, 63, 32);
|
||||
'''
|
||||
if ldrex:
|
||||
memFlags = ["Request::LLSC"]
|
||||
|
@ -171,9 +173,10 @@ let {{
|
|||
memFlags = []
|
||||
if writeback:
|
||||
accCode += "Base = Base %s;\n" % offset
|
||||
base = buildMemBase("MemoryImm", post, writeback)
|
||||
base = buildMemBase("MemoryDImm", post, writeback)
|
||||
|
||||
emitLoad(name, Name, True, eaCode, accCode, memFlags, [], base)
|
||||
emitLoad(name, Name, True, eaCode, accCode, \
|
||||
memFlags, [], base, double=True)
|
||||
|
||||
def buildDoubleRegLoad(mnem, post, add, writeback):
|
||||
name = mnem
|
||||
|
@ -192,14 +195,15 @@ let {{
|
|||
eaCode += ";"
|
||||
|
||||
accCode = '''
|
||||
Rdo = bits(Mem.ud, 31, 0);
|
||||
Rde = bits(Mem.ud, 63, 32);
|
||||
Dest = bits(Mem.ud, 31, 0);
|
||||
Dest2 = bits(Mem.ud, 63, 32);
|
||||
'''
|
||||
if writeback:
|
||||
accCode += "Base = Base %s;\n" % offset
|
||||
base = buildMemBase("MemoryReg", post, writeback)
|
||||
base = buildMemBase("MemoryDReg", post, writeback)
|
||||
|
||||
emitLoad(name, Name, False, eaCode, accCode, [], [], base)
|
||||
emitLoad(name, Name, False, eaCode, accCode,
|
||||
[], [], base, double=True)
|
||||
|
||||
def buildLoads(mnem, size=4, sign=False, user=False):
|
||||
buildImmLoad(mnem, True, True, True, size, sign, user)
|
||||
|
|
|
@ -39,7 +39,8 @@
|
|||
|
||||
let {{
|
||||
def loadStoreBaseWork(name, Name, imm, swp, codeBlobs, memFlags,
|
||||
instFlags, base = 'Memory', execTemplateBase = ''):
|
||||
instFlags, double, base = 'Memory',
|
||||
execTemplateBase = ''):
|
||||
# Make sure flags are in lists (convert to lists if not).
|
||||
memFlags = makeList(memFlags)
|
||||
instFlags = makeList(instFlags)
|
||||
|
@ -66,11 +67,19 @@ let {{
|
|||
declareTemplate = SwapDeclare
|
||||
constructTemplate = SwapConstructor
|
||||
elif imm:
|
||||
declareTemplate = LoadStoreImmDeclare
|
||||
constructTemplate = LoadStoreImmConstructor
|
||||
if double:
|
||||
declareTemplate = LoadStoreDImmDeclare
|
||||
constructTemplate = LoadStoreDImmConstructor
|
||||
else:
|
||||
declareTemplate = LoadStoreImmDeclare
|
||||
constructTemplate = LoadStoreImmConstructor
|
||||
else:
|
||||
declareTemplate = LoadStoreRegDeclare
|
||||
constructTemplate = LoadStoreRegConstructor
|
||||
if double:
|
||||
declareTemplate = LoadStoreDRegDeclare
|
||||
constructTemplate = LoadStoreDRegConstructor
|
||||
else:
|
||||
declareTemplate = LoadStoreRegDeclare
|
||||
constructTemplate = LoadStoreRegConstructor
|
||||
|
||||
# (header_output, decoder_output, decode_block, exec_output)
|
||||
return (declareTemplate.subst(iop),
|
||||
|
@ -80,12 +89,13 @@ let {{
|
|||
+ completeAccTemplate.subst(iop))
|
||||
|
||||
def loadStoreBase(name, Name, imm, eaCode, accCode, memFlags,
|
||||
instFlags, base = 'Memory', execTemplateBase = ''):
|
||||
instFlags, double, base = 'Memory',
|
||||
execTemplateBase = ''):
|
||||
codeBlobs = { "ea_code": eaCode,
|
||||
"memacc_code": accCode,
|
||||
"predicate_test": predicateTest }
|
||||
return loadStoreBaseWork(name, Name, imm, False, codeBlobs, memFlags,
|
||||
instFlags, base, execTemplateBase)
|
||||
instFlags, double, base, execTemplateBase)
|
||||
|
||||
def SwapBase(name, Name, eaCode, preAccCode, postAccCode, memFlags,
|
||||
instFlags):
|
||||
|
@ -94,7 +104,7 @@ let {{
|
|||
"postacc_code": postAccCode,
|
||||
"predicate_test": predicateTest }
|
||||
return loadStoreBaseWork(name, Name, False, True, codeBlobs, memFlags,
|
||||
instFlags, 'Swap', 'Swap')
|
||||
instFlags, False, 'Swap', 'Swap')
|
||||
|
||||
def memClassName(base, post, add, writeback, \
|
||||
size=4, sign=False, user=False):
|
||||
|
|
|
@ -61,14 +61,15 @@ let {{
|
|||
return memClassName("STORE_REGD", post, add, writeback,
|
||||
4, False, False)
|
||||
|
||||
def emitStore(name, Name, imm, eaCode, accCode, memFlags, instFlags, base):
|
||||
def emitStore(name, Name, imm, eaCode, accCode, \
|
||||
memFlags, instFlags, base, double=False):
|
||||
global header_output, decoder_output, exec_output
|
||||
|
||||
(newHeader,
|
||||
newDecoder,
|
||||
newExec) = loadStoreBase(name, Name, imm,
|
||||
eaCode, accCode,
|
||||
memFlags, instFlags,
|
||||
memFlags, instFlags, double,
|
||||
base, execTemplateBase = 'Store')
|
||||
|
||||
header_output += newHeader
|
||||
|
@ -139,12 +140,13 @@ let {{
|
|||
eaCode += offset
|
||||
eaCode += ";"
|
||||
|
||||
accCode = 'Mem.ud = (Rdo.ud & mask(32)) | (Rde.ud << 32);'
|
||||
accCode = 'Mem.ud = (Dest.ud & mask(32)) | (Dest2.ud << 32);'
|
||||
if writeback:
|
||||
accCode += "Base = Base %s;\n" % offset
|
||||
base = buildMemBase("MemoryImm", post, writeback)
|
||||
base = buildMemBase("MemoryDImm", post, writeback)
|
||||
|
||||
emitStore(name, Name, True, eaCode, accCode, [], [], base)
|
||||
emitStore(name, Name, True, eaCode, accCode, \
|
||||
[], [], base, double=True)
|
||||
|
||||
def buildDoubleRegStore(mnem, post, add, writeback):
|
||||
name = mnem
|
||||
|
@ -162,12 +164,13 @@ let {{
|
|||
eaCode += offset
|
||||
eaCode += ";"
|
||||
|
||||
accCode = 'Mem.ud = (Rdo.ud & mask(32)) | (Rde.ud << 32);'
|
||||
accCode = 'Mem.ud = (Dest.ud & mask(32)) | (Dest2.ud << 32);'
|
||||
if writeback:
|
||||
accCode += "Base = Base %s;\n" % offset
|
||||
base = buildMemBase("MemoryReg", post, writeback)
|
||||
base = buildMemBase("MemoryDReg", post, writeback)
|
||||
|
||||
emitStore(name, Name, False, eaCode, accCode, [], [], base)
|
||||
emitStore(name, Name, False, eaCode, accCode, \
|
||||
[], [], base, double=True)
|
||||
|
||||
def buildStores(mnem, size=4, sign=False, user=False):
|
||||
buildImmStore(mnem, True, True, True, size, sign, user)
|
||||
|
|
|
@ -90,6 +90,8 @@ def operands {{
|
|||
#Abstracted integer reg operands
|
||||
'Dest': ('IntReg', 'uw', 'dest', 'IsInteger', 0,
|
||||
maybePCRead, maybePCWrite),
|
||||
'Dest2': ('IntReg', 'uw', 'dest2', 'IsInteger', 0,
|
||||
maybePCRead, maybePCWrite),
|
||||
'IWDest': ('IntReg', 'uw', 'dest', 'IsInteger', 0,
|
||||
maybePCRead, maybeIWPCWrite),
|
||||
'AIWDest': ('IntReg', 'uw', 'dest', 'IsInteger', 0,
|
||||
|
@ -124,10 +126,6 @@ def operands {{
|
|||
'R7': ('IntReg', 'uw', '7', 'IsInteger', 5),
|
||||
'R0': ('IntReg', 'uw', '0', 'IsInteger', 0),
|
||||
|
||||
#Destination register for load/store double instructions
|
||||
'Rdo': ('IntReg', 'uw', '(RD & ~1)', 'IsInteger', 4, maybePCRead, maybePCWrite),
|
||||
'Rde': ('IntReg', 'uw', '(RD | 1)', 'IsInteger', 5, maybePCRead, maybePCWrite),
|
||||
|
||||
'LR': ('IntReg', 'uw', 'INTREG_LR', 'IsInteger', 9),
|
||||
'CondCodes': ('IntReg', 'uw', 'INTREG_CONDCODES', None, 10),
|
||||
|
||||
|
|
|
@ -314,6 +314,27 @@ def template SwapDeclare {{
|
|||
};
|
||||
}};
|
||||
|
||||
def template LoadStoreDImmDeclare {{
|
||||
/**
|
||||
* Static instruction class for "%(mnemonic)s".
|
||||
*/
|
||||
class %(class_name)s : public %(base_class)s
|
||||
{
|
||||
public:
|
||||
|
||||
/// Constructor.
|
||||
%(class_name)s(ExtMachInst machInst,
|
||||
uint32_t _dest, uint32_t _dest2,
|
||||
uint32_t _base, bool _add, int32_t _imm);
|
||||
|
||||
%(BasicExecDeclare)s
|
||||
|
||||
%(InitiateAccDeclare)s
|
||||
|
||||
%(CompleteAccDeclare)s
|
||||
};
|
||||
}};
|
||||
|
||||
def template LoadStoreImmDeclare {{
|
||||
/**
|
||||
* Static instruction class for "%(mnemonic)s".
|
||||
|
@ -334,6 +355,29 @@ def template LoadStoreImmDeclare {{
|
|||
};
|
||||
}};
|
||||
|
||||
def template LoadStoreDRegDeclare {{
|
||||
/**
|
||||
* Static instruction class for "%(mnemonic)s".
|
||||
*/
|
||||
class %(class_name)s : public %(base_class)s
|
||||
{
|
||||
public:
|
||||
|
||||
/// Constructor.
|
||||
%(class_name)s(ExtMachInst machInst,
|
||||
uint32_t _dest, uint32_t _dest2,
|
||||
uint32_t _base, bool _add,
|
||||
int32_t _shiftAmt, uint32_t _shiftType,
|
||||
uint32_t _index);
|
||||
|
||||
%(BasicExecDeclare)s
|
||||
|
||||
%(InitiateAccDeclare)s
|
||||
|
||||
%(CompleteAccDeclare)s
|
||||
};
|
||||
}};
|
||||
|
||||
def template LoadStoreRegDeclare {{
|
||||
/**
|
||||
* Static instruction class for "%(mnemonic)s".
|
||||
|
@ -374,6 +418,18 @@ def template SwapConstructor {{
|
|||
}
|
||||
}};
|
||||
|
||||
def template LoadStoreDImmConstructor {{
|
||||
inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
|
||||
uint32_t _dest, uint32_t _dest2,
|
||||
uint32_t _base, bool _add, int32_t _imm)
|
||||
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
|
||||
(IntRegIndex)_dest, (IntRegIndex)_dest2,
|
||||
(IntRegIndex)_base, _add, _imm)
|
||||
{
|
||||
%(constructor)s;
|
||||
}
|
||||
}};
|
||||
|
||||
def template LoadStoreImmConstructor {{
|
||||
inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
|
||||
uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
|
||||
|
@ -384,6 +440,20 @@ def template LoadStoreImmConstructor {{
|
|||
}
|
||||
}};
|
||||
|
||||
def template LoadStoreDRegConstructor {{
|
||||
inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
|
||||
uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
|
||||
int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
|
||||
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
|
||||
(IntRegIndex)_dest, (IntRegIndex)_dest2,
|
||||
(IntRegIndex)_base, _add,
|
||||
_shiftAmt, (ArmShiftType)_shiftType,
|
||||
(IntRegIndex)_index)
|
||||
{
|
||||
%(constructor)s;
|
||||
}
|
||||
}};
|
||||
|
||||
def template LoadStoreRegConstructor {{
|
||||
inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
|
||||
uint32_t _dest, uint32_t _base, bool _add,
|
||||
|
|
Loading…
Reference in a new issue