#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"
%(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;
}
%(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;
%(fp_enable_check)s;
%(op_decl)s;
- Mem = pkt->get<typeof(Mem)>();
+ getMem(pkt, Mem, traceData);
if (fault == NoFault) {
%(memacc_code)s;
}
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) {
}
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) {
}
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;
#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)
%(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) {
%(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);
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;
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;
}
}
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) {
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) {
}
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);
}
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);
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);
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;
--- /dev/null
+/*
+ * 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
%(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;
}
%(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;
%(op_decl)s;
%(op_rd)s;
- Mem = pkt->get<typeof(Mem)>();
+ getMem(pkt, Mem, traceData);
if (fault == NoFault) {
%(memacc_code)s;
}
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) {
}
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) {
}
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) {
}
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;
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) = \
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"
%(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;
}
%(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);
}
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) {
}
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) {
}
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
#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"
}
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
}
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;
}
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
%(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;
%(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;
}
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;
}
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
}
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;
}
#include <cmath>
#include <limits>
+#include "arch/generic/memhelpers.hh"
#include "arch/sparc/asi.hh"
#include "base/bigint.hh"
#include "cpu/base.hh"
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());
- }
- }
};
}
#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"
%(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;
%(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;
}
%(op_decl)s;
%(op_rd)s;
- Mem = get(pkt);
+ Mem = getMem(pkt, dataSize, traceData);
%(code)s;
if(fault == NoFault)
{
- fault = write(xc, Mem, EA, memFlags);
+ fault = writeMemAtomic(xc, traceData, Mem, dataSize, EA,
+ memFlags, NULL);
if(fault == NoFault)
{
%(op_wb)s;
if(fault == NoFault)
{
- fault = write(xc, Mem, EA, memFlags);
+ fault = writeMemTiming(xc, traceData, Mem, dataSize, EA,
+ memFlags, NULL);
}
return fault;
}
--- /dev/null
+/*
+ * 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