summaryrefslogtreecommitdiff
path: root/src/arch/arm
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:10 -0500
committerGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:10 -0500
commit54ab07e636a0e83527a87c5d88406e3b443b2e99 (patch)
tree328ec84643a3a0149b39c49b893a9ccc4f8d9729 /src/arch/arm
parent524a8195e18f17ee6e57bfbcb2752ac6bfa2d8ee (diff)
downloadgem5-54ab07e636a0e83527a87c5d88406e3b443b2e99.tar.xz
ARM: Implement the strex instructions.
Diffstat (limited to 'src/arch/arm')
-rw-r--r--src/arch/arm/insts/mem.hh66
-rw-r--r--src/arch/arm/isa/insts/ldr.isa4
-rw-r--r--src/arch/arm/isa/insts/macromem.isa2
-rw-r--r--src/arch/arm/isa/insts/mem.isa21
-rw-r--r--src/arch/arm/isa/insts/str.isa70
-rw-r--r--src/arch/arm/isa/operands.isa2
-rw-r--r--src/arch/arm/isa/templates/mem.isa162
7 files changed, 298 insertions, 29 deletions
diff --git a/src/arch/arm/insts/mem.hh b/src/arch/arm/insts/mem.hh
index d5b5d3519..ae3437120 100644
--- a/src/arch/arm/insts/mem.hh
+++ b/src/arch/arm/insts/mem.hh
@@ -142,6 +142,27 @@ class MemoryImm : public Memory
}
};
+class MemoryExImm : public MemoryImm
+{
+ protected:
+ IntRegIndex result;
+
+ MemoryExImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
+ IntRegIndex _result, IntRegIndex _dest, IntRegIndex _base,
+ bool _add, int32_t _imm)
+ : MemoryImm(mnem, _machInst, __opClass, _dest, _base, _add, _imm),
+ result(_result)
+ {}
+
+ void
+ printDest(std::ostream &os) const
+ {
+ printReg(os, result);
+ os << ", ";
+ MemoryImm::printDest(os);
+ }
+};
+
// The address is a base register plus an immediate.
class MemoryDImm : public MemoryImm
{
@@ -164,6 +185,27 @@ class MemoryDImm : public MemoryImm
}
};
+class MemoryExDImm : public MemoryDImm
+{
+ protected:
+ IntRegIndex result;
+
+ MemoryExDImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
+ IntRegIndex _result, IntRegIndex _dest, IntRegIndex _dest2,
+ IntRegIndex _base, bool _add, int32_t _imm)
+ : MemoryDImm(mnem, _machInst, __opClass, _dest, _dest2,
+ _base, _add, _imm), result(_result)
+ {}
+
+ void
+ printDest(std::ostream &os) const
+ {
+ printReg(os, result);
+ os << ", ";
+ MemoryDImm::printDest(os);
+ }
+};
+
// The address is a shifted register plus an immediate
class MemoryReg : public Memory
{
@@ -266,6 +308,14 @@ class MemoryOffset : public Base
{}
MemoryOffset(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass, IntRegIndex _result,
+ IntRegIndex _dest, IntRegIndex _dest2,
+ IntRegIndex _base, bool _add, int32_t _imm)
+ : Base(mnem, _machInst, __opClass, _result,
+ _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,
@@ -308,6 +358,14 @@ class MemoryPreIndex : public Base
{}
MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass, IntRegIndex _result,
+ IntRegIndex _dest, IntRegIndex _dest2,
+ IntRegIndex _base, bool _add, int32_t _imm)
+ : Base(mnem, _machInst, __opClass, _result,
+ _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,
@@ -350,6 +408,14 @@ class MemoryPostIndex : public Base
{}
MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass, IntRegIndex _result,
+ IntRegIndex _dest, IntRegIndex _dest2,
+ IntRegIndex _base, bool _add, int32_t _imm)
+ : Base(mnem, _machInst, __opClass, _result,
+ _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,
diff --git a/src/arch/arm/isa/insts/ldr.isa b/src/arch/arm/isa/insts/ldr.isa
index c170da688..ce87d7a9e 100644
--- a/src/arch/arm/isa/insts/ldr.isa
+++ b/src/arch/arm/isa/insts/ldr.isa
@@ -66,8 +66,8 @@ let {{
(newHeader,
newDecoder,
newExec) = loadStoreBase(name, Name, imm,
- eaCode, accCode,
- memFlags, instFlags, double,
+ eaCode, accCode, "",
+ memFlags, instFlags, double, False,
base, execTemplateBase = 'Load')
header_output += newHeader
diff --git a/src/arch/arm/isa/insts/macromem.isa b/src/arch/arm/isa/insts/macromem.isa
index f393c74f0..781cbca7a 100644
--- a/src/arch/arm/isa/insts/macromem.isa
+++ b/src/arch/arm/isa/insts/macromem.isa
@@ -87,6 +87,7 @@ let {{
microStrUopIop = InstObjParams('str_uop', 'MicroStrUop',
'MicroMemOp',
{'memacc_code': microStrUopCode,
+ 'postacc_code': "",
'ea_code': 'EA = Rb + (up ? imm : -imm);',
'predicate_test': predicateTest},
['IsMicroop'])
@@ -95,6 +96,7 @@ let {{
microStrFpUopIop = InstObjParams('strfp_uop', 'MicroStrFpUop',
'MicroMemOp',
{'memacc_code': microStrFpUopCode,
+ 'postacc_code': "",
'ea_code': 'EA = Rb + (up ? imm : -imm);',
'predicate_test': predicateTest},
['IsMicroop'])
diff --git a/src/arch/arm/isa/insts/mem.isa b/src/arch/arm/isa/insts/mem.isa
index db3665a54..e17235c81 100644
--- a/src/arch/arm/isa/insts/mem.isa
+++ b/src/arch/arm/isa/insts/mem.isa
@@ -39,7 +39,7 @@
let {{
def loadStoreBaseWork(name, Name, imm, swp, rfe, codeBlobs, memFlags,
- instFlags, double, base = 'Memory',
+ instFlags, double, strex, base = 'Memory',
execTemplateBase = ''):
# Make sure flags are in lists (convert to lists if not).
memFlags = makeList(memFlags)
@@ -70,6 +70,12 @@ let {{
if double:
declareTemplate = LoadStoreDImmDeclare
constructTemplate = LoadStoreDImmConstructor
+ if strex:
+ declareTemplate = StoreExDImmDeclare
+ constructTemplate = StoreExDImmConstructor
+ elif strex:
+ declareTemplate = StoreExImmDeclare
+ constructTemplate = StoreExImmConstructor
else:
declareTemplate = LoadStoreImmDeclare
constructTemplate = LoadStoreImmConstructor
@@ -88,14 +94,15 @@ let {{
+ initiateAccTemplate.subst(iop)
+ completeAccTemplate.subst(iop))
- def loadStoreBase(name, Name, imm, eaCode, accCode, memFlags,
- instFlags, double, base = 'Memory',
+ def loadStoreBase(name, Name, imm, eaCode, accCode, postAccCode,
+ memFlags, instFlags, double, strex, base = 'Memory',
execTemplateBase = ''):
codeBlobs = { "ea_code": eaCode,
"memacc_code": accCode,
+ "postacc_code": postAccCode,
"predicate_test": predicateTest }
return loadStoreBaseWork(name, Name, imm, False, False, codeBlobs,
- memFlags, instFlags, double, base,
+ memFlags, instFlags, double, strex, base,
execTemplateBase)
def RfeBase(name, Name, eaCode, accCode, memFlags, instFlags):
@@ -103,7 +110,8 @@ let {{
"memacc_code": accCode,
"predicate_test": predicateTest }
return loadStoreBaseWork(name, Name, False, False, True, codeBlobs,
- memFlags, instFlags, False, 'RfeOp', 'Load')
+ memFlags, instFlags, False, False,
+ 'RfeOp', 'Load')
def SwapBase(name, Name, eaCode, preAccCode, postAccCode, memFlags,
instFlags):
@@ -112,7 +120,8 @@ let {{
"postacc_code": postAccCode,
"predicate_test": predicateTest }
return loadStoreBaseWork(name, Name, False, True, False, codeBlobs,
- memFlags, instFlags, False, 'Swap', 'Swap')
+ memFlags, instFlags, False, 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 0c92b20df..f9002a6f7 100644
--- a/src/arch/arm/isa/insts/str.isa
+++ b/src/arch/arm/isa/insts/str.isa
@@ -61,23 +61,24 @@ let {{
return memClassName("STORE_REGD", post, add, writeback,
4, False, False)
- def emitStore(name, Name, imm, eaCode, accCode, \
- memFlags, instFlags, base, double=False):
+ def emitStore(name, Name, imm, eaCode, accCode, postAccCode, \
+ memFlags, instFlags, base, double=False, strex=False,
+ execTemplateBase = 'Store'):
global header_output, decoder_output, exec_output
(newHeader,
newDecoder,
newExec) = loadStoreBase(name, Name, imm,
- eaCode, accCode,
- memFlags, instFlags, double,
- base, execTemplateBase = 'Store')
+ eaCode, accCode, postAccCode,
+ memFlags, instFlags, double, strex,
+ base, execTemplateBase = execTemplateBase)
header_output += newHeader
decoder_output += newDecoder
exec_output += newExec
def buildImmStore(mnem, post, add, writeback, \
- size=4, sign=False, user=False):
+ size=4, sign=False, user=False, strex=False):
name = mnem
Name = storeImmClassName(post, add, writeback, \
size, sign, user)
@@ -97,15 +98,26 @@ let {{
{ "suffix" : buildMemSuffix(sign, size) }
if writeback:
accCode += "Base = Base %s;\n" % offset
- base = buildMemBase("MemoryImm", post, writeback)
- emitStore(name, Name, True, eaCode, accCode, \
- ["ArmISA::TLB::MustBeOne", \
- "ArmISA::TLB::AllowUnaligned", \
- "%d" % (size - 1)], [], base)
+ memFlags = ["ArmISA::TLB::MustBeOne", "%d" % (size - 1)]
+ if strex:
+ memFlags.append("Request::LLSC")
+ Name = "%s_%s" % (mnem.upper(), Name)
+ base = buildMemBase("MemoryExImm", post, writeback)
+ postAccCode = "Result = !writeResult;"
+ execTemplateBase = 'StoreEx'
+ else:
+ memFlags.append("ArmISA::TLB::AllowUnaligned")
+ base = buildMemBase("MemoryImm", post, writeback)
+ postAccCode = ""
+ execTemplateBase = 'Store'
+
+ emitStore(name, Name, True, eaCode, accCode, postAccCode, \
+ memFlags, [], base, strex=strex,
+ execTemplateBase = execTemplateBase)
def buildRegStore(mnem, post, add, writeback, \
- size=4, sign=False, user=False):
+ size=4, sign=False, user=False, strex=False):
name = mnem
Name = storeRegClassName(post, add, writeback,
size, sign, user)
@@ -128,12 +140,12 @@ let {{
accCode += "Base = Base %s;\n" % offset
base = buildMemBase("MemoryReg", post, writeback)
- emitStore(name, Name, False, eaCode, accCode, \
+ emitStore(name, Name, False, eaCode, accCode, "",\
["ArmISA::TLB::MustBeOne", \
"ArmISA::TLB::AllowUnaligned", \
"%d" % (size - 1)], [], base)
- def buildDoubleImmStore(mnem, post, add, writeback):
+ def buildDoubleImmStore(mnem, post, add, writeback, strex=False):
name = mnem
Name = storeDoubleImmClassName(post, add, writeback)
@@ -155,11 +167,20 @@ let {{
'''
if writeback:
accCode += "Base = Base %s;\n" % offset
- base = buildMemBase("MemoryDImm", post, writeback)
- emitStore(name, Name, True, eaCode, accCode, \
- ["ArmISA::TLB::MustBeOne",
- "ArmISA::TLB::AlignWord"], [], base, double=True)
+ memFlags = ["ArmISA::TLB::MustBeOne",
+ "ArmISA::TLB::AlignWord"]
+ if strex:
+ memFlags.append("Request::LLSC")
+ Name = "%s_%s" % (mnem.upper(), Name)
+ base = buildMemBase("MemoryExDImm", post, writeback)
+ postAccCode = "Result = !writeResult;"
+ else:
+ base = buildMemBase("MemoryDImm", post, writeback)
+ postAccCode = ""
+
+ emitStore(name, Name, True, eaCode, accCode, postAccCode, \
+ memFlags, [], base, double=True, strex=strex)
def buildDoubleRegStore(mnem, post, add, writeback):
name = mnem
@@ -186,9 +207,11 @@ let {{
accCode += "Base = Base %s;\n" % offset
base = buildMemBase("MemoryDReg", post, writeback)
- emitStore(name, Name, False, eaCode, accCode, \
- ["ArmISA::TLB::MustBeOne", \
- "ArmISA::TLB::AlignWord"], [], base, double=True)
+ memFlags = ["ArmISA::TLB::MustBeOne",
+ "ArmISA::TLB::AlignWord"]
+
+ emitStore(name, Name, False, eaCode, accCode, "", \
+ memFlags, [], base, double=True)
def buildStores(mnem, size=4, sign=False, user=False):
buildImmStore(mnem, True, True, True, size, sign, user)
@@ -226,4 +249,9 @@ let {{
buildStores("strht", size=2, user=True)
buildDoubleStores("strd")
+
+ buildImmStore("strex", False, True, False, size=4, strex=True)
+ buildImmStore("strexh", False, True, False, size=2, strex=True)
+ buildImmStore("strexb", False, True, False, size=1, strex=True)
+ buildDoubleImmStore("strexd", False, True, False, strex=True)
}};
diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa
index a8b0b197a..3fda93668 100644
--- a/src/arch/arm/isa/operands.isa
+++ b/src/arch/arm/isa/operands.isa
@@ -91,6 +91,8 @@ def operands {{
#Abstracted integer reg operands
'Dest': ('IntReg', 'uw', 'dest', 'IsInteger', 2,
maybePCRead, maybePCWrite),
+ 'Result': ('IntReg', 'uw', 'result', 'IsInteger', 2,
+ maybePCRead, maybePCWrite),
'Dest2': ('IntReg', 'uw', 'dest2', 'IsInteger', 2,
maybePCRead, maybePCWrite),
'IWDest': ('IntReg', 'uw', 'dest', 'IsInteger', 2,
diff --git a/src/arch/arm/isa/templates/mem.isa b/src/arch/arm/isa/templates/mem.isa
index e44fe41db..7c93cd4ee 100644
--- a/src/arch/arm/isa/templates/mem.isa
+++ b/src/arch/arm/isa/templates/mem.isa
@@ -190,6 +190,77 @@ def template StoreExecute {{
}
}};
+def template StoreExExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (%(predicate_test)s)
+ {
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ uint64_t writeResult;
+
+ if (fault == NoFault) {
+ fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
+ memAccessFlags, &writeResult);
+ if (traceData) { traceData->setData(Mem); }
+ }
+
+ if (fault == NoFault) {
+ %(postacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+ }
+
+ return fault;
+ }
+}};
+
+def template StoreExInitiateAcc {{
+ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (%(predicate_test)s)
+ {
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
+ memAccessFlags, NULL);
+ if (traceData) { traceData->setData(Mem); }
+ }
+
+ // Need to write back any potential address register update
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+ }
+
+ return fault;
+ }
+}};
+
def template StoreInitiateAcc {{
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
@@ -294,6 +365,30 @@ def template StoreCompleteAcc {{
}
}};
+def template StoreExCompleteAcc {{
+ Fault %(class_name)s::completeAcc(PacketPtr pkt,
+ %(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+
+ %(op_decl)s;
+ %(op_rd)s;
+
+ if (%(predicate_test)s)
+ {
+ uint64_t writeResult = pkt->req->getExtraData();
+ %(postacc_code)s;
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+ }
+
+ return fault;
+ }
+}};
+
def template RfeDeclare {{
/**
* Static instruction class for "%(mnemonic)s".
@@ -355,6 +450,27 @@ def template LoadStoreDImmDeclare {{
};
}};
+def template StoreExDImmDeclare {{
+ /**
+ * Static instruction class for "%(mnemonic)s".
+ */
+ class %(class_name)s : public %(base_class)s
+ {
+ public:
+
+ /// Constructor.
+ %(class_name)s(ExtMachInst machInst,
+ uint32_t _result, 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".
@@ -375,6 +491,27 @@ def template LoadStoreImmDeclare {{
};
}};
+def template StoreExImmDeclare {{
+ /**
+ * Static instruction class for "%(mnemonic)s".
+ */
+ class %(class_name)s : public %(base_class)s
+ {
+ public:
+
+ /// Constructor.
+ %(class_name)s(ExtMachInst machInst,
+ uint32_t _result, uint32_t _dest, uint32_t _base,
+ bool _add, int32_t _imm);
+
+ %(BasicExecDeclare)s
+
+ %(InitiateAccDeclare)s
+
+ %(CompleteAccDeclare)s
+ };
+}};
+
def template LoadStoreDRegDeclare {{
/**
* Static instruction class for "%(mnemonic)s".
@@ -460,6 +597,19 @@ def template LoadStoreDImmConstructor {{
}
}};
+def template StoreExDImmConstructor {{
+ inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
+ uint32_t _result, uint32_t _dest, uint32_t _dest2,
+ uint32_t _base, bool _add, int32_t _imm)
+ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
+ (IntRegIndex)_result,
+ (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)
@@ -470,6 +620,18 @@ def template LoadStoreImmConstructor {{
}
}};
+def template StoreExImmConstructor {{
+ inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
+ uint32_t _result, uint32_t _dest, uint32_t _base,
+ bool _add, int32_t _imm)
+ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
+ (IntRegIndex)_result, (IntRegIndex)_dest,
+ (IntRegIndex)_base, _add, _imm)
+ {
+ %(constructor)s;
+ }
+}};
+
def template LoadStoreDRegConstructor {{
inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,