summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:09 -0500
committerGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:09 -0500
commit9d4a1bf2ba936499277b96054fbc83c478c0c6be (patch)
treed4ced7dbf19e8c0e044bec654f3ea1c82cd809cf
parent28023f6f3d752fe600e4f610549ae27541b2ebce (diff)
downloadgem5-9d4a1bf2ba936499277b96054fbc83c478c0c6be.tar.xz
ARM: Explicitly keep track of the second destination for double loads/stores.
-rw-r--r--src/arch/arm/insts/mem.cc2
-rw-r--r--src/arch/arm/insts/mem.hh97
-rw-r--r--src/arch/arm/isa/formats/mem.isa12
-rw-r--r--src/arch/arm/isa/insts/ldr.isa26
-rw-r--r--src/arch/arm/isa/insts/mem.isa26
-rw-r--r--src/arch/arm/isa/insts/str.isa19
-rw-r--r--src/arch/arm/isa/operands.isa6
-rw-r--r--src/arch/arm/isa/templates/mem.isa70
8 files changed, 222 insertions, 36 deletions
diff --git a/src/arch/arm/insts/mem.cc b/src/arch/arm/insts/mem.cc
index 6cbe08ac8..521499847 100644
--- a/src/arch/arm/insts/mem.cc
+++ b/src/arch/arm/insts/mem.cc
@@ -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) {
diff --git a/src/arch/arm/insts/mem.hh b/src/arch/arm/insts/mem.hh
index 6ed99ba5b..dc4b7d627 100644
--- a/src/arch/arm/insts/mem.hh
+++ b/src/arch/arm/insts/mem.hh
@@ -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
{
diff --git a/src/arch/arm/isa/formats/mem.isa b/src/arch/arm/isa/formats/mem.isa
index 311ae5b66..1c69a5e00 100644
--- a/src/arch/arm/isa/formats/mem.isa
+++ b/src/arch/arm/isa/formats/mem.isa
@@ -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):
diff --git a/src/arch/arm/isa/insts/ldr.isa b/src/arch/arm/isa/insts/ldr.isa
index da20cab0b..6b8c925b6 100644
--- a/src/arch/arm/isa/insts/ldr.isa
+++ b/src/arch/arm/isa/insts/ldr.isa
@@ -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)
diff --git a/src/arch/arm/isa/insts/mem.isa b/src/arch/arm/isa/insts/mem.isa
index 21687b225..dc447cf8b 100644
--- a/src/arch/arm/isa/insts/mem.isa
+++ b/src/arch/arm/isa/insts/mem.isa
@@ -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):
diff --git a/src/arch/arm/isa/insts/str.isa b/src/arch/arm/isa/insts/str.isa
index 3349ba029..cf9eed74e 100644
--- a/src/arch/arm/isa/insts/str.isa
+++ b/src/arch/arm/isa/insts/str.isa
@@ -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)
diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa
index 903982f29..0f3534385 100644
--- a/src/arch/arm/isa/operands.isa
+++ b/src/arch/arm/isa/operands.isa
@@ -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),
diff --git a/src/arch/arm/isa/templates/mem.isa b/src/arch/arm/isa/templates/mem.isa
index e01470666..6e76b07c1 100644
--- a/src/arch/arm/isa/templates/mem.isa
+++ b/src/arch/arm/isa/templates/mem.isa
@@ -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,