ISA: Use readBytes/writeBytes for all instruction level memory operations.
authorGabe Black <gblack@eecs.umich.edu>
Sun, 3 Jul 2011 05:34:29 +0000 (22:34 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Sun, 3 Jul 2011 05:34:29 +0000 (22:34 -0700)
16 files changed:
src/arch/alpha/isa/main.isa
src/arch/alpha/isa/mem.isa
src/arch/arm/isa/includes.isa
src/arch/arm/isa/templates/mem.isa
src/arch/generic/memhelpers.hh [new file with mode: 0644]
src/arch/mips/isa/formats/mem.isa
src/arch/mips/isa/includes.isa
src/arch/power/isa/formats/mem.isa
src/arch/power/isa/includes.isa
src/arch/sparc/isa/formats/mem/swap.isa
src/arch/sparc/isa/formats/mem/util.isa
src/arch/sparc/isa/includes.isa
src/arch/x86/insts/microldstop.hh
src/arch/x86/isa/includes.isa
src/arch/x86/isa/microops/ldstop.isa
src/arch/x86/memhelpers.hh [new file with mode: 0644]

index 4b5678e81fe90080453b6aa814cab5e9a0e57760..c03a999707c741d57e20ba48915027cbcc0c413e 100644 (file)
@@ -73,6 +73,7 @@ output exec {{
 
 #include "arch/alpha/registers.hh"
 #include "arch/alpha/regredir.hh"
+#include "arch/generic/memhelpers.hh"
 #include "base/cp_annotate.hh"
 #include "base/fenv.hh"
 #include "config/ss_compatible_fp.hh"
index fe72e049e4f659da0edb0892c5f136a9e6ca28d0..ed5128204dd1ccc77458c37caceeac98a9e3ebc1 100644 (file)
@@ -197,7 +197,7 @@ def template LoadExecute {{
         %(ea_code)s;
 
         if (fault == NoFault) {
-            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
+            fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
             %(memacc_code)s;
         }
 
@@ -223,7 +223,7 @@ def template LoadInitiateAcc {{
         %(ea_code)s;
 
         if (fault == NoFault) {
-            fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
+            fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags);
         }
 
         return fault;
@@ -241,7 +241,7 @@ def template LoadCompleteAcc {{
         %(fp_enable_check)s;
         %(op_decl)s;
 
-        Mem = pkt->get<typeof(Mem)>();
+        getMem(pkt, Mem, traceData);
 
         if (fault == NoFault) {
             %(memacc_code)s;
@@ -273,8 +273,8 @@ def template StoreExecute {{
         }
 
         if (fault == NoFault) {
-            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
-                              memAccessFlags, NULL);
+            fault = writeMemAtomic(xc, traceData, Mem, EA,
+                    memAccessFlags, NULL);
         }
 
         if (fault == NoFault) {
@@ -307,8 +307,8 @@ def template StoreCondExecute {{
         }
 
         if (fault == NoFault) {
-            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
-                              memAccessFlags, &write_result);
+            fault = writeMemAtomic(xc, traceData, Mem, EA,
+                    memAccessFlags, &write_result);
         }
 
         if (fault == NoFault) {
@@ -340,8 +340,8 @@ def template StoreInitiateAcc {{
         }
 
         if (fault == NoFault) {
-            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
-                              memAccessFlags, NULL);
+            fault = writeMemTiming(xc, traceData, Mem, EA,
+                    memAccessFlags, NULL);
         }
 
         return fault;
index b54545e10a6d73700b234802926bafc1972e5d35..bfd6fedd4b0cc93bc3d49cda0b6d9a0074cbb5ec 100644 (file)
@@ -80,6 +80,7 @@ output exec {{
 #include "arch/arm/faults.hh"
 #include "arch/arm/isa_traits.hh"
 #include "arch/arm/utility.hh"
+#include "arch/generic/memhelpers.hh"
 #include "base/condcodes.hh"
 #include "sim/pseudo_inst.hh"
 #if defined(linux)
index cb255feda77076d90d00707b16edffc0b85ae8b4..422d37326c37b464f84517f72cd510ad3eba5d3e 100644 (file)
@@ -87,8 +87,8 @@ def template SwapExecute {{
             %(preacc_code)s;
 
             if (fault == NoFault) {
-                fault = xc->write((uint%(mem_acc_size)d_t&)Mem,
-                        EA, memAccessFlags, &memData);
+                fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
+                        &memData);
             }
 
             if (fault == NoFault) {
@@ -123,8 +123,8 @@ def template SwapInitiateAcc {{
             %(preacc_code)s;
 
             if (fault == NoFault) {
-                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
-                                  memAccessFlags, &memData);
+                fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
+                        &memData);
             }
         } else {
             xc->setPredicate(false);
@@ -147,7 +147,8 @@ def template SwapCompleteAcc {{
         if (%(predicate_test)s)
         {
             // ARM instructions will not have a pkt if the predicate is false
-            uint64_t memData = pkt->get<typeof(Mem)>();
+            getMem(pkt, Mem, traceData);
+            uint64_t memData = Mem;
 
             %(postacc_code)s;
 
@@ -174,7 +175,7 @@ def template LoadExecute {{
         if (%(predicate_test)s)
         {
             if (fault == NoFault) {
-                fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
+                fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
                 %(memacc_code)s;
             }
 
@@ -241,8 +242,8 @@ def template StoreExecute {{
             }
 
             if (fault == NoFault) {
-                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
-                                  memAccessFlags, NULL);
+                fault = writeMemAtomic(xc, traceData, Mem, EA,
+                        memAccessFlags, NULL);
             }
 
             if (fault == NoFault) {
@@ -314,8 +315,8 @@ def template StoreExExecute {{
             uint64_t writeResult;
 
             if (fault == NoFault) {
-                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
-                                  memAccessFlags, &writeResult);
+                fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
+                        &writeResult);
             }
 
             if (fault == NoFault) {
@@ -351,8 +352,8 @@ def template StoreExInitiateAcc {{
             }
 
             if (fault == NoFault) {
-                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
-                                  memAccessFlags, NULL);
+                fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
+                        NULL);
             }
         } else {
             xc->setPredicate(false);
@@ -380,8 +381,8 @@ def template StoreInitiateAcc {{
             }
 
             if (fault == NoFault) {
-                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
-                                  memAccessFlags, NULL);
+                fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
+                        NULL);
             }
         } else {
             xc->setPredicate(false);
@@ -437,7 +438,7 @@ def template LoadInitiateAcc {{
         if (%(predicate_test)s)
         {
             if (fault == NoFault) {
-                fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
+                fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags);
             }
         } else {
             xc->setPredicate(false);
@@ -489,7 +490,7 @@ def template LoadCompleteAcc {{
         if (%(predicate_test)s)
         {
             // ARM instructions will not have a pkt if the predicate is false
-            Mem = pkt->get<typeof(Mem)>();
+            getMem(pkt, Mem, traceData);
 
             if (fault == NoFault) {
                 %(memacc_code)s;
diff --git a/src/arch/generic/memhelpers.hh b/src/arch/generic/memhelpers.hh
new file mode 100644 (file)
index 0000000..f66a1a2
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2011 Google
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __ARCH_GENERIC_MEMHELPERS_HH__
+#define __ARCH_GENERIC_MEMHELPERS_HH__
+
+#include "base/types.hh"
+#include "sim/byteswap.hh"
+#include "sim/fault_fwd.hh"
+#include "sim/insttracer.hh"
+
+/// Read from memory in timing mode.
+template <class XC, class MemT>
+Fault
+readMemTiming(XC *xc, Trace::InstRecord *traceData, Addr addr,
+        MemT &mem, unsigned flags)
+{
+    return xc->readBytes(addr, (uint8_t *)&mem, sizeof(MemT), flags);
+}
+
+/// Extract the data returned from a timing mode read.
+template <class MemT>
+void
+getMem(PacketPtr pkt, MemT &mem, Trace::InstRecord *traceData)
+{
+    mem = pkt->get<MemT>();
+    if (traceData)
+        traceData->setData(mem);
+}
+
+/// Read from memory in atomic mode.
+template <class XC, class MemT>
+Fault
+readMemAtomic(XC *xc, Trace::InstRecord *traceData, Addr addr, MemT &mem,
+        unsigned flags)
+{
+    memset(&mem, 0, sizeof(mem));
+    Fault fault = readMemTiming(xc, traceData, addr, mem, flags);
+    if (fault == NoFault) {
+        mem = gtoh(mem);
+        if (traceData)
+            traceData->setData(mem);
+    }
+    return fault;
+}
+
+/// Write to memory in timing mode.
+template <class XC, class MemT>
+Fault
+writeMemTiming(XC *xc, Trace::InstRecord *traceData, MemT mem, Addr addr,
+        unsigned flags, uint64_t *res)
+{
+    if (traceData) {
+        traceData->setData(mem);
+    }
+    mem = TheISA::htog(mem);
+    return xc->writeBytes((uint8_t *)&mem, sizeof(MemT), addr, flags, res);
+}
+
+/// Write to memory in atomic mode.
+template <class XC, class MemT>
+Fault
+writeMemAtomic(XC *xc, Trace::InstRecord *traceData, const MemT &mem,
+        Addr addr, unsigned flags, uint64_t *res)
+{
+    Fault fault = writeMemTiming(xc, traceData, mem, addr, flags, res);
+    if (fault == NoFault && res != NULL) {
+        *res = gtoh((MemT)*res);
+    }
+    return fault;
+}
+
+#endif
index c4666e4ab6ebea113c1ac65fa0fd117737a03c29..bc3a2b3cef46d8d4ef0a67a708dbd78472692634 100644 (file)
@@ -216,7 +216,7 @@ def template LoadExecute {{
         %(ea_code)s;
 
         if (fault == NoFault) {
-            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
+            fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
             %(memacc_code)s;
         }
 
@@ -248,7 +248,7 @@ def template LoadInitiateAcc {{
         %(ea_code)s;
 
         if (fault == NoFault) {
-            fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
+            fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags);
         }
 
         return fault;
@@ -272,7 +272,7 @@ def template LoadCompleteAcc {{
         %(op_decl)s;
         %(op_rd)s;
 
-        Mem = pkt->get<typeof(Mem)>();
+        getMem(pkt, Mem, traceData);
 
         if (fault == NoFault) {
             %(memacc_code)s;
@@ -303,8 +303,8 @@ def template StoreExecute {{
         }
 
         if (fault == NoFault) {
-            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
-                              memAccessFlags, NULL);
+            fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
+                    NULL);
         }
 
         if (fault == NoFault) {
@@ -339,8 +339,8 @@ def template StoreFPExecute {{
         }
 
         if (fault == NoFault) {
-            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
-                              memAccessFlags, NULL);
+            fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
+                    NULL);
         }
 
         if (fault == NoFault) {
@@ -373,8 +373,8 @@ def template StoreCondExecute {{
         }
 
         if (fault == NoFault) {
-            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
-                              memAccessFlags, &write_result);
+            fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
+                    &write_result);
         }
 
         if (fault == NoFault) {
@@ -406,8 +406,8 @@ def template StoreInitiateAcc {{
         }
 
         if (fault == NoFault) {
-            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
-                              memAccessFlags, NULL);
+            fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
+                    NULL);
         }
 
         return fault;
@@ -559,14 +559,15 @@ def format LoadUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3;
 
 def format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
                      mem_flags = [], inst_flags = []) {{
-    decl_code = 'uint32_t mem_word = 0;\n'
-    decl_code += 'uint32_t unaligned_addr = Rs + disp;\n'
-    decl_code += 'uint32_t byte_offset = unaligned_addr & 3;\n'
-    decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n'
-    decl_code += '\tbyte_offset ^= 3;\n'
-    decl_code += '#endif\n'
-    decl_code += 'fault = xc->read(EA, (uint32_t&)mem_word, memAccessFlags);\n'
-    #decl_code += 'xc->readFunctional(EA,(uint32_t&)mem_word);'
+    decl_code = '''
+        uint32_t mem_word = 0;
+        uint32_t unaligned_addr = Rs + disp;
+        uint32_t byte_offset = unaligned_addr & 3;
+        #if BYTE_ORDER == BIG_ENDIAN
+            byte_offset ^= 3;
+        #endif
+        fault = readMemAtomic(xc, traceData, EA, mem_word, memAccessFlags);
+    '''
     memacc_code = decl_code + memacc_code + '\nMem = mem_word;\n'
 
     (header_output, decoder_output, decode_block, exec_output) = \
index 73d751f6eae2b8bf360b2a624c2df29a7a622686..9c118383962a2f94cf8aaa45887bc721dad5b6be 100644 (file)
@@ -68,6 +68,7 @@ using namespace MipsISA;
 output exec {{
 #include <math.h>
 
+#include "arch/generic/memhelpers.hh"
 #include "arch/mips/dsp.hh"
 #include "arch/mips/dt_constants.hh"
 #include "arch/mips/faults.hh"
index 014e4ff5ac0fc97fe32a97eb155fe1816ad17ff5..519275a16ff3d8a8903a350f9357ef4181bfdc24 100644 (file)
@@ -84,7 +84,7 @@ def template LoadExecute {{
         %(ea_code)s;
 
         if (fault == NoFault) {
-            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
+            fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
             %(memacc_code)s;
         }
 
@@ -109,7 +109,7 @@ def template LoadInitiateAcc {{
         %(ea_code)s;
 
         if (fault == NoFault) {
-            fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
+            fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags);
             xc->setEA(EA);
         }
 
@@ -132,7 +132,7 @@ def template LoadCompleteAcc {{
 
         EA = xc->getEA();
 
-        val = pkt->get<uint%(mem_acc_size)d_t>();
+        getMem(pkt, val, traceData);
         *((uint%(mem_acc_size)d_t*)&Mem) = val;
 
         if (fault == NoFault) {
@@ -164,8 +164,8 @@ def template StoreExecute {{
         }
 
         if (fault == NoFault) {
-            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
-                              memAccessFlags, NULL);
+            fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
+                    NULL);
         }
 
         if (fault == NoFault) {
@@ -193,8 +193,8 @@ def template StoreInitiateAcc {{
         }
 
         if (fault == NoFault) {
-            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
-                              memAccessFlags, NULL);
+            fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
+                    NULL);
         }
 
         // Need to write back any potential address register update
index 5c2b7414104e535563c5064edbbfb46078c06b2c..f6292eaab023146097c6ae64e7c8c2a6294690b4 100644 (file)
@@ -75,6 +75,7 @@ output exec {{
 #include <fenv.h>
 #endif
 
+#include "arch/generic/memhelpers.hh"
 #include "arch/power/faults.hh"
 #include "arch/power/isa_traits.hh"
 #include "arch/power/utility.hh"
index 99bbf3a68e40eedd07fbe8de1ea9d6609d4774ce..17a490c4b8d7be1f555f3ea7d26b387268d8b8f4 100644 (file)
@@ -50,8 +50,8 @@ def template SwapExecute {{
             }
             if (storeCond && fault == NoFault) {
                 %(EA_trunc)s
-                fault = xc->write((uint%(mem_acc_size)s_t)Mem,
-                        EA, %(asi_val)s, &mem_data);
+                fault = writeMemAtomic(xc, traceData, Mem, EA,
+                        %(asi_val)s, &mem_data);
             }
             if (fault == NoFault) {
                 // Handle the swapping
@@ -87,8 +87,8 @@ def template SwapInitiateAcc {{
             }
             if (fault == NoFault) {
                 %(EA_trunc)s
-                fault = xc->write((uint%(mem_acc_size)s_t)Mem,
-                        EA, %(asi_val)s, &mem_data);
+                fault = writeMemTiming(xc, traceData, Mem, EA, %(asi_val)s,
+                        &mem_data);
             }
             return fault;
         }
@@ -103,7 +103,8 @@ def template SwapCompleteAcc {{
             Fault fault = NoFault;
             %(op_decl)s;
 
-            uint64_t mem_data = pkt->get<uint%(mem_acc_size)s_t>();
+            getMem(pkt, Mem, traceData);
+            uint64_t mem_data = Mem;
 
             if (fault == NoFault) {
                 // Handle the swapping
index aaa04b4bf6896a8373590012e67a40bbb552e09a..06206c02bed4cfd8060f897318df5785dbb0b9c5 100644 (file)
@@ -143,7 +143,7 @@ def template LoadExecute {{
             %(fault_check)s;
             if (fault == NoFault) {
                 %(EA_trunc)s
-                fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, %(asi_val)s);
+                fault = readMemAtomic(xc, traceData, EA, Mem, %(asi_val)s);
             }
             if (fault == NoFault) {
                 %(code)s;
@@ -171,7 +171,7 @@ def template LoadInitiateAcc {{
             %(fault_check)s;
             if (fault == NoFault) {
                 %(EA_trunc)s
-                fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, %(asi_val)s);
+                fault = readMemTiming(xc, traceData, EA, Mem, %(asi_val)s);
             }
             return fault;
         }
@@ -184,7 +184,7 @@ def template LoadCompleteAcc {{
             Fault fault = NoFault;
             %(op_decl)s;
             %(op_rd)s;
-            Mem = pkt->get<typeof(Mem)>();
+            getMem(pkt, Mem, traceData);
             %(code)s;
             if (fault == NoFault) {
                 %(op_wb)s;
@@ -214,8 +214,7 @@ def template StoreExecute {{
             }
             if (storeCond && fault == NoFault) {
                 %(EA_trunc)s
-                fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
-                        EA, %(asi_val)s, 0);
+                fault = writeMemAtomic(xc, traceData, Mem, EA, %(asi_val)s, 0);
             }
             if (fault == NoFault) {
                 // Write the resulting state to the execution context
@@ -245,8 +244,7 @@ def template StoreInitiateAcc {{
             }
             if (storeCond && fault == NoFault) {
                 %(EA_trunc)s
-                fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
-                        EA, %(asi_val)s, 0);
+                fault = writeMemTiming(xc, traceData, Mem, EA, %(asi_val)s, 0);
             }
             return fault;
         }
index 885cd9cc23ea749749de835ceedb49746653ea10..db36777527d8320e2317900f390c9aa5682bd430 100644 (file)
@@ -70,6 +70,7 @@ output exec {{
 #include <cmath>
 #include <limits>
 
+#include "arch/generic/memhelpers.hh"
 #include "arch/sparc/asi.hh"
 #include "base/bigint.hh"
 #include "cpu/base.hh"
index 5487655e26b287115782f3b8b3e0fa045ffbeb4d..c618bc128a61ccde575510376996715b437e3e3d 100644 (file)
@@ -97,73 +97,6 @@ namespace X86ISA
 
         std::string generateDisassembly(Addr pc,
             const SymbolTable *symtab) const;
-
-        template<class Context, class MemType>
-        Fault read(Context *xc, Addr EA, MemType & Mem, unsigned flags) const
-        {
-            Fault fault = NoFault;
-            switch(dataSize)
-            {
-              case 1:
-                fault = xc->read(EA, (uint8_t&)Mem, flags);
-                break;
-              case 2:
-                fault = xc->read(EA, (uint16_t&)Mem, flags);
-                break;
-              case 4:
-                fault = xc->read(EA, (uint32_t&)Mem, flags);
-                break;
-              case 8:
-                fault = xc->read(EA, (uint64_t&)Mem, flags);
-                break;
-              default:
-                panic("Bad operand size %d for read at %#x.\n", dataSize, EA);
-            }
-            return fault;
-        }
-
-        template<class Context, class MemType>
-        Fault write(Context *xc, MemType & Mem, Addr EA, unsigned flags) const
-        {
-            Fault fault = NoFault;
-            switch(dataSize)
-            {
-              case 1:
-                fault = xc->write((uint8_t&)Mem, EA, flags, 0);
-                break;
-              case 2:
-                fault = xc->write((uint16_t&)Mem, EA, flags, 0);
-                break;
-              case 4:
-                fault = xc->write((uint32_t&)Mem, EA, flags, 0);
-                break;
-              case 8:
-                fault = xc->write((uint64_t&)Mem, EA, flags, 0);
-                break;
-              default:
-                panic("Bad operand size %d for write at %#x.\n", dataSize, EA);
-            }
-            return fault;
-        }
-
-        uint64_t
-        get(PacketPtr pkt) const
-        {
-            switch(dataSize)
-            {
-              case 1:
-                return pkt->get<uint8_t>();
-              case 2:
-                return pkt->get<uint16_t>();
-              case 4:
-                return pkt->get<uint32_t>();
-              case 8:
-                return pkt->get<uint64_t>();
-              default:
-                panic("Bad operand size %d for read at %#x.\n",
-                        dataSize, pkt->getAddr());
-            }
-        }
     };
 }
 
index 8d4af6829501a4d0ff65ac729d52bb6d6b57e9f0..dc8abbc6631ba2fd574b5a918e58a83bab1bb07e 100644 (file)
@@ -112,6 +112,7 @@ output exec {{
 #include "arch/x86/regs/misc.hh"
 #include "arch/x86/cpuid.hh"
 #include "arch/x86/faults.hh"
+#include "arch/x86/memhelpers.hh"
 #include "arch/x86/tlb.hh"
 #include "base/bigint.hh"
 #include "base/compiler.hh"
index f7a38b4864f6882a70aebaac75477636cdc75e0c..c88161f34d48f9d969d84f02eddc4163e001adb6 100644 (file)
@@ -98,7 +98,7 @@ def template MicroLoadExecute {{
         %(ea_code)s;
         DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
 
-        fault = read(xc, EA, Mem, memFlags);
+        fault = readMemAtomic(xc, traceData, EA, Mem, dataSize, memFlags);
 
         if (fault == NoFault) {
             %(code)s;
@@ -127,7 +127,7 @@ def template MicroLoadInitiateAcc {{
         %(ea_code)s;
         DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
 
-        fault = read(xc, EA, Mem, memFlags);
+        fault = readMemTiming(xc, traceData, EA, Mem, dataSize, memFlags);
 
         return fault;
     }
@@ -143,7 +143,7 @@ def template MicroLoadCompleteAcc {{
         %(op_decl)s;
         %(op_rd)s;
 
-        Mem = get(pkt);
+        Mem = getMem(pkt, dataSize, traceData);
 
         %(code)s;
 
@@ -174,7 +174,8 @@ def template MicroStoreExecute {{
 
         if(fault == NoFault)
         {
-            fault = write(xc, Mem, EA, memFlags);
+            fault = writeMemAtomic(xc, traceData, Mem, dataSize, EA,
+                    memFlags, NULL);
             if(fault == NoFault)
             {
                 %(op_wb)s;
@@ -201,7 +202,8 @@ def template MicroStoreInitiateAcc {{
 
         if(fault == NoFault)
         {
-            fault = write(xc, Mem, EA, memFlags);
+            fault = writeMemTiming(xc, traceData, Mem, dataSize, EA,
+                    memFlags, NULL);
         }
         return fault;
     }
diff --git a/src/arch/x86/memhelpers.hh b/src/arch/x86/memhelpers.hh
new file mode 100644 (file)
index 0000000..9dd54b9
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2011 Google
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __ARCH_X86_MEMHELPERS_HH__
+#define __ARCH_X86_MEMHELPERS_HH__
+
+#include "base/types.hh"
+#include "sim/byteswap.hh"
+#include "sim/fault_fwd.hh"
+#include "sim/insttracer.hh"
+
+namespace X86ISA
+{
+
+template <class XC>
+Fault
+readMemTiming(XC *xc, Trace::InstRecord *traceData, Addr addr,
+        uint64_t &mem, unsigned dataSize, unsigned flags)
+{
+    return xc->readBytes(addr, (uint8_t *)&mem, dataSize, flags);
+}
+
+static inline uint64_t
+getMem(PacketPtr pkt, unsigned dataSize, Trace::InstRecord *traceData)
+{
+    uint64_t mem;
+    switch (dataSize) {
+      case 1:
+        mem = pkt->get<uint8_t>();
+        break;
+      case 2:
+        mem = pkt->get<uint16_t>();
+        break;
+      case 4:
+        mem = pkt->get<uint32_t>();
+        break;
+      case 8:
+        mem = pkt->get<uint64_t>();
+        break;
+      default:
+        panic("Unhandled size in getMem.\n");
+    }
+    if (traceData)
+        traceData->setData(mem);
+    return mem;
+}
+
+template <class XC>
+Fault
+readMemAtomic(XC *xc, Trace::InstRecord *traceData, Addr addr, uint64_t &mem,
+        unsigned dataSize, unsigned flags)
+{
+    memset(&mem, 0, sizeof(mem));
+    Fault fault = readMemTiming(xc, traceData, addr, mem, dataSize, flags);
+    if (fault == NoFault) {
+        // If LE to LE, this is a nop, if LE to BE, the actual data ends up
+        // in the right place because the LSBs where at the low addresses on
+        // access. This doesn't work for BE guests.
+        mem = gtoh(mem);
+        if (traceData)
+            traceData->setData(mem);
+    }
+    return fault;
+}
+
+template <class XC>
+Fault
+writeMemTiming(XC *xc, Trace::InstRecord *traceData, uint64_t mem,
+        unsigned dataSize, Addr addr, unsigned flags, uint64_t *res)
+{
+    if (traceData) {
+        traceData->setData(mem);
+    }
+    mem = TheISA::htog(mem);
+    return xc->writeBytes((uint8_t *)&mem, dataSize, addr, flags, res);
+}
+
+template <class XC>
+Fault
+writeMemAtomic(XC *xc, Trace::InstRecord *traceData, uint64_t mem,
+        unsigned dataSize, Addr addr, unsigned flags, uint64_t *res)
+{
+    Fault fault = writeMemTiming(xc, traceData, mem, dataSize, addr, flags,
+            res);
+    if (fault == NoFault && res != NULL) {
+        *res = gtoh(*res);
+    }
+    return fault;
+}
+
+}
+
+#endif