diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2010-06-02 12:58:10 -0500 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2010-06-02 12:58:10 -0500 |
commit | 54ab07e636a0e83527a87c5d88406e3b443b2e99 (patch) | |
tree | 328ec84643a3a0149b39c49b893a9ccc4f8d9729 /src/arch/arm | |
parent | 524a8195e18f17ee6e57bfbcb2752ac6bfa2d8ee (diff) | |
download | gem5-54ab07e636a0e83527a87c5d88406e3b443b2e99.tar.xz |
ARM: Implement the strex instructions.
Diffstat (limited to 'src/arch/arm')
-rw-r--r-- | src/arch/arm/insts/mem.hh | 66 | ||||
-rw-r--r-- | src/arch/arm/isa/insts/ldr.isa | 4 | ||||
-rw-r--r-- | src/arch/arm/isa/insts/macromem.isa | 2 | ||||
-rw-r--r-- | src/arch/arm/isa/insts/mem.isa | 21 | ||||
-rw-r--r-- | src/arch/arm/isa/insts/str.isa | 70 | ||||
-rw-r--r-- | src/arch/arm/isa/operands.isa | 2 | ||||
-rw-r--r-- | src/arch/arm/isa/templates/mem.isa | 162 |
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, |