ARM: Respect the E bit of the CPSR when doing loads and stores.
authorGabe Black <gblack@eecs.umich.edu>
Wed, 2 Jun 2010 17:58:10 +0000 (12:58 -0500)
committerGabe Black <gblack@eecs.umich.edu>
Wed, 2 Jun 2010 17:58:10 +0000 (12:58 -0500)
src/arch/arm/insts/static_inst.hh
src/arch/arm/isa/insts/ldr.isa
src/arch/arm/isa/insts/macromem.isa
src/arch/arm/isa/insts/str.isa
src/arch/arm/isa/insts/swap.isa

index c0d3136804cc36a99ee4f64d113211f528290c3b..c26053cefc0e2d124288ee10c405c928c9ae9bec 100644 (file)
@@ -231,6 +231,17 @@ class ArmStaticInst : public StaticInst
                       (val & ~PcModeMask));
     }
 
+    template<class T>
+    static T
+    cSwap(T val, bool big)
+    {
+        if (big) {
+            return gtobe(val);
+        } else {
+            return gtole(val);
+        }
+    }
+
     // Perform an interworking branch.
     template<class XC>
     static void
index b216daa6d6d8e153ce63ccdbc5d04eef1421ab85..c170da68821de7f54c1ac5282dd304288b0c5894 100644 (file)
@@ -104,7 +104,8 @@ let {{
             if ldrex:
                 memFlags.append("Request::LLSC")
                 Name = "%s_%s" % (mnem.upper(), Name)
-            accCode = "IWDest = Mem%s;\n" % buildMemSuffix(sign, size)
+            accCode = "IWDest = cSwap(Mem%s, ((CPSR)Cpsr).e);" % \
+                buildMemSuffix(sign, size)
 
         if not prefetch and not ldrex:
             memFlags.append("ArmISA::TLB::AllowUnaligned")
@@ -131,10 +132,12 @@ let {{
         if add:
             wbDiff = 8
         accCode = '''
-        NPC = bits(Mem.ud, 31, 0);
-        uint32_t newCpsr = cpsrWriteByInstr(Cpsr | CondCodes,
-                                            bits(Mem.ud, 63, 32),
-                                            0xF, true);
+        CPSR cpsr = Cpsr;
+        NPC = cSwap<uint32_t>(Mem.ud, cpsr.e);
+        uint32_t newCpsr =
+            cpsrWriteByInstr(cpsr | CondCodes,
+                             cSwap<uint32_t>(Mem.ud >> 32, cpsr.e),
+                             0xF, true);
         Cpsr = ~CondCodesMask & newCpsr;
         CondCodes = CondCodesMask & newCpsr;
         '''
@@ -179,7 +182,8 @@ let {{
             temp = temp;
             ''' % buildMemSuffix(sign, size)
         else:
-            accCode = "IWDest = Mem%s;\n" % buildMemSuffix(sign, size)
+            accCode = "IWDest = cSwap(Mem%s, ((CPSR)Cpsr).e);" % \
+                buildMemSuffix(sign, size)
         if writeback:
             accCode += "Base = Base %s;\n" % offset
 
@@ -207,8 +211,9 @@ let {{
         eaCode += ";"
 
         accCode = '''
-        Dest = bits(Mem.ud, 31, 0);
-        Dest2 = bits(Mem.ud, 63, 32);
+        CPSR cpsr = Cpsr;
+        Dest = cSwap<uint32_t>(Mem.ud, cpsr.e);
+        Dest2 = cSwap<uint32_t>(Mem.ud >> 32, cpsr.e);
         '''
         if ldrex:
             memFlags = ["Request::LLSC"]
@@ -242,8 +247,9 @@ let {{
         eaCode += ";"
 
         accCode = '''
-        Dest = bits(Mem.ud, 31, 0);
-        Dest2 = bits(Mem.ud, 63, 32);
+        CPSR cpsr = Cpsr;
+        Dest = cSwap<uint32_t>(Mem.ud, cpsr.e);
+        Dest2 = cSwap<uint32_t>(Mem.ud >> 32, cpsr.e);
         '''
         if writeback:
             accCode += "Base = Base %s;\n" % offset
index 13eb70b39f55e9c21e713612479ec5d38ff51801..f393c74f0c2530757cf0f0773b8f90a9dab87205 100644 (file)
@@ -51,26 +51,29 @@ let {{
 }};
 
 let {{
+    microLdrUopCode = "IWRa = cSwap(Mem.uw, ((CPSR)Cpsr).e);"
     microLdrUopIop = InstObjParams('ldr_uop', 'MicroLdrUop',
                                    'MicroMemOp',
-                                   {'memacc_code': 'IWRa = Mem;',
+                                   {'memacc_code': microLdrUopCode,
                                     'ea_code': 'EA = Rb + (up ? imm : -imm);',
                                     'predicate_test': predicateTest},
                                    ['IsMicroop'])
 
+    microLdrFpUopCode = "Fa = cSwap(Mem.uw, ((CPSR)Cpsr).e);"
     microLdrFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrFpUop',
                                      'MicroMemOp',
-                                     {'memacc_code': 'Fa = Mem;',
+                                     {'memacc_code': microLdrFpUopCode,
                                       'ea_code': 'EA = Rb + (up ? imm : -imm);',
                                       'predicate_test': predicateTest},
                                      ['IsMicroop'])
 
     microLdrRetUopCode = '''
+        CPSR cpsr = Cpsr;
         uint32_t newCpsr =
-            cpsrWriteByInstr(Cpsr | CondCodes, Spsr, 0xF, true);
+            cpsrWriteByInstr(cpsr | CondCodes, Spsr, 0xF, true);
         Cpsr = ~CondCodesMask & newCpsr;
         CondCodes = CondCodesMask & newCpsr;
-        IWNPC = Mem | ((Spsr & 0x20) ? 1 : 0);
+        IWNPC = cSwap(Mem.uw, cpsr.e) | ((Spsr & 0x20) ? 1 : 0);
     '''
     microLdrRetUopIop = InstObjParams('ldr_ret_uop', 'MicroLdrRetUop',
                                       'MicroMemOp',
@@ -80,16 +83,18 @@ let {{
                                        'predicate_test': predicateTest},
                                       ['IsMicroop'])
 
+    microStrUopCode = "Mem = cSwap(Ra.uw, ((CPSR)Cpsr).e);"
     microStrUopIop = InstObjParams('str_uop', 'MicroStrUop',
                                    'MicroMemOp',
-                                   {'memacc_code': 'Mem = Ra;',
+                                   {'memacc_code': microStrUopCode,
                                     'ea_code': 'EA = Rb + (up ? imm : -imm);',
                                     'predicate_test': predicateTest},
                                    ['IsMicroop'])
 
+    microStrFpUopCode = "Mem = cSwap(Fa.uw, ((CPSR)Cpsr).e);"
     microStrFpUopIop = InstObjParams('strfp_uop', 'MicroStrFpUop',
                                      'MicroMemOp',
-                                     {'memacc_code': 'Mem = Fa;',
+                                     {'memacc_code': microStrFpUopCode,
                                       'ea_code': 'EA = Rb + (up ? imm : -imm);',
                                       'predicate_test': predicateTest},
                                      ['IsMicroop'])
index c22245947bad636115b2132d7bd44e8f7fab0d23..0c92b20df39eef83f40301be1b874b17da381c29 100644 (file)
@@ -93,7 +93,8 @@ let {{
             eaCode += offset
         eaCode += ";"
 
-        accCode = "Mem%s = Dest;\n" % buildMemSuffix(sign, size)
+        accCode = "Mem%(suffix)s = cSwap(Dest%(suffix)s, ((CPSR)Cpsr).e);" % \
+            { "suffix" : buildMemSuffix(sign, size) }
         if writeback:
             accCode += "Base = Base %s;\n" % offset
         base = buildMemBase("MemoryImm", post, writeback)
@@ -121,7 +122,8 @@ let {{
             eaCode += offset
         eaCode += ";"
 
-        accCode = "Mem%s = Dest;\n" % buildMemSuffix(sign, size)
+        accCode = "Mem%(suffix)s = cSwap(Dest%(suffix)s, ((CPSR)Cpsr).e);" % \
+            { "suffix" : buildMemSuffix(sign, size) }
         if writeback:
             accCode += "Base = Base %s;\n" % offset
         base = buildMemBase("MemoryReg", post, writeback)
@@ -146,7 +148,11 @@ let {{
             eaCode += offset
         eaCode += ";"
 
-        accCode = 'Mem.ud = (Dest.ud & mask(32)) | (Dest2.ud << 32);'
+        accCode = '''
+        CPSR cpsr = Cpsr;
+        Mem.ud = (uint64_t)cSwap(Dest.uw, cpsr.e) |
+                 ((uint64_t)cSwap(Dest2.uw, cpsr.e) << 32);
+        '''
         if writeback:
             accCode += "Base = Base %s;\n" % offset
         base = buildMemBase("MemoryDImm", post, writeback)
@@ -171,7 +177,11 @@ let {{
             eaCode += offset
         eaCode += ";"
 
-        accCode = 'Mem.ud = (Dest.ud & mask(32)) | (Dest2.ud << 32);'
+        accCode = '''
+        CPSR cpsr = Cpsr;
+        Mem.ud = (uint64_t)cSwap(Dest.uw, cpsr.e) |
+                 ((uint64_t)cSwap(Dest2.uw, cpsr.e) << 32);
+        '''
         if writeback:
             accCode += "Base = Base %s;\n" % offset
         base = buildMemBase("MemoryDReg", post, writeback)
index 9456c1314107869c0c4f6747019ecfbc6ad13196..29b5b444f56dbf6aa29c6b280d0a2339f0dba698 100644 (file)
@@ -44,7 +44,8 @@ let {{
     (newHeader,
      newDecoder,
      newExec) = SwapBase("swp", "Swp", "EA = Base;",
-                         "Mem = Op1;", "Dest = memData;",
+                         "Mem = cSwap(Op1.uw, ((CPSR)Cpsr).e);",
+                         "Dest = cSwap((uint32_t)memData, ((CPSR)Cpsr).e);",
                          ["Request::MEM_SWAP",
                           "ArmISA::TLB::AlignWord",
                           "ArmISA::TLB::MustBeOne"], [])
@@ -55,7 +56,8 @@ let {{
     (newHeader,
      newDecoder,
      newExec) = SwapBase("swpb", "Swpb", "EA = Base;",
-                         "Mem.ub = Op1.ub;", "Dest.ub = (uint8_t)memData;",
+                         "Mem.ub = cSwap(Op1.ub, ((CPSR)Cpsr).e);",
+                         "Dest.ub = cSwap((uint8_t)memData, ((CPSR)Cpsr).e);",
                          ["Request::MEM_SWAP",
                           "ArmISA::TLB::AlignByte",
                           "ArmISA::TLB::MustBeOne"], [])