From 9d4a1bf2ba936499277b96054fbc83c478c0c6be Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 2 Jun 2010 12:58:09 -0500 Subject: ARM: Explicitly keep track of the second destination for double loads/stores. --- src/arch/arm/insts/mem.cc | 2 +- src/arch/arm/insts/mem.hh | 97 ++++++++++++++++++++++++++++++++++++++ src/arch/arm/isa/formats/mem.isa | 12 +++-- src/arch/arm/isa/insts/ldr.isa | 26 +++++----- src/arch/arm/isa/insts/mem.isa | 26 ++++++---- src/arch/arm/isa/insts/str.isa | 19 ++++---- src/arch/arm/isa/operands.isa | 6 +-- src/arch/arm/isa/templates/mem.isa | 70 +++++++++++++++++++++++++++ 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 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, -- cgit v1.2.3