ARM: Explicitly keep track of the second destination for double loads/stores.
authorGabe Black <gblack@eecs.umich.edu>
Wed, 2 Jun 2010 17:58:09 +0000 (12:58 -0500)
committerGabe Black <gblack@eecs.umich.edu>
Wed, 2 Jun 2010 17:58:09 +0000 (12:58 -0500)
src/arch/arm/insts/mem.cc
src/arch/arm/insts/mem.hh
src/arch/arm/isa/formats/mem.isa
src/arch/arm/isa/insts/ldr.isa
src/arch/arm/isa/insts/mem.isa
src/arch/arm/isa/insts/str.isa
src/arch/arm/isa/operands.isa
src/arch/arm/isa/templates/mem.isa

index 6cbe08ac8de4d03675ad8d54e08b42c4ced3e299..521499847e7c119e5ed99ebd2bcac9f6c1136035 100644 (file)
@@ -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) {
index 6ed99ba5bbe527dcf7b7136d5d947784dd532597..dc4b7d6274b180dd02cbdc17c4467897fe5ad899 100644 (file)
@@ -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
     {
index 311ae5b66754c06f809d76a76063364cf2a7565e..1c69a5e0093fb8324f226fd9ca3ade85f327ed9c 100644 (file)
@@ -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):
index da20cab0b0d7d725092a2d637a3be698a3b12fff..6b8c925b658d628b75bed08db79d50c55529a4ce 100644 (file)
@@ -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)
index 21687b225d218cadd9467706095612485f548f33..dc447cf8bc905d7b90fa43476e1e3d250d16a609 100644 (file)
@@ -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):
index 3349ba029d95750beb4e34a18048f25e449613c8..cf9eed74e6073e05689ac2714db04e0b91d45dfd 100644 (file)
@@ -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)
index 903982f2904ba22b5f9ecf7c8e9920d63dd69a87..0f35343850e326103ad3ff0c9f1df77d5b577668 100644 (file)
@@ -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),
 
index e0147066606c267048069eac7df386da0751b799..6e76b07c193189715922636eed49208695579b79 100644 (file)
@@ -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,